History

Merge tag 'fsnotify_for_v5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull fsnotify updates from Jan Kara: "This implements the fanotify FAN_DIR_MODIFY event. This event reports the name in a directory under which a change happened and together with the directory filehandle and fstatat() allows reliable and efficient implementation of directory synchronization" * tag 'fsnotify_for_v5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fanotify: Fix the checks in fanotify_fsid_equal fanotify: report name info for FAN_DIR_MODIFY event fanotify: record name info for FAN_DIR_MODIFY event fanotify: Drop fanotify_event_has_fid() fanotify: prepare to report both parent and child fid's fanotify: send FAN_DIR_MODIFY event flavor with dir inode and name fanotify: divorce fanotify_path_event and fanotify_fid_event fanotify: Store fanotify handles differently fanotify: Simplify create_fd() fanotify: fix merging marks masks with FAN_ONDIR fanotify: merge duplicate events on parent and child fsnotify: replace inode pointer with an object id fsnotify: simplify arguments passing to fsnotify_parent() fsnotify: use helpers to access data by data_type fsnotify: funnel all dirent events through fsnotify_name() fsnotify: factor helpers fsnotify_dentry() and fsnotify_file() fsnotify: tidy up FS_ and FAN_ constants

Linus Torvalds committed 6 years ago

Commit b6ff1072 parents 74e934b 6def1a112 files · +637 −363Browse files

Showing the changes to include/linux (3 of 12 files). Show all

Unified · Split

3 files
  1. include/linux/fanotify.h +2 −1
  2. include/linux/fsnotify.h +58 −80
  3. include/linux/fsnotify_backend.h +49 −21
