hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/include/linux/fsnotify_backend.h
....@@ -38,6 +38,7 @@
3838 #define FS_DELETE 0x00000200 /* Subfile was deleted */
3939 #define FS_DELETE_SELF 0x00000400 /* Self was deleted */
4040 #define FS_MOVE_SELF 0x00000800 /* Self was moved */
41
+#define FS_OPEN_EXEC 0x00001000 /* File was opened for exec */
4142
4243 #define FS_UNMOUNT 0x00002000 /* inode on umount fs */
4344 #define FS_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
....@@ -45,36 +46,56 @@
4546
4647 #define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */
4748 #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */
49
+#define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */
4850
4951 #define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */
50
-#define FS_ISDIR 0x40000000 /* event occurred against dir */
51
-#define FS_IN_ONESHOT 0x80000000 /* only send event once */
52
+/*
53
+ * Set on inode mark that cares about things that happen to its children.
54
+ * Always set for dnotify and inotify.
55
+ * Set on inode/sb/mount marks that care about parent/name info.
56
+ */
57
+#define FS_EVENT_ON_CHILD 0x08000000
5258
5359 #define FS_DN_RENAME 0x10000000 /* file renamed */
5460 #define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */
55
-
56
-/* This inode cares about things that happen to its children. Always set for
57
- * dnotify and inotify. */
58
-#define FS_EVENT_ON_CHILD 0x08000000
59
-
60
-/* This is a list of all events that may get sent to a parernt based on fs event
61
- * happening to inodes inside that directory */
62
-#define FS_EVENTS_POSS_ON_CHILD (FS_ACCESS | FS_MODIFY | FS_ATTRIB |\
63
- FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN |\
64
- FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\
65
- FS_DELETE | FS_OPEN_PERM | FS_ACCESS_PERM)
61
+#define FS_ISDIR 0x40000000 /* event occurred against dir */
62
+#define FS_IN_ONESHOT 0x80000000 /* only send event once */
6663
6764 #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
6865
69
-#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
66
+/*
67
+ * Directory entry modification events - reported only to directory
68
+ * where entry is modified and not to a watching parent.
69
+ * The watching parent may get an FS_ATTRIB|FS_EVENT_ON_CHILD event
70
+ * when a directory entry inside a child subdir changes.
71
+ */
72
+#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE)
73
+
74
+#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \
75
+ FS_OPEN_EXEC_PERM)
76
+
77
+/*
78
+ * This is a list of all events that may get sent to a parent that is watching
79
+ * with flag FS_EVENT_ON_CHILD based on fs event on a child of that directory.
80
+ */
81
+#define FS_EVENTS_POSS_ON_CHILD (ALL_FSNOTIFY_PERM_EVENTS | \
82
+ FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
83
+ FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | \
84
+ FS_OPEN | FS_OPEN_EXEC)
85
+
86
+/*
87
+ * This is a list of all events that may get sent with the parent inode as the
88
+ * @to_tell argument of fsnotify().
89
+ * It may include events that can be sent to an inode/sb/mount mark, but cannot
90
+ * be sent to a parent watching children.
91
+ */
92
+#define FS_EVENTS_POSS_TO_PARENT (FS_EVENTS_POSS_ON_CHILD)
7093
7194 /* Events that can be reported to backends */
72
-#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
73
- FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
74
- FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
75
- FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
76
- FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
77
- FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME)
95
+#define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \
96
+ FS_EVENTS_POSS_ON_CHILD | \
97
+ FS_DELETE_SELF | FS_MOVE_SELF | FS_DN_RENAME | \
98
+ FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED)
7899
79100 /* Extra flags that may be reported with event or control handling of events */
80101 #define ALL_FSNOTIFY_FLAGS (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \
....@@ -96,18 +117,42 @@
96117 * these operations for each relevant group.
97118 *
98119 * handle_event - main call for a group to handle an fs event
120
+ * @group: group to notify
121
+ * @mask: event type and flags
122
+ * @data: object that event happened on
123
+ * @data_type: type of object for fanotify_data_XXX() accessors
124
+ * @dir: optional directory associated with event -
125
+ * if @file_name is not NULL, this is the directory that
126
+ * @file_name is relative to
127
+ * @file_name: optional file name associated with event
128
+ * @cookie: inotify rename cookie
129
+ * @iter_info: array of marks from this group that are interested in the event
130
+ *
131
+ * handle_inode_event - simple variant of handle_event() for groups that only
132
+ * have inode marks and don't have ignore mask
133
+ * @mark: mark to notify
134
+ * @mask: event type and flags
135
+ * @inode: inode that event happened on
136
+ * @dir: optional directory associated with event -
137
+ * if @file_name is not NULL, this is the directory that
138
+ * @file_name is relative to.
139
+ * @file_name: optional file name associated with event
140
+ * @cookie: inotify rename cookie
141
+ *
99142 * free_group_priv - called when a group refcnt hits 0 to clean up the private union
100143 * freeing_mark - called when a mark is being destroyed for some reason. The group
101
- * MUST be holding a reference on each mark and that reference must be
102
- * dropped in this function. inotify uses this function to send
103
- * userspace messages that marks have been removed.
144
+ * MUST be holding a reference on each mark and that reference must be
145
+ * dropped in this function. inotify uses this function to send
146
+ * userspace messages that marks have been removed.
104147 */
105148 struct fsnotify_ops {
106
- int (*handle_event)(struct fsnotify_group *group,
107
- struct inode *inode,
108
- u32 mask, const void *data, int data_type,
109
- const unsigned char *file_name, u32 cookie,
149
+ int (*handle_event)(struct fsnotify_group *group, u32 mask,
150
+ const void *data, int data_type, struct inode *dir,
151
+ const struct qstr *file_name, u32 cookie,
110152 struct fsnotify_iter_info *iter_info);
153
+ int (*handle_inode_event)(struct fsnotify_mark *mark, u32 mask,
154
+ struct inode *inode, struct inode *dir,
155
+ const struct qstr *file_name, u32 cookie);
111156 void (*free_group_priv)(struct fsnotify_group *group);
112157 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
113158 void (*free_event)(struct fsnotify_event *event);
....@@ -122,9 +167,7 @@
122167 */
123168 struct fsnotify_event {
124169 struct list_head list;
125
- /* inode may ONLY be dereferenced during handle_event(). */
126
- struct inode *inode; /* either the inode the event happened to or its parent */
127
- u32 mask; /* the type of access, bitwise OR for FS_* event types */
170
+ unsigned long objectid; /* identifier for queue merges */
128171 };
129172
130173 /*
....@@ -194,29 +237,58 @@
194237 /* allows a group to block waiting for a userspace response */
195238 struct list_head access_list;
196239 wait_queue_head_t access_waitq;
197
- int f_flags;
240
+ int flags; /* flags from fanotify_init() */
241
+ int f_flags; /* event_f_flags from fanotify_init() */
198242 unsigned int max_marks;
199243 struct user_struct *user;
200
- bool audit;
201244 } fanotify_data;
202245 #endif /* CONFIG_FANOTIFY */
203246 };
204247 };
205248
206
-/* when calling fsnotify tell it if the data is a path or inode */
207
-#define FSNOTIFY_EVENT_NONE 0
208
-#define FSNOTIFY_EVENT_PATH 1
209
-#define FSNOTIFY_EVENT_INODE 2
249
+/* When calling fsnotify tell it if the data is a path or inode */
250
+enum fsnotify_data_type {
251
+ FSNOTIFY_EVENT_NONE,
252
+ FSNOTIFY_EVENT_PATH,
253
+ FSNOTIFY_EVENT_INODE,
254
+};
255
+
256
+static inline struct inode *fsnotify_data_inode(const void *data, int data_type)
257
+{
258
+ switch (data_type) {
259
+ case FSNOTIFY_EVENT_INODE:
260
+ return (struct inode *)data;
261
+ case FSNOTIFY_EVENT_PATH:
262
+ return d_inode(((const struct path *)data)->dentry);
263
+ default:
264
+ return NULL;
265
+ }
266
+}
267
+
268
+static inline const struct path *fsnotify_data_path(const void *data,
269
+ int data_type)
270
+{
271
+ switch (data_type) {
272
+ case FSNOTIFY_EVENT_PATH:
273
+ return data;
274
+ default:
275
+ return NULL;
276
+ }
277
+}
210278
211279 enum fsnotify_obj_type {
212280 FSNOTIFY_OBJ_TYPE_INODE,
281
+ FSNOTIFY_OBJ_TYPE_PARENT,
213282 FSNOTIFY_OBJ_TYPE_VFSMOUNT,
283
+ FSNOTIFY_OBJ_TYPE_SB,
214284 FSNOTIFY_OBJ_TYPE_COUNT,
215285 FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
216286 };
217287
218288 #define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE)
289
+#define FSNOTIFY_OBJ_TYPE_PARENT_FL (1U << FSNOTIFY_OBJ_TYPE_PARENT)
219290 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
291
+#define FSNOTIFY_OBJ_TYPE_SB_FL (1U << FSNOTIFY_OBJ_TYPE_SB)
220292 #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
221293
222294 static inline bool fsnotify_valid_obj_type(unsigned int type)
....@@ -259,7 +331,9 @@
259331 }
260332
261333 FSNOTIFY_ITER_FUNCS(inode, INODE)
334
+FSNOTIFY_ITER_FUNCS(parent, PARENT)
262335 FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
336
+FSNOTIFY_ITER_FUNCS(sb, SB)
263337
264338 #define fsnotify_foreach_obj_type(type) \
265339 for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++)
....@@ -272,14 +346,17 @@
272346 typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t;
273347
274348 /*
275
- * Inode / vfsmount point to this structure which tracks all marks attached to
276
- * the inode / vfsmount. The reference to inode / vfsmount is held by this
349
+ * Inode/vfsmount/sb point to this structure which tracks all marks attached to
350
+ * the inode/vfsmount/sb. The reference to inode/vfsmount/sb is held by this
277351 * structure. We destroy this structure when there are no more marks attached
278352 * to it. The structure is protected by fsnotify_mark_srcu.
279353 */
280354 struct fsnotify_mark_connector {
281355 spinlock_t lock;
282
- unsigned int type; /* Type of object [lock] */
356
+ unsigned short type; /* Type of object [lock] */
357
+#define FSNOTIFY_CONN_FLAG_HAS_FSID 0x01
358
+ unsigned short flags; /* flags [lock] */
359
+ __kernel_fsid_t fsid; /* fsid of filesystem containing object */
283360 union {
284361 /* Object pointer [lock] */
285362 fsnotify_connp_t *obj;
....@@ -335,12 +412,28 @@
335412 /* called from the vfs helpers */
336413
337414 /* main fsnotify call to send events */
338
-extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
339
- const unsigned char *name, u32 cookie);
340
-extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask);
415
+extern int fsnotify(__u32 mask, const void *data, int data_type,
416
+ struct inode *dir, const struct qstr *name,
417
+ struct inode *inode, u32 cookie);
418
+extern int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
419
+ int data_type);
341420 extern void __fsnotify_inode_delete(struct inode *inode);
342421 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
422
+extern void fsnotify_sb_delete(struct super_block *sb);
343423 extern u32 fsnotify_get_cookie(void);
424
+
425
+static inline __u32 fsnotify_parent_needed_mask(__u32 mask)
426
+{
427
+ /* FS_EVENT_ON_CHILD is set on marks that want parent/name info */
428
+ if (!(mask & FS_EVENT_ON_CHILD))
429
+ return 0;
430
+ /*
431
+ * This object might be watched by a mark that cares about parent/name
432
+ * info, does it care about the specific set of events that can be
433
+ * reported with parent/name info?
434
+ */
435
+ return mask & FS_EVENTS_POSS_TO_PARENT;
436
+}
344437
345438 static inline int fsnotify_inode_watches_children(struct inode *inode)
346439 {
....@@ -407,6 +500,9 @@
407500 extern struct fsnotify_event *fsnotify_peek_first_event(struct fsnotify_group *group);
408501 /* return AND dequeue the first event on the notification queue */
409502 extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group *group);
503
+/* Remove event queued in the notification list */
504
+extern void fsnotify_remove_queued_event(struct fsnotify_group *group,
505
+ struct fsnotify_event *event);
410506
411507 /* functions used to manipulate the marks attached to inodes */
412508
....@@ -419,28 +515,35 @@
419515 /* Find mark belonging to given group in the list of marks */
420516 extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp,
421517 struct fsnotify_group *group);
518
+/* Get cached fsid of filesystem containing object */
519
+extern int fsnotify_get_conn_fsid(const struct fsnotify_mark_connector *conn,
520
+ __kernel_fsid_t *fsid);
422521 /* attach the mark to the object */
423522 extern int fsnotify_add_mark(struct fsnotify_mark *mark,
424523 fsnotify_connp_t *connp, unsigned int type,
425
- int allow_dups);
524
+ int allow_dups, __kernel_fsid_t *fsid);
426525 extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
427
- fsnotify_connp_t *connp, unsigned int type,
428
- int allow_dups);
526
+ fsnotify_connp_t *connp,
527
+ unsigned int type, int allow_dups,
528
+ __kernel_fsid_t *fsid);
529
+
429530 /* attach the mark to the inode */
430531 static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
431532 struct inode *inode,
432533 int allow_dups)
433534 {
434535 return fsnotify_add_mark(mark, &inode->i_fsnotify_marks,
435
- FSNOTIFY_OBJ_TYPE_INODE, allow_dups);
536
+ FSNOTIFY_OBJ_TYPE_INODE, allow_dups, NULL);
436537 }
437538 static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,
438539 struct inode *inode,
439540 int allow_dups)
440541 {
441542 return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks,
442
- FSNOTIFY_OBJ_TYPE_INODE, allow_dups);
543
+ FSNOTIFY_OBJ_TYPE_INODE, allow_dups,
544
+ NULL);
443545 }
546
+
444547 /* given a group and a mark, flag mark to be freed when all references are dropped */
445548 extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
446549 struct fsnotify_group *group);
....@@ -448,6 +551,8 @@
448551 extern void fsnotify_detach_mark(struct fsnotify_mark *mark);
449552 /* free mark */
450553 extern void fsnotify_free_mark(struct fsnotify_mark *mark);
554
+/* Wait until all marks queued for destruction are destroyed */
555
+extern void fsnotify_wait_marks_destroyed(void);
451556 /* run all the marks in a group, and clear all of the marks attached to given object type */
452557 extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsigned int type);
453558 /* run all the marks in a group, and clear all of the vfsmount marks */
....@@ -460,25 +565,34 @@
460565 {
461566 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
462567 }
568
+/* run all the marks in a group, and clear all of the sn marks */
569
+static inline void fsnotify_clear_sb_marks_by_group(struct fsnotify_group *group)
570
+{
571
+ fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_SB_FL);
572
+}
463573 extern void fsnotify_get_mark(struct fsnotify_mark *mark);
464574 extern void fsnotify_put_mark(struct fsnotify_mark *mark);
465
-extern void fsnotify_unmount_inodes(struct super_block *sb);
466575 extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
467576 extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
468577
469
-/* put here because inotify does some weird stuff when destroying watches */
470
-extern void fsnotify_init_event(struct fsnotify_event *event,
471
- struct inode *to_tell, u32 mask);
578
+static inline void fsnotify_init_event(struct fsnotify_event *event,
579
+ unsigned long objectid)
580
+{
581
+ INIT_LIST_HEAD(&event->list);
582
+ event->objectid = objectid;
583
+}
472584
473585 #else
474586
475
-static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
476
- const unsigned char *name, u32 cookie)
587
+static inline int fsnotify(__u32 mask, const void *data, int data_type,
588
+ struct inode *dir, const struct qstr *name,
589
+ struct inode *inode, u32 cookie)
477590 {
478591 return 0;
479592 }
480593
481
-static inline int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask)
594
+static inline int __fsnotify_parent(struct dentry *dentry, __u32 mask,
595
+ const void *data, int data_type)
482596 {
483597 return 0;
484598 }
....@@ -489,6 +603,9 @@
489603 static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
490604 {}
491605
606
+static inline void fsnotify_sb_delete(struct super_block *sb)
607
+{}
608
+
492609 static inline void fsnotify_update_flags(struct dentry *dentry)
493610 {}
494611