Skip to content

Commit

Permalink
rbd: use helpers to handle discard for layered images correctly
Browse files Browse the repository at this point in the history
Only allocate two osd ops for discard requests, since the
preallocation hint is only added for regular writes.  Use
rbd_img_obj_request_fill() to recreate the original write or discard
osd operations, isolating that logic to one place, and change the
assert in rbd_osd_req_create_copyup() to accept discard requests as
well.

Signed-off-by: Josh Durgin <[email protected]>
  • Loading branch information
jdurgin authored and idryomov committed Oct 14, 2014
1 parent 3b434a2 commit d3246fb
Showing 1 changed file with 22 additions and 32 deletions.
54 changes: 22 additions & 32 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1934,9 +1934,10 @@ static struct ceph_osd_request *rbd_osd_req_create(
}

/*
* Create a copyup osd request based on the information in the
* object request supplied. A copyup request has three osd ops,
* a copyup method call, a hint op, and a write op.
* 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)
Expand All @@ -1946,18 +1947,24 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
struct rbd_device *rbd_dev;
struct ceph_osd_client *osdc;
struct ceph_osd_request *osd_req;
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));
rbd_assert(img_request_write_test(img_request) ||
img_request_discard_test(img_request));

/* Allocate and initialize the request, for the three ops */
if (img_request_discard_test(img_request))
num_osd_ops = 2;

/* Allocate and initialize the request, for all the ops */

snapc = img_request->snapc;
rbd_dev = img_request->rbd_dev;
osdc = &rbd_dev->rbd_client->client->osdc;
osd_req = ceph_osdc_alloc_request(osdc, snapc, 3, false, GFP_ATOMIC);
osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops,
false, GFP_ATOMIC);
if (!osd_req)
return NULL; /* ENOMEM */

Expand Down Expand Up @@ -2337,10 +2344,9 @@ static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
u16 opcode;

if (op_type == OBJ_OP_DISCARD) {
if (!offset && (length == object_size)
&& (!img_request_layered_test(img_request) ||
(rbd_dev->parent_overlap <=
obj_request->img_offset))) {
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;
Expand Down Expand Up @@ -2500,7 +2506,8 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
struct page **pages;
u32 page_count;

rbd_assert(obj_request->type == OBJ_REQUEST_BIO);
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);
Expand Down Expand Up @@ -2538,11 +2545,10 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
struct ceph_osd_client *osdc;
struct rbd_device *rbd_dev;
struct page **pages;
enum obj_operation_type op_type;
u32 page_count;
int img_result;
u64 parent_length;
u64 offset;
u64 length;

rbd_assert(img_request_child_test(img_request));

Expand Down Expand Up @@ -2606,26 +2612,10 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0,
false, false);

/* Then the hint op */

osd_req_op_alloc_hint_init(osd_req, 1, rbd_obj_bytes(&rbd_dev->header),
rbd_obj_bytes(&rbd_dev->header));

/* And the original write request op */

offset = orig_request->offset;
length = orig_request->length;
osd_req_op_extent_init(osd_req, 2, CEPH_OSD_OP_WRITE,
offset, length, 0, 0);
if (orig_request->type == OBJ_REQUEST_BIO)
osd_req_op_extent_osd_data_bio(osd_req, 2,
orig_request->bio_list, length);
else
osd_req_op_extent_osd_data_pages(osd_req, 2,
orig_request->pages, length,
offset & ~PAGE_MASK, false, false);
/* Add the other op(s) */

rbd_osd_req_format_write(orig_request);
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. */

Expand Down

0 comments on commit d3246fb

Please sign in to comment.