summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-11 01:29:22 +0400
committerAlex Elder <elder@inktank.com>2013-05-13 23:12:40 +0400
commitb91f09f17b2a302f07022e2f766969e2536d71b3 (patch)
treeeb26ac4e2aa995cf45c2c6bdbbd4d62b49f1dc24 /drivers/block
parentebda6408f2227a774343c3cc2861384942143ff3 (diff)
downloadlinux-b91f09f17b2a302f07022e2f766969e2536d71b3.tar.xz
rbd: support reading parent page data for writes
Currently, rbd_img_obj_parent_read_full() assumes the incoming object request contains bio data. But if a layered image is part of a multi-layer stack of images it will result in read requests of page data to parent images. This is handling the same kind of issue as was resolved by this commit: 5b2ab72d rbd: support reading parent page data This resolves: http://tracker.ceph.com/issues/5027 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.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 597b9bbe2fc7..5161e80a38ef 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2165,6 +2165,8 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
u32 page_count;
int result;
u64 parent_length;
+ u64 offset;
+ u64 length;
rbd_assert(img_request_child_test(img_request));
@@ -2179,7 +2181,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
orig_request = img_request->obj_request;
rbd_assert(orig_request != NULL);
- rbd_assert(orig_request->type == OBJ_REQUEST_BIO);
+ rbd_assert(obj_request_type_valid(orig_request->type));
result = img_request->result;
parent_length = img_request->length;
rbd_assert(parent_length == img_request->xferred);
@@ -2211,11 +2213,17 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
/* Then the original write request op */
+ offset = orig_request->offset;
+ length = orig_request->length;
osd_req_op_extent_init(osd_req, 1, CEPH_OSD_OP_WRITE,
- orig_request->offset,
- orig_request->length, 0, 0);
- osd_req_op_extent_osd_data_bio(osd_req, 1, orig_request->bio_list,
- orig_request->length);
+ offset, length, 0, 0);
+ if (orig_request->type == OBJ_REQUEST_BIO)
+ osd_req_op_extent_osd_data_bio(osd_req, 1,
+ orig_request->bio_list, length);
+ else
+ osd_req_op_extent_osd_data_pages(osd_req, 1,
+ orig_request->pages, length,
+ offset & ~PAGE_MASK, false, false);
rbd_osd_req_format_write(orig_request);
@@ -2261,7 +2269,7 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
int result;
rbd_assert(obj_request_img_data_test(obj_request));
- rbd_assert(obj_request->type == OBJ_REQUEST_BIO);
+ rbd_assert(obj_request_type_valid(obj_request->type));
img_request = obj_request->img_request;
rbd_assert(img_request != NULL);