summaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2018-01-29 14:04:08 +0100
committerIlya Dryomov <idryomov@gmail.com>2018-04-02 10:12:40 +0200
commit51c3509e5e167cf0fdc82c81f4d85da46b1ee1ee (patch)
tree0e9e218474ae17bbb1635d2e5e7eeed579ca6f9a /drivers/block/rbd.c
parent3da691bf436690c4bb943d5d16e5934937625578 (diff)
downloadlinux-stable-51c3509e5e167cf0fdc82c81f4d85da46b1ee1ee.tar.gz
linux-stable-51c3509e5e167cf0fdc82c81f4d85da46b1ee1ee.tar.bz2
linux-stable-51c3509e5e167cf0fdc82c81f4d85da46b1ee1ee.zip
rbd: remove old request handling code
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c734
1 files changed, 4 insertions, 730 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 1bffad122dc2..e7e99e7fd874 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -231,8 +231,6 @@ enum obj_operation_type {
enum obj_req_flags {
OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */
OBJ_REQ_IMG_DATA, /* object usage: standalone = 0, image = 1 */
- OBJ_REQ_KNOWN, /* EXISTS flag valid: no = 0, yes = 1 */
- OBJ_REQ_EXISTS, /* target exists: no = 0, yes = 1 */
};
/*
@@ -271,27 +269,15 @@ struct rbd_obj_request {
* An object request associated with an image will have its
* img_data flag set; a standalone object request will not.
*
- * A standalone object request will have which == BAD_WHICH
- * and a null obj_request pointer.
- *
- * An object request initiated in support of a layered image
- * object (to check for its existence before a write) will
- * have which == BAD_WHICH and a non-null obj_request pointer.
- *
* Finally, an object request for rbd image data will have
* which != BAD_WHICH, and will have a non-null img_request
* pointer. The value of which will be in the range
* 0..(img_request->obj_request_count-1).
*/
- union {
- struct rbd_obj_request *obj_request; /* STAT op */
- struct {
- struct rbd_img_request *img_request;
- u64 img_offset;
- /* links for img_request->obj_requests list */
- struct list_head links;
- };
- };
+ struct rbd_img_request *img_request;
+ u64 img_offset;
+ /* links for img_request->obj_requests list */
+ struct list_head links;
u32 which; /* posn image request list */
enum obj_request_type type;
@@ -480,8 +466,6 @@ static bool single_major = true;
module_param(single_major, bool, S_IRUGO);
MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (default: true)");
-static int rbd_img_request_submit(struct rbd_img_request *img_request);
-
static ssize_t rbd_add(struct bus_type *bus, const char *buf,
size_t count);
static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
@@ -610,9 +594,6 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...)
# define rbd_assert(expr) ((void) 0)
#endif /* !RBD_DEBUG */
-static void rbd_osd_copyup_callback(struct rbd_obj_request *obj_request);
-static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request);
-static void rbd_img_parent_read(struct rbd_obj_request *obj_request);
static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
static int rbd_dev_refresh(struct rbd_device *rbd_dev);
@@ -1369,37 +1350,6 @@ static bool obj_request_done_test(struct rbd_obj_request *obj_request)
return test_bit(OBJ_REQ_DONE, &obj_request->flags) != 0;
}
-/*
- * This sets the KNOWN flag after (possibly) setting the EXISTS
- * flag. The latter is set based on the "exists" value provided.
- *
- * Note that for our purposes once an object exists it never goes
- * away again. It's possible that the response from two existence
- * checks are separated by the creation of the target object, and
- * the first ("doesn't exist") response arrives *after* the second
- * ("does exist"). In that case we ignore the second one.
- */
-static void obj_request_existence_set(struct rbd_obj_request *obj_request,
- bool exists)
-{
- if (exists)
- set_bit(OBJ_REQ_EXISTS, &obj_request->flags);
- set_bit(OBJ_REQ_KNOWN, &obj_request->flags);
- smp_mb();
-}
-
-static bool obj_request_known_test(struct rbd_obj_request *obj_request)
-{
- smp_mb();
- return test_bit(OBJ_REQ_KNOWN, &obj_request->flags) != 0;
-}
-
-static bool obj_request_exists_test(struct rbd_obj_request *obj_request)
-{
- smp_mb();
- return test_bit(OBJ_REQ_EXISTS, &obj_request->flags) != 0;
-}
-
static bool obj_request_overlaps_parent(struct rbd_obj_request *obj_request)
{
struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
@@ -1643,42 +1593,6 @@ static bool rbd_img_is_write(struct rbd_img_request *img_req)
}
}
-static void
-rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
-{
- u64 xferred = obj_request->xferred;
- u64 length = obj_request->length;
-
- dout("%s: obj %p img %p result %d %llu/%llu\n", __func__,
- obj_request, obj_request->img_request, obj_request->result,
- xferred, length);
- /*
- * ENOENT means a hole in the image. We zero-fill the entire
- * length of the request. A short read also implies zero-fill
- * to the end of the request. An error requires the whole
- * length of the request to be reported finished with an error
- * to the block layer. In each case we update the xferred
- * count to indicate the whole request was satisfied.
- */
- rbd_assert(obj_request->type != OBJ_REQUEST_NODATA);
- if (obj_request->result == -ENOENT) {
- if (obj_request->type == OBJ_REQUEST_BIO)
- zero_bios(&obj_request->bio_pos, 0, length);
- else
- zero_bvecs(&obj_request->bvec_pos, 0, length);
- obj_request->result = 0;
- } else if (xferred < length && !obj_request->result) {
- if (obj_request->type == OBJ_REQUEST_BIO)
- zero_bios(&obj_request->bio_pos, xferred,
- length - xferred);
- else
- zero_bvecs(&obj_request->bvec_pos, xferred,
- length - xferred);
- }
- obj_request->xferred = length;
- obj_request_done_set(obj_request);
-}
-
static void rbd_obj_request_complete(struct rbd_obj_request *obj_request)
{
dout("%s: obj %p cb %p\n", __func__, obj_request,
@@ -1686,93 +1600,6 @@ static void rbd_obj_request_complete(struct rbd_obj_request *obj_request)
obj_request->callback(obj_request);
}
-static void rbd_obj_request_error(struct rbd_obj_request *obj_request, int err)
-{
- obj_request->result = err;
- obj_request->xferred = 0;
- /*
- * kludge - mirror rbd_obj_request_submit() to match a put in
- * rbd_img_obj_callback()
- */
- if (obj_request_img_data_test(obj_request)) {
- WARN_ON(obj_request->callback != rbd_img_obj_callback);
- rbd_img_request_get(obj_request->img_request);
- }
- obj_request_done_set(obj_request);
- rbd_obj_request_complete(obj_request);
-}
-
-static void rbd_osd_read_callback(struct rbd_obj_request *obj_request)
-{
- struct rbd_img_request *img_request = NULL;
- struct rbd_device *rbd_dev = NULL;
- bool layered = false;
-
- if (obj_request_img_data_test(obj_request)) {
- img_request = obj_request->img_request;
- layered = img_request && img_request_layered_test(img_request);
- rbd_dev = img_request->rbd_dev;
- }
-
- dout("%s: obj %p img %p result %d %llu/%llu\n", __func__,
- obj_request, img_request, obj_request->result,
- obj_request->xferred, obj_request->length);
- if (layered && obj_request->result == -ENOENT &&
- obj_request->img_offset < rbd_dev->parent_overlap)
- rbd_img_parent_read(obj_request);
- else if (img_request)
- rbd_img_obj_request_read_callback(obj_request);
- else
- obj_request_done_set(obj_request);
-}
-
-static void rbd_osd_write_callback(struct rbd_obj_request *obj_request)
-{
- dout("%s: obj %p result %d %llu\n", __func__, obj_request,
- obj_request->result, obj_request->length);
- /*
- * There is no such thing as a successful short write. Set
- * it to our originally-requested length.
- */
- obj_request->xferred = obj_request->length;
- obj_request_done_set(obj_request);
-}
-
-static void rbd_osd_discard_callback(struct rbd_obj_request *obj_request)
-{
- dout("%s: obj %p result %d %llu\n", __func__, obj_request,
- obj_request->result, obj_request->length);
- /*
- * There is no such thing as a successful short discard. Set
- * it to our originally-requested length.
- */
- obj_request->xferred = obj_request->length;
- /* discarding a non-existent object is not a problem */
- if (obj_request->result == -ENOENT)
- obj_request->result = 0;
- obj_request_done_set(obj_request);
-}
-
-/*
- * For a simple stat call there's nothing to do. We'll do more if
- * this is part of a write sequence for a layered image.
- */
-static void rbd_osd_stat_callback(struct rbd_obj_request *obj_request)
-{
- dout("%s: obj %p\n", __func__, obj_request);
- obj_request_done_set(obj_request);
-}
-
-static void rbd_osd_call_callback(struct rbd_obj_request *obj_request)
-{
- dout("%s: obj %p\n", __func__, obj_request);
-
- if (obj_request_img_data_test(obj_request))
- rbd_osd_copyup_callback(obj_request);
- else
- obj_request_done_set(obj_request);
-}
-
static void rbd_obj_handle_request(struct rbd_obj_request *obj_req);
static void rbd_osd_req_callback(struct ceph_osd_request *osd_req)
@@ -1871,32 +1698,6 @@ static struct ceph_osd_request *rbd_osd_req_create(
CEPH_OSD_FLAG_WRITE : CEPH_OSD_FLAG_READ, obj_request);
}
-/*
- * Create a copyup osd request based on the information in the object
- * request supplied. A copyup request has two or three osd ops, a
- * copyup method call, potentially a hint op, and a write or truncate
- * or zero op.
- */
-static struct ceph_osd_request *
-rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
-{
- struct rbd_img_request *img_request;
- int num_osd_ops = 3;
-
- rbd_assert(obj_request_img_data_test(obj_request));
- img_request = obj_request->img_request;
- rbd_assert(img_request);
- rbd_assert(img_request_write_test(img_request) ||
- img_request_discard_test(img_request));
-
- if (img_request_discard_test(img_request))
- num_osd_ops = 2;
-
- return __rbd_osd_req_create(img_request->rbd_dev,
- img_request->snapc, num_osd_ops,
- CEPH_OSD_FLAG_WRITE, obj_request);
-}
-
static void rbd_osd_req_destroy(struct ceph_osd_request *osd_req)
{
ceph_osdc_put_request(osd_req);
@@ -2217,73 +2018,6 @@ out:
rbd_img_request_complete(img_request);
}
-/*
- * Add individual osd ops to the given ceph_osd_request and prepare
- * them for submission. num_ops is the current number of
- * osd operations already to the object request.
- */
-static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
- struct ceph_osd_request *osd_request,
- enum obj_operation_type op_type,
- unsigned int num_ops)
-{
- struct rbd_img_request *img_request = obj_request->img_request;
- struct rbd_device *rbd_dev = img_request->rbd_dev;
- u64 object_size = rbd_obj_bytes(&rbd_dev->header);
- u64 offset = obj_request->offset;
- u64 length = obj_request->length;
- u64 img_end;
- u16 opcode;
-
- if (op_type == OBJ_OP_DISCARD) {
- if (!offset && length == object_size &&
- (!img_request_layered_test(img_request) ||
- !obj_request_overlaps_parent(obj_request))) {
- opcode = CEPH_OSD_OP_DELETE;
- } else if ((offset + length == object_size)) {
- opcode = CEPH_OSD_OP_TRUNCATE;
- } else {
- down_read(&rbd_dev->header_rwsem);
- img_end = rbd_dev->header.image_size;
- up_read(&rbd_dev->header_rwsem);
-
- if (obj_request->img_offset + length == img_end)
- opcode = CEPH_OSD_OP_TRUNCATE;
- else
- opcode = CEPH_OSD_OP_ZERO;
- }
- } else if (op_type == OBJ_OP_WRITE) {
- if (!offset && length == object_size)
- opcode = CEPH_OSD_OP_WRITEFULL;
- else
- opcode = CEPH_OSD_OP_WRITE;
- osd_req_op_alloc_hint_init(osd_request, num_ops,
- object_size, object_size);
- num_ops++;
- } else {
- opcode = CEPH_OSD_OP_READ;
- }
-
- if (opcode == CEPH_OSD_OP_DELETE)
- osd_req_op_init(osd_request, num_ops, opcode, 0);
- else
- osd_req_op_extent_init(osd_request, num_ops, opcode,
- offset, length, 0, 0);
-
- if (obj_request->type == OBJ_REQUEST_BIO)
- osd_req_op_extent_osd_data_bio(osd_request, num_ops,
- &obj_request->bio_pos, length);
- else if (obj_request->type == OBJ_REQUEST_BVECS)
- osd_req_op_extent_osd_data_bvec_pos(osd_request, num_ops,
- &obj_request->bvec_pos);
-
- /* Discards are also writes */
- if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
- rbd_osd_req_format_write(obj_request);
- else
- rbd_osd_req_format_read(obj_request);
-}
-
static void rbd_osd_req_setup_data(struct rbd_obj_request *obj_req, u32 which)
{
switch (obj_req->type) {
@@ -2568,366 +2302,6 @@ out_unwind:
return -ENOMEM;
}
-static void
-rbd_osd_copyup_callback(struct rbd_obj_request *obj_request)
-{
- struct rbd_img_request *img_request;
- struct rbd_device *rbd_dev;
-
- dout("%s: obj %p\n", __func__, obj_request);
-
- rbd_assert(obj_request->type == OBJ_REQUEST_BIO ||
- obj_request->type == OBJ_REQUEST_NODATA);
- rbd_assert(obj_request_img_data_test(obj_request));
- img_request = obj_request->img_request;
- rbd_assert(img_request);
-
- rbd_dev = img_request->rbd_dev;
- rbd_assert(rbd_dev);
-
- /*
- * We want the transfer count to reflect the size of the
- * original write request. There is no such thing as a
- * successful short write, so if the request was successful
- * we can just set it to the originally-requested length.
- */
- if (!obj_request->result)
- obj_request->xferred = obj_request->length;
-
- obj_request_done_set(obj_request);
-}
-
-static void
-rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
-{
- struct rbd_obj_request *orig_request;
- struct ceph_osd_request *osd_req;
- struct rbd_device *rbd_dev;
- enum obj_operation_type op_type;
- int img_result;
- u64 parent_length;
-
- rbd_assert(img_request_child_test(img_request));
-
- /* First get what we need from the image request */
-
- orig_request = img_request->obj_request;
- rbd_assert(orig_request != NULL);
- rbd_assert(obj_request_type_valid(orig_request->type));
- img_result = img_request->result;
- parent_length = img_request->length;
- rbd_assert(img_result || parent_length == img_request->xferred);
- rbd_img_request_put(img_request);
-
- rbd_assert(orig_request->img_request);
- rbd_dev = orig_request->img_request->rbd_dev;
- rbd_assert(rbd_dev);
-
- /*
- * 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) {
- rbd_obj_request_submit(orig_request);
- return;
- }
-
- if (img_result)
- goto out_err;
-
- /*
- * The original osd request is of no use to use any more.
- * We need a new one that can hold the three ops in a copyup
- * request. Allocate the new copyup osd request for the
- * original request, and release the old one.
- */
- img_result = -ENOMEM;
- osd_req = rbd_osd_req_create_copyup(orig_request);
- if (!osd_req)
- goto out_err;
- rbd_osd_req_destroy(orig_request->osd_req);
- orig_request->osd_req = osd_req;
-
- /* Initialize the copyup op */
-
- osd_req_op_cls_init(osd_req, 0, CEPH_OSD_OP_CALL, "rbd", "copyup");
- osd_req_op_cls_request_data_bvecs(osd_req, 0, orig_request->copyup_bvecs,
- parent_length);
-
- /* Add the other op(s) */
-
- op_type = rbd_img_request_op_type(orig_request->img_request);
- rbd_img_obj_request_fill(orig_request, osd_req, op_type, 1);
-
- /* All set, send it off. */
-
- rbd_obj_request_submit(orig_request);
- return;
-
-out_err:
- rbd_obj_request_error(orig_request, img_result);
-}
-
-static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap);
-
-/*
- * Read from the parent image the range of data that covers the
- * entire target of the given object request. This is used for
- * satisfying a layered image write request when the target of an
- * object request from the image request does not exist.
- *
- * A page array big enough to hold the returned data is allocated
- * and supplied to rbd_img_request_fill() as the "data descriptor."
- * When the read completes, this page array will be transferred to
- * the original object request for the copyup operation.
- *
- * If an error occurs, it is recorded as the result of the original
- * object request in rbd_img_obj_exists_callback().
- */
-static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
-{
- struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
- struct rbd_img_request *parent_request = NULL;
- struct ceph_bvec_iter bvec_it = { 0 };
- u64 img_offset;
- u64 length;
- int result;
-
- rbd_assert(rbd_dev->parent != NULL);
-
- /*
- * Determine the byte range covered by the object in the
- * child image to which the original request was to be sent.
- */
- img_offset = obj_request->img_offset - obj_request->offset;
- length = rbd_obj_bytes(&rbd_dev->header);
-
- /*
- * There is no defined parent data beyond the parent
- * overlap, so limit what we read at that boundary if
- * necessary.
- */
- if (img_offset + length > rbd_dev->parent_overlap) {
- rbd_assert(img_offset < rbd_dev->parent_overlap);
- length = rbd_dev->parent_overlap - img_offset;
- }
-
- /*
- * Allocate a page array big enough to receive the data read
- * from the parent.
- */
- result = setup_copyup_bvecs(obj_request, length);
- if (result)
- goto out_err;
-
- result = -ENOMEM;
- parent_request = rbd_parent_request_create(obj_request,
- img_offset, length);
- if (!parent_request)
- goto out_err;
-
- bvec_it.bvecs = obj_request->copyup_bvecs;
- bvec_it.iter.bi_size = length;
- result = rbd_img_request_fill(parent_request, OBJ_REQUEST_BVECS,
- &bvec_it);
- if (result)
- goto out_err;
-
- parent_request->callback = rbd_img_obj_parent_read_full_callback;
-
- result = rbd_img_request_submit(parent_request);
- if (!result)
- return 0;
-
-out_err:
- if (parent_request)
- rbd_img_request_put(parent_request);
- return result;
-}
-
-static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
-{
- struct rbd_obj_request *orig_request;
- struct rbd_device *rbd_dev;
- int result;
-
- rbd_assert(!obj_request_img_data_test(obj_request));
-
- /*
- * All we need from the object request is the original
- * request and the result of the STAT op. Grab those, then
- * we're done with the request.
- */
- orig_request = obj_request->obj_request;
- obj_request->obj_request = NULL;
- rbd_obj_request_put(orig_request);
- rbd_assert(orig_request);
- rbd_assert(orig_request->img_request);
-
- result = obj_request->result;
- obj_request->result = 0;
-
- dout("%s: obj %p for obj %p result %d %llu/%llu\n", __func__,
- obj_request, orig_request, result,
- obj_request->xferred, obj_request->length);
- rbd_obj_request_put(obj_request);
-
- /*
- * If the overlap has become 0 (most likely because the
- * image has been flattened) we need to re-submit the
- * original request.
- */
- rbd_dev = orig_request->img_request->rbd_dev;
- if (!rbd_dev->parent_overlap) {
- rbd_obj_request_submit(orig_request);
- return;
- }
-
- /*
- * Our only purpose here is to determine whether the object
- * exists, and we don't want to treat the non-existence as
- * an error. If something else comes back, transfer the
- * error to the original request and complete it now.
- */
- if (!result) {
- obj_request_existence_set(orig_request, true);
- } else if (result == -ENOENT) {
- obj_request_existence_set(orig_request, false);
- } else {
- goto fail_orig_request;
- }
-
- /*
- * Resubmit the original request now that we have recorded
- * whether the target object exists.
- */
- result = rbd_img_obj_request_submit(orig_request);
- if (result)
- goto fail_orig_request;
-
- return;
-
-fail_orig_request:
- rbd_obj_request_error(orig_request, result);
-}
-
-static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
-{
- struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
- struct rbd_obj_request *stat_request;
- struct page **pages;
- int ret;
-
- stat_request = rbd_obj_request_create(OBJ_REQUEST_NODATA);
- if (!stat_request)
- return -ENOMEM;
-
- stat_request->object_no = obj_request->object_no;
-
- stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
- stat_request);
- if (!stat_request->osd_req) {
- ret = -ENOMEM;
- goto fail_stat_request;
- }
-
- /*
- * The response data for a STAT call consists of:
- * le64 length;
- * struct {
- * le32 tv_sec;
- * le32 tv_nsec;
- * } mtime;
- */
- pages = ceph_alloc_page_vector(1, GFP_NOIO);
- if (IS_ERR(pages)) {
- ret = PTR_ERR(pages);
- goto fail_stat_request;
- }
-
- osd_req_op_init(stat_request->osd_req, 0, CEPH_OSD_OP_STAT, 0);
- osd_req_op_raw_data_in_pages(stat_request->osd_req, 0, pages,
- 8 + sizeof(struct ceph_timespec),
- 0, false, true);
-
- rbd_obj_request_get(obj_request);
- stat_request->obj_request = obj_request;
- stat_request->callback = rbd_img_obj_exists_callback;
-
- rbd_obj_request_submit(stat_request);
- return 0;
-
-fail_stat_request:
- rbd_obj_request_put(stat_request);
- return ret;
-}
-
-static bool img_obj_request_simple(struct rbd_obj_request *obj_request)
-{
- struct rbd_img_request *img_request = obj_request->img_request;
- struct rbd_device *rbd_dev = img_request->rbd_dev;
-
- /* Reads */
- if (!img_request_write_test(img_request) &&
- !img_request_discard_test(img_request))
- return true;
-
- /* Non-layered writes */
- if (!img_request_layered_test(img_request))
- return true;
-
- /*
- * Layered writes outside of the parent overlap range don't
- * share any data with the parent.
- */
- if (!obj_request_overlaps_parent(obj_request))
- return true;
-
- /*
- * Entire-object layered writes - we will overwrite whatever
- * parent data there is anyway.
- */
- if (!obj_request->offset &&
- obj_request->length == rbd_obj_bytes(&rbd_dev->header))
- return true;
-
- /*
- * If the object is known to already exist, its parent data has
- * already been copied.
- */
- if (obj_request_known_test(obj_request) &&
- obj_request_exists_test(obj_request))
- return true;
-
- return false;
-}
-
-static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request)
-{
- rbd_assert(obj_request_img_data_test(obj_request));
- rbd_assert(obj_request_type_valid(obj_request->type));
- rbd_assert(obj_request->img_request);
-
- if (img_obj_request_simple(obj_request)) {
- rbd_obj_request_submit(obj_request);
- return 0;
- }
-
- /*
- * It's a layered write. The target object might exist but
- * we may not know that yet. If we know it doesn't exist,
- * start by reading the data for the full target object from
- * the parent so we can use it for a copyup to the target.
- */
- if (obj_request_known_test(obj_request))
- return rbd_img_obj_parent_read_full(obj_request);
-
- /* We don't know whether the target exists. Go find out. */
-
- return rbd_img_obj_exists_submit(obj_request);
-}
-
static int rbd_img_request_submit(struct rbd_img_request *img_request)
{
struct rbd_obj_request *obj_request;
@@ -3131,106 +2505,6 @@ static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap)
return 0;
}
-static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
-{
- struct rbd_obj_request *obj_request;
- struct rbd_device *rbd_dev;
- u64 obj_end;
- u64 img_xferred;
- int img_result;
-
- rbd_assert(img_request_child_test(img_request));
-
- /* First get what we need from the image request and release it */
-
- obj_request = img_request->obj_request;
- img_xferred = img_request->xferred;
- img_result = img_request->result;
- rbd_img_request_put(img_request);
-
- /*
- * If the overlap has become 0 (most likely because the
- * image has been flattened) we need to re-submit the
- * original request.
- */
- rbd_assert(obj_request);
- rbd_assert(obj_request->img_request);
- rbd_dev = obj_request->img_request->rbd_dev;
- if (!rbd_dev->parent_overlap) {
- rbd_obj_request_submit(obj_request);
- return;
- }
-
- obj_request->result = img_result;
- if (obj_request->result)
- goto out;
-
- /*
- * We need to zero anything beyond the parent overlap
- * boundary. Since rbd_img_obj_request_read_callback()
- * will zero anything beyond the end of a short read, an
- * easy way to do this is to pretend the data from the
- * parent came up short--ending at the overlap boundary.
- */
- rbd_assert(obj_request->img_offset < U64_MAX - obj_request->length);
- obj_end = obj_request->img_offset + obj_request->length;
- if (obj_end > rbd_dev->parent_overlap) {
- u64 xferred = 0;
-
- if (obj_request->img_offset < rbd_dev->parent_overlap)
- xferred = rbd_dev->parent_overlap -
- obj_request->img_offset;
-
- obj_request->xferred = min(img_xferred, xferred);
- } else {
- obj_request->xferred = img_xferred;
- }
-out:
- rbd_img_obj_request_read_callback(obj_request);
- rbd_obj_request_complete(obj_request);
-}
-
-static void rbd_img_parent_read(struct rbd_obj_request *obj_request)
-{
- struct rbd_img_request *img_request;
- int result;
-
- rbd_assert(obj_request_img_data_test(obj_request));
- rbd_assert(obj_request->img_request != NULL);
- rbd_assert(obj_request->result == (s32) -ENOENT);
- rbd_assert(obj_request_type_valid(obj_request->type));
-
- /* rbd_read_finish(obj_request, obj_request->length); */
- img_request = rbd_parent_request_create(obj_request,
- obj_request->img_offset,
- obj_request->length);
- result = -ENOMEM;
- if (!img_request)
- goto out_err;
-
- if (obj_request->type == OBJ_REQUEST_BIO)
- result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
- &obj_request->bio_pos);
- else
- result = rbd_img_request_fill(img_request, OBJ_REQUEST_BVECS,
- &obj_request->bvec_pos);
- if (result)
- goto out_err;
-
- img_request->callback = rbd_img_parent_read_callback;
- result = rbd_img_request_submit(img_request);
- if (result)
- goto out_err;
-
- return;
-out_err:
- if (img_request)
- rbd_img_request_put(img_request);
- obj_request->result = result;
- obj_request->xferred = 0;
- obj_request_done_set(obj_request);
-}
-
static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
{
struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;