aboutsummaryrefslogtreecommitdiffstats
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
commit02c74fbad9d4a5149756eb35be7300736e4904e9 (patch)
tree927c54fd4815af9d7fa5d10100618febe6f87642
parent392a9dad7e777296fe79d97a6b3acd735ad2eb5f (diff)
rbd: re-submit read request for flattened clone
If a clone image gets flattened while a parent read request is underway, the original rbd object request needs to be resubmitted. The reason is that by the time we get the response to the parent read request, the data read from the parent may be out of date. In other words, we could see this sequence of events: rbd client parent image/osd ---------- ---------------- original object ENOENT; issue parent read respond to parent read child image flattened original image header refresh <--- original object written independently here parent read response received Add code to rbd_img_parent_read_callback() to detect when a clone's parent image has disappeared (as evidenced by its parent overlap becoming 0), and re-submit the original read request in that case. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-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}