Christoph, >From my patch series, this is really the only patch that is a dependency to the patch you received earlier today: "fsnotify: call fsnotify_rmdir() hook from configfs" What you should know for wider context is that currently users can sign up for inotify notifications on configfs. If they do that with current kernel they will get notified when directory is removed not via vfs_rmdir() or via configfs_unregister_{group,subsystem}(). For reasons outside the scope of configfs, we intend to stop calling fsnotify hook from d_delete(). In order to preserve existing behavior (whether some users depends on it or not I do not know), we add explicit fsnotify hooks in configfs_unregister_{group,subsystem}(). For most pseduo filesystems that use simple_rmdir(), I chose a different approach of calling a new helper simple_remove(), where the new fsnotify hook is placed. For configfs, I could not use the same technique because configfs_remove_dir() is also called from execution path of vfs_rmdir(), where the new fsnotify hook is already called. Hope this context is sufficient for you to review the configfs patch and provide an ACK, so Jan or Al can carry the configfs patch. If you like me to post you the entire series, I can do that. Thanks, Amir. ---------- Forwarded message --------- From: Amir Goldstein <amir73il@xxxxxxxxx> Date: Thu, May 16, 2019 at 1:26 PM Subject: [PATCH v2 03/14] fsnotify: add empty fsnotify_{unlink,rmdir}() hooks To: Jan Kara <jack@xxxxxxx> Cc: Matthew Bobrowski <mbobrowski@xxxxxxxxxxxxxx>, <linux-fsdevel@xxxxxxxxxxxxxxx> We would like to move fsnotify_nameremove() calls from d_delete() into a higher layer where the hook makes more sense and so we can consider every d_delete() call site individually. Start by creating empty hook fsnotify_{unlink,rmdir}() and place them in the proper VFS call sites. After all d_delete() call sites will be converted to use the new hook, the new hook will generate the delete events and fsnotify_nameremove() hook will be removed. Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> --- fs/libfs.c | 11 ++++++++--- fs/namei.c | 2 ++ include/linux/fsnotify.h | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index ca1132f1d5c6..4db61ca8cc94 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -10,6 +10,7 @@ #include <linux/cred.h> #include <linux/mount.h> #include <linux/vfs.h> +#include <linux/fsnotify.h> #include <linux/quotaops.h> #include <linux/mutex.h> #include <linux/namei.h> @@ -367,11 +368,15 @@ int simple_remove(struct inode *dir, struct dentry *dentry) * protect d_delete() from accessing a freed dentry. */ dget(dentry); - if (d_is_dir(dentry)) + if (d_is_dir(dentry)) { ret = simple_rmdir(dir, dentry); - else + if (!ret) + fsnotify_rmdir(dir, dentry); + } else { ret = simple_unlink(dir, dentry); - + if (!ret) + fsnotify_unlink(dir, dentry); + } if (!ret) d_delete(dentry); dput(dentry); diff --git a/fs/namei.c b/fs/namei.c index 20831c2fbb34..209c51a5226c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3883,6 +3883,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) dentry->d_inode->i_flags |= S_DEAD; dont_mount(dentry); detach_mounts(dentry); + fsnotify_rmdir(dir, dentry); out: inode_unlock(dentry->d_inode); @@ -3999,6 +4000,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate if (!error) { dont_mount(dentry); detach_mounts(dentry); + fsnotify_unlink(dir, dentry); } } } diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 94972e8eb6d1..7f23eddefcd0 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -188,6 +188,19 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, &new_dentry->d_name, 0); } +/* + * fsnotify_unlink - 'name' was unlinked + * + * Caller must make sure that dentry->d_name is stable. + */ +static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry) +{ + /* Expected to be called before d_delete() */ + WARN_ON_ONCE(d_is_negative(dentry)); + + /* TODO: call fsnotify_dirent() */ +} + /* * fsnotify_mkdir - directory 'name' was created */ @@ -198,6 +211,19 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) fsnotify_dirent(inode, dentry, FS_CREATE | FS_ISDIR); } +/* + * fsnotify_rmdir - directory 'name' was removed + * + * Caller must make sure that dentry->d_name is stable. + */ +static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry) +{ + /* Expected to be called before d_delete() */ + WARN_ON_ONCE(d_is_negative(dentry)); + + /* TODO: call fsnotify_dirent() */ +} + /* * fsnotify_access - file was read */ -- 2.17.1