Skip to content

Commit 734a1a5

Browse files
krisman-at-collaborajankara
authored andcommitted
fanotify: Pre-allocate pool of error events
Pre-allocate slots for file system errors to have greater chances of succeeding, since error events can happen in GFP_NOFS context. This patch introduces a group-wide mempool of error events, shared by all FAN_FS_ERROR marks in this group. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Amir Goldstein <[email protected]> Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Gabriel Krisman Bertazi <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 8d11a4f commit 734a1a5

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

fs/notify/fanotify/fanotify.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,9 @@ static void fanotify_free_group_priv(struct fsnotify_group *group)
819819
if (group->fanotify_data.ucounts)
820820
dec_ucount(group->fanotify_data.ucounts,
821821
UCOUNT_FANOTIFY_GROUPS);
822+
823+
if (mempool_initialized(&group->fanotify_data.error_events_pool))
824+
mempool_exit(&group->fanotify_data.error_events_pool);
822825
}
823826

824827
static void fanotify_free_path_event(struct fanotify_event *event)

fs/notify/fanotify/fanotify.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ enum fanotify_event_type {
141141
FANOTIFY_EVENT_TYPE_PATH,
142142
FANOTIFY_EVENT_TYPE_PATH_PERM,
143143
FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
144+
FANOTIFY_EVENT_TYPE_FS_ERROR, /* struct fanotify_error_event */
144145
__FANOTIFY_EVENT_TYPE_NUM
145146
};
146147

@@ -196,6 +197,16 @@ FANOTIFY_NE(struct fanotify_event *event)
196197
return container_of(event, struct fanotify_name_event, fae);
197198
}
198199

200+
struct fanotify_error_event {
201+
struct fanotify_event fae;
202+
};
203+
204+
static inline struct fanotify_error_event *
205+
FANOTIFY_EE(struct fanotify_event *event)
206+
{
207+
return container_of(event, struct fanotify_error_event, fae);
208+
}
209+
199210
static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event)
200211
{
201212
if (event->type == FANOTIFY_EVENT_TYPE_FID)

fs/notify/fanotify/fanotify_user.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define FANOTIFY_DEFAULT_MAX_EVENTS 16384
3131
#define FANOTIFY_OLD_DEFAULT_MAX_MARKS 8192
3232
#define FANOTIFY_DEFAULT_MAX_GROUPS 128
33+
#define FANOTIFY_DEFAULT_FEE_POOL_SIZE 32
3334

3435
/*
3536
* Legacy fanotify marks limits (8192) is per group and we introduced a tunable
@@ -1054,6 +1055,15 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
10541055
return ERR_PTR(ret);
10551056
}
10561057

1058+
static int fanotify_group_init_error_pool(struct fsnotify_group *group)
1059+
{
1060+
if (mempool_initialized(&group->fanotify_data.error_events_pool))
1061+
return 0;
1062+
1063+
return mempool_init_kmalloc_pool(&group->fanotify_data.error_events_pool,
1064+
FANOTIFY_DEFAULT_FEE_POOL_SIZE,
1065+
sizeof(struct fanotify_error_event));
1066+
}
10571067

10581068
static int fanotify_add_mark(struct fsnotify_group *group,
10591069
fsnotify_connp_t *connp, unsigned int type,
@@ -1062,6 +1072,7 @@ static int fanotify_add_mark(struct fsnotify_group *group,
10621072
{
10631073
struct fsnotify_mark *fsn_mark;
10641074
__u32 added;
1075+
int ret = 0;
10651076

10661077
mutex_lock(&group->mark_mutex);
10671078
fsn_mark = fsnotify_find_mark(connp, group);
@@ -1072,13 +1083,26 @@ static int fanotify_add_mark(struct fsnotify_group *group,
10721083
return PTR_ERR(fsn_mark);
10731084
}
10741085
}
1086+
1087+
/*
1088+
* Error events are pre-allocated per group, only if strictly
1089+
* needed (i.e. FAN_FS_ERROR was requested).
1090+
*/
1091+
if (!(flags & FAN_MARK_IGNORED_MASK) && (mask & FAN_FS_ERROR)) {
1092+
ret = fanotify_group_init_error_pool(group);
1093+
if (ret)
1094+
goto out;
1095+
}
1096+
10751097
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
10761098
if (added & ~fsnotify_conn_mask(fsn_mark->connector))
10771099
fsnotify_recalc_mask(fsn_mark->connector);
1100+
1101+
out:
10781102
mutex_unlock(&group->mark_mutex);
10791103

10801104
fsnotify_put_mark(fsn_mark);
1081-
return 0;
1105+
return ret;
10821106
}
10831107

10841108
static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,

include/linux/fsnotify_backend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/atomic.h>
2020
#include <linux/user_namespace.h>
2121
#include <linux/refcount.h>
22+
#include <linux/mempool.h>
2223

2324
/*
2425
* IN_* from inotfy.h lines up EXACTLY with FS_*, this is so we can easily
@@ -246,6 +247,7 @@ struct fsnotify_group {
246247
int flags; /* flags from fanotify_init() */
247248
int f_flags; /* event_f_flags from fanotify_init() */
248249
struct ucounts *ucounts;
250+
mempool_t error_events_pool;
249251
} fanotify_data;
250252
#endif /* CONFIG_FANOTIFY */
251253
};

0 commit comments

Comments
 (0)