forked from Minki/linux
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/20211025192746.66445-20-krisman@collabora.com Reviewed-by: Amir Goldstein <amir73il@gmail.com> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
8d11a4f43e
commit
734a1a5ecc
@ -819,6 +819,9 @@ static void fanotify_free_group_priv(struct fsnotify_group *group)
|
|||||||
if (group->fanotify_data.ucounts)
|
if (group->fanotify_data.ucounts)
|
||||||
dec_ucount(group->fanotify_data.ucounts,
|
dec_ucount(group->fanotify_data.ucounts,
|
||||||
UCOUNT_FANOTIFY_GROUPS);
|
UCOUNT_FANOTIFY_GROUPS);
|
||||||
|
|
||||||
|
if (mempool_initialized(&group->fanotify_data.error_events_pool))
|
||||||
|
mempool_exit(&group->fanotify_data.error_events_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fanotify_free_path_event(struct fanotify_event *event)
|
static void fanotify_free_path_event(struct fanotify_event *event)
|
||||||
|
@ -141,6 +141,7 @@ enum fanotify_event_type {
|
|||||||
FANOTIFY_EVENT_TYPE_PATH,
|
FANOTIFY_EVENT_TYPE_PATH,
|
||||||
FANOTIFY_EVENT_TYPE_PATH_PERM,
|
FANOTIFY_EVENT_TYPE_PATH_PERM,
|
||||||
FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
|
FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
|
||||||
|
FANOTIFY_EVENT_TYPE_FS_ERROR, /* struct fanotify_error_event */
|
||||||
__FANOTIFY_EVENT_TYPE_NUM
|
__FANOTIFY_EVENT_TYPE_NUM
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,6 +197,16 @@ FANOTIFY_NE(struct fanotify_event *event)
|
|||||||
return container_of(event, struct fanotify_name_event, fae);
|
return container_of(event, struct fanotify_name_event, fae);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct fanotify_error_event {
|
||||||
|
struct fanotify_event fae;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct fanotify_error_event *
|
||||||
|
FANOTIFY_EE(struct fanotify_event *event)
|
||||||
|
{
|
||||||
|
return container_of(event, struct fanotify_error_event, fae);
|
||||||
|
}
|
||||||
|
|
||||||
static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event)
|
static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event)
|
||||||
{
|
{
|
||||||
if (event->type == FANOTIFY_EVENT_TYPE_FID)
|
if (event->type == FANOTIFY_EVENT_TYPE_FID)
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#define FANOTIFY_DEFAULT_MAX_EVENTS 16384
|
#define FANOTIFY_DEFAULT_MAX_EVENTS 16384
|
||||||
#define FANOTIFY_OLD_DEFAULT_MAX_MARKS 8192
|
#define FANOTIFY_OLD_DEFAULT_MAX_MARKS 8192
|
||||||
#define FANOTIFY_DEFAULT_MAX_GROUPS 128
|
#define FANOTIFY_DEFAULT_MAX_GROUPS 128
|
||||||
|
#define FANOTIFY_DEFAULT_FEE_POOL_SIZE 32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Legacy fanotify marks limits (8192) is per group and we introduced a tunable
|
* Legacy fanotify marks limits (8192) is per group and we introduced a tunable
|
||||||
@ -1054,6 +1055,15 @@ out_dec_ucounts:
|
|||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fanotify_group_init_error_pool(struct fsnotify_group *group)
|
||||||
|
{
|
||||||
|
if (mempool_initialized(&group->fanotify_data.error_events_pool))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return mempool_init_kmalloc_pool(&group->fanotify_data.error_events_pool,
|
||||||
|
FANOTIFY_DEFAULT_FEE_POOL_SIZE,
|
||||||
|
sizeof(struct fanotify_error_event));
|
||||||
|
}
|
||||||
|
|
||||||
static int fanotify_add_mark(struct fsnotify_group *group,
|
static int fanotify_add_mark(struct fsnotify_group *group,
|
||||||
fsnotify_connp_t *connp, unsigned int type,
|
fsnotify_connp_t *connp, unsigned int type,
|
||||||
@ -1062,6 +1072,7 @@ static int fanotify_add_mark(struct fsnotify_group *group,
|
|||||||
{
|
{
|
||||||
struct fsnotify_mark *fsn_mark;
|
struct fsnotify_mark *fsn_mark;
|
||||||
__u32 added;
|
__u32 added;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&group->mark_mutex);
|
mutex_lock(&group->mark_mutex);
|
||||||
fsn_mark = fsnotify_find_mark(connp, group);
|
fsn_mark = fsnotify_find_mark(connp, group);
|
||||||
@ -1072,13 +1083,26 @@ static int fanotify_add_mark(struct fsnotify_group *group,
|
|||||||
return PTR_ERR(fsn_mark);
|
return PTR_ERR(fsn_mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error events are pre-allocated per group, only if strictly
|
||||||
|
* needed (i.e. FAN_FS_ERROR was requested).
|
||||||
|
*/
|
||||||
|
if (!(flags & FAN_MARK_IGNORED_MASK) && (mask & FAN_FS_ERROR)) {
|
||||||
|
ret = fanotify_group_init_error_pool(group);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
|
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
|
||||||
if (added & ~fsnotify_conn_mask(fsn_mark->connector))
|
if (added & ~fsnotify_conn_mask(fsn_mark->connector))
|
||||||
fsnotify_recalc_mask(fsn_mark->connector);
|
fsnotify_recalc_mask(fsn_mark->connector);
|
||||||
|
|
||||||
|
out:
|
||||||
mutex_unlock(&group->mark_mutex);
|
mutex_unlock(&group->mark_mutex);
|
||||||
|
|
||||||
fsnotify_put_mark(fsn_mark);
|
fsnotify_put_mark(fsn_mark);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
|
static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/user_namespace.h>
|
#include <linux/user_namespace.h>
|
||||||
#include <linux/refcount.h>
|
#include <linux/refcount.h>
|
||||||
|
#include <linux/mempool.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IN_* from inotfy.h lines up EXACTLY with FS_*, this is so we can easily
|
* IN_* from inotfy.h lines up EXACTLY with FS_*, this is so we can easily
|
||||||
@ -246,6 +247,7 @@ struct fsnotify_group {
|
|||||||
int flags; /* flags from fanotify_init() */
|
int flags; /* flags from fanotify_init() */
|
||||||
int f_flags; /* event_f_flags from fanotify_init() */
|
int f_flags; /* event_f_flags from fanotify_init() */
|
||||||
struct ucounts *ucounts;
|
struct ucounts *ucounts;
|
||||||
|
mempool_t error_events_pool;
|
||||||
} fanotify_data;
|
} fanotify_data;
|
||||||
#endif /* CONFIG_FANOTIFY */
|
#endif /* CONFIG_FANOTIFY */
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user