Skip to content

Commit 83e9acb

Browse files
krisman-at-collaborajankara
authored andcommitted
fanotify: Support enqueueing of error events
Once an error event is triggered, enqueue it in the notification group, similarly to what is done for other events. FAN_FS_ERROR is not handled specially, since the memory is now handled by a preallocated mempool. For now, make the event unhashed. A future patch implements merging of this kind of event. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Amir Goldstein <[email protected]> Signed-off-by: Gabriel Krisman Bertazi <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 734a1a5 commit 83e9acb

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

fs/notify/fanotify/fanotify.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,27 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id,
574574
return &fne->fae;
575575
}
576576

577+
static struct fanotify_event *fanotify_alloc_error_event(
578+
struct fsnotify_group *group,
579+
__kernel_fsid_t *fsid,
580+
const void *data, int data_type)
581+
{
582+
struct fs_error_report *report =
583+
fsnotify_data_error_report(data, data_type);
584+
struct fanotify_error_event *fee;
585+
586+
if (WARN_ON_ONCE(!report))
587+
return NULL;
588+
589+
fee = mempool_alloc(&group->fanotify_data.error_events_pool, GFP_NOFS);
590+
if (!fee)
591+
return NULL;
592+
593+
fee->fae.type = FANOTIFY_EVENT_TYPE_FS_ERROR;
594+
595+
return &fee->fae;
596+
}
597+
577598
static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
578599
u32 mask, const void *data,
579600
int data_type, struct inode *dir,
@@ -641,6 +662,9 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
641662

642663
if (fanotify_is_perm_event(mask)) {
643664
event = fanotify_alloc_perm_event(path, gfp);
665+
} else if (fanotify_is_error_event(mask)) {
666+
event = fanotify_alloc_error_event(group, fsid, data,
667+
data_type);
644668
} else if (name_event && (file_name || child)) {
645669
event = fanotify_alloc_name_event(id, fsid, file_name, child,
646670
&hash, gfp);
@@ -850,6 +874,14 @@ static void fanotify_free_name_event(struct fanotify_event *event)
850874
kfree(FANOTIFY_NE(event));
851875
}
852876

877+
static void fanotify_free_error_event(struct fsnotify_group *group,
878+
struct fanotify_event *event)
879+
{
880+
struct fanotify_error_event *fee = FANOTIFY_EE(event);
881+
882+
mempool_free(fee, &group->fanotify_data.error_events_pool);
883+
}
884+
853885
static void fanotify_free_event(struct fsnotify_group *group,
854886
struct fsnotify_event *fsn_event)
855887
{
@@ -873,6 +905,9 @@ static void fanotify_free_event(struct fsnotify_group *group,
873905
case FANOTIFY_EVENT_TYPE_OVERFLOW:
874906
kfree(event);
875907
break;
908+
case FANOTIFY_EVENT_TYPE_FS_ERROR:
909+
fanotify_free_error_event(group, event);
910+
break;
876911
default:
877912
WARN_ON_ONCE(1);
878913
}

fs/notify/fanotify/fanotify.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
298298
return container_of(fse, struct fanotify_event, fse);
299299
}
300300

301+
static inline bool fanotify_is_error_event(u32 mask)
302+
{
303+
return mask & FAN_FS_ERROR;
304+
}
305+
301306
static inline bool fanotify_event_has_path(struct fanotify_event *event)
302307
{
303308
return event->type == FANOTIFY_EVENT_TYPE_PATH ||
@@ -327,6 +332,7 @@ static inline struct path *fanotify_event_path(struct fanotify_event *event)
327332
static inline bool fanotify_is_hashed_event(u32 mask)
328333
{
329334
return !(fanotify_is_perm_event(mask) ||
335+
fanotify_is_error_event(mask) ||
330336
fsnotify_is_overflow_event(mask));
331337
}
332338

0 commit comments

Comments
 (0)