Skip to content

Commit 29044da

Browse files
amir73iljankara
authored andcommitted
fsnotify: fix fsnotify hooks in pseudo filesystems
Commit 4924646 ("fsnotify: move fsnotify_nameremove() hook out of d_delete()") moved the fsnotify delete hook before d_delete() so fsnotify will have access to a positive dentry. This allowed a race where opening the deleted file via cached dentry is now possible after receiving the IN_DELETE event. To fix the regression in pseudo filesystems, convert d_delete() calls to d_drop() (see commit 46c46f8 ("devpts_pty_kill(): don't bother with d_delete()") and move the fsnotify hook after d_drop(). Add a missing fsnotify_unlink() hook in nfsdfs that was found during the audit of fsnotify hooks in pseudo filesystems. Note that the fsnotify hooks in simple_recursive_removal() follow d_invalidate(), so they require no change. Link: https://lore.kernel.org/r/[email protected] Reported-by: Ivan Delalande <[email protected]> Link: https://lore.kernel.org/linux-fsdevel/YeNyzoDM5hP5LtGW@visor/ Fixes: 4924646 ("fsnotify: move fsnotify_nameremove() hook out of d_delete()") Cc: [email protected] # v5.3+ Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent a37d9a1 commit 29044da

File tree

4 files changed

+9
-8
lines changed

4 files changed

+9
-8
lines changed

fs/configfs/dir.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,8 +1780,8 @@ void configfs_unregister_group(struct config_group *group)
17801780
configfs_detach_group(&group->cg_item);
17811781
d_inode(dentry)->i_flags |= S_DEAD;
17821782
dont_mount(dentry);
1783+
d_drop(dentry);
17831784
fsnotify_rmdir(d_inode(parent), dentry);
1784-
d_delete(dentry);
17851785
inode_unlock(d_inode(parent));
17861786

17871787
dput(dentry);
@@ -1922,10 +1922,10 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
19221922
configfs_detach_group(&group->cg_item);
19231923
d_inode(dentry)->i_flags |= S_DEAD;
19241924
dont_mount(dentry);
1925-
fsnotify_rmdir(d_inode(root), dentry);
19261925
inode_unlock(d_inode(dentry));
19271926

1928-
d_delete(dentry);
1927+
d_drop(dentry);
1928+
fsnotify_rmdir(d_inode(root), dentry);
19291929

19301930
inode_unlock(d_inode(root));
19311931

fs/devpts/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,8 @@ void devpts_pty_kill(struct dentry *dentry)
621621

622622
dentry->d_fsdata = NULL;
623623
drop_nlink(dentry->d_inode);
624-
fsnotify_unlink(d_inode(dentry->d_parent), dentry);
625624
d_drop(dentry);
625+
fsnotify_unlink(d_inode(dentry->d_parent), dentry);
626626
dput(dentry); /* d_alloc_name() in devpts_pty_new() */
627627
}
628628

fs/nfsd/nfsctl.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,8 @@ static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
12471247
clear_ncl(d_inode(dentry));
12481248
dget(dentry);
12491249
ret = simple_unlink(dir, dentry);
1250-
d_delete(dentry);
1250+
d_drop(dentry);
1251+
fsnotify_unlink(dir, dentry);
12511252
dput(dentry);
12521253
WARN_ON_ONCE(ret);
12531254
}
@@ -1338,8 +1339,8 @@ void nfsd_client_rmdir(struct dentry *dentry)
13381339
dget(dentry);
13391340
ret = simple_rmdir(dir, dentry);
13401341
WARN_ON_ONCE(ret);
1342+
d_drop(dentry);
13411343
fsnotify_rmdir(dir, dentry);
1342-
d_delete(dentry);
13431344
dput(dentry);
13441345
inode_unlock(dir);
13451346
}

net/sunrpc/rpc_pipe.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,9 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry)
600600

601601
dget(dentry);
602602
ret = simple_rmdir(dir, dentry);
603+
d_drop(dentry);
603604
if (!ret)
604605
fsnotify_rmdir(dir, dentry);
605-
d_delete(dentry);
606606
dput(dentry);
607607
return ret;
608608
}
@@ -613,9 +613,9 @@ static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
613613

614614
dget(dentry);
615615
ret = simple_unlink(dir, dentry);
616+
d_drop(dentry);
616617
if (!ret)
617618
fsnotify_unlink(dir, dentry);
618-
d_delete(dentry);
619619
dput(dentry);
620620
return ret;
621621
}

0 commit comments

Comments
 (0)