forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/fs/notify/fanotify/fanotify.h
....@@ -2,25 +2,240 @@
22 #include <linux/fsnotify_backend.h>
33 #include <linux/path.h>
44 #include <linux/slab.h>
5
+#include <linux/exportfs.h>
56
67 extern struct kmem_cache *fanotify_mark_cache;
7
-extern struct kmem_cache *fanotify_event_cachep;
8
+extern struct kmem_cache *fanotify_fid_event_cachep;
9
+extern struct kmem_cache *fanotify_path_event_cachep;
810 extern struct kmem_cache *fanotify_perm_event_cachep;
911
10
-/*
11
- * Structure for normal fanotify events. It gets allocated in
12
- * fanotify_handle_event() and freed when the information is retrieved by
13
- * userspace
14
- */
15
-struct fanotify_event_info {
16
- struct fsnotify_event fse;
17
- /*
18
- * We hold ref to this path so it may be dereferenced at any point
19
- * during this object's lifetime
20
- */
21
- struct path path;
22
- struct pid *tgid;
12
+/* Possible states of the permission event */
13
+enum {
14
+ FAN_EVENT_INIT,
15
+ FAN_EVENT_REPORTED,
16
+ FAN_EVENT_ANSWERED,
17
+ FAN_EVENT_CANCELED,
2318 };
19
+
20
+/*
21
+ * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation).
22
+ * fh buf should be dword aligned. On 64bit arch, the ext_buf pointer is
23
+ * stored in either the first or last 2 dwords.
24
+ */
25
+#define FANOTIFY_INLINE_FH_LEN (3 << 2)
26
+#define FANOTIFY_FH_HDR_LEN offsetof(struct fanotify_fh, buf)
27
+
28
+/* Fixed size struct for file handle */
29
+struct fanotify_fh {
30
+ u8 type;
31
+ u8 len;
32
+#define FANOTIFY_FH_FLAG_EXT_BUF 1
33
+ u8 flags;
34
+ u8 pad;
35
+ unsigned char buf[];
36
+} __aligned(4);
37
+
38
+/* Variable size struct for dir file handle + child file handle + name */
39
+struct fanotify_info {
40
+ /* size of dir_fh/file_fh including fanotify_fh hdr size */
41
+ u8 dir_fh_totlen;
42
+ u8 file_fh_totlen;
43
+ u8 name_len;
44
+ u8 pad;
45
+ unsigned char buf[];
46
+ /*
47
+ * (struct fanotify_fh) dir_fh starts at buf[0]
48
+ * (optional) file_fh starts at buf[dir_fh_totlen]
49
+ * name starts at buf[dir_fh_totlen + file_fh_totlen]
50
+ */
51
+} __aligned(4);
52
+
53
+static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh)
54
+{
55
+ return (fh->flags & FANOTIFY_FH_FLAG_EXT_BUF);
56
+}
57
+
58
+static inline char **fanotify_fh_ext_buf_ptr(struct fanotify_fh *fh)
59
+{
60
+ BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN % 4);
61
+ BUILD_BUG_ON(__alignof__(char *) - 4 + sizeof(char *) >
62
+ FANOTIFY_INLINE_FH_LEN);
63
+ return (char **)ALIGN((unsigned long)(fh->buf), __alignof__(char *));
64
+}
65
+
66
+static inline void *fanotify_fh_ext_buf(struct fanotify_fh *fh)
67
+{
68
+ return *fanotify_fh_ext_buf_ptr(fh);
69
+}
70
+
71
+static inline void *fanotify_fh_buf(struct fanotify_fh *fh)
72
+{
73
+ return fanotify_fh_has_ext_buf(fh) ? fanotify_fh_ext_buf(fh) : fh->buf;
74
+}
75
+
76
+static inline int fanotify_info_dir_fh_len(struct fanotify_info *info)
77
+{
78
+ if (!info->dir_fh_totlen ||
79
+ WARN_ON_ONCE(info->dir_fh_totlen < FANOTIFY_FH_HDR_LEN))
80
+ return 0;
81
+
82
+ return info->dir_fh_totlen - FANOTIFY_FH_HDR_LEN;
83
+}
84
+
85
+static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *info)
86
+{
87
+ BUILD_BUG_ON(offsetof(struct fanotify_info, buf) % 4);
88
+
89
+ return (struct fanotify_fh *)info->buf;
90
+}
91
+
92
+static inline int fanotify_info_file_fh_len(struct fanotify_info *info)
93
+{
94
+ if (!info->file_fh_totlen ||
95
+ WARN_ON_ONCE(info->file_fh_totlen < FANOTIFY_FH_HDR_LEN))
96
+ return 0;
97
+
98
+ return info->file_fh_totlen - FANOTIFY_FH_HDR_LEN;
99
+}
100
+
101
+static inline struct fanotify_fh *fanotify_info_file_fh(struct fanotify_info *info)
102
+{
103
+ return (struct fanotify_fh *)(info->buf + info->dir_fh_totlen);
104
+}
105
+
106
+static inline const char *fanotify_info_name(struct fanotify_info *info)
107
+{
108
+ return info->buf + info->dir_fh_totlen + info->file_fh_totlen;
109
+}
110
+
111
+static inline void fanotify_info_init(struct fanotify_info *info)
112
+{
113
+ info->dir_fh_totlen = 0;
114
+ info->file_fh_totlen = 0;
115
+ info->name_len = 0;
116
+}
117
+
118
+static inline void fanotify_info_copy_name(struct fanotify_info *info,
119
+ const struct qstr *name)
120
+{
121
+ info->name_len = name->len;
122
+ strcpy(info->buf + info->dir_fh_totlen + info->file_fh_totlen,
123
+ name->name);
124
+}
125
+
126
+/*
127
+ * Common structure for fanotify events. Concrete structs are allocated in
128
+ * fanotify_handle_event() and freed when the information is retrieved by
129
+ * userspace. The type of event determines how it was allocated, how it will
130
+ * be freed and which concrete struct it may be cast to.
131
+ */
132
+enum fanotify_event_type {
133
+ FANOTIFY_EVENT_TYPE_FID, /* fixed length */
134
+ FANOTIFY_EVENT_TYPE_FID_NAME, /* variable length */
135
+ FANOTIFY_EVENT_TYPE_PATH,
136
+ FANOTIFY_EVENT_TYPE_PATH_PERM,
137
+ FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
138
+};
139
+
140
+struct fanotify_event {
141
+ struct fsnotify_event fse;
142
+ u32 mask;
143
+ enum fanotify_event_type type;
144
+ struct pid *pid;
145
+};
146
+
147
+static inline void fanotify_init_event(struct fanotify_event *event,
148
+ unsigned long id, u32 mask)
149
+{
150
+ fsnotify_init_event(&event->fse, id);
151
+ event->mask = mask;
152
+ event->pid = NULL;
153
+}
154
+
155
+struct fanotify_fid_event {
156
+ struct fanotify_event fae;
157
+ __kernel_fsid_t fsid;
158
+ struct fanotify_fh object_fh;
159
+ /* Reserve space in object_fh.buf[] - access with fanotify_fh_buf() */
160
+ unsigned char _inline_fh_buf[FANOTIFY_INLINE_FH_LEN];
161
+};
162
+
163
+static inline struct fanotify_fid_event *
164
+FANOTIFY_FE(struct fanotify_event *event)
165
+{
166
+ return container_of(event, struct fanotify_fid_event, fae);
167
+}
168
+
169
+struct fanotify_name_event {
170
+ struct fanotify_event fae;
171
+ __kernel_fsid_t fsid;
172
+ struct fanotify_info info;
173
+};
174
+
175
+static inline struct fanotify_name_event *
176
+FANOTIFY_NE(struct fanotify_event *event)
177
+{
178
+ return container_of(event, struct fanotify_name_event, fae);
179
+}
180
+
181
+static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event)
182
+{
183
+ if (event->type == FANOTIFY_EVENT_TYPE_FID)
184
+ return &FANOTIFY_FE(event)->fsid;
185
+ else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME)
186
+ return &FANOTIFY_NE(event)->fsid;
187
+ else
188
+ return NULL;
189
+}
190
+
191
+static inline struct fanotify_fh *fanotify_event_object_fh(
192
+ struct fanotify_event *event)
193
+{
194
+ if (event->type == FANOTIFY_EVENT_TYPE_FID)
195
+ return &FANOTIFY_FE(event)->object_fh;
196
+ else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME)
197
+ return fanotify_info_file_fh(&FANOTIFY_NE(event)->info);
198
+ else
199
+ return NULL;
200
+}
201
+
202
+static inline struct fanotify_info *fanotify_event_info(
203
+ struct fanotify_event *event)
204
+{
205
+ if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME)
206
+ return &FANOTIFY_NE(event)->info;
207
+ else
208
+ return NULL;
209
+}
210
+
211
+static inline int fanotify_event_object_fh_len(struct fanotify_event *event)
212
+{
213
+ struct fanotify_info *info = fanotify_event_info(event);
214
+ struct fanotify_fh *fh = fanotify_event_object_fh(event);
215
+
216
+ if (info)
217
+ return info->file_fh_totlen ? fh->len : 0;
218
+ else
219
+ return fh ? fh->len : 0;
220
+}
221
+
222
+static inline int fanotify_event_dir_fh_len(struct fanotify_event *event)
223
+{
224
+ struct fanotify_info *info = fanotify_event_info(event);
225
+
226
+ return info ? fanotify_info_dir_fh_len(info) : 0;
227
+}
228
+
229
+struct fanotify_path_event {
230
+ struct fanotify_event fae;
231
+ struct path path;
232
+};
233
+
234
+static inline struct fanotify_path_event *
235
+FANOTIFY_PE(struct fanotify_event *event)
236
+{
237
+ return container_of(event, struct fanotify_path_event, fae);
238
+}
24239
25240 /*
26241 * Structure for permission fanotify events. It gets allocated and freed in
....@@ -29,29 +244,43 @@
29244 * group->notification_list to group->fanotify_data.access_list to wait for
30245 * user response.
31246 */
32
-struct fanotify_perm_event_info {
33
- struct fanotify_event_info fae;
34
- int response; /* userspace answer to question */
247
+struct fanotify_perm_event {
248
+ struct fanotify_event fae;
249
+ struct path path;
250
+ unsigned short response; /* userspace answer to the event */
251
+ unsigned short state; /* state of the event */
35252 int fd; /* fd we passed to userspace for this event */
36253 };
37254
38
-static inline struct fanotify_perm_event_info *
39
-FANOTIFY_PE(struct fsnotify_event *fse)
255
+static inline struct fanotify_perm_event *
256
+FANOTIFY_PERM(struct fanotify_event *event)
40257 {
41
- return container_of(fse, struct fanotify_perm_event_info, fae.fse);
258
+ return container_of(event, struct fanotify_perm_event, fae);
42259 }
43260
44261 static inline bool fanotify_is_perm_event(u32 mask)
45262 {
46263 return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) &&
47
- mask & FAN_ALL_PERM_EVENTS;
264
+ mask & FANOTIFY_PERM_EVENTS;
48265 }
49266
50
-static inline struct fanotify_event_info *FANOTIFY_E(struct fsnotify_event *fse)
267
+static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
51268 {
52
- return container_of(fse, struct fanotify_event_info, fse);
269
+ return container_of(fse, struct fanotify_event, fse);
53270 }
54271
55
-struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
56
- struct inode *inode, u32 mask,
57
- const struct path *path);
272
+static inline bool fanotify_event_has_path(struct fanotify_event *event)
273
+{
274
+ return event->type == FANOTIFY_EVENT_TYPE_PATH ||
275
+ event->type == FANOTIFY_EVENT_TYPE_PATH_PERM;
276
+}
277
+
278
+static inline struct path *fanotify_event_path(struct fanotify_event *event)
279
+{
280
+ if (event->type == FANOTIFY_EVENT_TYPE_PATH)
281
+ return &FANOTIFY_PE(event)->path;
282
+ else if (event->type == FANOTIFY_EVENT_TYPE_PATH_PERM)
283
+ return &FANOTIFY_PERM(event)->path;
284
+ else
285
+ return NULL;
286
+}