rbd: don't assign extent info in rbd_req_sync_op()
authorAlex Elder <elder@inktank.com>
Tue, 20 Nov 2012 04:55:21 +0000 (22:55 -0600)
committerAlex Elder <elder@inktank.com>
Thu, 17 Jan 2013 22:34:58 +0000 (16:34 -0600)
Move the assignment of the extent offset and length and payload
length out of rbd_req_sync_op() and into its caller in the one spot
where a read (and note--no write) operation might be initiated.

Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
drivers/block/rbd.c

index c6917b11800ba1cadde8e1ba990e9cd3b10964fc..235cda083137221d6fef8db843cf63e68b9529b0 100644 (file)
@@ -1025,19 +1025,15 @@ out_err:
        return NULL;
 }
 
-static struct ceph_osd_req_op *rbd_create_rw_op(int opcode, u32 payload_len)
+static struct ceph_osd_req_op *rbd_create_rw_op(int opcode, u64 ofs, u64 len)
 {
        struct ceph_osd_req_op *op;
 
        op = kzalloc(sizeof (*op), GFP_NOIO);
        if (!op)
                return NULL;
-       /*
-        * op extent offset and length will be set later on
-        * after ceph_calc_file_object_mapping().
-        */
+
        op->op = opcode;
-       op->payload_len = payload_len;
 
        return op;
 }
@@ -1047,6 +1043,42 @@ static void rbd_destroy_op(struct ceph_osd_req_op *op)
        kfree(op);
 }
 
+struct ceph_osd_req_op *rbd_osd_req_op_create(u16 opcode, ...)
+{
+       struct ceph_osd_req_op *op;
+       va_list args;
+
+       op = kzalloc(sizeof (*op), GFP_NOIO);
+       if (!op)
+               return NULL;
+       op->op = opcode;
+       va_start(args, opcode);
+       switch (opcode) {
+       case CEPH_OSD_OP_READ:
+       case CEPH_OSD_OP_WRITE:
+               /* rbd_osd_req_op_create(READ, offset, length) */
+               /* rbd_osd_req_op_create(WRITE, offset, length) */
+               op->extent.offset = va_arg(args, u64);
+               op->extent.length = va_arg(args, u64);
+               if (opcode == CEPH_OSD_OP_WRITE)
+                       op->payload_len = op->extent.length;
+               break;
+       default:
+               rbd_warn(NULL, "unsupported opcode %hu\n", opcode);
+               kfree(op);
+               op = NULL;
+               break;
+       }
+       va_end(args);
+
+       return op;
+}
+
+static void rbd_osd_req_op_destroy(struct ceph_osd_req_op *op)
+{
+       kfree(op);
+}
+
 static void rbd_coll_end_req_index(struct request *rq,
                                   struct rbd_req_coll *coll,
                                   int index,
@@ -1262,13 +1294,6 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev,
        if (IS_ERR(pages))
                return PTR_ERR(pages);
 
-       if (op->op == CEPH_OSD_OP_READ || op->op == CEPH_OSD_OP_WRITE) {
-               op->extent.offset = ofs;
-               op->extent.length = inbound_size;
-               if (op->op == CEPH_OSD_OP_WRITE)
-                       op->payload_len = inbound_size;
-       }
-
        ret = rbd_do_request(NULL, rbd_dev, NULL, CEPH_NOSNAP,
                          object_name, ofs, inbound_size, NULL,
                          pages, num_pages,
@@ -1304,7 +1329,6 @@ static int rbd_do_op(struct request *rq,
        u64 seg_len;
        int ret;
        struct ceph_osd_req_op *op;
-       u32 payload_len;
        int opcode;
        int flags;
        u64 snapid;
@@ -1319,22 +1343,17 @@ static int rbd_do_op(struct request *rq,
                opcode = CEPH_OSD_OP_WRITE;
                flags = CEPH_OSD_FLAG_WRITE|CEPH_OSD_FLAG_ONDISK;
                snapid = CEPH_NOSNAP;
-               payload_len = seg_len;
        } else {
                opcode = CEPH_OSD_OP_READ;
                flags = CEPH_OSD_FLAG_READ;
                rbd_assert(!snapc);
                snapid = rbd_dev->spec->snap_id;
-               payload_len = 0;
        }
 
        ret = -ENOMEM;
-       op = rbd_create_rw_op(opcode, payload_len);
+       op = rbd_osd_req_op_create(opcode, seg_ofs, seg_len);
        if (!op)
                goto done;
-       op->extent.offset = seg_ofs;
-       op->extent.length = seg_len;
-       op->payload_len = payload_len;
 
        /* we've taken care of segment sizes earlier when we
           cloned the bios. We should never have a segment
@@ -1352,7 +1371,7 @@ static int rbd_do_op(struct request *rq,
        if (ret < 0)
                rbd_coll_end_req_index(rq, coll, coll_index,
                                        (s32)ret, seg_len);
-       rbd_destroy_op(op);
+       rbd_osd_req_op_destroy(op);
 done:
        kfree(seg_name);
        return ret;
@@ -1370,13 +1389,13 @@ static int rbd_req_sync_read(struct rbd_device *rbd_dev,
        struct ceph_osd_req_op *op;
        int ret;
 
-       op = rbd_create_rw_op(CEPH_OSD_OP_READ, 0);
+       op = rbd_osd_req_op_create(CEPH_OSD_OP_READ, ofs, len);
        if (!op)
                return -ENOMEM;
 
        ret = rbd_req_sync_op(rbd_dev, CEPH_OSD_FLAG_READ,
                               op, object_name, ofs, len, buf, NULL, ver);
-       rbd_destroy_op(op);
+       rbd_osd_req_op_destroy(op);
 
        return ret;
 }
@@ -1391,7 +1410,7 @@ static int rbd_req_sync_notify_ack(struct rbd_device *rbd_dev,
        struct ceph_osd_req_op *op;
        int ret;
 
-       op = rbd_create_rw_op(CEPH_OSD_OP_NOTIFY_ACK, 0);
+       op = rbd_create_rw_op(CEPH_OSD_OP_NOTIFY_ACK, 0, 0);
        if (!op)
                return -ENOMEM;
 
@@ -1442,7 +1461,7 @@ static int rbd_req_sync_watch(struct rbd_device *rbd_dev, int start)
        __le64 version = 0;
        int ret;
 
-       op = rbd_create_rw_op(CEPH_OSD_OP_WATCH, 0);
+       op = rbd_create_rw_op(CEPH_OSD_OP_WATCH, 0, 0);
        if (!op)
                return -ENOMEM;
 
@@ -1505,9 +1524,10 @@ static int rbd_req_sync_exec(struct rbd_device *rbd_dev,
         * operation.
         */
        payload_size = class_name_len + method_name_len + outbound_size;
-       op = rbd_create_rw_op(CEPH_OSD_OP_CALL, payload_size);
+       op = rbd_create_rw_op(CEPH_OSD_OP_CALL, 0, 0);
        if (!op)
                return -ENOMEM;
+       op->payload_len = payload_size;
 
        op->cls.class_name = class_name;
        op->cls.class_len = (__u8) class_name_len;