diff options
| -rw-r--r-- | drivers/block/rbd.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index e1fa12b2ae2e..1222d583ac2c 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -1020,9 +1020,8 @@ static void rbd_simple_req_cb(struct ceph_osd_request *req, struct ceph_msg *msg | |||
| 1020 | static int rbd_req_sync_op(struct rbd_device *rbd_dev, | 1020 | static int rbd_req_sync_op(struct rbd_device *rbd_dev, |
| 1021 | struct ceph_snap_context *snapc, | 1021 | struct ceph_snap_context *snapc, |
| 1022 | u64 snapid, | 1022 | u64 snapid, |
| 1023 | int opcode, | ||
| 1024 | int flags, | 1023 | int flags, |
| 1025 | struct ceph_osd_req_op *orig_ops, | 1024 | struct ceph_osd_req_op *ops, |
| 1026 | const char *object_name, | 1025 | const char *object_name, |
| 1027 | u64 ofs, u64 len, | 1026 | u64 ofs, u64 len, |
| 1028 | char *buf, | 1027 | char *buf, |
| @@ -1032,28 +1031,14 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev, | |||
| 1032 | int ret; | 1031 | int ret; |
| 1033 | struct page **pages; | 1032 | struct page **pages; |
| 1034 | int num_pages; | 1033 | int num_pages; |
| 1035 | struct ceph_osd_req_op *ops = orig_ops; | 1034 | |
| 1036 | u32 payload_len; | 1035 | BUG_ON(ops == NULL); |
| 1037 | 1036 | ||
| 1038 | num_pages = calc_pages_for(ofs , len); | 1037 | num_pages = calc_pages_for(ofs , len); |
| 1039 | pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL); | 1038 | pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL); |
| 1040 | if (IS_ERR(pages)) | 1039 | if (IS_ERR(pages)) |
| 1041 | return PTR_ERR(pages); | 1040 | return PTR_ERR(pages); |
| 1042 | 1041 | ||
| 1043 | if (!orig_ops) { | ||
| 1044 | payload_len = (flags & CEPH_OSD_FLAG_WRITE ? len : 0); | ||
| 1045 | ret = -ENOMEM; | ||
| 1046 | ops = rbd_create_rw_ops(1, opcode, payload_len); | ||
| 1047 | if (!ops) | ||
| 1048 | goto done; | ||
| 1049 | |||
| 1050 | if ((flags & CEPH_OSD_FLAG_WRITE) && buf) { | ||
| 1051 | ret = ceph_copy_to_page_vector(pages, buf, ofs, len); | ||
| 1052 | if (ret < 0) | ||
| 1053 | goto done_ops; | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | ret = rbd_do_request(NULL, rbd_dev, snapc, snapid, | 1042 | ret = rbd_do_request(NULL, rbd_dev, snapc, snapid, |
| 1058 | object_name, ofs, len, NULL, | 1043 | object_name, ofs, len, NULL, |
| 1059 | pages, num_pages, | 1044 | pages, num_pages, |
| @@ -1063,14 +1048,11 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev, | |||
| 1063 | NULL, | 1048 | NULL, |
| 1064 | linger_req, ver); | 1049 | linger_req, ver); |
| 1065 | if (ret < 0) | 1050 | if (ret < 0) |
| 1066 | goto done_ops; | 1051 | goto done; |
| 1067 | 1052 | ||
| 1068 | if ((flags & CEPH_OSD_FLAG_READ) && buf) | 1053 | if ((flags & CEPH_OSD_FLAG_READ) && buf) |
| 1069 | ret = ceph_copy_from_page_vector(pages, buf, ofs, ret); | 1054 | ret = ceph_copy_from_page_vector(pages, buf, ofs, ret); |
| 1070 | 1055 | ||
| 1071 | done_ops: | ||
| 1072 | if (!orig_ops) | ||
| 1073 | rbd_destroy_ops(ops); | ||
| 1074 | done: | 1056 | done: |
| 1075 | ceph_release_page_vector(pages, num_pages); | 1057 | ceph_release_page_vector(pages, num_pages); |
| 1076 | return ret; | 1058 | return ret; |
| @@ -1177,12 +1159,20 @@ static int rbd_req_sync_read(struct rbd_device *rbd_dev, | |||
| 1177 | char *buf, | 1159 | char *buf, |
| 1178 | u64 *ver) | 1160 | u64 *ver) |
| 1179 | { | 1161 | { |
| 1180 | return rbd_req_sync_op(rbd_dev, NULL, | 1162 | struct ceph_osd_req_op *ops; |
| 1163 | int ret; | ||
| 1164 | |||
| 1165 | ops = rbd_create_rw_ops(1, CEPH_OSD_OP_READ, 0); | ||
| 1166 | if (!ops) | ||
| 1167 | return -ENOMEM; | ||
| 1168 | |||
| 1169 | ret = rbd_req_sync_op(rbd_dev, NULL, | ||
| 1181 | snapid, | 1170 | snapid, |
| 1182 | CEPH_OSD_OP_READ, | ||
| 1183 | CEPH_OSD_FLAG_READ, | 1171 | CEPH_OSD_FLAG_READ, |
| 1184 | NULL, | 1172 | ops, object_name, ofs, len, buf, NULL, ver); |
| 1185 | object_name, ofs, len, buf, NULL, ver); | 1173 | rbd_destroy_ops(ops); |
| 1174 | |||
| 1175 | return ret; | ||
| 1186 | } | 1176 | } |
| 1187 | 1177 | ||
| 1188 | /* | 1178 | /* |
| @@ -1262,7 +1252,6 @@ static int rbd_req_sync_watch(struct rbd_device *rbd_dev) | |||
| 1262 | 1252 | ||
| 1263 | ret = rbd_req_sync_op(rbd_dev, NULL, | 1253 | ret = rbd_req_sync_op(rbd_dev, NULL, |
| 1264 | CEPH_NOSNAP, | 1254 | CEPH_NOSNAP, |
| 1265 | 0, | ||
| 1266 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, | 1255 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, |
| 1267 | ops, | 1256 | ops, |
| 1268 | rbd_dev->header_name, | 1257 | rbd_dev->header_name, |
| @@ -1301,7 +1290,6 @@ static int rbd_req_sync_unwatch(struct rbd_device *rbd_dev) | |||
| 1301 | 1290 | ||
| 1302 | ret = rbd_req_sync_op(rbd_dev, NULL, | 1291 | ret = rbd_req_sync_op(rbd_dev, NULL, |
| 1303 | CEPH_NOSNAP, | 1292 | CEPH_NOSNAP, |
| 1304 | 0, | ||
| 1305 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, | 1293 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, |
| 1306 | ops, | 1294 | ops, |
| 1307 | rbd_dev->header_name, | 1295 | rbd_dev->header_name, |
| @@ -1360,7 +1348,6 @@ static int rbd_req_sync_notify(struct rbd_device *rbd_dev) | |||
| 1360 | 1348 | ||
| 1361 | ret = rbd_req_sync_op(rbd_dev, NULL, | 1349 | ret = rbd_req_sync_op(rbd_dev, NULL, |
| 1362 | CEPH_NOSNAP, | 1350 | CEPH_NOSNAP, |
| 1363 | 0, | ||
| 1364 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, | 1351 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, |
| 1365 | ops, | 1352 | ops, |
| 1366 | rbd_dev->header_name, | 1353 | rbd_dev->header_name, |
| @@ -1411,7 +1398,6 @@ static int rbd_req_sync_exec(struct rbd_device *rbd_dev, | |||
| 1411 | 1398 | ||
| 1412 | ret = rbd_req_sync_op(rbd_dev, NULL, | 1399 | ret = rbd_req_sync_op(rbd_dev, NULL, |
| 1413 | CEPH_NOSNAP, | 1400 | CEPH_NOSNAP, |
| 1414 | 0, | ||
| 1415 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, | 1401 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, |
| 1416 | ops, | 1402 | ops, |
| 1417 | object_name, 0, 0, NULL, NULL, ver); | 1403 | object_name, 0, 0, NULL, NULL, ver); |
