]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
rbd: introduce rbd_obj_issue_copyup_ops()
authorIlya Dryomov <idryomov@gmail.com>
Thu, 28 Feb 2019 09:49:12 +0000 (10:49 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 5 Mar 2019 17:55:17 +0000 (18:55 +0100)
In preparation for deep-flatten feature, split rbd_obj_issue_copyup()
into two functions and add a new write state to make the state machine
slightly more clear.  Make the copyup op optional and start using that
for when the overlap goes to 0.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
drivers/block/rbd.c

index f9cad40d95afcc44f34a30510f698cde200294d6..aa95227fdee2d824872443a31d16f0718168e6de 100644 (file)
@@ -236,7 +236,8 @@ enum obj_operation_type {
 enum rbd_obj_write_state {
        RBD_OBJ_WRITE_FLAT = 1,
        RBD_OBJ_WRITE_GUARD,
-       RBD_OBJ_WRITE_COPYUP,
+       RBD_OBJ_WRITE_READ_FROM_PARENT,
+       RBD_OBJ_WRITE_COPYUP_OPS,
 };
 
 struct rbd_obj_request {
@@ -2458,10 +2459,13 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes)
        return true;
 }
 
-static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
+#define MODS_ONLY      U32_MAX
+
+static int rbd_obj_issue_copyup_ops(struct rbd_obj_request *obj_req, u32 bytes)
 {
        struct rbd_img_request *img_req = obj_req->img_request;
-       unsigned int num_osd_ops = 1;
+       unsigned int num_osd_ops = (bytes != MODS_ONLY);
+       unsigned int which = 0;
        int ret;
 
        dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes);
@@ -2483,31 +2487,25 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
        if (!obj_req->osd_req)
                return -ENOMEM;
 
-       ret = osd_req_op_cls_init(obj_req->osd_req, 0, "rbd", "copyup");
-       if (ret)
-               return ret;
+       if (bytes != MODS_ONLY) {
+               ret = osd_req_op_cls_init(obj_req->osd_req, which, "rbd",
+                                         "copyup");
+               if (ret)
+                       return ret;
 
-       /*
-        * Only send non-zero copyup data to save some I/O and network
-        * bandwidth -- zero copyup data is equivalent to the object not
-        * existing.
-        */
-       if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
-               dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
-               bytes = 0;
+               osd_req_op_cls_request_data_bvecs(obj_req->osd_req, which++,
+                                                 obj_req->copyup_bvecs,
+                                                 obj_req->copyup_bvec_count,
+                                                 bytes);
        }
-       osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0,
-                                         obj_req->copyup_bvecs,
-                                         obj_req->copyup_bvec_count,
-                                         bytes);
 
        switch (img_req->op_type) {
        case OBJ_OP_WRITE:
-               __rbd_obj_setup_write(obj_req, 1);
+               __rbd_obj_setup_write(obj_req, which);
                break;
        case OBJ_OP_ZEROOUT:
                rbd_assert(!rbd_obj_is_entire(obj_req));
-               __rbd_obj_setup_zeroout(obj_req, 1);
+               __rbd_obj_setup_zeroout(obj_req, which);
                break;
        default:
                rbd_assert(0);
@@ -2521,6 +2519,22 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
        return 0;
 }
 
+static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
+{
+       /*
+        * Only send non-zero copyup data to save some I/O and network
+        * bandwidth -- zero copyup data is equivalent to the object not
+        * existing.
+        */
+       if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
+               dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
+               bytes = 0;
+       }
+
+       obj_req->write_state = RBD_OBJ_WRITE_COPYUP_OPS;
+       return rbd_obj_issue_copyup_ops(obj_req, bytes);
+}
+
 static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap)
 {
        u32 i;
@@ -2560,22 +2574,19 @@ static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
        if (!obj_req->num_img_extents) {
                /*
                 * The overlap has become 0 (most likely because the
-                * image has been flattened).  Use rbd_obj_issue_copyup()
-                * to re-submit the original write request -- the copyup
-                * operation itself will be a no-op, since someone must
-                * have populated the child object while we weren't
-                * looking.  Move to WRITE_FLAT state as we'll be done
-                * with the operation once the null copyup completes.
+                * image has been flattened).  Re-submit the original write
+                * request -- pass MODS_ONLY since the copyup isn't needed
+                * anymore.
                 */
-               obj_req->write_state = RBD_OBJ_WRITE_FLAT;
-               return rbd_obj_issue_copyup(obj_req, 0);
+               obj_req->write_state = RBD_OBJ_WRITE_COPYUP_OPS;
+               return rbd_obj_issue_copyup_ops(obj_req, MODS_ONLY);
        }
 
        ret = setup_copyup_bvecs(obj_req, rbd_obj_img_extents_bytes(obj_req));
        if (ret)
                return ret;
 
-       obj_req->write_state = RBD_OBJ_WRITE_COPYUP;
+       obj_req->write_state = RBD_OBJ_WRITE_READ_FROM_PARENT;
        return rbd_obj_read_from_parent(obj_req);
 }
 
@@ -2583,7 +2594,6 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
 {
        int ret;
 
-again:
        switch (obj_req->write_state) {
        case RBD_OBJ_WRITE_GUARD:
                rbd_assert(!obj_req->xferred);
@@ -2602,6 +2612,7 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
                }
                /* fall through */
        case RBD_OBJ_WRITE_FLAT:
+       case RBD_OBJ_WRITE_COPYUP_OPS:
                if (!obj_req->result)
                        /*
                         * There is no such thing as a successful short
@@ -2609,10 +2620,9 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
                         */
                        obj_req->xferred = obj_req->ex.oe_len;
                return true;
-       case RBD_OBJ_WRITE_COPYUP:
-               obj_req->write_state = RBD_OBJ_WRITE_GUARD;
+       case RBD_OBJ_WRITE_READ_FROM_PARENT:
                if (obj_req->result)
-                       goto again;
+                       return true;
 
                rbd_assert(obj_req->xferred);
                ret = rbd_obj_issue_copyup(obj_req, obj_req->xferred);