Blob Blame History Raw
From d9050368d1fa334186417398720cc8a6098ffdec Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Wed, 21 Jun 2017 01:42:27 +0200
Subject: [PATCH 3/4] rbd: copy compare-and-write osd requests before
 resubmission
Patch-mainline: Not yet, clustered LIO/RBD
References: bsc#1042210

This is similar to the osd_client request_reinit() logic used for linger
requests.

Signed-off-by: David Disseldorp <ddiss@suse.de>
Acked-by: Luis Henriques <lhenriques@suse.com>
---
 drivers/block/rbd.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3023,7 +3023,9 @@ static void
 rbd_img_obj_creatrunc_callback(struct rbd_obj_request *obj_request)
 {
 	struct rbd_obj_request *orig_request;
+	static struct ceph_osd_request *new_osd_req;
 	int result;
+	struct rbd_device *rbd_dev;
 
 	rbd_assert(!obj_request_img_data_test(obj_request));
 
@@ -3036,6 +3038,8 @@ rbd_img_obj_creatrunc_callback(struct rb
 	rbd_obj_request_put(orig_request);
 	rbd_assert(orig_request);
 	rbd_assert(orig_request->img_request);
+	rbd_dev = orig_request->img_request->rbd_dev;
+	rbd_assert(rbd_dev);
 
 	result = obj_request->result;
 	obj_request->result = 0;
@@ -3044,6 +3048,7 @@ rbd_img_obj_creatrunc_callback(struct rb
 		obj_request, orig_request, result,
 		obj_request->xferred, obj_request->length);
 	rbd_obj_request_put(obj_request);
+	obj_request = NULL;
 
 	if (result) {
 		orig_request->result = result;
@@ -3051,6 +3056,23 @@ rbd_img_obj_creatrunc_callback(struct rb
 	}
 
 	/*
+	 * We can't resubmit the original request without reinitialisation, as
+	 * the r_tid has been assigned, and reply filled.
+	 */
+	new_osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_CMP_AND_WRITE, 3,
+				     orig_request);
+	if (!new_osd_req) {
+		orig_request->result = -ENOMEM;
+		goto out;
+	}
+
+	rbd_osd_cmp_and_write_req_copy(new_osd_req, orig_request->osd_req);
+	ceph_osdc_put_request(orig_request->osd_req);
+	orig_request->osd_req = new_osd_req;
+
+	rbd_osd_req_format_rw(orig_request);
+
+	/*
 	 * Resubmit the original request now that we have truncated
 	 * the target object.
 	 */