diff options
author | Alex Elder <elder@inktank.com> | 2013-05-06 18:40:33 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2013-05-13 16:06:45 -0400 |
commit | bbea1c1a31b1128d34b2b5b4f28276969cce14e9 (patch) | |
tree | ae03ff03715c9b6617e6d6761ece79bb27af6b5a /drivers/block | |
parent | 02c74fbad9d4a5149756eb35be7300736e4904e9 (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.c | 29 |
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; |
2397 | out_err: | 2412 | out_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); |