@@ -1334,14 +1334,30 @@ static bool rbd_obj_is_tail(struct rbd_obj_request *obj_req)
13341334/*
13351335 * Must be called after rbd_obj_calc_img_extents().
13361336 */
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 )
13381338{
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 );
13431340
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 ;
13451361}
13461362
13471363static 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,
14421458static struct ceph_osd_request *
14431459rbd_obj_add_osd_request (struct rbd_obj_request * obj_req , int num_ops )
14441460{
1461+ rbd_assert (obj_req -> img_request -> snapc );
14451462 return __rbd_obj_add_osd_request (obj_req , obj_req -> img_request -> snapc ,
14461463 num_ops );
14471464}
@@ -1578,15 +1595,18 @@ static void rbd_img_request_init(struct rbd_img_request *img_request,
15781595 mutex_init (& img_request -> state_mutex );
15791596}
15801597
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+ */
15811603static void rbd_img_capture_header (struct rbd_img_request * img_req )
15821604{
15831605 struct rbd_device * rbd_dev = img_req -> rbd_dev ;
15841606
15851607 lockdep_assert_held (& rbd_dev -> header_rwsem );
15861608
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 ))
15901610 img_req -> snap_id = rbd_dev -> spec -> snap_id ;
15911611
15921612 if (rbd_dev_parent_get (rbd_dev ))
@@ -2233,9 +2253,6 @@ static int rbd_obj_init_write(struct rbd_obj_request *obj_req)
22332253 if (ret )
22342254 return ret ;
22352255
2236- if (rbd_obj_copyup_enabled (obj_req ))
2237- obj_req -> flags |= RBD_OBJ_FLAG_COPYUP_ENABLED ;
2238-
22392256 obj_req -> write_state = RBD_OBJ_WRITE_START ;
22402257 return 0 ;
22412258}
@@ -2341,8 +2358,6 @@ static int rbd_obj_init_zeroout(struct rbd_obj_request *obj_req)
23412358 if (ret )
23422359 return ret ;
23432360
2344- if (rbd_obj_copyup_enabled (obj_req ))
2345- obj_req -> flags |= RBD_OBJ_FLAG_COPYUP_ENABLED ;
23462361 if (!obj_req -> num_img_extents ) {
23472362 obj_req -> flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT ;
23482363 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)
32863301 case RBD_OBJ_WRITE_START :
32873302 rbd_assert (!* result );
32883303
3304+ rbd_obj_set_copyup_enabled (obj_req );
32893305 if (rbd_obj_write_is_noop (obj_req ))
32903306 return true;
32913307
@@ -3472,9 +3488,19 @@ static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)
34723488
34733489static void rbd_img_object_requests (struct rbd_img_request * img_req )
34743490{
3491+ struct rbd_device * rbd_dev = img_req -> rbd_dev ;
34753492 struct rbd_obj_request * obj_req ;
34763493
34773494 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+ }
34783504
34793505 for_each_obj_request (img_req , obj_req ) {
34803506 int result = 0 ;
@@ -3492,7 +3518,6 @@ static void rbd_img_object_requests(struct rbd_img_request *img_req)
34923518
34933519static bool rbd_img_advance (struct rbd_img_request * img_req , int * result )
34943520{
3495- struct rbd_device * rbd_dev = img_req -> rbd_dev ;
34963521 int ret ;
34973522
34983523again :
@@ -3513,9 +3538,6 @@ static bool rbd_img_advance(struct rbd_img_request *img_req, int *result)
35133538 if (* result )
35143539 return true;
35153540
3516- rbd_assert (!need_exclusive_lock (img_req ) ||
3517- __rbd_is_lock_owner (rbd_dev ));
3518-
35193541 rbd_img_object_requests (img_req );
35203542 if (!img_req -> pending .num_pending ) {
35213543 * result = img_req -> pending .result ;
@@ -3977,6 +3999,10 @@ static int rbd_post_acquire_action(struct rbd_device *rbd_dev)
39773999{
39784000 int ret ;
39794001
4002+ ret = rbd_dev_refresh (rbd_dev );
4003+ if (ret )
4004+ return ret ;
4005+
39804006 if (rbd_dev -> header .features & RBD_FEATURE_OBJECT_MAP ) {
39814007 ret = rbd_object_map_open (rbd_dev );
39824008 if (ret )
0 commit comments