Re: [PATCH] fanotify: support custom default close response

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

 



On Mon, Jun 23, 2025 at 9:26 PM Ibrahim Jirdeh <ibrahimjirdeh@xxxxxxxx> wrote:
>
> Currently the default response for pending events is FAN_ALLOW.
> This makes default close response configurable. The main goal
> of these changes would be to provide better handling for pending
> events for lazy file loading use cases which may back fanotify
> events by a long-lived daemon. For earlier discussion see:
> https://lore.kernel.org/linux-fsdevel/6za2mngeqslmqjg3icoubz37hbbxi6bi44canfsg2aajgkialt@c3ujlrjzkppr/

These lore links are typically placed at the commit message tail block
if related to a suggestion you would typically use:

Suggested-by: Amir Goldstein <amir73il@xxxxxxxxx>
Link: https://lore.kernel.org/linux-fsdevel/CAOQ4uxi6PvAcT1vL0d0e+7YjvkfU-kwFVVMAN-tc-FKXe1wtSg@xxxxxxxxxxxxxx/
Signed-off-by: Ibrahim Jirdeh <ibrahimjirdeh@xxxxxxxx>

This way reviewers whose response is "what a terrible idea!" can
point their arrows at me instead of you ;)

Note that this is a more accurate link to the message where the default
response API was proposed, so readers won't need to sift through
this long thread to find the reference.

> This implements the first approach outlined there of providing
> configuration for response on group close. This is supported by
> writing a response with
> .fd = FAN_NOFD
> .response = FAN_DENY | FAN_DEFAULT
> which modifies the group property default_response
>
> Signed-off-by: Ibrahim Jirdeh <ibrahimjirdeh@xxxxxxxx>
> ---
>  fs/notify/fanotify/fanotify_user.c  | 14 ++++++++++++--
>  include/linux/fanotify.h            |  2 +-
>  include/linux/fsnotify_backend.h    |  1 +
>  include/uapi/linux/fanotify.h       |  1 +
>  tools/include/uapi/linux/fanotify.h |  1 +
>  5 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
> index b192ee068a7a..02669abff4a5 100644
> --- a/fs/notify/fanotify/fanotify_user.c
> +++ b/fs/notify/fanotify/fanotify_user.c
> @@ -378,6 +378,13 @@ static int process_access_response(struct fsnotify_group *group,
>                 return -EINVAL;
>         }
>
> +       if (response & FAN_DEFAULT) {
> +               if (fd != FAN_NOFD)
> +                       return -EINVAL;

I think we also need to check that no bits other than the allowed bits
for default response
are set, for example, if user attempts to do:
 .response = FAN_DENY | FAN_AUDIT | FAN_DEFAULT

But that opens up the question, do we want to also allow custom
error in default response, e.g.:
 .response = FAN_DENY_ERRNO(EAGAIN) | FAN_DEFAULT

Anyway, we do not have to implement custom default error from the
start. It will complicate the implementation a bit, but as long as you deny
setting the default response with unsupported flags, we can extend it later.

> +               group->default_response = response & FANOTIFY_RESPONSE_ACCESS;
> +               return 0;
> +       }
> +
>         if ((response & FAN_AUDIT) && !FAN_GROUP_FLAG(group, FAN_ENABLE_AUDIT))
>                 return -EINVAL;
>
> @@ -1023,7 +1030,8 @@ static int fanotify_release(struct inode *ignored, struct file *file)
>                 event = list_first_entry(&group->fanotify_data.access_list,
>                                 struct fanotify_perm_event, fae.fse.list);
>                 list_del_init(&event->fae.fse.list);
> -               finish_permission_event(group, event, FAN_ALLOW, NULL);
> +               finish_permission_event(group, event,
> +                               group->default_response, NULL);
>                 spin_lock(&group->notification_lock);
>         }
>
> @@ -1040,7 +1048,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
>                         fsnotify_destroy_event(group, fsn_event);
>                 } else {
>                         finish_permission_event(group, FANOTIFY_PERM(event),
> -                                               FAN_ALLOW, NULL);
> +                                               group->default_response, NULL);
>                 }
>                 spin_lock(&group->notification_lock);
>         }
> @@ -1640,6 +1648,8 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
>                 goto out_destroy_group;
>         }
>
> +       group->default_response = FAN_ALLOW;
> +
>         BUILD_BUG_ON(!(FANOTIFY_ADMIN_INIT_FLAGS & FAN_UNLIMITED_QUEUE));
>         if (flags & FAN_UNLIMITED_QUEUE) {
>                 group->max_events = UINT_MAX;
> diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
> index 879cff5eccd4..182fc574b848 100644
> --- a/include/linux/fanotify.h
> +++ b/include/linux/fanotify.h
> @@ -134,7 +134,7 @@
>
>  /* These masks check for invalid bits in permission responses. */
>  #define FANOTIFY_RESPONSE_ACCESS (FAN_ALLOW | FAN_DENY)
> -#define FANOTIFY_RESPONSE_FLAGS (FAN_AUDIT | FAN_INFO)
> +#define FANOTIFY_RESPONSE_FLAGS (FAN_AUDIT | FAN_INFO | FAN_DEFAULT)
>  #define FANOTIFY_RESPONSE_VALID_MASK \
>         (FANOTIFY_RESPONSE_ACCESS | FANOTIFY_RESPONSE_FLAGS | \
>          (FAN_ERRNO_MASK << FAN_ERRNO_SHIFT))
> diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
> index d4034ddaf392..9683396acda6 100644
> --- a/include/linux/fsnotify_backend.h
> +++ b/include/linux/fsnotify_backend.h
> @@ -231,6 +231,7 @@ struct fsnotify_group {
>         unsigned int max_events;                /* maximum events allowed on the list */
>         enum fsnotify_group_prio priority;      /* priority for sending events */
>         bool shutdown;          /* group is being shut down, don't queue more events */
> +       unsigned int default_response; /* default response sent on group close */
>
>  #define FSNOTIFY_GROUP_USER    0x01 /* user allocated group */
>  #define FSNOTIFY_GROUP_DUPS    0x02 /* allow multiple marks per object */
> diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
> index e710967c7c26..7badde273a66 100644
> --- a/include/uapi/linux/fanotify.h
> +++ b/include/uapi/linux/fanotify.h
> @@ -254,6 +254,7 @@ struct fanotify_response_info_audit_rule {
>
>  #define FAN_AUDIT      0x10    /* Bitmask to create audit record for result */
>  #define FAN_INFO       0x20    /* Bitmask to indicate additional information */
> +#define FAN_DEFAULT    0x30    /* Bitmask to set default response on close */
>
>  /* No fd set in event */
>  #define FAN_NOFD       -1
> diff --git a/tools/include/uapi/linux/fanotify.h b/tools/include/uapi/linux/fanotify.h
> index e710967c7c26..7badde273a66 100644
> --- a/tools/include/uapi/linux/fanotify.h
> +++ b/tools/include/uapi/linux/fanotify.h
> @@ -254,6 +254,7 @@ struct fanotify_response_info_audit_rule {
>
>  #define FAN_AUDIT      0x10    /* Bitmask to create audit record for result */
>  #define FAN_INFO       0x20    /* Bitmask to indicate additional information */
> +#define FAN_DEFAULT    0x30    /* Bitmask to set default response on close */
>
>  /* No fd set in event */
>  #define FAN_NOFD       -1
> --
> 2.47.1
>





[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