aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index f9cad40d95af..aa95227fdee2 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -236,7 +236,8 @@ enum obj_operation_type {
236enum rbd_obj_write_state { 236enum rbd_obj_write_state {
237 RBD_OBJ_WRITE_FLAT = 1, 237 RBD_OBJ_WRITE_FLAT = 1,
238 RBD_OBJ_WRITE_GUARD, 238 RBD_OBJ_WRITE_GUARD,
239 RBD_OBJ_WRITE_COPYUP, 239 RBD_OBJ_WRITE_READ_FROM_PARENT,
240 RBD_OBJ_WRITE_COPYUP_OPS,
240}; 241};
241 242
242struct rbd_obj_request { 243struct rbd_obj_request {
@@ -2458,10 +2459,13 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes)
2458 return true; 2459 return true;
2459} 2460}
2460 2461
2461static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) 2462#define MODS_ONLY U32_MAX
2463
2464static int rbd_obj_issue_copyup_ops(struct rbd_obj_request *obj_req, u32 bytes)
2462{ 2465{
2463 struct rbd_img_request *img_req = obj_req->img_request; 2466 struct rbd_img_request *img_req = obj_req->img_request;
2464 unsigned int num_osd_ops = 1; 2467 unsigned int num_osd_ops = (bytes != MODS_ONLY);
2468 unsigned int which = 0;
2465 int ret; 2469 int ret;
2466 2470
2467 dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); 2471 dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes);
@@ -2483,31 +2487,25 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
2483 if (!obj_req->osd_req) 2487 if (!obj_req->osd_req)
2484 return -ENOMEM; 2488 return -ENOMEM;
2485 2489
2486 ret = osd_req_op_cls_init(obj_req->osd_req, 0, "rbd", "copyup"); 2490 if (bytes != MODS_ONLY) {
2487 if (ret) 2491 ret = osd_req_op_cls_init(obj_req->osd_req, which, "rbd",
2488 return ret; 2492 "copyup");
2493 if (ret)
2494 return ret;
2489 2495
2490 /* 2496 osd_req_op_cls_request_data_bvecs(obj_req->osd_req, which++,
2491 * Only send non-zero copyup data to save some I/O and network 2497 obj_req->copyup_bvecs,
2492 * bandwidth -- zero copyup data is equivalent to the object not 2498 obj_req->copyup_bvec_count,
2493 * existing. 2499 bytes);
2494 */
2495 if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
2496 dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
2497 bytes = 0;
2498 } 2500 }
2499 osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0,
2500 obj_req->copyup_bvecs,
2501 obj_req->copyup_bvec_count,
2502 bytes);
2503 2501
2504 switch (img_req->op_type) { 2502 switch (img_req->op_type) {
2505 case OBJ_OP_WRITE: 2503 case OBJ_OP_WRITE:
2506 __rbd_obj_setup_write(obj_req, 1); 2504 __rbd_obj_setup_write(obj_req, which);
2507 break; 2505 break;
2508 case OBJ_OP_ZEROOUT: 2506 case OBJ_OP_ZEROOUT:
2509 rbd_assert(!rbd_obj_is_entire(obj_req)); 2507 rbd_assert(!rbd_obj_is_entire(obj_req));
2510 __rbd_obj_setup_zeroout(obj_req, 1); 2508 __rbd_obj_setup_zeroout(obj_req, which);
2511 break; 2509 break;
2512 default: 2510 default:
2513 rbd_assert(0); 2511 rbd_assert(0);
@@ -2521,6 +2519,22 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
2521 return 0; 2519 return 0;
2522} 2520}
2523 2521
2522static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
2523{
2524 /*
2525 * Only send non-zero copyup data to save some I/O and network
2526 * bandwidth -- zero copyup data is equivalent to the object not
2527 * existing.
2528 */
2529 if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
2530 dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
2531 bytes = 0;
2532 }
2533
2534 obj_req->write_state = RBD_OBJ_WRITE_COPYUP_OPS;
2535 return rbd_obj_issue_copyup_ops(obj_req, bytes);
2536}
2537
2524static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap) 2538static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap)
2525{ 2539{
2526 u32 i; 2540 u32 i;
@@ -2560,22 +2574,19 @@ static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
2560 if (!obj_req->num_img_extents) { 2574 if (!obj_req->num_img_extents) {
2561 /* 2575 /*
2562 * The overlap has become 0 (most likely because the 2576 * The overlap has become 0 (most likely because the
2563 * image has been flattened). Use rbd_obj_issue_copyup() 2577 * image has been flattened). Re-submit the original write
2564 * to re-submit the original write request -- the copyup 2578 * request -- pass MODS_ONLY since the copyup isn't needed
2565 * operation itself will be a no-op, since someone must 2579 * anymore.
2566 * have populated the child object while we weren't
2567 * looking. Move to WRITE_FLAT state as we'll be done
2568 * with the operation once the null copyup completes.
2569 */ 2580 */
2570 obj_req->write_state = RBD_OBJ_WRITE_FLAT; 2581 obj_req->write_state = RBD_OBJ_WRITE_COPYUP_OPS;
2571 return rbd_obj_issue_copyup(obj_req, 0); 2582 return rbd_obj_issue_copyup_ops(obj_req, MODS_ONLY);
2572 } 2583 }
2573 2584
2574 ret = setup_copyup_bvecs(obj_req, rbd_obj_img_extents_bytes(obj_req)); 2585 ret = setup_copyup_bvecs(obj_req, rbd_obj_img_extents_bytes(obj_req));
2575 if (ret) 2586 if (ret)
2576 return ret; 2587 return ret;
2577 2588
2578 obj_req->write_state = RBD_OBJ_WRITE_COPYUP; 2589 obj_req->write_state = RBD_OBJ_WRITE_READ_FROM_PARENT;
2579 return rbd_obj_read_from_parent(obj_req); 2590 return rbd_obj_read_from_parent(obj_req);
2580} 2591}
2581 2592
@@ -2583,7 +2594,6 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
2583{ 2594{
2584 int ret; 2595 int ret;
2585 2596
2586again:
2587 switch (obj_req->write_state) { 2597 switch (obj_req->write_state) {
2588 case RBD_OBJ_WRITE_GUARD: 2598 case RBD_OBJ_WRITE_GUARD:
2589 rbd_assert(!obj_req->xferred); 2599 rbd_assert(!obj_req->xferred);
@@ -2602,6 +2612,7 @@ again:
2602 } 2612 }
2603 /* fall through */ 2613 /* fall through */
2604 case RBD_OBJ_WRITE_FLAT: 2614 case RBD_OBJ_WRITE_FLAT:
2615 case RBD_OBJ_WRITE_COPYUP_OPS:
2605 if (!obj_req->result) 2616 if (!obj_req->result)
2606 /* 2617 /*
2607 * There is no such thing as a successful short 2618 * There is no such thing as a successful short
@@ -2609,10 +2620,9 @@ again:
2609 */ 2620 */
2610 obj_req->xferred = obj_req->ex.oe_len; 2621 obj_req->xferred = obj_req->ex.oe_len;
2611 return true; 2622 return true;
2612 case RBD_OBJ_WRITE_COPYUP: 2623 case RBD_OBJ_WRITE_READ_FROM_PARENT:
2613 obj_req->write_state = RBD_OBJ_WRITE_GUARD;
2614 if (obj_req->result) 2624 if (obj_req->result)
2615 goto again; 2625 return true;
2616 2626
2617 rbd_assert(obj_req->xferred); 2627 rbd_assert(obj_req->xferred);
2618 ret = rbd_obj_issue_copyup(obj_req, obj_req->xferred); 2628 ret = rbd_obj_issue_copyup(obj_req, obj_req->xferred);