diff options
author | Alex Elder <elder@inktank.com> | 2013-05-06 17:40:33 -0500 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2013-05-13 15:06:46 -0500 |
commit | 638f5abed3f7d8a7fc24087bd760fa3d99f68a39 (patch) | |
tree | 6a37c092f07923eb17f36a11c1a46b40e762aca0 /drivers/block | |
parent | bbea1c1a31b1128d34b2b5b4f28276969cce14e9 (diff) | |
download | op-kernel-dev-638f5abed3f7d8a7fc24087bd760fa3d99f68a39.zip op-kernel-dev-638f5abed3f7d8a7fc24087bd760fa3d99f68a39.tar.gz |
rbd: re-submit flattened write request (part 2)
Add code to rbd_img_obj_exists_callback() to detect when a clone's
parent image has disappeared, and re-submit the original write
request in that case.
Kill off some redundant assertions.
This completes the resolution for:
http://tracker.ceph.com/issues/3763
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.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 5c27318..6b872f2 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -2516,6 +2516,7 @@ out_err: static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request) { struct rbd_obj_request *orig_request; + struct rbd_device *rbd_dev; int result; rbd_assert(!obj_request_img_data_test(obj_request)); @@ -2538,8 +2539,21 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request) obj_request->xferred, obj_request->length); rbd_obj_request_put(obj_request); - rbd_assert(orig_request); - rbd_assert(orig_request->img_request); + /* + * If the overlap has become 0 (most likely because the + * image has been flattened) we need to free the pages + * and re-submit the original write request. + */ + rbd_dev = orig_request->img_request->rbd_dev; + if (!rbd_dev->parent_overlap) { + struct ceph_osd_client *osdc; + + rbd_obj_request_put(orig_request); + osdc = &rbd_dev->rbd_client->client->osdc; + result = rbd_obj_request_submit(osdc, orig_request); + if (!result) + return; + } /* * Our only purpose here is to determine whether the object |