@@ -236,7 +236,8 @@ enum obj_operation_type {
236
236
enum rbd_obj_write_state {
237
237
RBD_OBJ_WRITE_FLAT = 1 ,
238
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
242
243
struct rbd_obj_request {
@@ -2458,10 +2459,13 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes)
2458
2459
return true;
2459
2460
}
2460
2461
2461
- static int rbd_obj_issue_copyup (struct rbd_obj_request * obj_req , u32 bytes )
2462
+ #define MODS_ONLY U32_MAX
2463
+
2464
+ static int rbd_obj_issue_copyup_ops (struct rbd_obj_request * obj_req , u32 bytes )
2462
2465
{
2463
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
2469
int ret ;
2466
2470
2467
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
2487
if (!obj_req -> osd_req )
2484
2488
return - ENOMEM ;
2485
2489
2486
- ret = osd_req_op_cls_init (obj_req -> osd_req , 0 , "rbd" , "copyup" );
2487
- if (ret )
2488
- return ret ;
2490
+ if (bytes != MODS_ONLY ) {
2491
+ ret = osd_req_op_cls_init (obj_req -> osd_req , which , "rbd" ,
2492
+ "copyup" );
2493
+ if (ret )
2494
+ return ret ;
2489
2495
2490
- /*
2491
- * Only send non-zero copyup data to save some I/O and network
2492
- * bandwidth -- zero copyup data is equivalent to the object not
2493
- * existing.
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 ;
2496
+ osd_req_op_cls_request_data_bvecs (obj_req -> osd_req , which ++ ,
2497
+ obj_req -> copyup_bvecs ,
2498
+ obj_req -> copyup_bvec_count ,
2499
+ bytes );
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
2502
switch (img_req -> op_type ) {
2505
2503
case OBJ_OP_WRITE :
2506
- __rbd_obj_setup_write (obj_req , 1 );
2504
+ __rbd_obj_setup_write (obj_req , which );
2507
2505
break ;
2508
2506
case OBJ_OP_ZEROOUT :
2509
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
2509
break ;
2512
2510
default :
2513
2511
rbd_assert (0 );
@@ -2521,6 +2519,22 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
2521
2519
return 0 ;
2522
2520
}
2523
2521
2522
+ static 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
+
2524
2538
static int setup_copyup_bvecs (struct rbd_obj_request * obj_req , u64 obj_overlap )
2525
2539
{
2526
2540
u32 i ;
@@ -2560,30 +2574,26 @@ static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
2560
2574
if (!obj_req -> num_img_extents ) {
2561
2575
/*
2562
2576
* The overlap has become 0 (most likely because the
2563
- * image has been flattened). Use rbd_obj_issue_copyup()
2564
- * to re-submit the original write request -- the copyup
2565
- * operation itself will be a no-op, since someone must
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.
2577
+ * image has been flattened). Re-submit the original write
2578
+ * request -- pass MODS_ONLY since the copyup isn't needed
2579
+ * anymore.
2569
2580
*/
2570
- obj_req -> write_state = RBD_OBJ_WRITE_FLAT ;
2571
- return rbd_obj_issue_copyup (obj_req , 0 );
2581
+ obj_req -> write_state = RBD_OBJ_WRITE_COPYUP_OPS ;
2582
+ return rbd_obj_issue_copyup_ops (obj_req , MODS_ONLY );
2572
2583
}
2573
2584
2574
2585
ret = setup_copyup_bvecs (obj_req , rbd_obj_img_extents_bytes (obj_req ));
2575
2586
if (ret )
2576
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
2590
return rbd_obj_read_from_parent (obj_req );
2580
2591
}
2581
2592
2582
2593
static bool rbd_obj_handle_write (struct rbd_obj_request * obj_req )
2583
2594
{
2584
2595
int ret ;
2585
2596
2586
- again :
2587
2597
switch (obj_req -> write_state ) {
2588
2598
case RBD_OBJ_WRITE_GUARD :
2589
2599
rbd_assert (!obj_req -> xferred );
@@ -2602,17 +2612,17 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
2602
2612
}
2603
2613
/* fall through */
2604
2614
case RBD_OBJ_WRITE_FLAT :
2615
+ case RBD_OBJ_WRITE_COPYUP_OPS :
2605
2616
if (!obj_req -> result )
2606
2617
/*
2607
2618
* There is no such thing as a successful short
2608
2619
* write -- indicate the whole request was satisfied.
2609
2620
*/
2610
2621
obj_req -> xferred = obj_req -> ex .oe_len ;
2611
2622
return true;
2612
- case RBD_OBJ_WRITE_COPYUP :
2613
- obj_req -> write_state = RBD_OBJ_WRITE_GUARD ;
2623
+ case RBD_OBJ_WRITE_READ_FROM_PARENT :
2614
2624
if (obj_req -> result )
2615
- goto again ;
2625
+ return true ;
2616
2626
2617
2627
rbd_assert (obj_req -> xferred );
2618
2628
ret = rbd_obj_issue_copyup (obj_req , obj_req -> xferred );
0 commit comments