@@ -1334,14 +1334,30 @@ static bool rbd_obj_is_tail(struct rbd_obj_request *obj_req)
1334
1334
/*
1335
1335
* Must be called after rbd_obj_calc_img_extents().
1336
1336
*/
1337
- static bool rbd_obj_copyup_enabled (struct rbd_obj_request * obj_req )
1337
+ static void rbd_obj_set_copyup_enabled (struct rbd_obj_request * obj_req )
1338
1338
{
1339
- if (!obj_req -> num_img_extents ||
1340
- (rbd_obj_is_entire (obj_req ) &&
1341
- !obj_req -> img_request -> snapc -> num_snaps ))
1342
- return false;
1339
+ rbd_assert (obj_req -> img_request -> snapc );
1343
1340
1344
- return true;
1341
+ if (obj_req -> img_request -> op_type == OBJ_OP_DISCARD ) {
1342
+ dout ("%s %p objno %llu discard\n" , __func__ , obj_req ,
1343
+ obj_req -> ex .oe_objno );
1344
+ return ;
1345
+ }
1346
+
1347
+ if (!obj_req -> num_img_extents ) {
1348
+ dout ("%s %p objno %llu not overlapping\n" , __func__ , obj_req ,
1349
+ obj_req -> ex .oe_objno );
1350
+ return ;
1351
+ }
1352
+
1353
+ if (rbd_obj_is_entire (obj_req ) &&
1354
+ !obj_req -> img_request -> snapc -> num_snaps ) {
1355
+ dout ("%s %p objno %llu entire\n" , __func__ , obj_req ,
1356
+ obj_req -> ex .oe_objno );
1357
+ return ;
1358
+ }
1359
+
1360
+ obj_req -> flags |= RBD_OBJ_FLAG_COPYUP_ENABLED ;
1345
1361
}
1346
1362
1347
1363
static u64 rbd_obj_img_extents_bytes (struct rbd_obj_request * obj_req )
@@ -1442,6 +1458,7 @@ __rbd_obj_add_osd_request(struct rbd_obj_request *obj_req,
1442
1458
static struct ceph_osd_request *
1443
1459
rbd_obj_add_osd_request (struct rbd_obj_request * obj_req , int num_ops )
1444
1460
{
1461
+ rbd_assert (obj_req -> img_request -> snapc );
1445
1462
return __rbd_obj_add_osd_request (obj_req , obj_req -> img_request -> snapc ,
1446
1463
num_ops );
1447
1464
}
@@ -1578,15 +1595,18 @@ static void rbd_img_request_init(struct rbd_img_request *img_request,
1578
1595
mutex_init (& img_request -> state_mutex );
1579
1596
}
1580
1597
1598
+ /*
1599
+ * Only snap_id is captured here, for reads. For writes, snapshot
1600
+ * context is captured in rbd_img_object_requests() after exclusive
1601
+ * lock is ensured to be held.
1602
+ */
1581
1603
static void rbd_img_capture_header (struct rbd_img_request * img_req )
1582
1604
{
1583
1605
struct rbd_device * rbd_dev = img_req -> rbd_dev ;
1584
1606
1585
1607
lockdep_assert_held (& rbd_dev -> header_rwsem );
1586
1608
1587
- if (rbd_img_is_write (img_req ))
1588
- img_req -> snapc = ceph_get_snap_context (rbd_dev -> header .snapc );
1589
- else
1609
+ if (!rbd_img_is_write (img_req ))
1590
1610
img_req -> snap_id = rbd_dev -> spec -> snap_id ;
1591
1611
1592
1612
if (rbd_dev_parent_get (rbd_dev ))
@@ -2233,9 +2253,6 @@ static int rbd_obj_init_write(struct rbd_obj_request *obj_req)
2233
2253
if (ret )
2234
2254
return ret ;
2235
2255
2236
- if (rbd_obj_copyup_enabled (obj_req ))
2237
- obj_req -> flags |= RBD_OBJ_FLAG_COPYUP_ENABLED ;
2238
-
2239
2256
obj_req -> write_state = RBD_OBJ_WRITE_START ;
2240
2257
return 0 ;
2241
2258
}
@@ -2341,8 +2358,6 @@ static int rbd_obj_init_zeroout(struct rbd_obj_request *obj_req)
2341
2358
if (ret )
2342
2359
return ret ;
2343
2360
2344
- if (rbd_obj_copyup_enabled (obj_req ))
2345
- obj_req -> flags |= RBD_OBJ_FLAG_COPYUP_ENABLED ;
2346
2361
if (!obj_req -> num_img_extents ) {
2347
2362
obj_req -> flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT ;
2348
2363
if (rbd_obj_is_entire (obj_req ))
@@ -3286,6 +3301,7 @@ static bool rbd_obj_advance_write(struct rbd_obj_request *obj_req, int *result)
3286
3301
case RBD_OBJ_WRITE_START :
3287
3302
rbd_assert (!* result );
3288
3303
3304
+ rbd_obj_set_copyup_enabled (obj_req );
3289
3305
if (rbd_obj_write_is_noop (obj_req ))
3290
3306
return true;
3291
3307
@@ -3472,9 +3488,19 @@ static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)
3472
3488
3473
3489
static void rbd_img_object_requests (struct rbd_img_request * img_req )
3474
3490
{
3491
+ struct rbd_device * rbd_dev = img_req -> rbd_dev ;
3475
3492
struct rbd_obj_request * obj_req ;
3476
3493
3477
3494
rbd_assert (!img_req -> pending .result && !img_req -> pending .num_pending );
3495
+ rbd_assert (!need_exclusive_lock (img_req ) ||
3496
+ __rbd_is_lock_owner (rbd_dev ));
3497
+
3498
+ if (rbd_img_is_write (img_req )) {
3499
+ rbd_assert (!img_req -> snapc );
3500
+ down_read (& rbd_dev -> header_rwsem );
3501
+ img_req -> snapc = ceph_get_snap_context (rbd_dev -> header .snapc );
3502
+ up_read (& rbd_dev -> header_rwsem );
3503
+ }
3478
3504
3479
3505
for_each_obj_request (img_req , obj_req ) {
3480
3506
int result = 0 ;
@@ -3492,7 +3518,6 @@ static void rbd_img_object_requests(struct rbd_img_request *img_req)
3492
3518
3493
3519
static bool rbd_img_advance (struct rbd_img_request * img_req , int * result )
3494
3520
{
3495
- struct rbd_device * rbd_dev = img_req -> rbd_dev ;
3496
3521
int ret ;
3497
3522
3498
3523
again :
@@ -3513,9 +3538,6 @@ static bool rbd_img_advance(struct rbd_img_request *img_req, int *result)
3513
3538
if (* result )
3514
3539
return true;
3515
3540
3516
- rbd_assert (!need_exclusive_lock (img_req ) ||
3517
- __rbd_is_lock_owner (rbd_dev ));
3518
-
3519
3541
rbd_img_object_requests (img_req );
3520
3542
if (!img_req -> pending .num_pending ) {
3521
3543
* result = img_req -> pending .result ;
@@ -3977,6 +3999,10 @@ static int rbd_post_acquire_action(struct rbd_device *rbd_dev)
3977
3999
{
3978
4000
int ret ;
3979
4001
4002
+ ret = rbd_dev_refresh (rbd_dev );
4003
+ if (ret )
4004
+ return ret ;
4005
+
3980
4006
if (rbd_dev -> header .features & RBD_FEATURE_OBJECT_MAP ) {
3981
4007
ret = rbd_object_map_open (rbd_dev );
3982
4008
if (ret )
0 commit comments