Add simple_end_creating() helper which combines fsnotify_create/mkdir() hook and simple_done_creating(). Use the new helper to consolidate this pattern in several pseudo fs which had open coded fsnotify_create/mkdir() hooks: binderfs, debugfs, nfsctl, tracefs, rpc_pipefs. For those filesystems, the paired fsnotify_delete() hook is already inside the library helper simple_recursive_removal(). Note that in debugfs_create_symlink(), the fsnotify hook was missing, so the missing hook is fixed by this change. Signed-off-by: Amir Goldstein --- drivers/android/binder/rust_binderfs.c | 11 +++-------- drivers/android/binderfs.c | 10 +++------- fs/debugfs/inode.c | 5 +---- fs/libfs.c | 14 ++++++++++++++ fs/nfsd/nfsctl.c | 11 +++-------- fs/tracefs/event_inode.c | 2 -- fs/tracefs/inode.c | 5 +---- include/linux/fs.h | 1 + net/sunrpc/rpc_pipe.c | 10 +++------- 9 files changed, 29 insertions(+), 40 deletions(-) diff --git a/drivers/android/binder/rust_binderfs.c b/drivers/android/binder/rust_binderfs.c index ade1c4d924992..d69490c6b9e09 100644 --- a/drivers/android/binder/rust_binderfs.c +++ b/drivers/android/binder/rust_binderfs.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -186,9 +185,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, inode->i_private = device; d_make_persistent(dentry, inode); - - fsnotify_create(root->d_inode, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return 0; @@ -481,8 +478,7 @@ static struct dentry *rust_binderfs_create_file(struct dentry *parent, const cha } d_make_persistent(dentry, new_inode); - fsnotify_create(parent->d_inode, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; } @@ -522,8 +518,7 @@ static struct dentry *binderfs_create_dir(struct dentry *parent, inc_nlink(parent->d_inode); set_nlink(new_inode, 2); d_make_persistent(dentry, new_inode); - fsnotify_mkdir(parent->d_inode, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; } diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 361d69f756f50..60277f0bb679f 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -190,8 +189,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, } inode->i_private = device; d_make_persistent(dentry, inode); - fsnotify_create(root->d_inode, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); binder_add_device(device); @@ -490,8 +488,7 @@ struct dentry *binderfs_create_file(struct dentry *parent, const char *name, new_inode->i_fop = fops; new_inode->i_private = data; d_make_persistent(dentry, new_inode); - fsnotify_create(parent_inode, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; // borrowed } @@ -521,8 +518,7 @@ static struct dentry *binderfs_create_dir(struct dentry *parent, set_nlink(new_inode, 2); d_make_persistent(dentry, new_inode); inc_nlink(parent_inode); - fsnotify_mkdir(parent_inode, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; } diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 4598142355b97..f51b008d42cbf 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -409,7 +409,7 @@ static struct dentry *debugfs_failed_creating(struct dentry *dentry) static struct dentry *debugfs_end_creating(struct dentry *dentry) { - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; // borrowed } @@ -448,7 +448,6 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, DEBUGFS_I(inode)->aux = (void *)aux; d_make_persistent(dentry, inode); - fsnotify_create(d_inode(dentry->d_parent), dentry); return debugfs_end_creating(dentry); } @@ -590,7 +589,6 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) inc_nlink(inode); d_make_persistent(dentry, inode); inc_nlink(d_inode(dentry->d_parent)); - fsnotify_mkdir(d_inode(dentry->d_parent), dentry); return debugfs_end_creating(dentry); } EXPORT_SYMBOL_GPL(debugfs_create_dir); @@ -632,7 +630,6 @@ struct dentry *debugfs_create_automount(const char *name, inc_nlink(inode); d_make_persistent(dentry, inode); inc_nlink(d_inode(dentry->d_parent)); - fsnotify_mkdir(d_inode(dentry->d_parent), dentry); return debugfs_end_creating(dentry); } EXPORT_SYMBOL(debugfs_create_automount); diff --git a/fs/libfs.c b/fs/libfs.c index 74134ba2e8d1e..2f6dcae40ce7f 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -2322,3 +2322,17 @@ void simple_done_creating(struct dentry *child) dput(child); } EXPORT_SYMBOL(simple_done_creating); + +/* + * Like simple_done_creating(), but also fires fsnotify_create() for the + * new dentry. Call on the success path after d_make_persistent(). + * Use simple_done_creating() on the failure path where the child dentry is + * still negative. + */ +void simple_end_creating(struct dentry *child) +{ + fsnotify_create(child->d_parent->d_inode, child); + inode_unlock(child->d_parent->d_inode); + dput(child); +} +EXPORT_SYMBOL(simple_end_creating); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index e9acd2cd602cb..6e600d52b66d0 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "idmap.h" @@ -1146,8 +1145,7 @@ static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *nc } d_make_persistent(dentry, inode); inc_nlink(dir); - fsnotify_mkdir(dir, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; // borrowed } @@ -1178,8 +1176,7 @@ static void _nfsd_symlink(struct dentry *parent, const char *name, inode->i_size = strlen(content); d_make_persistent(dentry, inode); - fsnotify_create(dir, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); } #else static inline void _nfsd_symlink(struct dentry *parent, const char *name, @@ -1219,7 +1216,6 @@ static int nfsdfs_create_files(struct dentry *root, struct nfsdfs_client *ncl, struct dentry **fdentries) { - struct inode *dir = d_inode(root); struct dentry *dentry; for (int i = 0; files->name && files->name[0]; i++, files++) { @@ -1236,10 +1232,9 @@ static int nfsdfs_create_files(struct dentry *root, inode->i_fop = files->ops; inode->i_private = ncl; d_make_persistent(dentry, inode); - fsnotify_create(dir, dentry); if (fdentries) fdentries[i] = dentry; // borrowed - simple_done_creating(dentry); + simple_end_creating(dentry); } return 0; } diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 8e5ac464b3284..059ea7560b9b4 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -14,7 +14,6 @@ * inodes/dentries in a just-in-time (JIT) manner. The eventfs will clean up * and delete the inodes/dentries when they are no longer referenced. */ -#include #include #include #include @@ -826,7 +825,6 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry d_make_persistent(dentry, inode); /* The dentry of the "events" parent does keep track though */ inc_nlink(dentry->d_parent->d_inode); - fsnotify_mkdir(dentry->d_parent->d_inode, dentry); tracefs_end_creating(dentry); return ei; diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 51c00c8fa1755..90a15c064e309 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -578,7 +577,7 @@ struct dentry *tracefs_failed_creating(struct dentry *dentry) struct dentry *tracefs_end_creating(struct dentry *dentry) { - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; // borrowed } @@ -661,7 +660,6 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, inode->i_uid = d_inode(dentry->d_parent)->i_uid; inode->i_gid = d_inode(dentry->d_parent)->i_gid; d_make_persistent(dentry, inode); - fsnotify_create(d_inode(dentry->d_parent), dentry); return tracefs_end_creating(dentry); } @@ -693,7 +691,6 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, inc_nlink(inode); d_make_persistent(dentry, inode); inc_nlink(d_inode(dentry->d_parent)); - fsnotify_mkdir(d_inode(dentry->d_parent), dentry); return tracefs_end_creating(dentry); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 8b3dd145b25ec..8e5080be34308 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3271,6 +3271,7 @@ extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int extern void simple_release_fs(struct vfsmount **mount, int *count); struct dentry *simple_start_creating(struct dentry *, const char *); void simple_done_creating(struct dentry *); +void simple_end_creating(struct dentry *); extern ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos, const void *from, size_t available); diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 9d349cfbc4831..84d0ba37d9d6f 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -544,8 +543,7 @@ static int rpc_new_file(struct dentry *parent, inode->i_fop = i_fop; rpc_inode_setowner(inode, private); d_make_persistent(dentry, inode); - fsnotify_create(dir, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return 0; } @@ -569,8 +567,7 @@ static struct dentry *rpc_new_dir(struct dentry *parent, inode->i_ino = iunique(dir->i_sb, 100); inc_nlink(dir); d_make_persistent(dentry, inode); - fsnotify_mkdir(dir, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return dentry; // borrowed } @@ -667,8 +664,7 @@ int rpc_mkpipe_dentry(struct dentry *parent, const char *name, rpc_inode_setowner(inode, private); pipe->dentry = dentry; // borrowed d_make_persistent(dentry, inode); - fsnotify_create(dir, dentry); - simple_done_creating(dentry); + simple_end_creating(dentry); return 0; failed: -- 2.53.0