aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 9717e20f3477..4edcb6d85f01 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2682,14 +2682,36 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
2682 struct rbd_obj_request *obj_request; 2682 struct rbd_obj_request *obj_request;
2683 struct rbd_device *rbd_dev; 2683 struct rbd_device *rbd_dev;
2684 u64 obj_end; 2684 u64 obj_end;
2685 u64 img_xferred;
2686 int img_result;
2685 2687
2686 rbd_assert(img_request_child_test(img_request)); 2688 rbd_assert(img_request_child_test(img_request));
2687 2689
2690 /* First get what we need from the image request and release it */
2691
2688 obj_request = img_request->obj_request; 2692 obj_request = img_request->obj_request;
2693 img_xferred = img_request->xferred;
2694 img_result = img_request->result;
2695 rbd_img_request_put(img_request);
2696
2697 /*
2698 * If the overlap has become 0 (most likely because the
2699 * image has been flattened) we need to re-submit the
2700 * original request.
2701 */
2689 rbd_assert(obj_request); 2702 rbd_assert(obj_request);
2690 rbd_assert(obj_request->img_request); 2703 rbd_assert(obj_request->img_request);
2704 rbd_dev = obj_request->img_request->rbd_dev;
2705 if (!rbd_dev->parent_overlap) {
2706 struct ceph_osd_client *osdc;
2707
2708 osdc = &rbd_dev->rbd_client->client->osdc;
2709 img_result = rbd_obj_request_submit(osdc, obj_request);
2710 if (!img_result)
2711 return;
2712 }
2691 2713
2692 obj_request->result = img_request->result; 2714 obj_request->result = img_result;
2693 if (obj_request->result) 2715 if (obj_request->result)
2694 goto out; 2716 goto out;
2695 2717
@@ -2702,7 +2724,6 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
2702 */ 2724 */
2703 rbd_assert(obj_request->img_offset < U64_MAX - obj_request->length); 2725 rbd_assert(obj_request->img_offset < U64_MAX - obj_request->length);
2704 obj_end = obj_request->img_offset + obj_request->length; 2726 obj_end = obj_request->img_offset + obj_request->length;
2705 rbd_dev = obj_request->img_request->rbd_dev;
2706 if (obj_end > rbd_dev->parent_overlap) { 2727 if (obj_end > rbd_dev->parent_overlap) {
2707 u64 xferred = 0; 2728 u64 xferred = 0;
2708 2729
@@ -2710,12 +2731,11 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
2710 xferred = rbd_dev->parent_overlap - 2731 xferred = rbd_dev->parent_overlap -
2711 obj_request->img_offset; 2732 obj_request->img_offset;
2712 2733
2713 obj_request->xferred = min(img_request->xferred, xferred); 2734 obj_request->xferred = min(img_xferred, xferred);
2714 } else { 2735 } else {
2715 obj_request->xferred = img_request->xferred; 2736 obj_request->xferred = img_xferred;
2716 } 2737 }
2717out: 2738out:
2718 rbd_img_request_put(img_request);
2719 rbd_img_obj_request_read_callback(obj_request); 2739 rbd_img_obj_request_read_callback(obj_request);
2720 rbd_obj_request_complete(obj_request); 2740 rbd_obj_request_complete(obj_request);
2721} 2741}