aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-10-28 17:21:56 -0400
committerEric Paris <eparis@redhat.com>2010-10-28 17:22:13 -0400
commitff8bcbd03da881bf1171910c6c07d44bd3c0a234 (patch)
treeec7ad24bf2923bc19c48f1160a05328299193a8d
parent2868201965419b9011f3f07fd80e765181343cb1 (diff)
fsnotify: correctly handle return codes from listeners
When fsnotify groups return errors they are ignored. For permissions events these should be passed back up the stack, but for most events these should continue to be ignored. Signed-off-by: Eric Paris <eparis@redhat.com>
-rw-r--r--fs/notify/fsnotify.c20
-rw-r--r--include/linux/fsnotify_backend.h2
2 files changed, 14 insertions, 8 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 4498a208df94..57ecadd85abf 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -252,20 +252,23 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
252 252
253 if (inode_group > vfsmount_group) { 253 if (inode_group > vfsmount_group) {
254 /* handle inode */ 254 /* handle inode */
255 send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, 255 ret = send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
256 data_is, cookie, file_name, &event); 256 data_is, cookie, file_name, &event);
257 /* we didn't use the vfsmount_mark */ 257 /* we didn't use the vfsmount_mark */
258 vfsmount_group = NULL; 258 vfsmount_group = NULL;
259 } else if (vfsmount_group > inode_group) { 259 } else if (vfsmount_group > inode_group) {
260 send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, 260 ret = send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
261 data_is, cookie, file_name, &event); 261 data_is, cookie, file_name, &event);
262 inode_group = NULL; 262 inode_group = NULL;
263 } else { 263 } else {
264 send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, 264 ret = send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
265 mask, data, data_is, cookie, file_name, 265 mask, data, data_is, cookie, file_name,
266 &event); 266 &event);
267 } 267 }
268 268
269 if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
270 goto out;
271
269 if (inode_group) 272 if (inode_group)
270 inode_node = srcu_dereference(inode_node->next, 273 inode_node = srcu_dereference(inode_node->next,
271 &fsnotify_mark_srcu); 274 &fsnotify_mark_srcu);
@@ -273,7 +276,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
273 vfsmount_node = srcu_dereference(vfsmount_node->next, 276 vfsmount_node = srcu_dereference(vfsmount_node->next,
274 &fsnotify_mark_srcu); 277 &fsnotify_mark_srcu);
275 } 278 }
276 279 ret = 0;
280out:
277 srcu_read_unlock(&fsnotify_mark_srcu, idx); 281 srcu_read_unlock(&fsnotify_mark_srcu, idx);
278 /* 282 /*
279 * fsnotify_create_event() took a reference so the event can't be cleaned 283 * fsnotify_create_event() took a reference so the event can't be cleaned
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 825329534162..026892187c83 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -64,6 +64,8 @@
64 64
65#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) 65#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
66 66
67#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
68
67#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ 69#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
68 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \ 70 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
69 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \ 71 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \