aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-06 18:40:33 -0400
committerAlex Elder <elder@inktank.com>2013-05-13 16:06:45 -0400
commitbbea1c1a31b1128d34b2b5b4f28276969cce14e9 (patch)
treeae03ff03715c9b6617e6d6761ece79bb27af6b5a /drivers/block
parent02c74fbad9d4a5149756eb35be7300736e4904e9 (diff)
rbd: re-submit write request for flattened clone
Add code to rbd_img_parent_read_full_callback() to detect when a clone's parent image has disappeared, and re-submit the original write request in that case. (See the previous commit for more reasoning about why this is appropriate.) Rename some variables in rbd_img_obj_parent_read_full_callback() to match the convention used in the previous patch. 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.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4edcb6d85f01..5c2731859e8a 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2319,7 +2319,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2319 struct rbd_device *rbd_dev; 2319 struct rbd_device *rbd_dev;
2320 struct page **pages; 2320 struct page **pages;
2321 u32 page_count; 2321 u32 page_count;
2322 int result; 2322 int img_result;
2323 u64 parent_length; 2323 u64 parent_length;
2324 u64 offset; 2324 u64 offset;
2325 u64 length; 2325 u64 length;
@@ -2338,7 +2338,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2338 orig_request = img_request->obj_request; 2338 orig_request = img_request->obj_request;
2339 rbd_assert(orig_request != NULL); 2339 rbd_assert(orig_request != NULL);
2340 rbd_assert(obj_request_type_valid(orig_request->type)); 2340 rbd_assert(obj_request_type_valid(orig_request->type));
2341 result = img_request->result; 2341 img_result = img_request->result;
2342 parent_length = img_request->length; 2342 parent_length = img_request->length;
2343 rbd_assert(parent_length == img_request->xferred); 2343 rbd_assert(parent_length == img_request->xferred);
2344 rbd_img_request_put(img_request); 2344 rbd_img_request_put(img_request);
@@ -2347,7 +2347,22 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2347 rbd_dev = orig_request->img_request->rbd_dev; 2347 rbd_dev = orig_request->img_request->rbd_dev;
2348 rbd_assert(rbd_dev); 2348 rbd_assert(rbd_dev);
2349 2349
2350 if (result) 2350 /*
2351 * If the overlap has become 0 (most likely because the
2352 * image has been flattened) we need to free the pages
2353 * and re-submit the original write request.
2354 */
2355 if (!rbd_dev->parent_overlap) {
2356 struct ceph_osd_client *osdc;
2357
2358 ceph_release_page_vector(pages, page_count);
2359 osdc = &rbd_dev->rbd_client->client->osdc;
2360 img_result = rbd_obj_request_submit(osdc, orig_request);
2361 if (!img_result)
2362 return;
2363 }
2364
2365 if (img_result)
2351 goto out_err; 2366 goto out_err;
2352 2367
2353 /* 2368 /*
@@ -2356,7 +2371,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2356 * request. Allocate the new copyup osd request for the 2371 * request. Allocate the new copyup osd request for the
2357 * original request, and release the old one. 2372 * original request, and release the old one.
2358 */ 2373 */
2359 result = -ENOMEM; 2374 img_result = -ENOMEM;
2360 osd_req = rbd_osd_req_create_copyup(orig_request); 2375 osd_req = rbd_osd_req_create_copyup(orig_request);
2361 if (!osd_req) 2376 if (!osd_req)
2362 goto out_err; 2377 goto out_err;
@@ -2391,13 +2406,13 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2391 2406
2392 orig_request->callback = rbd_img_obj_copyup_callback; 2407 orig_request->callback = rbd_img_obj_copyup_callback;
2393 osdc = &rbd_dev->rbd_client->client->osdc; 2408 osdc = &rbd_dev->rbd_client->client->osdc;
2394 result = rbd_obj_request_submit(osdc, orig_request); 2409 img_result = rbd_obj_request_submit(osdc, orig_request);
2395 if (!result) 2410 if (!img_result)
2396 return; 2411 return;
2397out_err: 2412out_err:
2398 /* Record the error code and complete the request */ 2413 /* Record the error code and complete the request */
2399 2414
2400 orig_request->result = result; 2415 orig_request->result = img_result;
2401 orig_request->xferred = 0; 2416 orig_request->xferred = 0;
2402 obj_request_done_set(orig_request); 2417 obj_request_done_set(orig_request);
2403 rbd_obj_request_complete(orig_request); 2418 rbd_obj_request_complete(orig_request);