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>
This commit is contained in:
@@ -252,20 +252,23 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
|
|||||||
|
|
||||||
if (inode_group > vfsmount_group) {
|
if (inode_group > vfsmount_group) {
|
||||||
/* handle inode */
|
/* handle inode */
|
||||||
send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
|
ret = send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
|
||||||
data_is, cookie, file_name, &event);
|
data_is, cookie, file_name, &event);
|
||||||
/* we didn't use the vfsmount_mark */
|
/* we didn't use the vfsmount_mark */
|
||||||
vfsmount_group = NULL;
|
vfsmount_group = NULL;
|
||||||
} else if (vfsmount_group > inode_group) {
|
} else if (vfsmount_group > inode_group) {
|
||||||
send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
|
ret = send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
|
||||||
data_is, cookie, file_name, &event);
|
data_is, cookie, file_name, &event);
|
||||||
inode_group = NULL;
|
inode_group = NULL;
|
||||||
} else {
|
} else {
|
||||||
send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
|
ret = send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
|
||||||
mask, data, data_is, cookie, file_name,
|
mask, data, data_is, cookie, file_name,
|
||||||
&event);
|
&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (inode_group)
|
if (inode_group)
|
||||||
inode_node = srcu_dereference(inode_node->next,
|
inode_node = srcu_dereference(inode_node->next,
|
||||||
&fsnotify_mark_srcu);
|
&fsnotify_mark_srcu);
|
||||||
@@ -273,7 +276,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
|
|||||||
vfsmount_node = srcu_dereference(vfsmount_node->next,
|
vfsmount_node = srcu_dereference(vfsmount_node->next,
|
||||||
&fsnotify_mark_srcu);
|
&fsnotify_mark_srcu);
|
||||||
}
|
}
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
srcu_read_unlock(&fsnotify_mark_srcu, idx);
|
srcu_read_unlock(&fsnotify_mark_srcu, idx);
|
||||||
/*
|
/*
|
||||||
* fsnotify_create_event() took a reference so the event can't be cleaned
|
* fsnotify_create_event() took a reference so the event can't be cleaned
|
||||||
|
@@ -64,6 +64,8 @@
|
|||||||
|
|
||||||
#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
|
#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
|
||||||
|
|
||||||
|
#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
|
||||||
|
|
||||||
#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
|
#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
|
||||||
FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
|
FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
|
||||||
FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
|
FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
|
||||||
|
Reference in New Issue
Block a user