diff options
author | Eric Paris <eparis@redhat.com> | 2009-05-21 17:01:43 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2009-06-11 14:57:53 -0400 |
commit | 62ffe5dfba056f7ba81d710fee9f28c58a42fdd6 (patch) | |
tree | ac0d4afc641bdc8ff76779545fde9c6ae539bdaf | |
parent | a2d8bc6cb4a3024661baf877242f123787d0c054 (diff) |
fsnotify: include pathnames with entries when possible
When inotify wants to send events to a directory about a child it includes
the name of the original file. This patch collects that filename and makes
it available for notification.
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | fs/notify/fsnotify.c | 7 | ||||
-rw-r--r-- | fs/notify/notification.c | 16 | ||||
-rw-r--r-- | include/linux/fsnotify.h | 28 | ||||
-rw-r--r-- | include/linux/fsnotify_backend.h | 11 |
4 files changed, 41 insertions, 21 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 7fc760067a62..675129fa9fdd 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -114,7 +114,8 @@ void __fsnotify_parent(struct dentry *dentry, __u32 mask) | |||
114 | * specifies these are events which came from a child. */ | 114 | * specifies these are events which came from a child. */ |
115 | mask |= FS_EVENT_ON_CHILD; | 115 | mask |= FS_EVENT_ON_CHILD; |
116 | 116 | ||
117 | fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE); | 117 | fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, |
118 | dentry->d_name.name); | ||
118 | dput(parent); | 119 | dput(parent); |
119 | } | 120 | } |
120 | 121 | ||
@@ -131,7 +132,7 @@ EXPORT_SYMBOL_GPL(__fsnotify_parent); | |||
131 | * out to all of the registered fsnotify_group. Those groups can then use the | 132 | * out to all of the registered fsnotify_group. Those groups can then use the |
132 | * notification event in whatever means they feel necessary. | 133 | * notification event in whatever means they feel necessary. |
133 | */ | 134 | */ |
134 | void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is) | 135 | void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const char *file_name) |
135 | { | 136 | { |
136 | struct fsnotify_group *group; | 137 | struct fsnotify_group *group; |
137 | struct fsnotify_event *event = NULL; | 138 | struct fsnotify_event *event = NULL; |
@@ -156,7 +157,7 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is) | |||
156 | if (!group->ops->should_send_event(group, to_tell, mask)) | 157 | if (!group->ops->should_send_event(group, to_tell, mask)) |
157 | continue; | 158 | continue; |
158 | if (!event) { | 159 | if (!event) { |
159 | event = fsnotify_create_event(to_tell, mask, data, data_is); | 160 | event = fsnotify_create_event(to_tell, mask, data, data_is, file_name); |
160 | /* shit, we OOM'd and now we can't tell, maybe | 161 | /* shit, we OOM'd and now we can't tell, maybe |
161 | * someday someone else will want to do something | 162 | * someday someone else will want to do something |
162 | * here */ | 163 | * here */ |
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index dddecc74e63d..c69b18b9aba5 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
@@ -78,6 +78,7 @@ void fsnotify_put_event(struct fsnotify_event *event) | |||
78 | if (event->data_type == FSNOTIFY_EVENT_PATH) | 78 | if (event->data_type == FSNOTIFY_EVENT_PATH) |
79 | path_put(&event->path); | 79 | path_put(&event->path); |
80 | 80 | ||
81 | kfree(event->file_name); | ||
81 | kmem_cache_free(fsnotify_event_cachep, event); | 82 | kmem_cache_free(fsnotify_event_cachep, event); |
82 | } | 83 | } |
83 | } | 84 | } |
@@ -262,6 +263,9 @@ static void initialize_event(struct fsnotify_event *event) | |||
262 | event->data_type = FSNOTIFY_EVENT_NONE; | 263 | event->data_type = FSNOTIFY_EVENT_NONE; |
263 | 264 | ||
264 | event->to_tell = NULL; | 265 | event->to_tell = NULL; |
266 | |||
267 | event->file_name = NULL; | ||
268 | event->name_len = 0; | ||
265 | } | 269 | } |
266 | 270 | ||
267 | /* | 271 | /* |
@@ -274,9 +278,10 @@ static void initialize_event(struct fsnotify_event *event) | |||
274 | * @mask what actually happened. | 278 | * @mask what actually happened. |
275 | * @data pointer to the object which was actually affected | 279 | * @data pointer to the object which was actually affected |
276 | * @data_type flag indication if the data is a file, path, inode, nothing... | 280 | * @data_type flag indication if the data is a file, path, inode, nothing... |
281 | * @name the filename, if available | ||
277 | */ | 282 | */ |
278 | struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, | 283 | struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, |
279 | void *data, int data_type) | 284 | void *data, int data_type, const char *name) |
280 | { | 285 | { |
281 | struct fsnotify_event *event; | 286 | struct fsnotify_event *event; |
282 | 287 | ||
@@ -285,6 +290,15 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, | |||
285 | return NULL; | 290 | return NULL; |
286 | 291 | ||
287 | initialize_event(event); | 292 | initialize_event(event); |
293 | |||
294 | if (name) { | ||
295 | event->file_name = kstrdup(name, GFP_KERNEL); | ||
296 | if (!event->file_name) { | ||
297 | kmem_cache_free(fsnotify_event_cachep, event); | ||
298 | return NULL; | ||
299 | } | ||
300 | event->name_len = strlen(event->file_name); | ||
301 | } | ||
288 | event->to_tell = to_tell; | 302 | event->to_tell = to_tell; |
289 | 303 | ||
290 | switch (data_type) { | 304 | switch (data_type) { |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index db12d9de3526..180740e9ec82 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -58,7 +58,7 @@ static inline void fsnotify_link_count(struct inode *inode) | |||
58 | { | 58 | { |
59 | inotify_inode_queue_event(inode, IN_ATTRIB, 0, NULL, NULL); | 59 | inotify_inode_queue_event(inode, IN_ATTRIB, 0, NULL, NULL); |
60 | 60 | ||
61 | fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE); | 61 | fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL); |
62 | } | 62 | } |
63 | 63 | ||
64 | /* | 64 | /* |
@@ -91,8 +91,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, | |||
91 | inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name, | 91 | inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name, |
92 | source); | 92 | source); |
93 | 93 | ||
94 | fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE); | 94 | fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name); |
95 | fsnotify(new_dir, new_dir_mask, new_dir, FSNOTIFY_EVENT_INODE); | 95 | fsnotify(new_dir, new_dir_mask, new_dir, FSNOTIFY_EVENT_INODE, new_name); |
96 | 96 | ||
97 | if (target) { | 97 | if (target) { |
98 | inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL, NULL); | 98 | inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL, NULL); |
@@ -104,7 +104,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, | |||
104 | 104 | ||
105 | if (source) { | 105 | if (source) { |
106 | inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); | 106 | inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); |
107 | fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE); | 107 | fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL); |
108 | } | 108 | } |
109 | audit_inode_child(new_name, moved, new_dir); | 109 | audit_inode_child(new_name, moved, new_dir); |
110 | } | 110 | } |
@@ -138,7 +138,7 @@ static inline void fsnotify_inoderemove(struct inode *inode) | |||
138 | inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL, NULL); | 138 | inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL, NULL); |
139 | inotify_inode_is_dead(inode); | 139 | inotify_inode_is_dead(inode); |
140 | 140 | ||
141 | fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE); | 141 | fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL); |
142 | __fsnotify_inode_delete(inode); | 142 | __fsnotify_inode_delete(inode); |
143 | } | 143 | } |
144 | 144 | ||
@@ -151,7 +151,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | |||
151 | dentry->d_inode); | 151 | dentry->d_inode); |
152 | audit_inode_child(dentry->d_name.name, dentry, inode); | 152 | audit_inode_child(dentry->d_name.name, dentry, inode); |
153 | 153 | ||
154 | fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE); | 154 | fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name); |
155 | } | 155 | } |
156 | 156 | ||
157 | /* | 157 | /* |
@@ -166,7 +166,7 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct | |||
166 | fsnotify_link_count(inode); | 166 | fsnotify_link_count(inode); |
167 | audit_inode_child(new_dentry->d_name.name, new_dentry, dir); | 167 | audit_inode_child(new_dentry->d_name.name, new_dentry, dir); |
168 | 168 | ||
169 | fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE); | 169 | fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name); |
170 | } | 170 | } |
171 | 171 | ||
172 | /* | 172 | /* |
@@ -180,7 +180,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
180 | inotify_inode_queue_event(inode, mask, 0, dentry->d_name.name, d_inode); | 180 | inotify_inode_queue_event(inode, mask, 0, dentry->d_name.name, d_inode); |
181 | audit_inode_child(dentry->d_name.name, dentry, inode); | 181 | audit_inode_child(dentry->d_name.name, dentry, inode); |
182 | 182 | ||
183 | fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE); | 183 | fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name); |
184 | } | 184 | } |
185 | 185 | ||
186 | /* | 186 | /* |
@@ -197,7 +197,7 @@ static inline void fsnotify_access(struct dentry *dentry) | |||
197 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 197 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); |
198 | 198 | ||
199 | fsnotify_parent(dentry, mask); | 199 | fsnotify_parent(dentry, mask); |
200 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE); | 200 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL); |
201 | } | 201 | } |
202 | 202 | ||
203 | /* | 203 | /* |
@@ -214,7 +214,7 @@ static inline void fsnotify_modify(struct dentry *dentry) | |||
214 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 214 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); |
215 | 215 | ||
216 | fsnotify_parent(dentry, mask); | 216 | fsnotify_parent(dentry, mask); |
217 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE); | 217 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL); |
218 | } | 218 | } |
219 | 219 | ||
220 | /* | 220 | /* |
@@ -231,7 +231,7 @@ static inline void fsnotify_open(struct dentry *dentry) | |||
231 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 231 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); |
232 | 232 | ||
233 | fsnotify_parent(dentry, mask); | 233 | fsnotify_parent(dentry, mask); |
234 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE); | 234 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL); |
235 | } | 235 | } |
236 | 236 | ||
237 | /* | 237 | /* |
@@ -250,7 +250,7 @@ static inline void fsnotify_close(struct file *file) | |||
250 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 250 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); |
251 | 251 | ||
252 | fsnotify_parent(dentry, mask); | 252 | fsnotify_parent(dentry, mask); |
253 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE); | 253 | fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL); |
254 | } | 254 | } |
255 | 255 | ||
256 | /* | 256 | /* |
@@ -267,7 +267,7 @@ static inline void fsnotify_xattr(struct dentry *dentry) | |||
267 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 267 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); |
268 | 268 | ||
269 | fsnotify_parent(dentry, mask); | 269 | fsnotify_parent(dentry, mask); |
270 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE); | 270 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL); |
271 | } | 271 | } |
272 | 272 | ||
273 | /* | 273 | /* |
@@ -303,7 +303,7 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) | |||
303 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); | 303 | inotify_inode_queue_event(inode, mask, 0, NULL, NULL); |
304 | 304 | ||
305 | fsnotify_parent(dentry, mask); | 305 | fsnotify_parent(dentry, mask); |
306 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE); | 306 | fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL); |
307 | } | 307 | } |
308 | } | 308 | } |
309 | 309 | ||
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 15f8f82a5c57..52692f405890 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -192,6 +192,9 @@ struct fsnotify_event { | |||
192 | int data_type; /* which of the above union we have */ | 192 | int data_type; /* which of the above union we have */ |
193 | atomic_t refcnt; /* how many groups still are using/need to send this event */ | 193 | atomic_t refcnt; /* how many groups still are using/need to send this event */ |
194 | __u32 mask; /* the type of access, bitwise OR for FS_* event types */ | 194 | __u32 mask; /* the type of access, bitwise OR for FS_* event types */ |
195 | |||
196 | char *file_name; | ||
197 | size_t name_len; | ||
195 | }; | 198 | }; |
196 | 199 | ||
197 | /* | 200 | /* |
@@ -224,7 +227,7 @@ struct fsnotify_mark_entry { | |||
224 | /* called from the vfs helpers */ | 227 | /* called from the vfs helpers */ |
225 | 228 | ||
226 | /* main fsnotify call to send events */ | 229 | /* main fsnotify call to send events */ |
227 | extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is); | 230 | extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const char *name); |
228 | extern void __fsnotify_parent(struct dentry *dentry, __u32 mask); | 231 | extern void __fsnotify_parent(struct dentry *dentry, __u32 mask); |
229 | extern void __fsnotify_inode_delete(struct inode *inode); | 232 | extern void __fsnotify_inode_delete(struct inode *inode); |
230 | 233 | ||
@@ -319,10 +322,12 @@ extern void fsnotify_put_mark(struct fsnotify_mark_entry *entry); | |||
319 | 322 | ||
320 | /* put here because inotify does some weird stuff when destroying watches */ | 323 | /* put here because inotify does some weird stuff when destroying watches */ |
321 | extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, | 324 | extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, |
322 | void *data, int data_is); | 325 | void *data, int data_is, const char *name); |
326 | |||
323 | #else | 327 | #else |
324 | 328 | ||
325 | static inline void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is) | 329 | static inline void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, |
330 | const char *name); | ||
326 | {} | 331 | {} |
327 | 332 | ||
328 | static inline void __fsnotify_parent(struct dentry *dentry, __u32 mask) | 333 | static inline void __fsnotify_parent(struct dentry *dentry, __u32 mask) |