|
@@ -135,13 +135,12 @@ void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(__fsnotify_parent);
|
|
|
|
|
|
-static void send_to_group(__u32 mask,
|
|
|
- struct fsnotify_group *group,
|
|
|
- void *data, int data_is, const char *file_name,
|
|
|
- u32 cookie, struct fsnotify_event **event,
|
|
|
- struct inode *to_tell)
|
|
|
+static void send_to_group(struct fsnotify_group *group, struct inode *to_tell,
|
|
|
+ struct vfsmount *mnt, __u32 mask, void *data,
|
|
|
+ int data_is, u32 cookie, const char *file_name,
|
|
|
+ struct fsnotify_event **event)
|
|
|
{
|
|
|
- if (!group->ops->should_send_event(group, to_tell, mask,
|
|
|
+ if (!group->ops->should_send_event(group, to_tell, mnt, mask,
|
|
|
data, data_is))
|
|
|
return;
|
|
|
if (!*event) {
|
|
@@ -159,15 +158,9 @@ static void send_to_group(__u32 mask,
|
|
|
group->ops->handle_event(group, *event);
|
|
|
}
|
|
|
|
|
|
-static bool needed_by_vfsmount(__u32 test_mask, void *data, int data_is)
|
|
|
+static bool needed_by_vfsmount(__u32 test_mask, struct vfsmount *mnt)
|
|
|
{
|
|
|
- struct path *path;
|
|
|
-
|
|
|
- if (data_is == FSNOTIFY_EVENT_PATH)
|
|
|
- path = (struct path *)data;
|
|
|
- else if (data_is == FSNOTIFY_EVENT_FILE)
|
|
|
- path = &((struct file *)data)->f_path;
|
|
|
- else
|
|
|
+ if (!mnt)
|
|
|
return false;
|
|
|
|
|
|
/* hook in this when mnt->mnt_fsnotify_mask is defined */
|
|
@@ -184,6 +177,7 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const
|
|
|
{
|
|
|
struct fsnotify_group *group;
|
|
|
struct fsnotify_event *event = NULL;
|
|
|
+ struct vfsmount *mnt = NULL;
|
|
|
int idx;
|
|
|
/* global tests shouldn't care about events on child only the specific event */
|
|
|
__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
|
|
@@ -198,10 +192,15 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const
|
|
|
!(test_mask & fsnotify_vfsmount_mask))
|
|
|
return;
|
|
|
|
|
|
+ if (data_is == FSNOTIFY_EVENT_PATH)
|
|
|
+ mnt = ((struct path *)data)->mnt;
|
|
|
+ else if (data_is == FSNOTIFY_EVENT_FILE)
|
|
|
+ mnt = ((struct file *)data)->f_path.mnt;
|
|
|
+
|
|
|
/* if this inode's directed listeners don't care and nothing on the vfsmount
|
|
|
* listeners list cares, nothing to do */
|
|
|
if (!(test_mask & to_tell->i_fsnotify_mask) &&
|
|
|
- !needed_by_vfsmount(test_mask, data, data_is))
|
|
|
+ !needed_by_vfsmount(test_mask, mnt))
|
|
|
return;
|
|
|
|
|
|
/*
|
|
@@ -214,16 +213,16 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const
|
|
|
if (test_mask & to_tell->i_fsnotify_mask) {
|
|
|
list_for_each_entry_rcu(group, &fsnotify_inode_groups, inode_group_list) {
|
|
|
if (test_mask & group->mask) {
|
|
|
- send_to_group(mask, group, data, data_is,
|
|
|
- file_name, cookie, &event, to_tell);
|
|
|
+ send_to_group(group, to_tell, NULL, mask, data, data_is,
|
|
|
+ cookie, file_name, &event);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (needed_by_vfsmount(test_mask, data, data_is)) {
|
|
|
+ if (needed_by_vfsmount(test_mask, mnt)) {
|
|
|
list_for_each_entry_rcu(group, &fsnotify_vfsmount_groups, vfsmount_group_list) {
|
|
|
if (test_mask & group->mask) {
|
|
|
- send_to_group(mask, group, data, data_is,
|
|
|
- file_name, cookie, &event, to_tell);
|
|
|
+ send_to_group(group, to_tell, mnt, mask, data, data_is,
|
|
|
+ cookie, file_name, &event);
|
|
|
}
|
|
|
}
|
|
|
}
|