aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-11-19 23:55:21 -0500
committerAlex Elder <elder@inktank.com>2013-01-17 17:34:58 -0500
commit8d23bf29095e5fab84535035e7a27c4920812c44 (patch)
treec3b9b07fecc29a27798bd4ed5332f0fb2523bcb0 /drivers/block/rbd.c
parentc561191813e232aa52022532751855ff5c9fa319 (diff)
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/rbd.c')
-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:
1025 return NULL; 1025 return NULL;
1026} 1026}
1027 1027
1028static struct ceph_osd_req_op *rbd_create_rw_op(int opcode, u32 payload_len) 1028static struct ceph_osd_req_op *rbd_create_rw_op(int opcode, u64 ofs, u64 len)
1029{ 1029{
1030 struct ceph_osd_req_op *op; 1030 struct ceph_osd_req_op *op;
1031 1031
1032 op = kzalloc(sizeof (*op), GFP_NOIO); 1032 op = kzalloc(sizeof (*op), GFP_NOIO);
1033 if (!op) 1033 if (!op)
1034 return NULL; 1034 return NULL;
1035 /* 1035
1036 * op extent offset and length will be set later on
1037 * after ceph_calc_file_object_mapping().
1038 */
1039 op->op = opcode; 1036 op->op = opcode;
1040 op->payload_len = payload_len;
1041 1037
1042 return op; 1038 return op;
1043} 1039}
@@ -1047,6 +1043,42 @@ static void rbd_destroy_op(struct ceph_osd_req_op *op)
1047 kfree(op); 1043 kfree(op);
1048} 1044}
1049 1045
1046struct ceph_osd_req_op *rbd_osd_req_op_create(u16 opcode, ...)
1047{
1048 struct ceph_osd_req_op *op;
1049 va_list args;
1050
1051 op = kzalloc(sizeof (*op), GFP_NOIO);
1052 if (!op)
1053 return NULL;
1054 op->op = opcode;
1055 va_start(args, opcode);
1056 switch (opcode) {
1057 case CEPH_OSD_OP_READ:
1058 case CEPH_OSD_OP_WRITE:
1059 /* rbd_osd_req_op_create(READ, offset, length) */
1060 /* rbd_osd_req_op_create(WRITE, offset, length) */
1061 op->extent.offset = va_arg(args, u64);
1062 op->extent.length = va_arg(args, u64);
1063 if (opcode == CEPH_OSD_OP_WRITE)
1064 op->payload_len = op->extent.length;
1065 break;
1066 default:
1067 rbd_warn(NULL, "unsupported opcode %hu\n", opcode);
1068 kfree(op);
1069 op = NULL;
1070 break;
1071 }
1072 va_end(args);
1073
1074 return op;
1075}
1076
1077static void rbd_osd_req_op_destroy(struct ceph_osd_req_op *op)
1078{
1079 kfree(op);
1080}
1081
1050static void rbd_coll_end_req_index(struct request *rq, 1082static void rbd_coll_end_req_index(struct request *rq,
1051 struct rbd_req_coll *coll, 1083 struct rbd_req_coll *coll,
1052 int index, 1084 int index,
@@ -1262,13 +1294,6 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev,
1262 if (IS_ERR(pages)) 1294 if (IS_ERR(pages))
1263 return PTR_ERR(pages); 1295 return PTR_ERR(pages);
1264 1296
1265 if (op->op == CEPH_OSD_OP_READ || op->op == CEPH_OSD_OP_WRITE) {
1266 op->extent.offset = ofs;
1267 op->extent.length = inbound_size;
1268 if (op->op == CEPH_OSD_OP_WRITE)
1269 op->payload_len = inbound_size;
1270 }
1271
1272 ret = rbd_do_request(NULL, rbd_dev, NULL, CEPH_NOSNAP, 1297 ret = rbd_do_request(NULL, rbd_dev, NULL, CEPH_NOSNAP,
1273 object_name, ofs, inbound_size, NULL, 1298 object_name, ofs, inbound_size, NULL,
1274 pages, num_pages, 1299 pages, num_pages,
@@ -1304,7 +1329,6 @@ static int rbd_do_op(struct request *rq,
1304 u64 seg_len; 1329 u64 seg_len;
1305 int ret; 1330 int ret;
1306 struct ceph_osd_req_op *op; 1331 struct ceph_osd_req_op *op;
1307 u32 payload_len;
1308 int opcode; 1332 int opcode;
1309 int flags; 1333 int flags;
1310 u64 snapid; 1334 u64 snapid;
@@ -1319,22 +1343,17 @@ static int rbd_do_op(struct request *rq,
1319 opcode = CEPH_OSD_OP_WRITE; 1343 opcode = CEPH_OSD_OP_WRITE;
1320 flags = CEPH_OSD_FLAG_WRITE|CEPH_OSD_FLAG_ONDISK; 1344 flags = CEPH_OSD_FLAG_WRITE|CEPH_OSD_FLAG_ONDISK;
1321 snapid = CEPH_NOSNAP; 1345 snapid = CEPH_NOSNAP;
1322 payload_len = seg_len;
1323 } else { 1346 } else {
1324 opcode = CEPH_OSD_OP_READ; 1347 opcode = CEPH_OSD_OP_READ;
1325 flags = CEPH_OSD_FLAG_READ; 1348 flags = CEPH_OSD_FLAG_READ;
1326 rbd_assert(!snapc); 1349 rbd_assert(!snapc);
1327 snapid = rbd_dev->spec->snap_id; 1350 snapid = rbd_dev->spec->snap_id;
1328 payload_len = 0;
1329 } 1351 }
1330 1352
1331 ret = -ENOMEM; 1353 ret = -ENOMEM;
1332 op = rbd_create_rw_op(opcode, payload_len); 1354 op = rbd_osd_req_op_create(opcode, seg_ofs, seg_len);
1333 if (!op) 1355 if (!op)
1334 goto done; 1356 goto done;
1335 op->extent.offset = seg_ofs;
1336 op->extent.length = seg_len;
1337 op->payload_len = payload_len;
1338 1357
1339 /* we've taken care of segment sizes earlier when we 1358 /* we've taken care of segment sizes earlier when we
1340 cloned the bios. We should never have a segment 1359 cloned the bios. We should never have a segment
@@ -1352,7 +1371,7 @@ static int rbd_do_op(struct request *rq,
1352 if (ret < 0) 1371 if (ret < 0)
1353 rbd_coll_end_req_index(rq, coll, coll_index, 1372 rbd_coll_end_req_index(rq, coll, coll_index,
1354 (s32)ret, seg_len); 1373 (s32)ret, seg_len);
1355 rbd_destroy_op(op); 1374 rbd_osd_req_op_destroy(op);
1356done: 1375done:
1357 kfree(seg_name); 1376 kfree(seg_name);
1358 return ret; 1377 return ret;
@@ -1370,13 +1389,13 @@ static int rbd_req_sync_read(struct rbd_device *rbd_dev,
1370 struct ceph_osd_req_op *op; 1389 struct ceph_osd_req_op *op;
1371 int ret; 1390 int ret;
1372 1391
1373 op = rbd_create_rw_op(CEPH_OSD_OP_READ, 0); 1392 op = rbd_osd_req_op_create(CEPH_OSD_OP_READ, ofs, len);
1374 if (!op) 1393 if (!op)
1375 return -ENOMEM; 1394 return -ENOMEM;
1376 1395
1377 ret = rbd_req_sync_op(rbd_dev, CEPH_OSD_FLAG_READ, 1396 ret = rbd_req_sync_op(rbd_dev, CEPH_OSD_FLAG_READ,
1378 op, object_name, ofs, len, buf, NULL, ver); 1397 op, object_name, ofs, len, buf, NULL, ver);
1379 rbd_destroy_op(op); 1398 rbd_osd_req_op_destroy(op);
1380 1399
1381 return ret; 1400 return ret;
1382} 1401}
@@ -1391,7 +1410,7 @@ static int rbd_req_sync_notify_ack(struct rbd_device *rbd_dev,
1391 struct ceph_osd_req_op *op; 1410 struct ceph_osd_req_op *op;
1392 int ret; 1411 int ret;
1393 1412
1394 op = rbd_create_rw_op(CEPH_OSD_OP_NOTIFY_ACK, 0); 1413 op = rbd_create_rw_op(CEPH_OSD_OP_NOTIFY_ACK, 0, 0);
1395 if (!op) 1414 if (!op)
1396 return -ENOMEM; 1415 return -ENOMEM;
1397 1416
@@ -1442,7 +1461,7 @@ static int rbd_req_sync_watch(struct rbd_device *rbd_dev, int start)
1442 __le64 version = 0; 1461 __le64 version = 0;
1443 int ret; 1462 int ret;
1444 1463
1445 op = rbd_create_rw_op(CEPH_OSD_OP_WATCH, 0); 1464 op = rbd_create_rw_op(CEPH_OSD_OP_WATCH, 0, 0);
1446 if (!op) 1465 if (!op)
1447 return -ENOMEM; 1466 return -ENOMEM;
1448 1467
@@ -1505,9 +1524,10 @@ static int rbd_req_sync_exec(struct rbd_device *rbd_dev,
1505 * operation. 1524 * operation.
1506 */ 1525 */
1507 payload_size = class_name_len + method_name_len + outbound_size; 1526 payload_size = class_name_len + method_name_len + outbound_size;
1508 op = rbd_create_rw_op(CEPH_OSD_OP_CALL, payload_size); 1527 op = rbd_create_rw_op(CEPH_OSD_OP_CALL, 0, 0);
1509 if (!op) 1528 if (!op)
1510 return -ENOMEM; 1529 return -ENOMEM;
1530 op->payload_len = payload_size;
1511 1531
1512 op->cls.class_name = class_name; 1532 op->cls.class_name = class_name;
1513 op->cls.class_len = (__u8) class_name_len; 1533 op->cls.class_len = (__u8) class_name_len;