hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/include/linux/fsnotify.h
....@@ -17,39 +17,102 @@
1717 #include <linux/slab.h>
1818 #include <linux/bug.h>
1919
20
-/* Notify this dentry's parent about a child's events. */
21
-static inline int fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask)
20
+/*
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).
24
+ *
25
+ * Unlike fsnotify_parent(), the event will be reported regardless of the
26
+ * FS_EVENT_ON_CHILD mask on the parent inode and will not be reported if only
27
+ * the child is interested and not the parent.
28
+ */
29
+static inline void fsnotify_name(struct inode *dir, __u32 mask,
30
+ struct inode *child,
31
+ const struct qstr *name, u32 cookie)
2232 {
23
- if (!dentry)
24
- dentry = path->dentry;
25
-
26
- return __fsnotify_parent(path, dentry, mask);
33
+ fsnotify(mask, child, FSNOTIFY_EVENT_INODE, dir, name, NULL, cookie);
2734 }
2835
29
-/* simple call site for access decisions */
30
-static inline int fsnotify_perm(struct file *file, int mask)
36
+static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry,
37
+ __u32 mask)
38
+{
39
+ fsnotify_name(dir, mask, d_inode(dentry), &dentry->d_name, 0);
40
+}
41
+
42
+static inline void fsnotify_inode(struct inode *inode, __u32 mask)
43
+{
44
+ if (S_ISDIR(inode->i_mode))
45
+ mask |= FS_ISDIR;
46
+
47
+ fsnotify(mask, inode, FSNOTIFY_EVENT_INODE, NULL, NULL, inode, 0);
48
+}
49
+
50
+/* Notify this dentry's parent about a child's events. */
51
+static inline int fsnotify_parent(struct dentry *dentry, __u32 mask,
52
+ const void *data, int data_type)
53
+{
54
+ struct inode *inode = d_inode(dentry);
55
+
56
+ if (S_ISDIR(inode->i_mode)) {
57
+ mask |= FS_ISDIR;
58
+
59
+ /* sb/mount marks are not interested in name of directory */
60
+ if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
61
+ goto notify_child;
62
+ }
63
+
64
+ /* disconnected dentry cannot notify parent */
65
+ if (IS_ROOT(dentry))
66
+ goto notify_child;
67
+
68
+ return __fsnotify_parent(dentry, mask, data, data_type);
69
+
70
+notify_child:
71
+ return fsnotify(mask, data, data_type, NULL, NULL, inode, 0);
72
+}
73
+
74
+/*
75
+ * Simple wrappers to consolidate calls to fsnotify_parent() when an event
76
+ * is on a file/dentry.
77
+ */
78
+static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask)
79
+{
80
+ fsnotify_parent(dentry, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE);
81
+}
82
+
83
+static inline int fsnotify_file(struct file *file, __u32 mask)
3184 {
3285 const struct path *path = &file->f_path;
33
- struct inode *inode = file_inode(file);
34
- __u32 fsnotify_mask = 0;
35
- int ret;
3686
3787 if (file->f_mode & FMODE_NONOTIFY)
3888 return 0;
89
+
90
+ return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH);
91
+}
92
+
93
+/* Simple call site for access decisions */
94
+static inline int fsnotify_perm(struct file *file, int mask)
95
+{
96
+ int ret;
97
+ __u32 fsnotify_mask = 0;
98
+
3999 if (!(mask & (MAY_READ | MAY_OPEN)))
40100 return 0;
41
- if (mask & MAY_OPEN)
101
+
102
+ if (mask & MAY_OPEN) {
42103 fsnotify_mask = FS_OPEN_PERM;
43
- else if (mask & MAY_READ)
104
+
105
+ if (file->f_flags & __FMODE_EXEC) {
106
+ ret = fsnotify_file(file, FS_OPEN_EXEC_PERM);
107
+
108
+ if (ret)
109
+ return ret;
110
+ }
111
+ } else if (mask & MAY_READ) {
44112 fsnotify_mask = FS_ACCESS_PERM;
45
- else
46
- BUG();
113
+ }
47114
48
- ret = fsnotify_parent(path, NULL, fsnotify_mask);
49
- if (ret)
50
- return ret;
51
-
52
- return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
115
+ return fsnotify_file(file, fsnotify_mask);
53116 }
54117
55118 /*
....@@ -57,21 +120,22 @@
57120 */
58121 static inline void fsnotify_link_count(struct inode *inode)
59122 {
60
- fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
123
+ fsnotify_inode(inode, FS_ATTRIB);
61124 }
62125
63126 /*
64127 * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir
65128 */
66129 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
67
- const unsigned char *old_name,
68
- int isdir, struct inode *target, struct dentry *moved)
130
+ const struct qstr *old_name,
131
+ int isdir, struct inode *target,
132
+ struct dentry *moved)
69133 {
70134 struct inode *source = moved->d_inode;
71135 u32 fs_cookie = fsnotify_get_cookie();
72
- __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM);
73
- __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO);
74
- const unsigned char *new_name = moved->d_name.name;
136
+ __u32 old_dir_mask = FS_MOVED_FROM;
137
+ __u32 new_dir_mask = FS_MOVED_TO;
138
+ const struct qstr *new_name = &moved->d_name;
75139
76140 if (old_dir == new_dir)
77141 old_dir_mask |= FS_DN_RENAME;
....@@ -81,16 +145,12 @@
81145 new_dir_mask |= FS_ISDIR;
82146 }
83147
84
- fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name,
85
- fs_cookie);
86
- fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name,
87
- fs_cookie);
148
+ fsnotify_name(old_dir, old_dir_mask, source, old_name, fs_cookie);
149
+ fsnotify_name(new_dir, new_dir_mask, source, new_name, fs_cookie);
88150
89151 if (target)
90152 fsnotify_link_count(target);
91
-
92
- if (source)
93
- fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0);
153
+ fsnotify_inode(source, FS_MOVE_SELF);
94154 audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE);
95155 }
96156
....@@ -111,24 +171,11 @@
111171 }
112172
113173 /*
114
- * fsnotify_nameremove - a filename was removed from a directory
115
- */
116
-static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
117
-{
118
- __u32 mask = FS_DELETE;
119
-
120
- if (isdir)
121
- mask |= FS_ISDIR;
122
-
123
- fsnotify_parent(NULL, dentry, mask);
124
-}
125
-
126
-/*
127174 * fsnotify_inoderemove - an inode is going away
128175 */
129176 static inline void fsnotify_inoderemove(struct inode *inode)
130177 {
131
- fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
178
+ fsnotify_inode(inode, FS_DELETE_SELF);
132179 __fsnotify_inode_delete(inode);
133180 }
134181
....@@ -139,7 +186,7 @@
139186 {
140187 audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
141188
142
- fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
189
+ fsnotify_dirent(inode, dentry, FS_CREATE);
143190 }
144191
145192 /*
....@@ -147,12 +194,62 @@
147194 * Note: We have to pass also the linked inode ptr as some filesystems leave
148195 * new_dentry->d_inode NULL and instantiate inode pointer later
149196 */
150
-static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry)
197
+static inline void fsnotify_link(struct inode *dir, struct inode *inode,
198
+ struct dentry *new_dentry)
151199 {
152200 fsnotify_link_count(inode);
153201 audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);
154202
155
- fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0);
203
+ fsnotify_name(dir, FS_CREATE, inode, &new_dentry->d_name, 0);
204
+}
205
+
206
+/*
207
+ * fsnotify_delete - @dentry was unlinked and unhashed
208
+ *
209
+ * Caller must make sure that dentry->d_name is stable.
210
+ *
211
+ * Note: unlike fsnotify_unlink(), we have to pass also the unlinked inode
212
+ * as this may be called after d_delete() and old_dentry may be negative.
213
+ */
214
+static inline void fsnotify_delete(struct inode *dir, struct inode *inode,
215
+ struct dentry *dentry)
216
+{
217
+ __u32 mask = FS_DELETE;
218
+
219
+ if (S_ISDIR(inode->i_mode))
220
+ mask |= FS_ISDIR;
221
+
222
+ fsnotify_name(dir, mask, inode, &dentry->d_name, 0);
223
+}
224
+
225
+/**
226
+ * d_delete_notify - delete a dentry and call fsnotify_delete()
227
+ * @dentry: The dentry to delete
228
+ *
229
+ * This helper is used to guaranty that the unlinked inode cannot be found
230
+ * by lookup of this name after fsnotify_delete() event has been delivered.
231
+ */
232
+static inline void d_delete_notify(struct inode *dir, struct dentry *dentry)
233
+{
234
+ struct inode *inode = d_inode(dentry);
235
+
236
+ ihold(inode);
237
+ d_delete(dentry);
238
+ fsnotify_delete(dir, inode, dentry);
239
+ iput(inode);
240
+}
241
+
242
+/*
243
+ * fsnotify_unlink - 'name' was unlinked
244
+ *
245
+ * Caller must make sure that dentry->d_name is stable.
246
+ */
247
+static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry)
248
+{
249
+ if (WARN_ON_ONCE(d_is_negative(dentry)))
250
+ return;
251
+
252
+ fsnotify_delete(dir, d_inode(dentry), dentry);
156253 }
157254
158255 /*
....@@ -160,12 +257,22 @@
160257 */
161258 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
162259 {
163
- __u32 mask = (FS_CREATE | FS_ISDIR);
164
- struct inode *d_inode = dentry->d_inode;
165
-
166260 audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
167261
168
- fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
262
+ fsnotify_dirent(inode, dentry, FS_CREATE | FS_ISDIR);
263
+}
264
+
265
+/*
266
+ * fsnotify_rmdir - directory 'name' was removed
267
+ *
268
+ * Caller must make sure that dentry->d_name is stable.
269
+ */
270
+static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry)
271
+{
272
+ if (WARN_ON_ONCE(d_is_negative(dentry)))
273
+ return;
274
+
275
+ fsnotify_delete(dir, d_inode(dentry), dentry);
169276 }
170277
171278 /*
....@@ -173,17 +280,7 @@
173280 */
174281 static inline void fsnotify_access(struct file *file)
175282 {
176
- const struct path *path = &file->f_path;
177
- struct inode *inode = file_inode(file);
178
- __u32 mask = FS_ACCESS;
179
-
180
- if (S_ISDIR(inode->i_mode))
181
- mask |= FS_ISDIR;
182
-
183
- if (!(file->f_mode & FMODE_NONOTIFY)) {
184
- fsnotify_parent(path, NULL, mask);
185
- fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
186
- }
283
+ fsnotify_file(file, FS_ACCESS);
187284 }
188285
189286 /*
....@@ -191,17 +288,7 @@
191288 */
192289 static inline void fsnotify_modify(struct file *file)
193290 {
194
- const struct path *path = &file->f_path;
195
- struct inode *inode = file_inode(file);
196
- __u32 mask = FS_MODIFY;
197
-
198
- if (S_ISDIR(inode->i_mode))
199
- mask |= FS_ISDIR;
200
-
201
- if (!(file->f_mode & FMODE_NONOTIFY)) {
202
- fsnotify_parent(path, NULL, mask);
203
- fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
204
- }
291
+ fsnotify_file(file, FS_MODIFY);
205292 }
206293
207294 /*
....@@ -209,24 +296,12 @@
209296 */
210297 static inline void fsnotify_open(struct file *file)
211298 {
212
- const struct path *path = &file->f_path;
213
- struct inode *inode = file_inode(file);
214
- struct path lower_path;
215299 __u32 mask = FS_OPEN;
216300
217
- if (S_ISDIR(inode->i_mode))
218
- mask |= FS_ISDIR;
301
+ if (file->f_flags & __FMODE_EXEC)
302
+ mask |= FS_OPEN_EXEC;
219303
220
- if (path->dentry->d_op && path->dentry->d_op->d_canonical_path) {
221
- path->dentry->d_op->d_canonical_path(path, &lower_path);
222
- fsnotify_parent(&lower_path, NULL, mask);
223
- fsnotify(lower_path.dentry->d_inode, mask, &lower_path,
224
- FSNOTIFY_EVENT_PATH, NULL, 0);
225
- path_put(&lower_path);
226
- }
227
-
228
- fsnotify_parent(path, NULL, mask);
229
- fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
304
+ fsnotify_file(file, mask);
230305 }
231306
232307 /*
....@@ -234,18 +309,10 @@
234309 */
235310 static inline void fsnotify_close(struct file *file)
236311 {
237
- const struct path *path = &file->f_path;
238
- struct inode *inode = file_inode(file);
239
- fmode_t mode = file->f_mode;
240
- __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
312
+ __u32 mask = (file->f_mode & FMODE_WRITE) ? FS_CLOSE_WRITE :
313
+ FS_CLOSE_NOWRITE;
241314
242
- if (S_ISDIR(inode->i_mode))
243
- mask |= FS_ISDIR;
244
-
245
- if (!(file->f_mode & FMODE_NONOTIFY)) {
246
- fsnotify_parent(path, NULL, mask);
247
- fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
248
- }
315
+ fsnotify_file(file, mask);
249316 }
250317
251318 /*
....@@ -253,14 +320,7 @@
253320 */
254321 static inline void fsnotify_xattr(struct dentry *dentry)
255322 {
256
- struct inode *inode = dentry->d_inode;
257
- __u32 mask = FS_ATTRIB;
258
-
259
- if (S_ISDIR(inode->i_mode))
260
- mask |= FS_ISDIR;
261
-
262
- fsnotify_parent(NULL, dentry, mask);
263
- fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
323
+ fsnotify_dentry(dentry, FS_ATTRIB);
264324 }
265325
266326 /*
....@@ -269,7 +329,6 @@
269329 */
270330 static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
271331 {
272
- struct inode *inode = dentry->d_inode;
273332 __u32 mask = 0;
274333
275334 if (ia_valid & ATTR_UID)
....@@ -290,13 +349,8 @@
290349 if (ia_valid & ATTR_MODE)
291350 mask |= FS_ATTRIB;
292351
293
- if (mask) {
294
- if (S_ISDIR(inode->i_mode))
295
- mask |= FS_ISDIR;
296
-
297
- fsnotify_parent(NULL, dentry, mask);
298
- fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
299
- }
352
+ if (mask)
353
+ fsnotify_dentry(dentry, mask);
300354 }
301355
302356 #endif /* _LINUX_FS_NOTIFY_H */