diff options
Diffstat (limited to 'fs/notify/fsnotify.c')
-rw-r--r-- | fs/notify/fsnotify.c | 42 |
1 files changed, 12 insertions, 30 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 4bb21d67d9b1..9d3e9c50066a 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -128,8 +128,7 @@ static int send_to_group(struct inode *to_tell, | |||
128 | struct fsnotify_mark *vfsmount_mark, | 128 | struct fsnotify_mark *vfsmount_mark, |
129 | __u32 mask, void *data, | 129 | __u32 mask, void *data, |
130 | int data_is, u32 cookie, | 130 | int data_is, u32 cookie, |
131 | const unsigned char *file_name, | 131 | const unsigned char *file_name) |
132 | struct fsnotify_event **event) | ||
133 | { | 132 | { |
134 | struct fsnotify_group *group = NULL; | 133 | struct fsnotify_group *group = NULL; |
135 | __u32 inode_test_mask = 0; | 134 | __u32 inode_test_mask = 0; |
@@ -170,27 +169,17 @@ static int send_to_group(struct inode *to_tell, | |||
170 | 169 | ||
171 | pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p" | 170 | pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p" |
172 | " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x" | 171 | " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x" |
173 | " data=%p data_is=%d cookie=%d event=%p\n", | 172 | " data=%p data_is=%d cookie=%d\n", |
174 | __func__, group, to_tell, mask, inode_mark, | 173 | __func__, group, to_tell, mask, inode_mark, |
175 | inode_test_mask, vfsmount_mark, vfsmount_test_mask, data, | 174 | inode_test_mask, vfsmount_mark, vfsmount_test_mask, data, |
176 | data_is, cookie, *event); | 175 | data_is, cookie); |
177 | 176 | ||
178 | if (!inode_test_mask && !vfsmount_test_mask) | 177 | if (!inode_test_mask && !vfsmount_test_mask) |
179 | return 0; | 178 | return 0; |
180 | 179 | ||
181 | if (group->ops->should_send_event(group, to_tell, inode_mark, | 180 | return group->ops->handle_event(group, to_tell, inode_mark, |
182 | vfsmount_mark, mask, data, | 181 | vfsmount_mark, mask, data, data_is, |
183 | data_is) == false) | 182 | file_name, cookie); |
184 | return 0; | ||
185 | |||
186 | if (!*event) { | ||
187 | *event = fsnotify_create_event(to_tell, mask, data, | ||
188 | data_is, file_name, | ||
189 | cookie, GFP_KERNEL); | ||
190 | if (!*event) | ||
191 | return -ENOMEM; | ||
192 | } | ||
193 | return group->ops->handle_event(group, inode_mark, vfsmount_mark, *event); | ||
194 | } | 183 | } |
195 | 184 | ||
196 | /* | 185 | /* |
@@ -205,7 +194,6 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
205 | struct hlist_node *inode_node = NULL, *vfsmount_node = NULL; | 194 | struct hlist_node *inode_node = NULL, *vfsmount_node = NULL; |
206 | struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; | 195 | struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; |
207 | struct fsnotify_group *inode_group, *vfsmount_group; | 196 | struct fsnotify_group *inode_group, *vfsmount_group; |
208 | struct fsnotify_event *event = NULL; | ||
209 | struct mount *mnt; | 197 | struct mount *mnt; |
210 | int idx, ret = 0; | 198 | int idx, ret = 0; |
211 | /* global tests shouldn't care about events on child only the specific event */ | 199 | /* global tests shouldn't care about events on child only the specific event */ |
@@ -258,18 +246,18 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
258 | 246 | ||
259 | if (inode_group > vfsmount_group) { | 247 | if (inode_group > vfsmount_group) { |
260 | /* handle inode */ | 248 | /* handle inode */ |
261 | ret = send_to_group(to_tell, inode_mark, NULL, mask, data, | 249 | ret = send_to_group(to_tell, inode_mark, NULL, mask, |
262 | data_is, cookie, file_name, &event); | 250 | data, data_is, cookie, file_name); |
263 | /* we didn't use the vfsmount_mark */ | 251 | /* we didn't use the vfsmount_mark */ |
264 | vfsmount_group = NULL; | 252 | vfsmount_group = NULL; |
265 | } else if (vfsmount_group > inode_group) { | 253 | } else if (vfsmount_group > inode_group) { |
266 | ret = send_to_group(to_tell, NULL, vfsmount_mark, mask, data, | 254 | ret = send_to_group(to_tell, NULL, vfsmount_mark, mask, |
267 | data_is, cookie, file_name, &event); | 255 | data, data_is, cookie, file_name); |
268 | inode_group = NULL; | 256 | inode_group = NULL; |
269 | } else { | 257 | } else { |
270 | ret = send_to_group(to_tell, inode_mark, vfsmount_mark, | 258 | ret = send_to_group(to_tell, inode_mark, vfsmount_mark, |
271 | mask, data, data_is, cookie, file_name, | 259 | mask, data, data_is, cookie, |
272 | &event); | 260 | file_name); |
273 | } | 261 | } |
274 | 262 | ||
275 | if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) | 263 | if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) |
@@ -285,12 +273,6 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
285 | ret = 0; | 273 | ret = 0; |
286 | out: | 274 | out: |
287 | srcu_read_unlock(&fsnotify_mark_srcu, idx); | 275 | srcu_read_unlock(&fsnotify_mark_srcu, idx); |
288 | /* | ||
289 | * fsnotify_create_event() took a reference so the event can't be cleaned | ||
290 | * up while we are still trying to add it to lists, drop that one. | ||
291 | */ | ||
292 | if (event) | ||
293 | fsnotify_put_event(event); | ||
294 | 276 | ||
295 | return ret; | 277 | return ret; |
296 | } | 278 | } |