include/linux/fanotify.h+2−1
@@ -47,7 +47,8 @@ · 46 unmodified lines
4747 * Directory entry modification events - reported only to directory
4848 * where entry is modified and not to a watching parent.
4949 */
50−#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE)
50+#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE | \
51+ FAN_DIR_MODIFY)
5152
5253 /* Events that can only be reported with data type FSNOTIFY_EVENT_INODE */
5354 #define FANOTIFY_INODE_EVENTS (FANOTIFY_DIRENT_EVENTS | \
include/linux/fsnotify.h+58−80
@@ -18,39 +18,63 @@ · 17 unmodified lines
1818 #include <linux/bug.h>
1919
2020 /*
21− * Notify this @dir inode about a change in the directory entry @dentry.
21+ * Notify this @dir inode about a change in a child directory entry.
22+ * The directory entry may have turned positive or negative or its inode may
23+ * have changed (i.e. renamed over).
2224 *
2325 * Unlike fsnotify_parent(), the event will be reported regardless of the
2426 * FS_EVENT_ON_CHILD mask on the parent inode.
2527 */
26−static inline int fsnotify_dirent(struct inode *dir, struct dentry *dentry,
27− __u32 mask)
28+static inline void fsnotify_name(struct inode *dir, __u32 mask,
29+ struct inode *child,
30+ const struct qstr *name, u32 cookie)
2831 {
29− return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
30− &dentry->d_name, 0);
32+ fsnotify(dir, mask, child, FSNOTIFY_EVENT_INODE, name, cookie);
33+ /*
34+ * Send another flavor of the event without child inode data and
35+ * without the specific event type (e.g. FS_CREATE|FS_IS_DIR).
36+ * The name is relative to the dir inode the event is reported to.
37+ */
38+ fsnotify(dir, FS_DIR_MODIFY, dir, FSNOTIFY_EVENT_INODE, name, 0);
3139 }
3240
33−/* Notify this dentry's parent about a child's events. */
34−static inline int fsnotify_parent(const struct path *path,
35− struct dentry *dentry, __u32 mask)
41+static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry,
42+ __u32 mask)
3643 {
37− if (!dentry)
38− dentry = path->dentry;
39−
40− return __fsnotify_parent(path, dentry, mask);
44+ fsnotify_name(dir, mask, d_inode(dentry), &dentry->d_name, 0);
4145 }
4246
4347 /*
44− * Simple wrapper to consolidate calls fsnotify_parent()/fsnotify() when
45− * an event is on a path.
48+ * Simple wrappers to consolidate calls fsnotify_parent()/fsnotify() when
49+ * an event is on a file/dentry.
4650 */
47−static inline int fsnotify_path(struct inode *inode, const struct path *path,
48− __u32 mask)
51+static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask)
52+{
53+ struct inode *inode = d_inode(dentry);
54+
55+ if (S_ISDIR(inode->i_mode))
56+ mask |= FS_ISDIR;
57+
58+ fsnotify_parent(dentry, mask, inode, FSNOTIFY_EVENT_INODE);
59+ fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
60+}
61+
62+static inline int fsnotify_file(struct file *file, __u32 mask)
4963 {
50− int ret = fsnotify_parent(path, NULL, mask);
64+ const struct path *path = &file->f_path;
65+ struct inode *inode = file_inode(file);
66+ int ret;
67+
68+ if (file->f_mode & FMODE_NONOTIFY)
69+ return 0;
70+
71+ if (S_ISDIR(inode->i_mode))
72+ mask |= FS_ISDIR;
5173
74+ ret = fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH);
5275 if (ret)
5376 return ret;
77+
5478 return fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
5579 }
5680
@@ -58,19 +82,16 @@ static inline int fsnotify_path(struct inode *inode, const struct path *path, · 1 unmodified line
5882 static inline int fsnotify_perm(struct file *file, int mask)
5983 {
6084 int ret;
61− const struct path *path = &file->f_path;
62− struct inode *inode = file_inode(file);
6385 __u32 fsnotify_mask = 0;
6486
65− if (file->f_mode & FMODE_NONOTIFY)
66− return 0;
6787 if (!(mask & (MAY_READ | MAY_OPEN)))
6888 return 0;
89+
6990 if (mask & MAY_OPEN) {
7091 fsnotify_mask = FS_OPEN_PERM;
7192
7293 if (file->f_flags & __FMODE_EXEC) {
73− ret = fsnotify_path(inode, path, FS_OPEN_EXEC_PERM);
94+ ret = fsnotify_file(file, FS_OPEN_EXEC_PERM);
7495
7596 if (ret)
7697 return ret;
@@ -79,10 +100,7 @@ static inline int fsnotify_perm(struct file *file, int mask) · 2 unmodified lines
79100 fsnotify_mask = FS_ACCESS_PERM;
80101 }
81102
82− if (S_ISDIR(inode->i_mode))
83− fsnotify_mask |= FS_ISDIR;
84−
85− return fsnotify_path(inode, path, fsnotify_mask);
103+ return fsnotify_file(file, fsnotify_mask);
86104 }
87105
88106 /*
@@ -122,10 +140,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, · 33 unmodified lines
122140 mask |= FS_ISDIR;
123141 }
124142
125− fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name,
126− fs_cookie);
127− fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name,
128− fs_cookie);
143+ fsnotify_name(old_dir, old_dir_mask, source, old_name, fs_cookie);
144+ fsnotify_name(new_dir, new_dir_mask, source, new_name, fs_cookie);
129145
130146 if (target)
131147 fsnotify_link_count(target);
@@ -180,12 +196,13 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) · 48 unmodified lines
180196 * Note: We have to pass also the linked inode ptr as some filesystems leave
181197 * new_dentry->d_inode NULL and instantiate inode pointer later
182198 */
183−static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry)
199+static inline void fsnotify_link(struct inode *dir, struct inode *inode,
200+ struct dentry *new_dentry)
184201 {
185202 fsnotify_link_count(inode);
186203 audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);
187204
188− fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, &new_dentry->d_name, 0);
205+ fsnotify_name(dir, FS_CREATE, inode, &new_dentry->d_name, 0);
189206 }
190207
191208 /*
@@ -229,15 +246,7 @@ static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry) · 37 unmodified lines
229246 */
230247 static inline void fsnotify_access(struct file *file)
231248 {
232− const struct path *path = &file->f_path;
233− struct inode *inode = file_inode(file);
234− __u32 mask = FS_ACCESS;
235−
236− if (S_ISDIR(inode->i_mode))
237− mask |= FS_ISDIR;
238−
239− if (!(file->f_mode & FMODE_NONOTIFY))
240− fsnotify_path(inode, path, mask);
249+ fsnotify_file(file, FS_ACCESS);
241250 }
242251
243252 /*
@@ -245,15 +254,7 @@ static inline void fsnotify_access(struct file *file) · 1 unmodified line
245254 */
246255 static inline void fsnotify_modify(struct file *file)
247256 {
248− const struct path *path = &file->f_path;
249− struct inode *inode = file_inode(file);
250− __u32 mask = FS_MODIFY;
251−
252− if (S_ISDIR(inode->i_mode))
253− mask |= FS_ISDIR;
254−
255− if (!(file->f_mode & FMODE_NONOTIFY))
256− fsnotify_path(inode, path, mask);
257+ fsnotify_file(file, FS_MODIFY);
257258 }
258259
259260 /*
@@ -261,16 +262,12 @@ static inline void fsnotify_modify(struct file *file) · 1 unmodified line
261262 */
262263 static inline void fsnotify_open(struct file *file)
263264 {
264− const struct path *path = &file->f_path;
265− struct inode *inode = file_inode(file);
266265 __u32 mask = FS_OPEN;
267266
268− if (S_ISDIR(inode->i_mode))
269− mask |= FS_ISDIR;
270267 if (file->f_flags & __FMODE_EXEC)
271268 mask |= FS_OPEN_EXEC;
272269
273− fsnotify_path(inode, path, mask);
270+ fsnotify_file(file, mask);
274271 }
275272
276273 /*
@@ -278,16 +275,10 @@ static inline void fsnotify_open(struct file *file) · 1 unmodified line
278275 */
279276 static inline void fsnotify_close(struct file *file)
280277 {
281− const struct path *path = &file->f_path;
282− struct inode *inode = file_inode(file);
283− fmode_t mode = file->f_mode;
284− __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
278+ __u32 mask = (file->f_mode & FMODE_WRITE) ? FS_CLOSE_WRITE :
279+ FS_CLOSE_NOWRITE;
285280
286− if (S_ISDIR(inode->i_mode))
287− mask |= FS_ISDIR;
288−
289− if (!(file->f_mode & FMODE_NONOTIFY))
290− fsnotify_path(inode, path, mask);
281+ fsnotify_file(file, mask);
291282 }
292283
293284 /*
@@ -295,14 +286,7 @@ static inline void fsnotify_close(struct file *file) · 1 unmodified line
295286 */
296287 static inline void fsnotify_xattr(struct dentry *dentry)
297288 {
298− struct inode *inode = dentry->d_inode;
299− __u32 mask = FS_ATTRIB;
300−
301− if (S_ISDIR(inode->i_mode))
302− mask |= FS_ISDIR;
303−
304− fsnotify_parent(NULL, dentry, mask);
305− fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
289+ fsnotify_dentry(dentry, FS_ATTRIB);
306290 }
307291
308292 /*
@@ -311,7 +295,6 @@ static inline void fsnotify_xattr(struct dentry *dentry) · 2 unmodified lines
311295 */
312296 static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
313297 {
314− struct inode *inode = dentry->d_inode;
315298 __u32 mask = 0;
316299
317300 if (ia_valid & ATTR_UID)
@@ -332,13 +315,8 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) · 14 unmodified lines
332315 if (ia_valid & ATTR_MODE)
333316 mask |= FS_ATTRIB;
334317
335− if (mask) {
336− if (S_ISDIR(inode->i_mode))
337− mask |= FS_ISDIR;
338−
339− fsnotify_parent(NULL, dentry, mask);
340− fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
341− }
318+ if (mask)
319+ fsnotify_dentry(dentry, mask);
342320 }
343321
344322 #endif /* _LINUX_FS_NOTIFY_H */
include/linux/fsnotify_backend.h+49−21
@@ -47,18 +47,18 @@ · 46 unmodified lines
4747 #define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */
4848 #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */
4949 #define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */
50+#define FS_DIR_MODIFY 0x00080000 /* Directory entry was modified */
5051
5152 #define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */
52−#define FS_ISDIR 0x40000000 /* event occurred against dir */
53−#define FS_IN_ONESHOT 0x80000000 /* only send event once */
54−
55−#define FS_DN_RENAME 0x10000000 /* file renamed */
56−#define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */
57−
5853 /* This inode cares about things that happen to its children. Always set for
5954 * dnotify and inotify. */
6055 #define FS_EVENT_ON_CHILD 0x08000000
6156
57+#define FS_DN_RENAME 0x10000000 /* file renamed */
58+#define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */
59+#define FS_ISDIR 0x40000000 /* event occurred against dir */
60+#define FS_IN_ONESHOT 0x80000000 /* only send event once */
61+
6262 #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
6363
6464 /*
@@ -67,7 +67,8 @@ · 2 unmodified lines
6767 * The watching parent may get an FS_ATTRIB|FS_EVENT_ON_CHILD event
6868 * when a directory entry inside a child subdir changes.
6969 */
70−#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE)
70+#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE | \
71+ FS_DIR_MODIFY)
7172
7273 #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \
7374 FS_OPEN_EXEC_PERM)
@@ -133,8 +134,7 @@ struct fsnotify_ops { · 59 unmodified lines
133134 */
134135 struct fsnotify_event {
135136 struct list_head list;
136− /* inode may ONLY be dereferenced during handle_event(). */
137− struct inode *inode; /* either the inode the event happened to or its parent */
137+ unsigned long objectid; /* identifier for queue merges */
138138 };
139139
140140 /*
@@ -213,10 +213,36 @@ struct fsnotify_group { · 72 unmodified lines
213213 };
214214 };
215215
216−/* when calling fsnotify tell it if the data is a path or inode */
217−#define FSNOTIFY_EVENT_NONE 0
218−#define FSNOTIFY_EVENT_PATH 1
219−#define FSNOTIFY_EVENT_INODE 2
216+/* When calling fsnotify tell it if the data is a path or inode */
217+enum fsnotify_data_type {
218+ FSNOTIFY_EVENT_NONE,
219+ FSNOTIFY_EVENT_PATH,
220+ FSNOTIFY_EVENT_INODE,
221+};
222+
223+static inline const struct inode *fsnotify_data_inode(const void *data,
224+ int data_type)
225+{
226+ switch (data_type) {
227+ case FSNOTIFY_EVENT_INODE:
228+ return data;
229+ case FSNOTIFY_EVENT_PATH:
230+ return d_inode(((const struct path *)data)->dentry);
231+ default:
232+ return NULL;
233+ }
234+}
235+
236+static inline const struct path *fsnotify_data_path(const void *data,
237+ int data_type)
238+{
239+ switch (data_type) {
240+ case FSNOTIFY_EVENT_PATH:
241+ return data;
242+ default:
243+ return NULL;
244+ }
245+}
220246
221247 enum fsnotify_obj_type {
222248 FSNOTIFY_OBJ_TYPE_INODE,
@@ -351,9 +377,10 @@ struct fsnotify_mark { · 128 unmodified lines
351377 /* called from the vfs helpers */
352378
353379 /* main fsnotify call to send events */
354−extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
355− const struct qstr *name, u32 cookie);
356−extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask);
380+extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data,
381+ int data_type, const struct qstr *name, u32 cookie);
382+extern int fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
383+ int data_type);
357384 extern void __fsnotify_inode_delete(struct inode *inode);
358385 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
359386 extern void fsnotify_sb_delete(struct super_block *sb);
@@ -500,21 +527,22 @@ extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); · 140 unmodified lines
500527 extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
501528
502529 static inline void fsnotify_init_event(struct fsnotify_event *event,
503− struct inode *inode)
530+ unsigned long objectid)
504531 {
505532 INIT_LIST_HEAD(&event->list);
506− event->inode = inode;
533+ event->objectid = objectid;
507534 }
508535
509536 #else
510537
511−static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
512− const struct qstr *name, u32 cookie)
538+static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data,
539+ int data_type, const struct qstr *name, u32 cookie)
513540 {
514541 return 0;
515542 }
516543
517−static inline int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask)
544+static inline int fsnotify_parent(struct dentry *dentry, __u32 mask,
545+ const void *data, int data_type)
518546 {
519547 return 0;
520548 }