aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/notify/dnotify/dnotify.c4
-rw-r--r--fs/notify/fsnotify.c39
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c3
3 files changed, 23 insertions, 23 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index e0a847bd53be..9eddafa4c7ba 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -133,8 +133,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
133 * userspace notification for that pair. 133 * userspace notification for that pair.
134 */ 134 */
135static bool dnotify_should_send_event(struct fsnotify_group *group, 135static bool dnotify_should_send_event(struct fsnotify_group *group,
136 struct inode *inode, __u32 mask, 136 struct inode *inode, struct vfsmount *mnt,
137 void *data, int data_type) 137 __u32 mask, void *data, int data_type)
138{ 138{
139 struct fsnotify_mark_entry *entry; 139 struct fsnotify_mark_entry *entry;
140 bool send; 140 bool send;
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index a61aaa710825..78c440c343a8 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -135,13 +135,12 @@ void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
135} 135}
136EXPORT_SYMBOL_GPL(__fsnotify_parent); 136EXPORT_SYMBOL_GPL(__fsnotify_parent);
137 137
138static void send_to_group(__u32 mask, 138static void send_to_group(struct fsnotify_group *group, struct inode *to_tell,
139 struct fsnotify_group *group, 139 struct vfsmount *mnt, __u32 mask, void *data,
140 void *data, int data_is, const char *file_name, 140 int data_is, u32 cookie, const char *file_name,
141 u32 cookie, struct fsnotify_event **event, 141 struct fsnotify_event **event)
142 struct inode *to_tell)
143{ 142{
144 if (!group->ops->should_send_event(group, to_tell, mask, 143 if (!group->ops->should_send_event(group, to_tell, mnt, mask,
145 data, data_is)) 144 data, data_is))
146 return; 145 return;
147 if (!*event) { 146 if (!*event) {
@@ -159,15 +158,9 @@ static void send_to_group(__u32 mask,
159 group->ops->handle_event(group, *event); 158 group->ops->handle_event(group, *event);
160} 159}
161 160
162static bool needed_by_vfsmount(__u32 test_mask, void *data, int data_is) 161static bool needed_by_vfsmount(__u32 test_mask, struct vfsmount *mnt)
163{ 162{
164 struct path *path; 163 if (!mnt)
165
166 if (data_is == FSNOTIFY_EVENT_PATH)
167 path = (struct path *)data;
168 else if (data_is == FSNOTIFY_EVENT_FILE)
169 path = &((struct file *)data)->f_path;
170 else
171 return false; 164 return false;
172 165
173 /* hook in this when mnt->mnt_fsnotify_mask is defined */ 166 /* 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
184{ 177{
185 struct fsnotify_group *group; 178 struct fsnotify_group *group;
186 struct fsnotify_event *event = NULL; 179 struct fsnotify_event *event = NULL;
180 struct vfsmount *mnt = NULL;
187 int idx; 181 int idx;
188 /* global tests shouldn't care about events on child only the specific event */ 182 /* global tests shouldn't care about events on child only the specific event */
189 __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); 183 __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
198 !(test_mask & fsnotify_vfsmount_mask)) 192 !(test_mask & fsnotify_vfsmount_mask))
199 return; 193 return;
200 194
195 if (data_is == FSNOTIFY_EVENT_PATH)
196 mnt = ((struct path *)data)->mnt;
197 else if (data_is == FSNOTIFY_EVENT_FILE)
198 mnt = ((struct file *)data)->f_path.mnt;
199
201 /* if this inode's directed listeners don't care and nothing on the vfsmount 200 /* if this inode's directed listeners don't care and nothing on the vfsmount
202 * listeners list cares, nothing to do */ 201 * listeners list cares, nothing to do */
203 if (!(test_mask & to_tell->i_fsnotify_mask) && 202 if (!(test_mask & to_tell->i_fsnotify_mask) &&
204 !needed_by_vfsmount(test_mask, data, data_is)) 203 !needed_by_vfsmount(test_mask, mnt))
205 return; 204 return;
206 205
207 /* 206 /*
@@ -214,16 +213,16 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const
214 if (test_mask & to_tell->i_fsnotify_mask) { 213 if (test_mask & to_tell->i_fsnotify_mask) {
215 list_for_each_entry_rcu(group, &fsnotify_inode_groups, inode_group_list) { 214 list_for_each_entry_rcu(group, &fsnotify_inode_groups, inode_group_list) {
216 if (test_mask & group->mask) { 215 if (test_mask & group->mask) {
217 send_to_group(mask, group, data, data_is, 216 send_to_group(group, to_tell, NULL, mask, data, data_is,
218 file_name, cookie, &event, to_tell); 217 cookie, file_name, &event);
219 } 218 }
220 } 219 }
221 } 220 }
222 if (needed_by_vfsmount(test_mask, data, data_is)) { 221 if (needed_by_vfsmount(test_mask, mnt)) {
223 list_for_each_entry_rcu(group, &fsnotify_vfsmount_groups, vfsmount_group_list) { 222 list_for_each_entry_rcu(group, &fsnotify_vfsmount_groups, vfsmount_group_list) {
224 if (test_mask & group->mask) { 223 if (test_mask & group->mask) {
225 send_to_group(mask, group, data, data_is, 224 send_to_group(group, to_tell, mnt, mask, data, data_is,
226 file_name, cookie, &event, to_tell); 225 cookie, file_name, &event);
227 } 226 }
228 } 227 }
229 } 228 }
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 0a0f5d0f0d0a..8075ae708ed4 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -141,7 +141,8 @@ static void inotify_freeing_mark(struct fsnotify_mark_entry *entry, struct fsnot
141} 141}
142 142
143static bool inotify_should_send_event(struct fsnotify_group *group, struct inode *inode, 143static bool inotify_should_send_event(struct fsnotify_group *group, struct inode *inode,
144 __u32 mask, void *data, int data_type) 144 struct vfsmount *mnt, __u32 mask, void *data,
145 int data_type)
145{ 146{
146 struct fsnotify_mark_entry *entry; 147 struct fsnotify_mark_entry *entry;
147 bool send; 148 bool send;