rbd: use helpers to handle discard for layered images correctly
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 <josh.durgin@inktank.com>
This commit is contained in:
parent
3b434a2aff
commit
d3246fb0da
1 changed files with 22 additions and 32 deletions
|
@ -1934,9 +1934,10 @@ static struct ceph_osd_request *rbd_osd_req_create(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a copyup osd request based on the information in the
|
* Create a copyup osd request based on the information in the object
|
||||||
* object request supplied. A copyup request has three osd ops,
|
* request supplied. A copyup request has two or three osd ops, a
|
||||||
* a copyup method call, a hint op, and a write op.
|
* copyup method call, potentially a hint op, and a write or truncate
|
||||||
|
* or zero op.
|
||||||
*/
|
*/
|
||||||
static struct ceph_osd_request *
|
static struct ceph_osd_request *
|
||||||
rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
|
rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
|
||||||
|
@ -1946,18 +1947,24 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
|
||||||
struct rbd_device *rbd_dev;
|
struct rbd_device *rbd_dev;
|
||||||
struct ceph_osd_client *osdc;
|
struct ceph_osd_client *osdc;
|
||||||
struct ceph_osd_request *osd_req;
|
struct ceph_osd_request *osd_req;
|
||||||
|
int num_osd_ops = 3;
|
||||||
|
|
||||||
rbd_assert(obj_request_img_data_test(obj_request));
|
rbd_assert(obj_request_img_data_test(obj_request));
|
||||||
img_request = obj_request->img_request;
|
img_request = obj_request->img_request;
|
||||||
rbd_assert(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;
|
snapc = img_request->snapc;
|
||||||
rbd_dev = img_request->rbd_dev;
|
rbd_dev = img_request->rbd_dev;
|
||||||
osdc = &rbd_dev->rbd_client->client->osdc;
|
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)
|
if (!osd_req)
|
||||||
return NULL; /* ENOMEM */
|
return NULL; /* ENOMEM */
|
||||||
|
|
||||||
|
@ -2337,10 +2344,9 @@ static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
|
||||||
u16 opcode;
|
u16 opcode;
|
||||||
|
|
||||||
if (op_type == OBJ_OP_DISCARD) {
|
if (op_type == OBJ_OP_DISCARD) {
|
||||||
if (!offset && (length == object_size)
|
if (!offset && length == object_size &&
|
||||||
&& (!img_request_layered_test(img_request) ||
|
(!img_request_layered_test(img_request) ||
|
||||||
(rbd_dev->parent_overlap <=
|
!obj_request_overlaps_parent(obj_request))) {
|
||||||
obj_request->img_offset))) {
|
|
||||||
opcode = CEPH_OSD_OP_DELETE;
|
opcode = CEPH_OSD_OP_DELETE;
|
||||||
} else if ((offset + length == object_size)) {
|
} else if ((offset + length == object_size)) {
|
||||||
opcode = CEPH_OSD_OP_TRUNCATE;
|
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||||
|
@ -2500,7 +2506,8 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
u32 page_count;
|
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));
|
rbd_assert(obj_request_img_data_test(obj_request));
|
||||||
img_request = obj_request->img_request;
|
img_request = obj_request->img_request;
|
||||||
rbd_assert(img_request);
|
rbd_assert(img_request);
|
||||||
|
@ -2538,11 +2545,10 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
|
||||||
struct ceph_osd_client *osdc;
|
struct ceph_osd_client *osdc;
|
||||||
struct rbd_device *rbd_dev;
|
struct rbd_device *rbd_dev;
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
|
enum obj_operation_type op_type;
|
||||||
u32 page_count;
|
u32 page_count;
|
||||||
int img_result;
|
int img_result;
|
||||||
u64 parent_length;
|
u64 parent_length;
|
||||||
u64 offset;
|
|
||||||
u64 length;
|
|
||||||
|
|
||||||
rbd_assert(img_request_child_test(img_request));
|
rbd_assert(img_request_child_test(img_request));
|
||||||
|
|
||||||
|
@ -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,
|
osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0,
|
||||||
false, false);
|
false, false);
|
||||||
|
|
||||||
/* Then the hint op */
|
/* Add the other op(s) */
|
||||||
|
|
||||||
osd_req_op_alloc_hint_init(osd_req, 1, rbd_obj_bytes(&rbd_dev->header),
|
op_type = rbd_img_request_op_type(orig_request->img_request);
|
||||||
rbd_obj_bytes(&rbd_dev->header));
|
rbd_img_obj_request_fill(orig_request, osd_req, op_type, 1);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
rbd_osd_req_format_write(orig_request);
|
|
||||||
|
|
||||||
/* All set, send it off. */
|
/* All set, send it off. */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue