Amir Goldstein <amir73il@xxxxxxxxx> writes: > On Fri, Oct 15, 2021 at 12:39 AM Gabriel Krisman Bertazi > <krisman@xxxxxxxxxxxxx> wrote: >> >> Error events (FAN_FS_ERROR) against the same file system can be merged >> by simply iterating the error count. The hash is taken from the fsid, >> without considering the FH. This means that only the first error object >> is reported. >> >> Signed-off-by: Gabriel Krisman Bertazi <krisman@xxxxxxxxxxxxx> >> --- >> fs/notify/fanotify/fanotify.c | 39 ++++++++++++++++++++++++++++++++--- >> fs/notify/fanotify/fanotify.h | 4 +++- >> 2 files changed, 39 insertions(+), 4 deletions(-) >> >> diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c >> index 9b970359570a..7032083df62a 100644 >> --- a/fs/notify/fanotify/fanotify.c >> +++ b/fs/notify/fanotify/fanotify.c >> @@ -111,6 +111,16 @@ static bool fanotify_name_event_equal(struct fanotify_name_event *fne1, >> return fanotify_info_equal(info1, info2); >> } >> >> +static bool fanotify_error_event_equal(struct fanotify_error_event *fee1, >> + struct fanotify_error_event *fee2) >> +{ >> + /* Error events against the same file system are always merged. */ >> + if (!fanotify_fsid_equal(&fee1->fsid, &fee2->fsid)) >> + return false; >> + >> + return true; >> +} >> + >> static bool fanotify_should_merge(struct fanotify_event *old, >> struct fanotify_event *new) >> { >> @@ -141,6 +151,9 @@ static bool fanotify_should_merge(struct fanotify_event *old, >> case FANOTIFY_EVENT_TYPE_FID_NAME: >> return fanotify_name_event_equal(FANOTIFY_NE(old), >> FANOTIFY_NE(new)); >> + case FANOTIFY_EVENT_TYPE_FS_ERROR: >> + return fanotify_error_event_equal(FANOTIFY_EE(old), >> + FANOTIFY_EE(new)); >> default: >> WARN_ON_ONCE(1); >> } >> @@ -148,6 +161,22 @@ static bool fanotify_should_merge(struct fanotify_event *old, >> return false; >> } >> >> +static void fanotify_merge_error_event(struct fanotify_error_event *dest, >> + struct fanotify_error_event *origin) >> +{ >> + dest->err_count++; >> +} >> + >> +static void fanotify_merge_event(struct fanotify_event *dest, >> + struct fanotify_event *origin) >> +{ >> + dest->mask |= origin->mask; >> + >> + if (origin->type == FANOTIFY_EVENT_TYPE_FS_ERROR) >> + fanotify_merge_error_event(FANOTIFY_EE(dest), >> + FANOTIFY_EE(origin)); >> +} >> + >> /* Limit event merges to limit CPU overhead per event */ >> #define FANOTIFY_MAX_MERGE_EVENTS 128 >> >> @@ -175,7 +204,7 @@ static int fanotify_merge(struct fsnotify_group *group, >> if (++i > FANOTIFY_MAX_MERGE_EVENTS) >> break; >> if (fanotify_should_merge(old, new)) { >> - old->mask |= new->mask; >> + fanotify_merge_event(old, new); >> return 1; >> } >> } >> @@ -577,7 +606,8 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, >> static struct fanotify_event *fanotify_alloc_error_event( >> struct fsnotify_group *group, >> __kernel_fsid_t *fsid, >> - const void *data, int data_type) >> + const void *data, int data_type, >> + unsigned int *hash) >> { >> struct fs_error_report *report = >> fsnotify_data_error_report(data, data_type); >> @@ -591,6 +621,9 @@ static struct fanotify_event *fanotify_alloc_error_event( >> return NULL; >> >> fee->fae.type = FANOTIFY_EVENT_TYPE_FS_ERROR; >> + fee->err_count = 1; >> + >> + *hash ^= fanotify_hash_fsid(fsid); >> >> return &fee->fae; >> } > > Forgot to store fee->fsid? Not really. this is part of the FID info record support, which is done in patch 23. -- Gabriel Krisman Bertazi