aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/fsnotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify/fsnotify.c')
-rw-r--r--fs/notify/fsnotify.c35
1 files changed, 17 insertions, 18 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 59dc7a02bd0c..6f2777ce87a1 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -149,8 +149,8 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt,
149 struct fsnotify_event **event) 149 struct fsnotify_event **event)
150{ 150{
151 struct fsnotify_group *group = NULL; 151 struct fsnotify_group *group = NULL;
152 __u32 inode_test_mask = (mask & ~FS_EVENT_ON_CHILD); 152 __u32 inode_test_mask = 0;
153 __u32 vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD); 153 __u32 vfsmount_test_mask = 0;
154 154
155 if (unlikely(!inode_mark && !vfsmount_mark)) { 155 if (unlikely(!inode_mark && !vfsmount_mark)) {
156 BUG(); 156 BUG();
@@ -170,12 +170,14 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt,
170 /* does the inode mark tell us to do something? */ 170 /* does the inode mark tell us to do something? */
171 if (inode_mark) { 171 if (inode_mark) {
172 group = inode_mark->group; 172 group = inode_mark->group;
173 inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
173 inode_test_mask &= inode_mark->mask; 174 inode_test_mask &= inode_mark->mask;
174 inode_test_mask &= ~inode_mark->ignored_mask; 175 inode_test_mask &= ~inode_mark->ignored_mask;
175 } 176 }
176 177
177 /* does the vfsmount_mark tell us to do something? */ 178 /* does the vfsmount_mark tell us to do something? */
178 if (vfsmount_mark) { 179 if (vfsmount_mark) {
180 vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
179 group = vfsmount_mark->group; 181 group = vfsmount_mark->group;
180 vfsmount_test_mask &= vfsmount_mark->mask; 182 vfsmount_test_mask &= vfsmount_mark->mask;
181 vfsmount_test_mask &= ~vfsmount_mark->ignored_mask; 183 vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
@@ -183,9 +185,12 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt,
183 vfsmount_test_mask &= ~inode_mark->ignored_mask; 185 vfsmount_test_mask &= ~inode_mark->ignored_mask;
184 } 186 }
185 187
186 pr_debug("%s: group=%p to_tell=%p mnt=%p mark=%p mask=%x data=%p" 188 pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x inode_mark=%p"
187 " data_is=%d cookie=%d event=%p\n", __func__, group, to_tell, 189 " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
188 mnt, inode_mark, mask, data, data_is, cookie, *event); 190 " data=%p data_is=%d cookie=%d event=%p\n",
191 __func__, group, to_tell, mnt, mask, inode_mark,
192 inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
193 data_is, cookie, *event);
189 194
190 if (!inode_test_mask && !vfsmount_test_mask) 195 if (!inode_test_mask && !vfsmount_test_mask)
191 return 0; 196 return 0;
@@ -214,7 +219,7 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt,
214int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, 219int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
215 const unsigned char *file_name, u32 cookie) 220 const unsigned char *file_name, u32 cookie)
216{ 221{
217 struct hlist_node *inode_node, *vfsmount_node; 222 struct hlist_node *inode_node = NULL, *vfsmount_node = NULL;
218 struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; 223 struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL;
219 struct fsnotify_group *inode_group, *vfsmount_group; 224 struct fsnotify_group *inode_group, *vfsmount_group;
220 struct fsnotify_event *event = NULL; 225 struct fsnotify_event *event = NULL;
@@ -245,19 +250,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
245 (test_mask & to_tell->i_fsnotify_mask)) 250 (test_mask & to_tell->i_fsnotify_mask))
246 inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, 251 inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first,
247 &fsnotify_mark_srcu); 252 &fsnotify_mark_srcu);
248 else
249 inode_node = NULL;
250 253
251 if (mnt) { 254 if (mnt && ((mask & FS_MODIFY) ||
252 if ((mask & FS_MODIFY) || 255 (test_mask & mnt->mnt_fsnotify_mask))) {
253 (test_mask & mnt->mnt_fsnotify_mask)) 256 vfsmount_node = srcu_dereference(mnt->mnt_fsnotify_marks.first,
254 vfsmount_node = srcu_dereference(mnt->mnt_fsnotify_marks.first, 257 &fsnotify_mark_srcu);
255 &fsnotify_mark_srcu); 258 inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first,
256 else 259 &fsnotify_mark_srcu);
257 vfsmount_node = NULL;
258 } else {
259 mnt = NULL;
260 vfsmount_node = NULL;
261 } 260 }
262 261
263 while (inode_node || vfsmount_node) { 262 while (inode_node || vfsmount_node) {