From: Jan Kara <jack@suse.cz>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Jan Kara <jack@suse.cz>,
Matthew Bobrowski <mbobrowski@mbobrowski.org>,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v5 01/17] fsnotify: annotate directory entry modification events
Date: Wed, 6 Feb 2019 15:14:17 +0100 [thread overview]
Message-ID: <20190206141417.GA28837@quack2.suse.cz> (raw)
In-Reply-To: <20190110170444.30616-2-amir73il@gmail.com>
On Thu 10-01-19 19:04:28, Amir Goldstein wrote:
> "dirent" events are referring to events that modify directory entries,
> such as create,delete,rename. Those events should always be reported
> on a watched directory, regardless if FS_EVENT_ON_CHILD is set
> on the watch mask.
>
> fsnotify_nameremove() and fsnotify_move() were modified to no longer
> set the FS_EVENT_ON_CHILD event bit. This is a semantic change to
> align with the "dirent" event definition. It has no effect on any
> existing backend, because dnotify, inotify and audit always requets the
> child events and fanotify does not get the delete,rename events.
>
> The fsnotify_dirent() helper is used instead of fsnotify_parent() to
> report a dirent event to dentry->d_parent without FS_EVENT_ON_CHILD
> and regardless if parent has the FS_EVENT_ON_CHILD bit set.
>
> Unlike fsnotify_parent(), fsnotify_dirent() assumes that dentry->d_name
> and dentry->d_parent are stable. For fsnotify_create()/fsnotify_mkdir(),
> this assumption is abviously correct. For fsnotify_nameremove(), it is
> less trvial, so we use dget_parent() and take_dentry_name_snapshot() to
> grab stable references.
>
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
I've taken the liberty of removing the case analysis from
fsnotify_nameremove() comment. That is bound to become out of date pretty
soon and not very useful for the reader. Otherwise the patch looks good and
I've added it to my tree.
Honza
> ---
> include/linux/fsnotify.h | 68 ++++++++++++++++++++++++++++++++++------
> 1 file changed, 59 insertions(+), 9 deletions(-)
>
> diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
> index 2ccb08cb5d6a..116907928c7f 100644
> --- a/include/linux/fsnotify.h
> +++ b/include/linux/fsnotify.h
> @@ -17,8 +17,22 @@
> #include <linux/slab.h>
> #include <linux/bug.h>
>
> +/*
> + * Notify this @dir inode about a change in the directory entry @dentry.
> + *
> + * Unlike fsnotify_parent(), the event will be reported regardless of the
> + * FS_EVENT_ON_CHILD mask on the parent inode.
> + */
> +static inline int fsnotify_dirent(struct inode *dir, struct dentry *dentry,
> + __u32 mask)
> +{
> + return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
> + dentry->d_name.name, 0);
> +}
> +
> /* Notify this dentry's parent about a child's events. */
> -static inline int fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask)
> +static inline int fsnotify_parent(const struct path *path,
> + struct dentry *dentry, __u32 mask)
> {
> if (!dentry)
> dentry = path->dentry;
> @@ -85,8 +99,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
> {
> struct inode *source = moved->d_inode;
> u32 fs_cookie = fsnotify_get_cookie();
> - __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM);
> - __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO);
> + __u32 old_dir_mask = FS_MOVED_FROM;
> + __u32 new_dir_mask = FS_MOVED_TO;
> const unsigned char *new_name = moved->d_name.name;
>
> if (old_dir == new_dir)
> @@ -128,15 +142,54 @@ static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt)
>
> /*
> * fsnotify_nameremove - a filename was removed from a directory
> + *
> + * Called from d_delete() and nfs_complete_sillyrename().
> + * The latter is called from nfs client ->unlink() ->rmdir() ->rename()
> + * under parent vfs inode lock.
> + *
> + * Most filesystems call d_delete() from ->unlink() ->rmdir() ->rename()
> + * ops under parent vfs inode lock.
> + *
> + * Some pseudo filesystems call d_delete() without parent inode lock.
> + * Those filesystems have no ->rename() op and they do not call
> + * d_move() directly, so d_parent and d_name are stable by definition.
> + * Examples: devpts, efivarfs, rpc_pipefs, functionfs.
> + *
> + * Some clustered filesystems call d_delete() on remote nodes, not under
> + * vfs parent inode lock, but they use cluster distributed locks on local
> + * and remote nodes. Those filesystems call d_delete() under their cluster
> + * lock. Examples:
> + * - in ceph_fill_trace() under CEPH_MDS_R_PARENT_LOCKED
> + * - in ocfs2_dentry_convert_worker() under ocfs2_dentry_lock
> + * But those filesystems also call d_move() under the same cluster lock
> + * (i.e. FS_RENAME_DOES_D_MOVE), so d_parent and d_name are also stable.
> + *
> + * However, to be on the safe side and be reselient to future callers
> + * and out of tree users of d_delete(), we do not assume that d_parent and
> + * d_name are stable and we use dget_parent() and take_dentry_name_snapshot()
> + * to grab stable references.
> */
> static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
> {
> + struct dentry *parent;
> + struct name_snapshot name;
> __u32 mask = FS_DELETE;
>
> + /* d_delete() of pseudo inode? (e.g. __ns_get_path() playing tricks) */
> + if (IS_ROOT(dentry))
> + return;
> +
> if (isdir)
> mask |= FS_ISDIR;
>
> - fsnotify_parent(NULL, dentry, mask);
> + parent = dget_parent(dentry);
> + take_dentry_name_snapshot(&name, dentry);
> +
> + fsnotify(d_inode(parent), mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
> + name.name, 0);
> +
> + release_dentry_name_snapshot(&name);
> + dput(parent);
> }
>
> /*
> @@ -155,7 +208,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
> {
> audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
>
> - fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
> + fsnotify_dirent(inode, dentry, FS_CREATE);
> }
>
> /*
> @@ -176,12 +229,9 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct
> */
> static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
> {
> - __u32 mask = (FS_CREATE | FS_ISDIR);
> - struct inode *d_inode = dentry->d_inode;
> -
> audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
>
> - fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
> + fsnotify_dirent(inode, dentry, FS_CREATE | FS_ISDIR);
> }
>
> /*
> --
> 2.17.1
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
next prev parent reply other threads:[~2019-02-06 14:14 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-10 17:04 [PATCH v5 00/17] fanotify: add support for more event types Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 01/17] fsnotify: annotate directory entry modification events Amir Goldstein
2019-02-06 14:14 ` Jan Kara [this message]
2019-01-10 17:04 ` [PATCH v5 02/17] fsnotify: remove dirent events from FS_EVENTS_POSS_ON_CHILD mask Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 03/17] fsnotify: send all event types to super block marks Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 04/17] fsnotify: move mask out of struct fsnotify_event Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 05/17] fanotify: rename struct fanotify_{,perm_}event_info Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 06/17] fanotify: open code fill_event_metadata() Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 07/17] fanotify: encode file identifier for FAN_REPORT_FID Amir Goldstein
2019-01-11 8:10 ` kbuild test robot
2019-01-11 8:37 ` Amir Goldstein
2019-01-18 18:39 ` Paul Burton
2019-01-10 17:04 ` [PATCH v5 08/17] fanotify: copy event fid info to user Amir Goldstein
2019-02-06 17:41 ` Jan Kara
2019-01-10 17:04 ` [PATCH v5 09/17] fanotify: enable FAN_REPORT_FID init flag Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 10/17] fanotify: cache fsid in fsnotify_mark_connector Amir Goldstein
2019-01-11 3:13 ` kbuild test robot
2019-01-14 7:30 ` Dan Carpenter
2019-01-14 7:30 ` Dan Carpenter
2019-01-14 9:17 ` Amir Goldstein
2019-02-07 14:48 ` Jan Kara
2019-02-07 16:31 ` Amir Goldstein
2019-02-08 10:15 ` Jan Kara
2019-01-10 17:04 ` [PATCH v5 11/17] vfs: add vfs_get_fsid() helper Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 12/17] fanotify: use vfs_get_fsid() helper instead of vfs_statfs() Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 13/17] fsnotify: report FS_ISDIR flag with MOVE_SELF and DELETE_SELF events Amir Goldstein
2019-02-07 14:57 ` Jan Kara
2019-01-10 17:04 ` [PATCH v5 14/17] fanotify: check FS_ISDIR flag instead of d_is_dir() Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 15/17] fanotify: support events with data type FSNOTIFY_EVENT_INODE Amir Goldstein
2019-02-07 15:18 ` Jan Kara
2019-02-07 16:10 ` Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 16/17] fanotify: add support for create/attrib/move/delete events Amir Goldstein
2019-01-10 17:04 ` [PATCH v5 17/17] fanotify: report FAN_ONDIR to listener with FAN_REPORT_FID Amir Goldstein
2019-02-07 16:26 ` [PATCH v5 00/17] fanotify: add support for more event types Jan Kara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190206141417.GA28837@quack2.suse.cz \
--to=jack@suse.cz \
--cc=amir73il@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mbobrowski@mbobrowski.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).