Re: Patch "fanotify: introduce group flag FAN_REPORT_TARGET_FID" has been added to the 5.15-stable tree

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

 



On Tue, Mar 19, 2024 at 1:11 AM Sasha Levin <sashal@xxxxxxxxxx> wrote:
>
> This is a note to let you know that I've just added the patch titled
>
>     fanotify: introduce group flag FAN_REPORT_TARGET_FID
>
> to the 5.15-stable tree which can be found at:
>     http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
>
> The filename of the patch is:
>      fanotify-introduce-group-flag-fan_report_target_fid.patch
> and it can be found in the queue-5.15 subdirectory.
>
> If you, or anyone else, feels it should not be added to the stable tree,
> please let <stable@xxxxxxxxxxxxxxx> know about it.
>

Hi Chuck,

Please follow up with update of man page fanotify_init(2) after merge:

       FAN_REPORT_TARGET_FID (since Linux 5.17)

For the records, the following fix commit are explicitly mentioned in
test fanotify14:

        .tags = (const struct tst_tag[]) {
                {"linux-git", "ceaf69f8eadc"},
                {"linux-git", "8698e3bab4dd"},

Because we took the opportunity of new API flags (FAN_RENAME and
FAN_REPORT_TARGET_FID) to refine the semantics of some legacy
undefined behavior.

Since you backported both those commits, no further action item here.

Thanks,
Amir.

>
>
> commit 590125f72397ab80cf7946dec01a3f5d700e530e
> Author: Amir Goldstein <amir73il@xxxxxxxxx>
> Date:   Mon Nov 29 22:15:29 2021 +0200
>
>     fanotify: introduce group flag FAN_REPORT_TARGET_FID
>
>     [ Upstream commit d61fd650e9d206a71fda789f02a1ced4b19944c4 ]
>
>     FAN_REPORT_FID is ambiguous in that it reports the fid of the child for
>     some events and the fid of the parent for create/delete/move events.
>
>     The new FAN_REPORT_TARGET_FID flag is an implicit request to report
>     the fid of the target object of the operation (a.k.a the child inode)
>     also in create/delete/move events in addition to the fid of the parent
>     and the name of the child.
>
>     To reduce the test matrix for uninteresting use cases, the new
>     FAN_REPORT_TARGET_FID flag requires both FAN_REPORT_NAME and
>     FAN_REPORT_FID.  The convenience macro FAN_REPORT_DFID_NAME_TARGET
>     combines FAN_REPORT_TARGET_FID with all the required flags.
>
>     Link: https://lore.kernel.org/r/20211129201537.1932819-4-amir73il@xxxxxxxxx
>     Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
>     Signed-off-by: Jan Kara <jack@xxxxxxx>
>     Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
>
> diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
> index 652fe84cb8acd..85e542b164c8c 100644
> --- a/fs/notify/fanotify/fanotify.c
> +++ b/fs/notify/fanotify/fanotify.c
> @@ -458,17 +458,41 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode,
>  }
>
>  /*
> - * The inode to use as identifier when reporting fid depends on the event.
> - * Report the modified directory inode on dirent modification events.
> - * Report the "victim" inode otherwise.
> + * FAN_REPORT_FID is ambiguous in that it reports the fid of the child for
> + * some events and the fid of the parent for create/delete/move events.
> + *
> + * With the FAN_REPORT_TARGET_FID flag, the fid of the child is reported
> + * also in create/delete/move events in addition to the fid of the parent
> + * and the name of the child.
> + */
> +static inline bool fanotify_report_child_fid(unsigned int fid_mode, u32 mask)
> +{
> +       if (mask & ALL_FSNOTIFY_DIRENT_EVENTS)
> +               return (fid_mode & FAN_REPORT_TARGET_FID);
> +
> +       return (fid_mode & FAN_REPORT_FID) && !(mask & FAN_ONDIR);
> +}
> +
> +/*
> + * The inode to use as identifier when reporting fid depends on the event
> + * and the group flags.
> + *
> + * With the group flag FAN_REPORT_TARGET_FID, always report the child fid.
> + *
> + * Without the group flag FAN_REPORT_TARGET_FID, report the modified directory
> + * fid on dirent events and the child fid otherwise.
> + *
>   * For example:
> - * FS_ATTRIB reports the child inode even if reported on a watched parent.
> - * FS_CREATE reports the modified dir inode and not the created inode.
> + * FS_ATTRIB reports the child fid even if reported on a watched parent.
> + * FS_CREATE reports the modified dir fid without FAN_REPORT_TARGET_FID.
> + *       and reports the created child fid with FAN_REPORT_TARGET_FID.
>   */
>  static struct inode *fanotify_fid_inode(u32 event_mask, const void *data,
> -                                       int data_type, struct inode *dir)
> +                                       int data_type, struct inode *dir,
> +                                       unsigned int fid_mode)
>  {
> -       if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS)
> +       if ((event_mask & ALL_FSNOTIFY_DIRENT_EVENTS) &&
> +           !(fid_mode & FAN_REPORT_TARGET_FID))
>                 return dir;
>
>         return fsnotify_data_inode(data, data_type);
> @@ -647,10 +671,11 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
>  {
>         struct fanotify_event *event = NULL;
>         gfp_t gfp = GFP_KERNEL_ACCOUNT;
> -       struct inode *id = fanotify_fid_inode(mask, data, data_type, dir);
> +       unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
> +       struct inode *id = fanotify_fid_inode(mask, data, data_type, dir,
> +                                             fid_mode);
>         struct inode *dirid = fanotify_dfid_inode(mask, data, data_type, dir);
>         const struct path *path = fsnotify_data_path(data, data_type);
> -       unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
>         struct mem_cgroup *old_memcg;
>         struct inode *child = NULL;
>         bool name_event = false;
> @@ -660,11 +685,10 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
>
>         if ((fid_mode & FAN_REPORT_DIR_FID) && dirid) {
>                 /*
> -                * With both flags FAN_REPORT_DIR_FID and FAN_REPORT_FID, we
> -                * report the child fid for events reported on a non-dir child
> +                * For certain events and group flags, report the child fid
>                  * in addition to reporting the parent fid and maybe child name.
>                  */
> -               if ((fid_mode & FAN_REPORT_FID) && id != dirid && !ondir)
> +               if (fanotify_report_child_fid(fid_mode, mask) && id != dirid)
>                         child = id;
>
>                 id = dirid;
> diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
> index e8f6c843e9204..bfafda0447ea7 100644
> --- a/fs/notify/fanotify/fanotify_user.c
> +++ b/fs/notify/fanotify/fanotify_user.c
> @@ -1275,6 +1275,15 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
>         if ((fid_mode & FAN_REPORT_NAME) && !(fid_mode & FAN_REPORT_DIR_FID))
>                 return -EINVAL;
>
> +       /*
> +        * FAN_REPORT_TARGET_FID requires FAN_REPORT_NAME and FAN_REPORT_FID
> +        * and is used as an indication to report both dir and child fid on all
> +        * dirent events.
> +        */
> +       if ((fid_mode & FAN_REPORT_TARGET_FID) &&
> +           (!(fid_mode & FAN_REPORT_NAME) || !(fid_mode & FAN_REPORT_FID)))
> +               return -EINVAL;
> +
>         f_flags = O_RDWR | FMODE_NONOTIFY;
>         if (flags & FAN_CLOEXEC)
>                 f_flags |= O_CLOEXEC;
> @@ -1685,7 +1694,7 @@ static int __init fanotify_user_setup(void)
>                                      FANOTIFY_DEFAULT_MAX_USER_MARKS);
>
>         BUILD_BUG_ON(FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS);
> -       BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 11);
> +       BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 12);
>         BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 9);
>
>         fanotify_mark_cache = KMEM_CACHE(fsnotify_mark,
> diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
> index 616af2ea20f30..376e050e6f384 100644
> --- a/include/linux/fanotify.h
> +++ b/include/linux/fanotify.h
> @@ -25,7 +25,7 @@ extern struct ctl_table fanotify_table[]; /* for sysctl */
>
>  #define FANOTIFY_CLASS_BITS    (FAN_CLASS_NOTIF | FANOTIFY_PERM_CLASSES)
>
> -#define FANOTIFY_FID_BITS      (FAN_REPORT_FID | FAN_REPORT_DFID_NAME)
> +#define FANOTIFY_FID_BITS      (FAN_REPORT_DFID_NAME_TARGET)
>
>  #define FANOTIFY_INFO_MODES    (FANOTIFY_FID_BITS | FAN_REPORT_PIDFD)
>
> diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
> index bd1932c2074d5..60f73639a896a 100644
> --- a/include/uapi/linux/fanotify.h
> +++ b/include/uapi/linux/fanotify.h
> @@ -57,9 +57,13 @@
>  #define FAN_REPORT_FID         0x00000200      /* Report unique file id */
>  #define FAN_REPORT_DIR_FID     0x00000400      /* Report unique directory id */
>  #define FAN_REPORT_NAME                0x00000800      /* Report events with name */
> +#define FAN_REPORT_TARGET_FID  0x00001000      /* Report dirent target id  */
>
>  /* Convenience macro - FAN_REPORT_NAME requires FAN_REPORT_DIR_FID */
>  #define FAN_REPORT_DFID_NAME   (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)
> +/* Convenience macro - FAN_REPORT_TARGET_FID requires all other FID flags */
> +#define FAN_REPORT_DFID_NAME_TARGET (FAN_REPORT_DFID_NAME | \
> +                                    FAN_REPORT_FID | FAN_REPORT_TARGET_FID)
>
>  /* Deprecated - do not use this in programs and do not add new flags here! */
>  #define FAN_ALL_INIT_FLAGS     (FAN_CLOEXEC | FAN_NONBLOCK | \





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux