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 >