From: Alex Elder <elder@inktank.com>
Date: Fri, 10 May 2013 21:29:22 +0000 (-0500)
Subject: rbd: support reading parent page data for writes
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=b91f09f17b2a302f07022e2f766969e2536d71b3;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git

rbd: support reading parent page data for writes

Currently, rbd_img_obj_parent_read_full() assumes the incoming
object request contains bio data.  But if a layered image is part of
a multi-layer stack of images it will result in read requests of
page data to parent images.

This is handling the same kind of issue as was resolved by this
commit:
    5b2ab72d  rbd: support reading parent page data

This resolves:
    http://tracker.ceph.com/issues/5027

Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
---

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 597b9bbe2fc7..5161e80a38ef 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2165,6 +2165,8 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
 	u32 page_count;
 	int result;
 	u64 parent_length;
+	u64 offset;
+	u64 length;
 
 	rbd_assert(img_request_child_test(img_request));
 
@@ -2179,7 +2181,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(orig_request->type == OBJ_REQUEST_BIO);
+	rbd_assert(obj_request_type_valid(orig_request->type));
 	result = img_request->result;
 	parent_length = img_request->length;
 	rbd_assert(parent_length == img_request->xferred);
@@ -2211,11 +2213,17 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
 
 	/* Then the original write request op */
 
+	offset = orig_request->offset;
+	length = orig_request->length;
 	osd_req_op_extent_init(osd_req, 1, CEPH_OSD_OP_WRITE,
-					orig_request->offset,
-					orig_request->length, 0, 0);
-	osd_req_op_extent_osd_data_bio(osd_req, 1, orig_request->bio_list,
-					orig_request->length);
+					offset, length, 0, 0);
+	if (orig_request->type == OBJ_REQUEST_BIO)
+		osd_req_op_extent_osd_data_bio(osd_req, 1,
+					orig_request->bio_list, length);
+	else
+		osd_req_op_extent_osd_data_pages(osd_req, 1,
+					orig_request->pages, length,
+					offset & ~PAGE_MASK, false, false);
 
 	rbd_osd_req_format_write(orig_request);
 
@@ -2261,7 +2269,7 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
 	int result;
 
 	rbd_assert(obj_request_img_data_test(obj_request));
-	rbd_assert(obj_request->type == OBJ_REQUEST_BIO);
+	rbd_assert(obj_request_type_valid(obj_request->type));
 
 	img_request = obj_request->img_request;
 	rbd_assert(img_request != NULL);