Skip to content

Commit 8798d07

Browse files
committed
rbd: always kick acquire on "acquired" and "released" notifications
Skipping the "lock has been released" notification if the lock owner is not what we expect based on owner_cid can lead to I/O hangs. One example is our own notifications: because owner_cid is cleared in rbd_unlock(), when we get our own notification it is processed as unexpected/duplicate and maybe_kick_acquire() isn't called. If a peer that requested the lock then doesn't go through with acquiring it, I/O requests that came in while the lock was being quiesced would be stalled until another I/O request is submitted and kicks acquire from rbd_img_exclusive_lock(). This makes the comment in rbd_release_lock() actually true: prior to this change the canceled work was being requeued in response to the "lock has been acquired" notification from rbd_handle_acquired_lock(). Cc: stable@vger.kernel.org # 5.3+ Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Tested-by: Robin Geuze <robin.geuze@nl.team.blue>
1 parent 2734d6c commit 8798d07

1 file changed

Lines changed: 7 additions & 13 deletions

File tree

drivers/block/rbd.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4203,15 +4203,11 @@ static void rbd_handle_acquired_lock(struct rbd_device *rbd_dev, u8 struct_v,
42034203
if (!rbd_cid_equal(&cid, &rbd_empty_cid)) {
42044204
down_write(&rbd_dev->lock_rwsem);
42054205
if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) {
4206-
/*
4207-
* we already know that the remote client is
4208-
* the owner
4209-
*/
4210-
up_write(&rbd_dev->lock_rwsem);
4211-
return;
4206+
dout("%s rbd_dev %p cid %llu-%llu == owner_cid\n",
4207+
__func__, rbd_dev, cid.gid, cid.handle);
4208+
} else {
4209+
rbd_set_owner_cid(rbd_dev, &cid);
42124210
}
4213-
4214-
rbd_set_owner_cid(rbd_dev, &cid);
42154211
downgrade_write(&rbd_dev->lock_rwsem);
42164212
} else {
42174213
down_read(&rbd_dev->lock_rwsem);
@@ -4236,14 +4232,12 @@ static void rbd_handle_released_lock(struct rbd_device *rbd_dev, u8 struct_v,
42364232
if (!rbd_cid_equal(&cid, &rbd_empty_cid)) {
42374233
down_write(&rbd_dev->lock_rwsem);
42384234
if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) {
4239-
dout("%s rbd_dev %p unexpected owner, cid %llu-%llu != owner_cid %llu-%llu\n",
4235+
dout("%s rbd_dev %p cid %llu-%llu != owner_cid %llu-%llu\n",
42404236
__func__, rbd_dev, cid.gid, cid.handle,
42414237
rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle);
4242-
up_write(&rbd_dev->lock_rwsem);
4243-
return;
4238+
} else {
4239+
rbd_set_owner_cid(rbd_dev, &rbd_empty_cid);
42444240
}
4245-
4246-
rbd_set_owner_cid(rbd_dev, &rbd_empty_cid);
42474241
downgrade_write(&rbd_dev->lock_rwsem);
42484242
} else {
42494243
down_read(&rbd_dev->lock_rwsem);

0 commit comments

Comments
 (0)