diff options
| -rw-r--r-- | fs/notify/fsnotify.c | 35 |
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, | |||
| 214 | int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | 219 | int 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) { |
