From d4ddef84f94fba501e2ac6ee0a9c13b6d8a9ae03 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 6 May 2013 17:40:33 -0500 Subject: [PATCH] --- yaml --- r: 375615 b: refs/heads/master c: bbea1c1a31b1128d34b2b5b4f28276969cce14e9 h: refs/heads/master i: 375613: 0dbdd4e3fa80560021d4e65872fa166b0433a141 375611: 641d5bdb13e9074ae73bc7ee16a8caddf9626603 375607: fed14519956019065b858b0505dc54190979cce0 375599: abdb5783b6378892c01c18ffba8e6b9332f9cdf4 375583: d8609cee5c18c9caaf3bbf0789458d5c060757e7 375551: ce0d482f90f30a5b407ff5adbf308cd28b7453c0 v: v3 --- [refs] | 2 +- trunk/drivers/block/rbd.c | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index ab87148b1da6..98da4a3ac38b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 02c74fbad9d4a5149756eb35be7300736e4904e9 +refs/heads/master: bbea1c1a31b1128d34b2b5b4f28276969cce14e9 diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index 4edcb6d85f01..5c2731859e8a 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -2319,7 +2319,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) struct rbd_device *rbd_dev; struct page **pages; u32 page_count; - int result; + int img_result; u64 parent_length; u64 offset; u64 length; @@ -2338,7 +2338,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(obj_request_type_valid(orig_request->type)); - result = img_request->result; + img_result = img_request->result; parent_length = img_request->length; rbd_assert(parent_length == img_request->xferred); rbd_img_request_put(img_request); @@ -2347,7 +2347,22 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) rbd_dev = orig_request->img_request->rbd_dev; rbd_assert(rbd_dev); - if (result) + /* + * 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. + */ + if (!rbd_dev->parent_overlap) { + struct ceph_osd_client *osdc; + + ceph_release_page_vector(pages, page_count); + osdc = &rbd_dev->rbd_client->client->osdc; + img_result = rbd_obj_request_submit(osdc, orig_request); + if (!img_result) + return; + } + + if (img_result) goto out_err; /* @@ -2356,7 +2371,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) * request. Allocate the new copyup osd request for the * original request, and release the old one. */ - result = -ENOMEM; + img_result = -ENOMEM; osd_req = rbd_osd_req_create_copyup(orig_request); if (!osd_req) goto out_err; @@ -2391,13 +2406,13 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) orig_request->callback = rbd_img_obj_copyup_callback; osdc = &rbd_dev->rbd_client->client->osdc; - result = rbd_obj_request_submit(osdc, orig_request); - if (!result) + img_result = rbd_obj_request_submit(osdc, orig_request); + if (!img_result) return; out_err: /* Record the error code and complete the request */ - orig_request->result = result; + orig_request->result = img_result; orig_request->xferred = 0; obj_request_done_set(orig_request); rbd_obj_request_complete(orig_request);