diff options
author | Josh Durgin <josh.durgin@inktank.com> | 2014-04-07 19:49:21 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@redhat.com> | 2014-10-14 13:03:36 -0400 |
commit | d3246fb0da5d70838469c01d5b6b11163b49cd86 (patch) | |
tree | 1770ff1c699df0469a02d5cabd7060afa810b9e2 | |
parent | 3b434a2aff38029ea053ce6c8fced53b2d01f7f0 (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.c | 54 |
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 | */ |
1941 | static struct ceph_osd_request * | 1942 | static struct ceph_osd_request * |
1942 | rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request) | 1943 | 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) | |||
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 | ||