diff options
author | Eric Paris <eparis@redhat.com> | 2009-12-17 21:24:34 -0500 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2010-07-28 09:59:01 -0400 |
commit | 6e5f77b32e9097a8a68a8d453799676cacf70cad (patch) | |
tree | 2a0211ecd5d79648e74fdf9f851a0669c5e4cc8a /fs/notify | |
parent | cb2d429faf2cae62d3c51e28099a181d5fe8c244 (diff) |
fsnotify: intoduce a notification merge argument
Each group can define their own notification (and secondary_q) merge
function. Inotify does tail drop, fanotify does matching and drop which
can actually allocate a completely new event. But for fanotify to properly
deal with permissions events it needs to know the new event which was
ultimately added to the notification queue. This patch just implements a
void ** argument which is passed to the merge function. fanotify can use
this field to pass the new event back to higher layers.
Signed-off-by: Eric Paris <eparis@redhat.com>
for fanotify to properly deal with permissions events
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 6 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 6 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 2 | ||||
-rw-r--r-- | fs/notify/notification.c | 7 |
4 files changed, 14 insertions, 7 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 060b177146e8..95a330d2f8a1 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -27,7 +27,9 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) | |||
27 | return false; | 27 | return false; |
28 | } | 28 | } |
29 | 29 | ||
30 | static int fanotify_merge(struct list_head *list, struct fsnotify_event *event) | 30 | static int fanotify_merge(struct list_head *list, |
31 | struct fsnotify_event *event, | ||
32 | void **arg) | ||
31 | { | 33 | { |
32 | struct fsnotify_event_holder *test_holder; | 34 | struct fsnotify_event_holder *test_holder; |
33 | struct fsnotify_event *test_event; | 35 | struct fsnotify_event *test_event; |
@@ -92,7 +94,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, struct fsnotify_e | |||
92 | 94 | ||
93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 95 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
94 | 96 | ||
95 | ret = fsnotify_add_notify_event(group, event, NULL, fanotify_merge); | 97 | ret = fsnotify_add_notify_event(group, event, NULL, fanotify_merge, NULL); |
96 | /* -EEXIST means this event was merged with another, not that it was an error */ | 98 | /* -EEXIST means this event was merged with another, not that it was an error */ |
97 | if (ret == -EEXIST) | 99 | if (ret == -EEXIST) |
98 | ret = 0; | 100 | ret = 0; |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 1d237e1bf7b1..daa666a6e6c9 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -67,7 +67,9 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new | |||
67 | return false; | 67 | return false; |
68 | } | 68 | } |
69 | 69 | ||
70 | static int inotify_merge(struct list_head *list, struct fsnotify_event *event) | 70 | static int inotify_merge(struct list_head *list, |
71 | struct fsnotify_event *event, | ||
72 | void **arg) | ||
71 | { | 73 | { |
72 | struct fsnotify_event_holder *last_holder; | 74 | struct fsnotify_event_holder *last_holder; |
73 | struct fsnotify_event *last_event; | 75 | struct fsnotify_event *last_event; |
@@ -114,7 +116,7 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev | |||
114 | fsn_event_priv->group = group; | 116 | fsn_event_priv->group = group; |
115 | event_priv->wd = wd; | 117 | event_priv->wd = wd; |
116 | 118 | ||
117 | ret = fsnotify_add_notify_event(group, event, fsn_event_priv, inotify_merge); | 119 | ret = fsnotify_add_notify_event(group, event, fsn_event_priv, inotify_merge, NULL); |
118 | if (ret) { | 120 | if (ret) { |
119 | inotify_free_event_priv(fsn_event_priv); | 121 | inotify_free_event_priv(fsn_event_priv); |
120 | /* EEXIST says we tail matched, EOVERFLOW isn't something | 122 | /* EEXIST says we tail matched, EOVERFLOW isn't something |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 19d274057bfa..1ce71f5b9589 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -525,7 +525,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, | |||
525 | fsn_event_priv->group = group; | 525 | fsn_event_priv->group = group; |
526 | event_priv->wd = i_mark->wd; | 526 | event_priv->wd = i_mark->wd; |
527 | 527 | ||
528 | ret = fsnotify_add_notify_event(group, ignored_event, fsn_event_priv, NULL); | 528 | ret = fsnotify_add_notify_event(group, ignored_event, fsn_event_priv, NULL, NULL); |
529 | if (ret) | 529 | if (ret) |
530 | inotify_free_event_priv(fsn_event_priv); | 530 | inotify_free_event_priv(fsn_event_priv); |
531 | 531 | ||
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index 7fc8d004084c..2d50a40ab1e4 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
@@ -137,7 +137,10 @@ struct fsnotify_event_private_data *fsnotify_remove_priv_from_event(struct fsnot | |||
137 | */ | 137 | */ |
138 | int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_event *event, | 138 | int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_event *event, |
139 | struct fsnotify_event_private_data *priv, | 139 | struct fsnotify_event_private_data *priv, |
140 | int (*merge)(struct list_head *, struct fsnotify_event *)) | 140 | int (*merge)(struct list_head *, |
141 | struct fsnotify_event *, | ||
142 | void **arg), | ||
143 | void **arg) | ||
141 | { | 144 | { |
142 | struct fsnotify_event_holder *holder = NULL; | 145 | struct fsnotify_event_holder *holder = NULL; |
143 | struct list_head *list = &group->notification_list; | 146 | struct list_head *list = &group->notification_list; |
@@ -170,7 +173,7 @@ alloc_holder: | |||
170 | if (!list_empty(list) && merge) { | 173 | if (!list_empty(list) && merge) { |
171 | int ret; | 174 | int ret; |
172 | 175 | ||
173 | ret = merge(list, event); | 176 | ret = merge(list, event, arg); |
174 | if (ret) { | 177 | if (ret) { |
175 | mutex_unlock(&group->notification_mutex); | 178 | mutex_unlock(&group->notification_mutex); |
176 | if (holder != &event->holder) | 179 | if (holder != &event->holder) |