linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Josef Bacik <josef@toxicpanda.com>,
	kernel-team@fb.com, linux-fsdevel@vger.kernel.org,
	 brauner@kernel.org, torvalds@linux-foundation.org,
	viro@zeniv.linux.org.uk,  linux-xfs@vger.kernel.org,
	linux-btrfs@vger.kernel.org, linux-mm@kvack.org,
	 linux-ext4@vger.kernel.org
Subject: Re: [PATCH v8 03/19] fsnotify: add helper to check if file is actually being watched
Date: Wed, 20 Nov 2024 17:42:18 +0100	[thread overview]
Message-ID: <CAOQ4uxj4pwH2hfmNL0N=q8-rOF6d=-Z_yWLEwHQ671t1EvRn6A@mail.gmail.com> (raw)
In-Reply-To: <20241120160247.sdvonyxkpmf4wnt2@quack3>

On Wed, Nov 20, 2024 at 5:02 PM Jan Kara <jack@suse.cz> wrote:
>
> On Fri 15-11-24 10:30:16, Josef Bacik wrote:
> > From: Amir Goldstein <amir73il@gmail.com>
> >
> > So far, we set FMODE_NONOTIFY_ flags at open time if we know that there
> > are no permission event watchers at all on the filesystem, but lack of
> > FMODE_NONOTIFY_ flags does not mean that the file is actually watched.
> >
> > To make the flags more accurate we add a helper that checks if the
> > file's inode, mount, sb or parent are being watched for a set of events.
> >
> > This is going to be used for setting FMODE_NONOTIFY_HSM only when the
> > specific file is actually watched for pre-content events.
> >
> > Signed-off-by: Amir Goldstein <amir73il@gmail.com>
>
> I did some changes here as well. See below:
>
> > -/* Are there any inode/mount/sb objects that are interested in this event? */
> > -static inline bool fsnotify_object_watched(struct inode *inode, __u32 mnt_mask,
> > -                                        __u32 mask)
> > +/* Are there any inode/mount/sb objects that watch for these events? */
> > +static inline __u32 fsnotify_object_watched(struct inode *inode, __u32 mnt_mask,
> > +                                         __u32 events_mask)
> >  {
> >       __u32 marks_mask = READ_ONCE(inode->i_fsnotify_mask) | mnt_mask |
> >                          READ_ONCE(inode->i_sb->s_fsnotify_mask);
> >
> > -     return mask & marks_mask & ALL_FSNOTIFY_EVENTS;
> > +     return events_mask & marks_mask;
> >  }
> >
> > +/* Are there any inode/mount/sb/parent objects that watch for these events? */
> > +__u32 fsnotify_file_object_watched(struct file *file, __u32 events_mask)
> > +{
> > +     struct dentry *dentry = file->f_path.dentry;
> > +     struct dentry *parent;
> > +     __u32 marks_mask, mnt_mask =
> > +             READ_ONCE(real_mount(file->f_path.mnt)->mnt_fsnotify_mask);
> > +
> > +     marks_mask = fsnotify_object_watched(d_inode(dentry), mnt_mask,
> > +                                          events_mask);
> > +
> > +     if (likely(!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)))
> > +             return marks_mask;
> > +
> > +     parent = dget_parent(dentry);
> > +     marks_mask |= fsnotify_inode_watches_children(d_inode(parent));
> > +     dput(parent);
> > +
> > +     return marks_mask & events_mask;
> > +}
> > +EXPORT_SYMBOL_GPL(fsnotify_file_object_watched);
>
> I find it confusing that fsnotify_object_watched() does not take parent
> into account while fsnotify_file_object_watched() does. Furthermore the
> naming doesn't very well reflect the fact we are actually returning a mask
> of events. I've ended up dropping this helper (it's used in a single place
> anyway) and instead doing the same directly in file_set_fsnotify_mode().
>
> @@ -658,6 +660,27 @@ void file_set_fsnotify_mode(struct file *file)
>                 file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
>                 return;
>         }
> +
> +       /*
> +        * OK, there are some pre-content watchers. Check if anybody can be
> +        * watching for pre-content events on *this* file.
> +        */
> +       mnt_mask = READ_ONCE(real_mount(file->f_path.mnt)->mnt_fsnotify_mask);
> +       if (likely(!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED) &&
> +           !fsnotify_object_watched(d_inode(dentry), mnt_mask,
> +                                    FSNOTIFY_PRE_CONTENT_EVENTS))) {
> +               file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
> +               return;
> +       }
> +
> +       /* Even parent is not watching for pre-content events on this file? */
> +       parent = dget_parent(dentry);
> +       p_mask = fsnotify_inode_watches_children(d_inode(parent));
> +       dput(parent);
> +       if (!(p_mask & FSNOTIFY_PRE_CONTENT_EVENTS)) {
> +               file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
> +               return;
> +       }
>  }
>

