Skip to content

Commit 17f8dc2

Browse files
lxbszidryomov
authored andcommitted
ceph: switch to use cap_delay_lock for the unlink delay list
The same list item will be used in both cap_delay_list and cap_unlink_delay_list, so it's buggy to use two different locks to protect them. Cc: [email protected] Fixes: dbc347e ("ceph: add ceph_cap_unlink_work to fire check_caps() immediately") Link: https://lists.ceph.io/hyperkitty/list/[email protected]/thread/AODC76VXRAMXKLFDCTK4TKFDDPWUSCN5 Reported-by: Marc Ruhmann <[email protected]> Signed-off-by: Xiubo Li <[email protected]> Reviewed-by: Ilya Dryomov <[email protected]> Tested-by: Marc Ruhmann <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent b372e96 commit 17f8dc2

File tree

3 files changed

+7
-9
lines changed

3 files changed

+7
-9
lines changed

fs/ceph/caps.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4783,13 +4783,13 @@ int ceph_drop_caps_for_unlink(struct inode *inode)
47834783

47844784
doutc(mdsc->fsc->client, "%p %llx.%llx\n", inode,
47854785
ceph_vinop(inode));
4786-
spin_lock(&mdsc->cap_unlink_delay_lock);
4786+
spin_lock(&mdsc->cap_delay_lock);
47874787
ci->i_ceph_flags |= CEPH_I_FLUSH;
47884788
if (!list_empty(&ci->i_cap_delay_list))
47894789
list_del_init(&ci->i_cap_delay_list);
47904790
list_add_tail(&ci->i_cap_delay_list,
47914791
&mdsc->cap_unlink_delay_list);
4792-
spin_unlock(&mdsc->cap_unlink_delay_lock);
4792+
spin_unlock(&mdsc->cap_delay_lock);
47934793

47944794
/*
47954795
* Fire the work immediately, because the MDS maybe

fs/ceph/mds_client.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,7 +2504,7 @@ static void ceph_cap_unlink_work(struct work_struct *work)
25042504
struct ceph_client *cl = mdsc->fsc->client;
25052505

25062506
doutc(cl, "begin\n");
2507-
spin_lock(&mdsc->cap_unlink_delay_lock);
2507+
spin_lock(&mdsc->cap_delay_lock);
25082508
while (!list_empty(&mdsc->cap_unlink_delay_list)) {
25092509
struct ceph_inode_info *ci;
25102510
struct inode *inode;
@@ -2516,15 +2516,15 @@ static void ceph_cap_unlink_work(struct work_struct *work)
25162516

25172517
inode = igrab(&ci->netfs.inode);
25182518
if (inode) {
2519-
spin_unlock(&mdsc->cap_unlink_delay_lock);
2519+
spin_unlock(&mdsc->cap_delay_lock);
25202520
doutc(cl, "on %p %llx.%llx\n", inode,
25212521
ceph_vinop(inode));
25222522
ceph_check_caps(ci, CHECK_CAPS_FLUSH);
25232523
iput(inode);
2524-
spin_lock(&mdsc->cap_unlink_delay_lock);
2524+
spin_lock(&mdsc->cap_delay_lock);
25252525
}
25262526
}
2527-
spin_unlock(&mdsc->cap_unlink_delay_lock);
2527+
spin_unlock(&mdsc->cap_delay_lock);
25282528
doutc(cl, "done\n");
25292529
}
25302530

@@ -5404,7 +5404,6 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
54045404
INIT_LIST_HEAD(&mdsc->cap_wait_list);
54055405
spin_lock_init(&mdsc->cap_delay_lock);
54065406
INIT_LIST_HEAD(&mdsc->cap_unlink_delay_list);
5407-
spin_lock_init(&mdsc->cap_unlink_delay_lock);
54085407
INIT_LIST_HEAD(&mdsc->snap_flush_list);
54095408
spin_lock_init(&mdsc->snap_flush_lock);
54105409
mdsc->last_cap_flush_tid = 1;

fs/ceph/mds_client.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,8 @@ struct ceph_mds_client {
461461
struct delayed_work delayed_work; /* delayed work */
462462
unsigned long last_renew_caps; /* last time we renewed our caps */
463463
struct list_head cap_delay_list; /* caps with delayed release */
464-
spinlock_t cap_delay_lock; /* protects cap_delay_list */
465464
struct list_head cap_unlink_delay_list; /* caps with delayed release for unlink */
466-
spinlock_t cap_unlink_delay_lock; /* protects cap_unlink_delay_list */
465+
spinlock_t cap_delay_lock; /* protects cap_delay_list and cap_unlink_delay_list */
467466
struct list_head snap_flush_list; /* cap_snaps ready to flush */
468467
spinlock_t snap_flush_lock;
469468

0 commit comments

Comments
 (0)