aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Durgin <josh.durgin@inktank.com>2014-04-07 19:49:21 -0400
committerIlya Dryomov <idryomov@redhat.com>2014-10-14 13:03:36 -0400
commitd3246fb0da5d70838469c01d5b6b11163b49cd86 (patch)
tree1770ff1c699df0469a02d5cabd7060afa810b9e2
parent3b434a2aff38029ea053ce6c8fced53b2d01f7f0 (diff)
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>
-rw-r--r--drivers/block/rbd.c54
1 files changed, 22 insertions, 32 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index c07cb1dbc1c5..e1dcd36ae072 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1934,9 +1934,10 @@ static struct ceph_osd_request *rbd_osd_req_create(
1934} 1934}
1935 1935
1936/* 1936/*
1937 * Create a copyup osd request based on the information in the 1937 * Create a copyup osd request based on the information in the object
1938 * object request supplied. A copyup request has three osd ops, 1938 * request supplied. A copyup request has two or three osd ops, a
1939 * a copyup method call, a hint op, and a write op. 1939 * copyup method call, potentially a hint op, and a write or truncate
1940 * or zero op.
1940 */ 1941 */
1941static struct ceph_osd_request * 1942static struct ceph_osd_request *
1942rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request) 1943rbd_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)
1946 struct rbd_device *rbd_dev; 1947 struct rbd_device *rbd_dev;
1947 struct ceph_osd_client *osdc; 1948 struct ceph_osd_client *osdc;
1948 struct ceph_osd_request *osd_req; 1949 struct ceph_osd_request *osd_req;
1950 int num_osd_ops = 3;
1949 1951
1950 rbd_assert(obj_request_img_data_test(obj_request)); 1952 rbd_assert(obj_request_img_data_test(obj_request));
1951 img_request = obj_request->img_request; 1953 img_request = obj_request->img_request;
1952 rbd_assert(img_request); 1954 rbd_assert(img_request);
1953 rbd_assert(img_request_write_test(img_request)); 1955 rbd_assert(img_request_write_test(img_request) ||
1956 img_request_discard_test(img_request));
1954 1957
1955 /* Allocate and initialize the request, for the three ops */ 1958 if (img_request_discard_test(img_request))
1959 num_osd_ops = 2;
1960
1961 /* Allocate and initialize the request, for all the ops */
1956 1962
1957 snapc = img_request->snapc; 1963 snapc = img_request->snapc;
1958 rbd_dev = img_request->rbd_dev; 1964 rbd_dev = img_request->rbd_dev;
1959 osdc = &rbd_dev->rbd_client->client->osdc; 1965 osdc = &rbd_dev->rbd_client->client->osdc;
1960 osd_req = ceph_osdc_alloc_request(osdc, snapc, 3, false, GFP_ATOMIC); 1966 osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops,
1967 false, GFP_ATOMIC);
1961 if (!osd_req) 1968 if (!osd_req)
1962 return NULL; /* ENOMEM */ 1969 return NULL; /* ENOMEM */
1963 1970
@@ -2337,10 +2344,9 @@ static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
2337 u16 opcode; 2344 u16 opcode;
2338 2345
2339 if (op_type == OBJ_OP_DISCARD) { 2346 if (op_type == OBJ_OP_DISCARD) {
2340 if (!offset && (length == object_size) 2347 if (!offset && length == object_size &&
2341 && (!img_request_layered_test(img_request) || 2348 (!img_request_layered_test(img_request) ||
2342 (rbd_dev->parent_overlap <= 2349 !obj_request_overlaps_parent(obj_request))) {
2343 obj_request->img_offset))) {
2344 opcode = CEPH_OSD_OP_DELETE; 2350 opcode = CEPH_OSD_OP_DELETE;
2345 } else if ((offset + length == object_size)) { 2351 } else if ((offset + length == object_size)) {
2346 opcode = CEPH_OSD_OP_TRUNCATE; 2352 opcode = CEPH_OSD_OP_TRUNCATE;
@@ -2500,7 +2506,8 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
2500 struct page **pages; 2506 struct page **pages;
2501 u32 page_count; 2507 u32 page_count;
2502 2508
2503 rbd_assert(obj_request->type == OBJ_REQUEST_BIO); 2509 rbd_assert(obj_request->type == OBJ_REQUEST_BIO ||
2510 obj_request->type == OBJ_REQUEST_NODATA);
2504 rbd_assert(obj_request_img_data_test(obj_request)); 2511 rbd_assert(obj_request_img_data_test(obj_request));
2505 img_request = obj_request->img_request; 2512 img_request = obj_request->img_request;
2506 rbd_assert(img_request); 2513 rbd_assert(img_request);
@@ -2538,11 +2545,10 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2538 struct ceph_osd_client *osdc; 2545 struct ceph_osd_client *osdc;
2539 struct rbd_device *rbd_dev; 2546 struct rbd_device *rbd_dev;
2540 struct page **pages; 2547 struct page **pages;
2548 enum obj_operation_type op_type;
2541 u32 page_count; 2549 u32 page_count;
2542 int img_result; 2550 int img_result;
2543 u64 parent_length; 2551 u64 parent_length;
2544 u64 offset;
2545 u64 length;
2546 2552
2547 rbd_assert(img_request_child_test(img_request)); 2553 rbd_assert(img_request_child_test(img_request));
2548 2554
@@ -2606,26 +2612,10 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
2606 osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0, 2612 osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0,
2607 false, false); 2613 false, false);
2608 2614
2609 /* Then the hint op */ 2615 /* Add the other op(s) */
2610
2611 osd_req_op_alloc_hint_init(osd_req, 1, rbd_obj_bytes(&rbd_dev->header),
2612 rbd_obj_bytes(&rbd_dev->header));
2613
2614 /* And the original write request op */
2615
2616 offset = orig_request->offset;
2617 length = orig_request->length;
2618 osd_req_op_extent_init(osd_req, 2, CEPH_OSD_OP_WRITE,
2619 offset, length, 0, 0);
2620 if (orig_request->type == OBJ_REQUEST_BIO)
2621 osd_req_op_extent_osd_data_bio(osd_req, 2,
2622 orig_request->bio_list, length);
2623 else
2624 osd_req_op_extent_osd_data_pages(osd_req, 2,
2625 orig_request->pages, length,
2626 offset & ~PAGE_MASK, false, false);
2627 2616
2628 rbd_osd_req_format_write(orig_request); 2617 op_type = rbd_img_request_op_type(orig_request->img_request);
2618 rbd_img_obj_request_fill(orig_request, osd_req, op_type, 1);
2629 2619
2630 /* All set, send it off. */ 2620 /* All set, send it off. */
2631 2621