Re: [PATCH 1/3] fsnotify: use accessor to set FMODE_NONOTIFY_*

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Feb 4, 2025 at 11:43 AM Christian Brauner <brauner@xxxxxxxxxx> wrote:
>
> On Mon, Feb 03, 2025 at 11:32:03PM +0100, Amir Goldstein wrote:
> > The FMODE_NONOTIFY_* bits are a 2-bits mode.  Open coding manipulation
> > of those bits is risky.  Use an accessor file_set_fsnotify_mode() to
> > set the mode.
> >
> > Rename file_set_fsnotify_mode() => file_set_fsnotify_mode_from_watchers()
> > to make way for the simple accessor name.
> >
> > Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> > ---
> >  drivers/tty/pty.c        |  2 +-
> >  fs/notify/fsnotify.c     | 18 ++++++++++++------
> >  fs/open.c                |  7 ++++---
> >  include/linux/fs.h       |  9 ++++++++-
> >  include/linux/fsnotify.h |  4 ++--
> >  5 files changed, 27 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
> > index df08f13052ff4..8bb1a01fef2a1 100644
> > --- a/drivers/tty/pty.c
> > +++ b/drivers/tty/pty.c
> > @@ -798,7 +798,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
> >       nonseekable_open(inode, filp);
> >
> >       /* We refuse fsnotify events on ptmx, since it's a shared resource */
> > -     filp->f_mode |= FMODE_NONOTIFY;
> > +     file_set_fsnotify_mode(filp, FMODE_NONOTIFY);
> >
> >       retval = tty_alloc_file(filp);
> >       if (retval)
> > diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
> > index 8ee495a58d0ad..77a1521335a10 100644
> > --- a/fs/notify/fsnotify.c
> > +++ b/fs/notify/fsnotify.c
> > @@ -648,7 +648,7 @@ EXPORT_SYMBOL_GPL(fsnotify);
> >   * Later, fsnotify permission hooks do not check if there are permission event
> >   * watches, but that there were permission event watches at open time.
> >   */
> > -void file_set_fsnotify_mode(struct file *file)
> > +void file_set_fsnotify_mode_from_watchers(struct file *file)
> >  {
> >       struct dentry *dentry = file->f_path.dentry, *parent;
> >       struct super_block *sb = dentry->d_sb;
> > @@ -665,7 +665,7 @@ void file_set_fsnotify_mode(struct file *file)
> >        */
> >       if (likely(!fsnotify_sb_has_priority_watchers(sb,
> >                                               FSNOTIFY_PRIO_CONTENT))) {
> > -             file->f_mode |= FMODE_NONOTIFY_PERM;
> > +             file_set_fsnotify_mode(file, FMODE_NONOTIFY_PERM);
> >               return;
> >       }
> >
> > @@ -676,7 +676,7 @@ void file_set_fsnotify_mode(struct file *file)
> >       if ((!d_is_dir(dentry) && !d_is_reg(dentry)) ||
> >           likely(!fsnotify_sb_has_priority_watchers(sb,
> >                                               FSNOTIFY_PRIO_PRE_CONTENT))) {
> > -             file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
> > +             file_set_fsnotify_mode(file, FMODE_NONOTIFY_HSM);
> >               return;
> >       }
> >
> > @@ -686,19 +686,25 @@ void file_set_fsnotify_mode(struct file *file)
> >        */
> >       mnt_mask = READ_ONCE(real_mount(file->f_path.mnt)->mnt_fsnotify_mask);
> >       if (unlikely(fsnotify_object_watched(d_inode(dentry), mnt_mask,
> > -                                  FSNOTIFY_PRE_CONTENT_EVENTS)))
> > +                                  FSNOTIFY_PRE_CONTENT_EVENTS))) {
> > +             /* Enable pre-content events */
> > +             file_set_fsnotify_mode(file, 0);
> >               return;
> > +     }
> >
> >       /* Is parent watching for pre-content events on this file? */
> >       if (dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED) {
> >               parent = dget_parent(dentry);
> >               p_mask = fsnotify_inode_watches_children(d_inode(parent));
> >               dput(parent);
> > -             if (p_mask & FSNOTIFY_PRE_CONTENT_EVENTS)
> > +             if (p_mask & FSNOTIFY_PRE_CONTENT_EVENTS) {
> > +                     /* Enable pre-content events */
> > +                     file_set_fsnotify_mode(file, 0);
> >                       return;
> > +             }
> >       }
> >       /* Nobody watching for pre-content events from this file */
> > -     file->f_mode |= FMODE_NONOTIFY | FMODE_NONOTIFY_PERM;
> > +     file_set_fsnotify_mode(file, FMODE_NONOTIFY_HSM);
> >  }
> >  #endif
> >
> > diff --git a/fs/open.c b/fs/open.c
> > index 932e5a6de63bb..3fcbfff8aede8 100644
> > --- a/fs/open.c
> > +++ b/fs/open.c
> > @@ -905,7 +905,8 @@ static int do_dentry_open(struct file *f,
> >       f->f_sb_err = file_sample_sb_err(f);
> >
> >       if (unlikely(f->f_flags & O_PATH)) {
> > -             f->f_mode = FMODE_PATH | FMODE_OPENED | FMODE_NONOTIFY;
> > +             f->f_mode = FMODE_PATH | FMODE_OPENED;
> > +             file_set_fsnotify_mode(f, FMODE_NONOTIFY);
> >               f->f_op = &empty_fops;
> >               return 0;
> >       }
> > @@ -938,7 +939,7 @@ static int do_dentry_open(struct file *f,
> >        * If FMODE_NONOTIFY was already set for an fanotify fd, this doesn't
> >        * change anything.
> >        */
> > -     file_set_fsnotify_mode(f);
> > +     file_set_fsnotify_mode_from_watchers(f);
> >       error = fsnotify_open_perm(f);
> >       if (error)
> >               goto cleanup_all;
> > @@ -1122,7 +1123,7 @@ struct file *dentry_open_nonotify(const struct path *path, int flags,
> >       if (!IS_ERR(f)) {
> >               int error;
> >
> > -             f->f_mode |= FMODE_NONOTIFY;
> > +             file_set_fsnotify_mode(f, FMODE_NONOTIFY);
> >               error = vfs_open(path, f);
> >               if (error) {
> >                       fput(f);
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index be3ad155ec9f7..e73d9b998780d 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -206,6 +206,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
> >   * FMODE_NONOTIFY_PERM - suppress permission (incl. pre-content) events.
> >   * FMODE_NONOTIFY | FMODE_NONOTIFY_PERM - suppress only pre-content events.
> >   */
> > +#define FMODE_NONOTIFY_HSM \
> > +     (FMODE_NONOTIFY | FMODE_NONOTIFY_PERM)
>
> After this patch series this define is used exactly twice and it's
> currently identical to FMODE_FSNOTIFY_HSM. I suggest to remove it and
> simply pass FMODE_NONOTIFY | FMODE_NONOTIFY_PERM in the two places it's
> used. I can do this myself though so if Jan doesn't have other comments
> don't bother resending.
>

I thought that
file_set_fsnotify_mode(file, FMODE_NONOTIFY_HSM);
is more readable then
file_set_fsnotify_mode(FMODE_NONOTIFY | FMODE_NONOTIFY_PERM);
and makes it clearer that the individual bits should not be messed with

but since Jan was one who pushed for open coding
f->f_mode = FMODE_PATH | FMODE_OPENED | FMODE_NONOTIFY;
I think he will agree with you,
so I humbly accept your suggestion :)

Thanks,
Amir.





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux