Skip to content

Commit d6dd643

Browse files
committed
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "A bunch of race fixes, mostly around lazy pathwalk. All of it is -stable fodder, a large part going back to 2013" * 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: make sure that __dentry_kill() always invalidates d_seq, unhashed or not fix __legitimize_mnt()/mntput() race fix mntput/mntput race root dentries need RCU-delayed freeing
2 parents ec0c967 + 4c0d7cd commit d6dd643

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

fs/dcache.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,14 +358,11 @@ static void dentry_unlink_inode(struct dentry * dentry)
358358
__releases(dentry->d_inode->i_lock)
359359
{
360360
struct inode *inode = dentry->d_inode;
361-
bool hashed = !d_unhashed(dentry);
362361

363-
if (hashed)
364-
raw_write_seqcount_begin(&dentry->d_seq);
362+
raw_write_seqcount_begin(&dentry->d_seq);
365363
__d_clear_type_and_inode(dentry);
366364
hlist_del_init(&dentry->d_u.d_alias);
367-
if (hashed)
368-
raw_write_seqcount_end(&dentry->d_seq);
365+
raw_write_seqcount_end(&dentry->d_seq);
369366
spin_unlock(&dentry->d_lock);
370367
spin_unlock(&inode->i_lock);
371368
if (!inode->i_nlink)
@@ -1932,10 +1929,12 @@ struct dentry *d_make_root(struct inode *root_inode)
19321929

19331930
if (root_inode) {
19341931
res = d_alloc_anon(root_inode->i_sb);
1935-
if (res)
1932+
if (res) {
1933+
res->d_flags |= DCACHE_RCUACCESS;
19361934
d_instantiate(res, root_inode);
1937-
else
1935+
} else {
19381936
iput(root_inode);
1937+
}
19391938
}
19401939
return res;
19411940
}

fs/namespace.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,12 +659,21 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
659659
return 0;
660660
mnt = real_mount(bastard);
661661
mnt_add_count(mnt, 1);
662+
smp_mb(); // see mntput_no_expire()
662663
if (likely(!read_seqretry(&mount_lock, seq)))
663664
return 0;
664665
if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
665666
mnt_add_count(mnt, -1);
666667
return 1;
667668
}
669+
lock_mount_hash();
670+
if (unlikely(bastard->mnt_flags & MNT_DOOMED)) {
671+
mnt_add_count(mnt, -1);
672+
unlock_mount_hash();
673+
return 1;
674+
}
675+
unlock_mount_hash();
676+
/* caller will mntput() */
668677
return -1;
669678
}
670679

@@ -1195,12 +1204,27 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);
11951204
static void mntput_no_expire(struct mount *mnt)
11961205
{
11971206
rcu_read_lock();
1198-
mnt_add_count(mnt, -1);
1199-
if (likely(mnt->mnt_ns)) { /* shouldn't be the last one */
1207+
if (likely(READ_ONCE(mnt->mnt_ns))) {
1208+
/*
1209+
* Since we don't do lock_mount_hash() here,
1210+
* ->mnt_ns can change under us. However, if it's
1211+
* non-NULL, then there's a reference that won't
1212+
* be dropped until after an RCU delay done after
1213+
* turning ->mnt_ns NULL. So if we observe it
1214+
* non-NULL under rcu_read_lock(), the reference
1215+
* we are dropping is not the final one.
1216+
*/
1217+
mnt_add_count(mnt, -1);
12001218
rcu_read_unlock();
12011219
return;
12021220
}
12031221
lock_mount_hash();
1222+
/*
1223+
* make sure that if __legitimize_mnt() has not seen us grab
1224+
* mount_lock, we'll see their refcount increment here.
1225+
*/
1226+
smp_mb();
1227+
mnt_add_count(mnt, -1);
12041228
if (mnt_get_count(mnt)) {
12051229
rcu_read_unlock();
12061230
unlock_mount_hash();

0 commit comments

Comments
 (0)