aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorJosh Durgin <josh.durgin@inktank.com>2014-04-04 20:32:15 -0400
committerIlya Dryomov <idryomov@redhat.com>2014-10-14 13:03:35 -0400
commit3b434a2aff38029ea053ce6c8fced53b2d01f7f0 (patch)
treef4055dab80a6681ee134c49844b81a0149262950 /drivers/block/rbd.c
parent1c220881e307b62cc2f77d911219de332aa3f61e (diff)
rbd: extract a method for adding object operations
rbd_img_request_fill() creates a ceph_osd_request and has logic for adding the appropriate osd ops to it based on the request type and image properties. For layered images, the original rbd_obj_request is resent with a copyup operation in front, using a new ceph_osd_request. The logic for adding the original operations should be the same as when first sending them, so move it to a helper function. op_type only needs to be checked once, so create a helper for that as well and call it outside the loop in rbd_img_request_fill(). Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c133
1 files changed, 78 insertions, 55 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 6fb93cd6957f..c07cb1dbc1c5 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1672,6 +1672,17 @@ static bool img_request_layered_test(struct rbd_img_request *img_request)
1672 return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0; 1672 return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0;
1673} 1673}
1674 1674
1675static enum obj_operation_type
1676rbd_img_request_op_type(struct rbd_img_request *img_request)
1677{
1678 if (img_request_write_test(img_request))
1679 return OBJ_OP_WRITE;
1680 else if (img_request_discard_test(img_request))
1681 return OBJ_OP_DISCARD;
1682 else
1683 return OBJ_OP_READ;
1684}
1685
1675static void 1686static void
1676rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request) 1687rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
1677{ 1688{
@@ -2308,6 +2319,68 @@ out:
2308} 2319}
2309 2320
2310/* 2321/*
2322 * Add individual osd ops to the given ceph_osd_request and prepare
2323 * them for submission. num_ops is the current number of
2324 * osd operations already to the object request.
2325 */
2326static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
2327 struct ceph_osd_request *osd_request,
2328 enum obj_operation_type op_type,
2329 unsigned int num_ops)
2330{
2331 struct rbd_img_request *img_request = obj_request->img_request;
2332 struct rbd_device *rbd_dev = img_request->rbd_dev;
2333 u64 object_size = rbd_obj_bytes(&rbd_dev->header);
2334 u64 offset = obj_request->offset;
2335 u64 length = obj_request->length;
2336 u64 img_end;
2337 u16 opcode;
2338
2339 if (op_type == OBJ_OP_DISCARD) {
2340 if (!offset && (length == object_size)
2341 && (!img_request_layered_test(img_request) ||
2342 (rbd_dev->parent_overlap <=
2343 obj_request->img_offset))) {
2344 opcode = CEPH_OSD_OP_DELETE;
2345 } else if ((offset + length == object_size)) {
2346 opcode = CEPH_OSD_OP_TRUNCATE;
2347 } else {
2348 down_read(&rbd_dev->header_rwsem);
2349 img_end = rbd_dev->header.image_size;
2350 up_read(&rbd_dev->header_rwsem);
2351
2352 if (obj_request->img_offset + length == img_end)
2353 opcode = CEPH_OSD_OP_TRUNCATE;
2354 else
2355 opcode = CEPH_OSD_OP_ZERO;
2356 }
2357 } else if (op_type == OBJ_OP_WRITE) {
2358 opcode = CEPH_OSD_OP_WRITE;
2359 osd_req_op_alloc_hint_init(osd_request, num_ops,
2360 object_size, object_size);
2361 num_ops++;
2362 } else {
2363 opcode = CEPH_OSD_OP_READ;
2364 }
2365
2366 osd_req_op_extent_init(osd_request, num_ops, opcode, offset, length,
2367 0, 0);
2368 if (obj_request->type == OBJ_REQUEST_BIO)
2369 osd_req_op_extent_osd_data_bio(osd_request, num_ops,
2370 obj_request->bio_list, length);
2371 else if (obj_request->type == OBJ_REQUEST_PAGES)
2372 osd_req_op_extent_osd_data_pages(osd_request, num_ops,
2373 obj_request->pages, length,
2374 offset & ~PAGE_MASK, false, false);
2375
2376 /* Discards are also writes */
2377 if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
2378 rbd_osd_req_format_write(obj_request);
2379 else
2380 rbd_osd_req_format_read(obj_request);
2381}
2382
2383/*
2311 * Split up an image request into one or more object requests, each 2384 * Split up an image request into one or more object requests, each
2312 * to a different object. The "type" parameter indicates whether 2385 * to a different object. The "type" parameter indicates whether
2313 * "data_desc" is the pointer to the head of a list of bio 2386 * "data_desc" is the pointer to the head of a list of bio
@@ -2326,11 +2399,8 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
2326 unsigned int bio_offset = 0; 2399 unsigned int bio_offset = 0;
2327 struct page **pages = NULL; 2400 struct page **pages = NULL;
2328 enum obj_operation_type op_type; 2401 enum obj_operation_type op_type;
2329 u64 object_size = rbd_obj_bytes(&rbd_dev->header);
2330 u64 img_offset; 2402 u64 img_offset;
2331 u64 img_end;
2332 u64 resid; 2403 u64 resid;
2333 u16 opcode;
2334 2404
2335 dout("%s: img %p type %d data_desc %p\n", __func__, img_request, 2405 dout("%s: img %p type %d data_desc %p\n", __func__, img_request,
2336 (int)type, data_desc); 2406 (int)type, data_desc);
@@ -2338,6 +2408,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
2338 img_offset = img_request->offset; 2408 img_offset = img_request->offset;
2339 resid = img_request->length; 2409 resid = img_request->length;
2340 rbd_assert(resid > 0); 2410 rbd_assert(resid > 0);
2411 op_type = rbd_img_request_op_type(img_request);
2341 2412
2342 if (type == OBJ_REQUEST_BIO) { 2413 if (type == OBJ_REQUEST_BIO) {
2343 bio_list = data_desc; 2414 bio_list = data_desc;
@@ -2352,7 +2423,6 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
2352 const char *object_name; 2423 const char *object_name;
2353 u64 offset; 2424 u64 offset;
2354 u64 length; 2425 u64 length;
2355 unsigned int which = 0;
2356 2426
2357 object_name = rbd_segment_name(rbd_dev, img_offset); 2427 object_name = rbd_segment_name(rbd_dev, img_offset);
2358 if (!object_name) 2428 if (!object_name)
@@ -2395,66 +2465,19 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
2395 pages += page_count; 2465 pages += page_count;
2396 } 2466 }
2397 2467
2398 if (img_request_discard_test(img_request)) {
2399 op_type = OBJ_OP_DISCARD;
2400 if (!offset && (length == object_size)
2401 && (!img_request_layered_test(img_request) ||
2402 (rbd_dev->parent_overlap <=
2403 obj_request->img_offset))) {
2404 opcode = CEPH_OSD_OP_DELETE;
2405 } else if ((offset + length == object_size)) {
2406 opcode = CEPH_OSD_OP_TRUNCATE;
2407 } else {
2408 down_read(&rbd_dev->header_rwsem);
2409 img_end = rbd_dev->header.image_size;
2410 up_read(&rbd_dev->header_rwsem);
2411
2412 if (obj_request->img_offset + length == img_end)
2413 opcode = CEPH_OSD_OP_TRUNCATE;
2414 else
2415 opcode = CEPH_OSD_OP_ZERO;
2416 }
2417 } else if (img_request_write_test(img_request)) {
2418 op_type = OBJ_OP_WRITE;
2419 opcode = CEPH_OSD_OP_WRITE;
2420 } else {
2421 op_type = OBJ_OP_READ;
2422 opcode = CEPH_OSD_OP_READ;
2423 }
2424
2425 osd_req = rbd_osd_req_create(rbd_dev, op_type, 2468 osd_req = rbd_osd_req_create(rbd_dev, op_type,
2426 (op_type == OBJ_OP_WRITE) ? 2 : 1, 2469 (op_type == OBJ_OP_WRITE) ? 2 : 1,
2427 obj_request); 2470 obj_request);
2428 if (!osd_req) 2471 if (!osd_req)
2429 goto out_unwind; 2472 goto out_unwind;
2473
2430 obj_request->osd_req = osd_req; 2474 obj_request->osd_req = osd_req;
2431 obj_request->callback = rbd_img_obj_callback; 2475 obj_request->callback = rbd_img_obj_callback;
2432 rbd_img_request_get(img_request); 2476 obj_request->img_offset = img_offset;
2433
2434 if (op_type == OBJ_OP_WRITE) {
2435 osd_req_op_alloc_hint_init(osd_req, which,
2436 rbd_obj_bytes(&rbd_dev->header),
2437 rbd_obj_bytes(&rbd_dev->header));
2438 which++;
2439 }
2440
2441 osd_req_op_extent_init(osd_req, which, opcode, offset, length,
2442 0, 0);
2443 if (type == OBJ_REQUEST_BIO)
2444 osd_req_op_extent_osd_data_bio(osd_req, which,
2445 obj_request->bio_list, length);
2446 else if (type == OBJ_REQUEST_PAGES)
2447 osd_req_op_extent_osd_data_pages(osd_req, which,
2448 obj_request->pages, length,
2449 offset & ~PAGE_MASK, false, false);
2450 2477
2451 /* Discards are also writes */ 2478 rbd_img_obj_request_fill(obj_request, osd_req, op_type, 0);
2452 if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
2453 rbd_osd_req_format_write(obj_request);
2454 else
2455 rbd_osd_req_format_read(obj_request);
2456 2479
2457 obj_request->img_offset = img_offset; 2480 rbd_img_request_get(img_request);
2458 2481
2459 img_offset += length; 2482 img_offset += length;
2460 resid -= length; 2483 resid -= length;