Nice!

Note that I had a "hidden motive" for future optimization when I changed
return value of fsnotify_object_watched() to a mask -

I figured that while we are doing the checks above, we can check for the
same price the mask ALL_FSNOTIFY_PERM_EVENTS
then we get several answers for the same price:
1. Is the specific file watched by HSM?
2. Is the specific file watched by open permission events?
3. Is the specific file watched by post-open FAN_ACCESS_PERM?

If the answers are No, No, No, we get some extra optimization
in the (uncommon) use case that there are permission event watchers
on some random inodes in the filesystem.

If the answers are Yes, Yes, No, or No, Yes, No we can return a special
value from file_set_fsnotify_mode() to indicate that permission events
are needed ONLY for fsnotify_open_perm() hook, but not thereafter.

This would implement the semantic change of "respect FAN_ACCESS_PERM
only if it existed at open time" that can save a lot of unneeded cycles in
the very hot read/write path, for example, when watcher only cares about
FAN_OPEN_EXEC_PERM.

I wasn't sure that any of this was worth the effort at this time, but
just in case
this gives you ideas of other useful optimizations we can do with the
object combined marks_mask if we get it for free.

Thanks,
Amir.


  reply	other threads:[~2024-11-20 16:42 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-15 15:30 [PATCH v8 00/19] fanotify: add pre-content hooks Josef Bacik
2024-11-15 15:30 ` [PATCH v8 01/19] fs: get rid of __FMODE_NONOTIFY kludge Josef Bacik
2024-11-18 18:14   ` Jan Kara
2024-11-15 15:30 ` [PATCH v8 02/19] fsnotify: opt-in for permission events at file open time Josef Bacik
2024-11-20 15:53   ` Jan Kara
2024-11-20 16:12     ` Amir Goldstein
2024-11-21  9:39       ` Jan Kara
2024-11-21 10:09         ` Christian Brauner
2024-11-21 11:04           ` Amir Goldstein
2024-11-21 11:16             ` Jan Kara
2024-11-21 11:32               ` Amir Goldstein
2024-11-21  9:45     ` Christian Brauner
2024-11-21 11:39       ` Amir Goldstein
2024-11-15 15:30 ` [PATCH v8 03/19] fsnotify: add helper to check if file is actually being watched Josef Bacik
2024-11-20 16:02   ` Jan Kara
2024-11-20 16:42     ` Amir Goldstein [this message]
2024-11-21  8:54       ` Jan Kara
2024-11-15 15:30 ` [PATCH v8 04/19] fanotify: don't skip extra event info if no info_mode is set Josef Bacik
2024-11-15 15:30 ` [PATCH v8 05/19] fanotify: rename a misnamed constant Josef Bacik
2024-11-15 15:30 ` [PATCH v8 06/19] fanotify: reserve event bit of deprecated FAN_DIR_MODIFY Josef Bacik
2024-11-15 15:30 ` [PATCH v8 07/19] fsnotify: introduce pre-content permission events Josef Bacik
2024-11-15 15:30 ` [PATCH v8 08/19] fsnotify: pass optional file access range in pre-content event Josef Bacik
2024-11-15 15:30 ` [PATCH v8 09/19] fsnotify: generate pre-content permission event on truncate Josef Bacik
2024-11-20 15:23   ` Jan Kara
2024-11-20 15:57     ` Amir Goldstein
2024-11-20 16:16       ` Jan Kara
2024-11-15 15:30 ` [PATCH v8 10/19] fanotify: introduce FAN_PRE_ACCESS permission event Josef Bacik
2024-11-15 15:59   ` Amir Goldstein
2024-11-21 10:44   ` Jan Kara
2024-11-21 14:18     ` Amir Goldstein
2024-11-21 16:36       ` Jan Kara
2024-11-21 18:31         ` Amir Goldstein
2024-11-21 18:37           ` Amir Goldstein
2024-11-22 12:42             ` Jan Kara
2024-11-22 13:51               ` Amir Goldstein
2024-11-27 12:18                 ` Jan Kara
2024-11-27 12:20                   ` Amir Goldstein
2024-11-15 15:30 ` [PATCH v8 11/19] fanotify: report file range info with pre-content events Josef Bacik
2024-11-15 15:30 ` [PATCH v8 12/19] fanotify: allow to set errno in FAN_DENY permission response Josef Bacik
2024-11-15 15:30 ` [PATCH v8 13/19] fanotify: add a helper to check for pre content events Josef Bacik
2024-11-20 15:44   ` Jan Kara
2024-11-20 16:43     ` Amir Goldstein
2024-11-15 15:30 ` [PATCH v8 14/19] fanotify: disable readahead if we have pre-content watches Josef Bacik
2024-11-15 15:30 ` [PATCH v8 15/19] mm: don't allow huge faults for files with pre content watches Josef Bacik
2025-01-31 19:17   ` [REGRESSION] " Alex Williamson
2025-01-31 19:59     ` Linus Torvalds
2025-02-01  1:19       ` Peter Xu
2025-02-01 14:38         ` Christian Brauner
2025-02-02  0:58           ` Linus Torvalds
2025-02-02  7:46             ` Amir Goldstein
2025-02-02 10:04               ` Christian Brauner
2025-02-03 12:41                 ` Jan Kara
2025-02-03 20:39                   ` Amir Goldstein
2025-02-03 21:41                     ` Alex Williamson
2025-02-03 22:04                       ` Amir Goldstein
2024-11-15 15:30 ` [PATCH v8 16/19] fsnotify: generate pre-content permission event on page fault Josef Bacik
2024-12-08 16:58   ` Klara Modin
2024-12-09 10:45     ` Aithal, Srikanth
2024-12-09 12:34       ` Jan Kara
2024-12-09 12:31     ` Jan Kara
2024-12-09 12:56       ` Klara Modin
2024-12-09 14:16         ` Jan Kara
2024-12-10 21:12     ` Randy Dunlap
2024-12-11 16:30       ` Jan Kara
2024-11-15 15:30 ` [PATCH v8 17/19] xfs: add pre-content fsnotify hook for write faults Josef Bacik
2024-11-21 10:22   ` Jan Kara
2024-11-15 15:30 ` [PATCH v8 18/19] btrfs: disable defrag on pre-content watched files Josef Bacik
2024-11-15 15:30 ` [PATCH v8 19/19] fs: enable pre-content events on supported file systems Josef Bacik
2024-11-21 11:29 ` [PATCH v8 00/19] fanotify: add pre-content hooks 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='CAOQ4uxj4pwH2hfmNL0N=q8-rOF6d=-Z_yWLEwHQ671t1EvRn6A@mail.gmail.com' \
    --to=amir73il@gmail.com \
    --cc=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=josef@toxicpanda.com \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /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