summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder2012-11-20 05:55:21 +0100
committerAlex Elder2013-01-17 23:34:58 +0100
commit8d23bf29095e5fab84535035e7a27c4920812c44 (patch)
treec3b9b07fecc29a27798bd4ed5332f0fb2523bcb0 /drivers/block
parentrbd: don't assign extent info in rbd_do_request() (diff)
downloadkernel-qcow2-linux-8d23bf29095e5fab84535035e7a27c4920812c44.tar.gz
kernel-qcow2-linux-8d23bf29095e5fab84535035e7a27c4920812c44.tar.xz
kernel-qcow2-linux-8d23bf29095e5fab84535035e7a27c4920812c44.zip
rbd: don't assign extent info in rbd_req_sync_op()
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>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c72
1 files changed, 46 insertions, 26 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index c6917b11800b..235cda083137 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -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;