diff options
Diffstat (limited to 'include/linux/fsnotify.h')
-rw-r--r-- | include/linux/fsnotify.h | 161 |
1 files changed, 78 insertions, 83 deletions
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 01755909ce81..e4e2204187ee 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -11,8 +11,6 @@ | |||
11 | * (C) Copyright 2005 Robert Love | 11 | * (C) Copyright 2005 Robert Love |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/dnotify.h> | ||
15 | #include <linux/inotify.h> | ||
16 | #include <linux/fsnotify_backend.h> | 14 | #include <linux/fsnotify_backend.h> |
17 | #include <linux/audit.h> | 15 | #include <linux/audit.h> |
18 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -21,35 +19,52 @@ | |||
21 | * fsnotify_d_instantiate - instantiate a dentry for inode | 19 | * fsnotify_d_instantiate - instantiate a dentry for inode |
22 | * Called with dcache_lock held. | 20 | * Called with dcache_lock held. |
23 | */ | 21 | */ |
24 | static inline void fsnotify_d_instantiate(struct dentry *entry, | 22 | static inline void fsnotify_d_instantiate(struct dentry *dentry, |
25 | struct inode *inode) | 23 | struct inode *inode) |
26 | { | 24 | { |
27 | __fsnotify_d_instantiate(entry, inode); | 25 | __fsnotify_d_instantiate(dentry, inode); |
28 | |||
29 | inotify_d_instantiate(entry, inode); | ||
30 | } | 26 | } |
31 | 27 | ||
32 | /* Notify this dentry's parent about a child's events. */ | 28 | /* Notify this dentry's parent about a child's events. */ |
33 | static inline void fsnotify_parent(struct dentry *dentry, __u32 mask) | 29 | static inline void fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask) |
34 | { | 30 | { |
35 | __fsnotify_parent(dentry, mask); | 31 | if (!dentry) |
32 | dentry = file->f_path.dentry; | ||
33 | |||
34 | __fsnotify_parent(file, dentry, mask); | ||
35 | } | ||
36 | 36 | ||
37 | inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); | 37 | /* simple call site for access decisions */ |
38 | static inline int fsnotify_perm(struct file *file, int mask) | ||
39 | { | ||
40 | struct inode *inode = file->f_path.dentry->d_inode; | ||
41 | __u32 fsnotify_mask = 0; | ||
42 | |||
43 | if (file->f_mode & FMODE_NONOTIFY) | ||
44 | return 0; | ||
45 | if (!(mask & (MAY_READ | MAY_OPEN))) | ||
46 | return 0; | ||
47 | if (mask & MAY_OPEN) | ||
48 | fsnotify_mask = FS_OPEN_PERM; | ||
49 | else if (mask & MAY_READ) | ||
50 | fsnotify_mask = FS_ACCESS_PERM; | ||
51 | else | ||
52 | BUG(); | ||
53 | |||
54 | return fsnotify(inode, fsnotify_mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); | ||
38 | } | 55 | } |
39 | 56 | ||
40 | /* | 57 | /* |
41 | * fsnotify_d_move - entry has been moved | 58 | * fsnotify_d_move - dentry has been moved |
42 | * Called with dcache_lock and entry->d_lock held. | 59 | * Called with dcache_lock and dentry->d_lock held. |
43 | */ | 60 | */ |
44 | static inline void fsnotify_d_move(struct dentry *entry) | 61 | static inline void fsnotify_d_move(struct dentry *dentry) |
45 | { | 62 | { |
46 | /* | 63 | /* |
47 | * On move we need to update entry->d_flags to indicate if the new parent | 64 | * On move we need to update dentry->d_flags to indicate if the new parent |
48 | * cares about events from this entry. | 65 | * cares about events from this dentry. |
49 | */ | 66 | */ |
50 | __fsnotify_update_dcache_flags(entry); | 67 | __fsnotify_update_dcache_flags(dentry); |
51 | |||
52 | inotify_d_move(entry); | ||
53 | } | 68 | } |
54 | 69 | ||
55 | /* | 70 | /* |
@@ -57,8 +72,6 @@ static inline void fsnotify_d_move(struct dentry *entry) | |||
57 | */ | 72 | */ |
58 | static inline void fsnotify_link_count(struct inode *inode) | 73 | static inline void fsnotify_link_count(struct inode *inode) |
59 | { | 74 | { |
60 | inotify_inode_queue_event(inode, IN_ATTRIB, 0, NULL, NULL); | ||
61 | |||
62 | fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 75 | fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0); |
63 | } | 76 | } |
64 | 77 | ||
@@ -66,45 +79,31 @@ static inline void fsnotify_link_count(struct inode *inode) | |||
66 | * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir | 79 | * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir |
67 | */ | 80 | */ |
68 | static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, | 81 | static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, |
69 | const char *old_name, | 82 | const unsigned char *old_name, |
70 | int isdir, struct inode *target, struct dentry *moved) | 83 | int isdir, struct inode *target, struct dentry *moved) |
71 | { | 84 | { |
72 | struct inode *source = moved->d_inode; | 85 | struct inode *source = moved->d_inode; |
73 | u32 in_cookie = inotify_get_cookie(); | ||
74 | u32 fs_cookie = fsnotify_get_cookie(); | 86 | u32 fs_cookie = fsnotify_get_cookie(); |
75 | __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM); | 87 | __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM); |
76 | __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO); | 88 | __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO); |
77 | const char *new_name = moved->d_name.name; | 89 | const unsigned char *new_name = moved->d_name.name; |
78 | 90 | ||
79 | if (old_dir == new_dir) | 91 | if (old_dir == new_dir) |
80 | old_dir_mask |= FS_DN_RENAME; | 92 | old_dir_mask |= FS_DN_RENAME; |
81 | 93 | ||
82 | if (isdir) { | 94 | if (isdir) { |
83 | isdir = IN_ISDIR; | ||
84 | old_dir_mask |= FS_IN_ISDIR; | 95 | old_dir_mask |= FS_IN_ISDIR; |
85 | new_dir_mask |= FS_IN_ISDIR; | 96 | new_dir_mask |= FS_IN_ISDIR; |
86 | } | 97 | } |
87 | 98 | ||
88 | inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir, in_cookie, old_name, | ||
89 | source); | ||
90 | inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, in_cookie, new_name, | ||
91 | source); | ||
92 | |||
93 | fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie); | 99 | fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie); |
94 | fsnotify(new_dir, new_dir_mask, new_dir, FSNOTIFY_EVENT_INODE, new_name, fs_cookie); | 100 | fsnotify(new_dir, new_dir_mask, new_dir, FSNOTIFY_EVENT_INODE, new_name, fs_cookie); |
95 | 101 | ||
96 | if (target) { | 102 | if (target) |
97 | inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL, NULL); | ||
98 | inotify_inode_is_dead(target); | ||
99 | |||
100 | /* this is really a link_count change not a removal */ | ||
101 | fsnotify_link_count(target); | 103 | fsnotify_link_count(target); |
102 | } | ||
103 | 104 | ||
104 | if (source) { | 105 | if (source) |
105 | inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); | ||
106 | fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 106 | fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); |
107 | } | ||
108 | audit_inode_child(moved, new_dir); | 107 | audit_inode_child(moved, new_dir); |
109 | } | 108 | } |
110 | 109 | ||
@@ -117,6 +116,14 @@ static inline void fsnotify_inode_delete(struct inode *inode) | |||
117 | } | 116 | } |
118 | 117 | ||
119 | /* | 118 | /* |
119 | * fsnotify_vfsmount_delete - a vfsmount is being destroyed, clean up is needed | ||
120 | */ | ||
121 | static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt) | ||
122 | { | ||
123 | __fsnotify_vfsmount_delete(mnt); | ||
124 | } | ||
125 | |||
126 | /* | ||
120 | * fsnotify_nameremove - a filename was removed from a directory | 127 | * fsnotify_nameremove - a filename was removed from a directory |
121 | */ | 128 | */ |
122 | static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) | 129 | static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) |
@@ -126,7 +133,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) | |||
126 | if (isdir) | 133 | if (isdir) |
127 | mask |= FS_IN_ISDIR; | 134 | mask |= FS_IN_ISDIR; |
128 | 135 | ||
129 | fsnotify_parent(dentry, mask); | 136 | fsnotify_parent(NULL, dentry, mask); |
130 | } | 137 | } |
131 | 138 | ||
132 | /* | 139 | /* |
@@ -134,9 +141,6 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir) | |||
134 | */ | 141 | */ |
135 | static inline void fsnotify_inoderemove(struct inode *inode) | 142 | static inline void fsnotify_inoderemove(struct inode *inode) |
136 | { | 143 | { |
137 | inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL, NULL); | ||
138 | inotify_inode_is_dead(inode); | ||
139 | |||
140 | fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 144 | fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL, 0); |
141 | __fsnotify_inode_delete(inode); | 145 | __fsnotify_inode_delete(inode); |
142 | } | 146 | } |
@@ -146,8 +150,6 @@ static inline void fsnotify_inoderemove(struct inode *inode) | |||
146 | */ | 150 | */ |
147 | static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | 151 | static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) |
148 | { | 152 | { |
149 | inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name, | ||
150 | dentry->d_inode); | ||
151 | audit_inode_child(dentry, inode); | 153 | audit_inode_child(dentry, inode); |
152 | 154 | ||
153 | fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); | 155 | fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); |
@@ -160,8 +162,6 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | |||
160 | */ | 162 | */ |
161 | static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) | 163 | static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) |
162 | { | 164 | { |
163 | inotify_inode_queue_event(dir, IN_CREATE, 0, new_dentry->d_name.name, | ||
164 | inode); | ||
165 | fsnotify_link_count(inode); | 165 | fsnotify_link_count(inode); |
166 | audit_inode_child(new_dentry, dir); | 166 | audit_inode_child(new_dentry, dir); |
167 | 167 | ||
@@ -176,7 +176,6 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
176 | __u32 mask = (FS_CREATE | FS_IN_ISDIR); | 176 | __u32 mask = (FS_CREATE | FS_IN_ISDIR); |
177 | struct inode *d_inode = dentry->d_inode; | 177 | struct inode *d_inode = dentry->d_inode; |
178 | 178 | ||
179 | inotify_inode_queue_event(inode, mask, 0, dentry->d_name.name, d_inode); | ||
180 | audit_inode_child(dentry, inode); | 179 | audit_inode_child(dentry, inode); |
181 | 180 | ||
182 | fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); | 181 | fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); |
@@ -185,52 +184,52 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
185 | /* | 184 | /* |
186 | * fsnotify_access - file was read | 185 | * fsnotify_access - file was read |
187 | */ | 186 | */ |
188 | static inline void fsnotify_access(struct dentry *dentry) | 187 | static inline void fsnotify_access(struct file *file) |
189 | { | 188 | { |
190 | struct inode *inode = dentry->d_inode; | 189 | struct inode *inode = file->f_path.dentry->d_inode; |
191 | __u32 mask = FS_ACCESS; | 190 | __u32 mask = FS_ACCESS; |
192 | 191 | ||
193 | if (S_ISDIR(inode->i_mode)) | 192 | if (S_ISDIR(inode->i_mode)) |
194 | mask |= FS_IN_ISDIR; | 193 | mask |= FS_IN_ISDIR; |
195 | 194 | ||
196 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 195 | if (!(file->f_mode & FMODE_NONOTIFY)) { |
197 | 196 | fsnotify_parent(file, NULL, mask); | |
198 | fsnotify_parent(dentry, mask); | 197 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); |
199 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 198 | } |
200 | } | 199 | } |
201 | 200 | ||
202 | /* | 201 | /* |
203 | * fsnotify_modify - file was modified | 202 | * fsnotify_modify - file was modified |
204 | */ | 203 | */ |
205 | static inline void fsnotify_modify(struct dentry *dentry) | 204 | static inline void fsnotify_modify(struct file *file) |
206 | { | 205 | { |
207 | struct inode *inode = dentry->d_inode; | 206 | struct inode *inode = file->f_path.dentry->d_inode; |
208 | __u32 mask = FS_MODIFY; | 207 | __u32 mask = FS_MODIFY; |
209 | 208 | ||
210 | if (S_ISDIR(inode->i_mode)) | 209 | if (S_ISDIR(inode->i_mode)) |
211 | mask |= FS_IN_ISDIR; | 210 | mask |= FS_IN_ISDIR; |
212 | 211 | ||
213 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 212 | if (!(file->f_mode & FMODE_NONOTIFY)) { |
214 | 213 | fsnotify_parent(file, NULL, mask); | |
215 | fsnotify_parent(dentry, mask); | 214 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); |
216 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 215 | } |
217 | } | 216 | } |
218 | 217 | ||
219 | /* | 218 | /* |
220 | * fsnotify_open - file was opened | 219 | * fsnotify_open - file was opened |
221 | */ | 220 | */ |
222 | static inline void fsnotify_open(struct dentry *dentry) | 221 | static inline void fsnotify_open(struct file *file) |
223 | { | 222 | { |
224 | struct inode *inode = dentry->d_inode; | 223 | struct inode *inode = file->f_path.dentry->d_inode; |
225 | __u32 mask = FS_OPEN; | 224 | __u32 mask = FS_OPEN; |
226 | 225 | ||
227 | if (S_ISDIR(inode->i_mode)) | 226 | if (S_ISDIR(inode->i_mode)) |
228 | mask |= FS_IN_ISDIR; | 227 | mask |= FS_IN_ISDIR; |
229 | 228 | ||
230 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 229 | if (!(file->f_mode & FMODE_NONOTIFY)) { |
231 | 230 | fsnotify_parent(file, NULL, mask); | |
232 | fsnotify_parent(dentry, mask); | 231 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); |
233 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 232 | } |
234 | } | 233 | } |
235 | 234 | ||
236 | /* | 235 | /* |
@@ -238,18 +237,17 @@ static inline void fsnotify_open(struct dentry *dentry) | |||
238 | */ | 237 | */ |
239 | static inline void fsnotify_close(struct file *file) | 238 | static inline void fsnotify_close(struct file *file) |
240 | { | 239 | { |
241 | struct dentry *dentry = file->f_path.dentry; | 240 | struct inode *inode = file->f_path.dentry->d_inode; |
242 | struct inode *inode = dentry->d_inode; | ||
243 | fmode_t mode = file->f_mode; | 241 | fmode_t mode = file->f_mode; |
244 | __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; | 242 | __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; |
245 | 243 | ||
246 | if (S_ISDIR(inode->i_mode)) | 244 | if (S_ISDIR(inode->i_mode)) |
247 | mask |= FS_IN_ISDIR; | 245 | mask |= FS_IN_ISDIR; |
248 | 246 | ||
249 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 247 | if (!(file->f_mode & FMODE_NONOTIFY)) { |
250 | 248 | fsnotify_parent(file, NULL, mask); | |
251 | fsnotify_parent(dentry, mask); | 249 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); |
252 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); | 250 | } |
253 | } | 251 | } |
254 | 252 | ||
255 | /* | 253 | /* |
@@ -263,9 +261,7 @@ static inline void fsnotify_xattr(struct dentry *dentry) | |||
263 | if (S_ISDIR(inode->i_mode)) | 261 | if (S_ISDIR(inode->i_mode)) |
264 | mask |= FS_IN_ISDIR; | 262 | mask |= FS_IN_ISDIR; |
265 | 263 | ||
266 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 264 | fsnotify_parent(NULL, dentry, mask); |
267 | |||
268 | fsnotify_parent(dentry, mask); | ||
269 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 265 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); |
270 | } | 266 | } |
271 | 267 | ||
@@ -299,19 +295,18 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) | |||
299 | if (mask) { | 295 | if (mask) { |
300 | if (S_ISDIR(inode->i_mode)) | 296 | if (S_ISDIR(inode->i_mode)) |
301 | mask |= FS_IN_ISDIR; | 297 | mask |= FS_IN_ISDIR; |
302 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | ||
303 | 298 | ||
304 | fsnotify_parent(dentry, mask); | 299 | fsnotify_parent(NULL, dentry, mask); |
305 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 300 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); |
306 | } | 301 | } |
307 | } | 302 | } |
308 | 303 | ||
309 | #if defined(CONFIG_INOTIFY) || defined(CONFIG_FSNOTIFY) /* notify helpers */ | 304 | #if defined(CONFIG_FSNOTIFY) /* notify helpers */ |
310 | 305 | ||
311 | /* | 306 | /* |
312 | * fsnotify_oldname_init - save off the old filename before we change it | 307 | * fsnotify_oldname_init - save off the old filename before we change it |
313 | */ | 308 | */ |
314 | static inline const char *fsnotify_oldname_init(const char *name) | 309 | static inline const unsigned char *fsnotify_oldname_init(const unsigned char *name) |
315 | { | 310 | { |
316 | return kstrdup(name, GFP_KERNEL); | 311 | return kstrdup(name, GFP_KERNEL); |
317 | } | 312 | } |
@@ -319,22 +314,22 @@ static inline const char *fsnotify_oldname_init(const char *name) | |||
319 | /* | 314 | /* |
320 | * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init | 315 | * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init |
321 | */ | 316 | */ |
322 | static inline void fsnotify_oldname_free(const char *old_name) | 317 | static inline void fsnotify_oldname_free(const unsigned char *old_name) |
323 | { | 318 | { |
324 | kfree(old_name); | 319 | kfree(old_name); |
325 | } | 320 | } |
326 | 321 | ||
327 | #else /* CONFIG_INOTIFY || CONFIG_FSNOTIFY */ | 322 | #else /* CONFIG_FSNOTIFY */ |
328 | 323 | ||
329 | static inline const char *fsnotify_oldname_init(const char *name) | 324 | static inline const char *fsnotify_oldname_init(const unsigned char *name) |
330 | { | 325 | { |
331 | return NULL; | 326 | return NULL; |
332 | } | 327 | } |
333 | 328 | ||
334 | static inline void fsnotify_oldname_free(const char *old_name) | 329 | static inline void fsnotify_oldname_free(const unsigned char *old_name) |
335 | { | 330 | { |
336 | } | 331 | } |
337 | 332 | ||
338 | #endif /* ! CONFIG_INOTIFY */ | 333 | #endif /* CONFIG_FSNOTIFY */ |
339 | 334 | ||
340 | #endif /* _LINUX_FS_NOTIFY_H */ | 335 | #endif /* _LINUX_FS_NOTIFY_H */ |