summaryrefslogtreecommitdiff
path: root/fs/notify/fanotify/fanotify.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-04-29 21:06:13 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2021-04-29 21:06:13 +0300
commit3644286f6cbcea86f6fa4d308e7ac06bf2a3715a (patch)
treed052231d1029d3e4f783c9b74b295eb07d194130 /fs/notify/fanotify/fanotify.h
parent767fcbc80f63d7f08ff6c0858fe33583e6fdd327 (diff)
parent59cda49ecf6c9a32fae4942420701b6e087204f6 (diff)
downloadlinux-3644286f6cbcea86f6fa4d308e7ac06bf2a3715a.tar.xz
Merge tag 'fsnotify_for_v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull fsnotify updates from Jan Kara: - support for limited fanotify functionality for unpriviledged users - faster merging of fanotify events - a few smaller fsnotify improvements * tag 'fsnotify_for_v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: shmem: allow reporting fanotify events with file handles on tmpfs fs: introduce a wrapper uuid_to_fsid() fanotify_user: use upper_32_bits() to verify mask fanotify: support limited functionality for unprivileged users fanotify: configurable limits via sysfs fanotify: limit number of event merge attempts fsnotify: use hash table for faster events merge fanotify: mix event info and pid into merge key hash fanotify: reduce event objectid to 29-bit hash fsnotify: allow fsnotify_{peek,remove}_first_event with empty queue
Diffstat (limited to 'fs/notify/fanotify/fanotify.h')
-rw-r--r--fs/notify/fanotify/fanotify.h46
1 files changed, 43 insertions, 3 deletions
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index 896c819a1786..4a5e555dc3d2 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -3,6 +3,7 @@
#include <linux/path.h>
#include <linux/slab.h>
#include <linux/exportfs.h>
+#include <linux/hashtable.h>
extern struct kmem_cache *fanotify_mark_cache;
extern struct kmem_cache *fanotify_fid_event_cachep;
@@ -115,6 +116,11 @@ static inline void fanotify_info_init(struct fanotify_info *info)
info->name_len = 0;
}
+static inline unsigned int fanotify_info_len(struct fanotify_info *info)
+{
+ return info->dir_fh_totlen + info->file_fh_totlen + info->name_len;
+}
+
static inline void fanotify_info_copy_name(struct fanotify_info *info,
const struct qstr *name)
{
@@ -135,19 +141,31 @@ enum fanotify_event_type {
FANOTIFY_EVENT_TYPE_PATH,
FANOTIFY_EVENT_TYPE_PATH_PERM,
FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
+ __FANOTIFY_EVENT_TYPE_NUM
};
+#define FANOTIFY_EVENT_TYPE_BITS \
+ (ilog2(__FANOTIFY_EVENT_TYPE_NUM - 1) + 1)
+#define FANOTIFY_EVENT_HASH_BITS \
+ (32 - FANOTIFY_EVENT_TYPE_BITS)
+
struct fanotify_event {
struct fsnotify_event fse;
+ struct hlist_node merge_list; /* List for hashed merge */
u32 mask;
- enum fanotify_event_type type;
+ struct {
+ unsigned int type : FANOTIFY_EVENT_TYPE_BITS;
+ unsigned int hash : FANOTIFY_EVENT_HASH_BITS;
+ };
struct pid *pid;
};
static inline void fanotify_init_event(struct fanotify_event *event,
- unsigned long id, u32 mask)
+ unsigned int hash, u32 mask)
{
- fsnotify_init_event(&event->fse, id);
+ fsnotify_init_event(&event->fse);
+ INIT_HLIST_NODE(&event->merge_list);
+ event->hash = hash;
event->mask = mask;
event->pid = NULL;
}
@@ -284,3 +302,25 @@ static inline struct path *fanotify_event_path(struct fanotify_event *event)
else
return NULL;
}
+
+/*
+ * Use 128 size hash table to speed up events merge.
+ */
+#define FANOTIFY_HTABLE_BITS (7)
+#define FANOTIFY_HTABLE_SIZE (1 << FANOTIFY_HTABLE_BITS)
+#define FANOTIFY_HTABLE_MASK (FANOTIFY_HTABLE_SIZE - 1)
+
+/*
+ * Permission events and overflow event do not get merged - don't hash them.
+ */
+static inline bool fanotify_is_hashed_event(u32 mask)
+{
+ return !fanotify_is_perm_event(mask) && !(mask & FS_Q_OVERFLOW);
+}
+
+static inline unsigned int fanotify_event_hash_bucket(
+ struct fsnotify_group *group,
+ struct fanotify_event *event)
+{
+ return event->hash & FANOTIFY_HTABLE_MASK;
+}