From f638c12a4e47f10aa9adbc4a0060f6e5269efc5e Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 17 Dec 2009 21:24:21 -0500 Subject: [PATCH] --- yaml --- r: 207626 b: refs/heads/master c: b4e4e1407312ae5a267ed7d716e6d4e7120a8430 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/notify/notification.c | 29 ++++++++++++++++++++++---- trunk/include/linux/fsnotify_backend.h | 3 +++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index d7886cc0ac8e..22483d028d0b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 74766bbfa99adf8cb8119df6121851edba21c9d9 +refs/heads/master: b4e4e1407312ae5a267ed7d716e6d4e7120a8430 diff --git a/trunk/fs/notify/notification.c b/trunk/fs/notify/notification.c index 6dc96b35e4a7..bc9470c7ece7 100644 --- a/trunk/fs/notify/notification.c +++ b/trunk/fs/notify/notification.c @@ -284,11 +284,33 @@ static void initialize_event(struct fsnotify_event *event) spin_lock_init(&event->lock); - event->data_type = FSNOTIFY_EVENT_NONE; - INIT_LIST_HEAD(&event->private_data_list); } +struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_event) +{ + struct fsnotify_event *event; + + event = kmem_cache_alloc(fsnotify_event_cachep, GFP_KERNEL); + if (!event) + return NULL; + + memcpy(event, old_event, sizeof(*event)); + initialize_event(event); + + if (event->name_len) { + event->file_name = kstrdup(old_event->file_name, GFP_KERNEL); + if (!event->file_name) { + kmem_cache_free(fsnotify_event_cachep, event); + return NULL; + } + } + if (event->data_type == FSNOTIFY_EVENT_PATH) + path_get(&event->path); + + return event; +} + /* * fsnotify_create_event - Allocate a new event which will be sent to each * group's handle_event function if the group was interested in this @@ -324,6 +346,7 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, event->sync_cookie = cookie; event->to_tell = to_tell; + event->data_type = data_type; switch (data_type) { case FSNOTIFY_EVENT_FILE: { @@ -340,12 +363,10 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, event->path.dentry = path->dentry; event->path.mnt = path->mnt; path_get(&event->path); - event->data_type = FSNOTIFY_EVENT_PATH; break; } case FSNOTIFY_EVENT_INODE: event->inode = data; - event->data_type = FSNOTIFY_EVENT_INODE; break; case FSNOTIFY_EVENT_NONE: event->inode = NULL; diff --git a/trunk/include/linux/fsnotify_backend.h b/trunk/include/linux/fsnotify_backend.h index 25789d45fad8..3a7fff235539 100644 --- a/trunk/include/linux/fsnotify_backend.h +++ b/trunk/include/linux/fsnotify_backend.h @@ -363,6 +363,9 @@ extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 void *data, int data_is, const char *name, u32 cookie, gfp_t gfp); +/* fanotify likes to change events after they are on lists... */ +extern struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_event); + #else static inline void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,