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>
This commit is contained in:
Alex Elder 2012-11-19 22:55:21 -06:00
parent c561191813
commit 8d23bf2909
1 changed files with 46 additions and 26 deletions

View 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;