aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-05-21 17:01:47 -0400
committerEric Paris <eparis@redhat.com>2009-06-11 14:57:54 -0400
commit47882c6f51e8ef41fbbe2bbb746a1ea3228dd7ca (patch)
treed3dd3e8d0e4d3e3793f32107077839f787e35fcd /fs/notify
parent62ffe5dfba056f7ba81d710fee9f28c58a42fdd6 (diff)
fsnotify: add correlations between events
As part of the standard inotify events it includes a correlation cookie between two dentry move operations. This patch includes the same behaviour in fsnotify events. It is needed so that inotify userspace can be implemented on top of fsnotify. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fsnotify.c6
-rw-r--r--fs/notify/notification.c20
2 files changed, 21 insertions, 5 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 675129fa9fdd..f11d75f02368 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -115,7 +115,7 @@ void __fsnotify_parent(struct dentry *dentry, __u32 mask)
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 dentry->d_name.name, 0);
119 dput(parent); 119 dput(parent);
120 } 120 }
121 121
@@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(__fsnotify_parent);
132 * 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
133 * notification event in whatever means they feel necessary. 133 * notification event in whatever means they feel necessary.
134 */ 134 */
135void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const char *file_name) 135void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const char *file_name, u32 cookie)
136{ 136{
137 struct fsnotify_group *group; 137 struct fsnotify_group *group;
138 struct fsnotify_event *event = NULL; 138 struct fsnotify_event *event = NULL;
@@ -157,7 +157,7 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const
157 if (!group->ops->should_send_event(group, to_tell, mask)) 157 if (!group->ops->should_send_event(group, to_tell, mask))
158 continue; 158 continue;
159 if (!event) { 159 if (!event) {
160 event = fsnotify_create_event(to_tell, mask, data, data_is, file_name); 160 event = fsnotify_create_event(to_tell, mask, data, data_is, file_name, cookie);
161 /* shit, we OOM'd and now we can't tell, maybe 161 /* shit, we OOM'd and now we can't tell, maybe
162 * someday someone else will want to do something 162 * someday someone else will want to do something
163 * here */ 163 * here */
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index c69b18b9aba5..346f6e5c3553 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -35,6 +35,7 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <linux/list.h> 37#include <linux/list.h>
38#include <linux/module.h>
38#include <linux/mount.h> 39#include <linux/mount.h>
39#include <linux/mutex.h> 40#include <linux/mutex.h>
40#include <linux/namei.h> 41#include <linux/namei.h>
@@ -56,6 +57,17 @@ static struct kmem_cache *fsnotify_event_holder_cachep;
56 * get set to 0 so it will never get 'freed' 57 * get set to 0 so it will never get 'freed'
57 */ 58 */
58static struct fsnotify_event q_overflow_event; 59static struct fsnotify_event q_overflow_event;
60static atomic_t fsnotify_sync_cookie = ATOMIC_INIT(0);
61
62/**
63 * fsnotify_get_cookie - return a unique cookie for use in synchronizing events.
64 * Called from fsnotify_move, which is inlined into filesystem modules.
65 */
66u32 fsnotify_get_cookie(void)
67{
68 return atomic_inc_return(&fsnotify_sync_cookie);
69}
70EXPORT_SYMBOL_GPL(fsnotify_get_cookie);
59 71
60/* return true if the notify queue is empty, false otherwise */ 72/* return true if the notify queue is empty, false otherwise */
61bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group) 73bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group)
@@ -266,6 +278,8 @@ static void initialize_event(struct fsnotify_event *event)
266 278
267 event->file_name = NULL; 279 event->file_name = NULL;
268 event->name_len = 0; 280 event->name_len = 0;
281
282 event->sync_cookie = 0;
269} 283}
270 284
271/* 285/*
@@ -280,8 +294,8 @@ static void initialize_event(struct fsnotify_event *event)
280 * @data_type flag indication if the data is a file, path, inode, nothing... 294 * @data_type flag indication if the data is a file, path, inode, nothing...
281 * @name the filename, if available 295 * @name the filename, if available
282 */ 296 */
283struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, 297struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, void *data,
284 void *data, int data_type, const char *name) 298 int data_type, const char *name, u32 cookie)
285{ 299{
286 struct fsnotify_event *event; 300 struct fsnotify_event *event;
287 301
@@ -299,6 +313,8 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask,
299 } 313 }
300 event->name_len = strlen(event->file_name); 314 event->name_len = strlen(event->file_name);
301 } 315 }
316
317 event->sync_cookie = cookie;
302 event->to_tell = to_tell; 318 event->to_tell = to_tell;
303 319
304 switch (data_type) { 320 switch (data_type) {