diff options
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 2 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 88 | ||||
-rw-r--r-- | fs/notify/fsnotify.c | 2 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 4 |
4 files changed, 38 insertions, 58 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index bda588b831ad..3344bdd5506e 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -128,7 +128,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, | |||
128 | * userspace notification for that pair. | 128 | * userspace notification for that pair. |
129 | */ | 129 | */ |
130 | static bool dnotify_should_send_event(struct fsnotify_group *group, | 130 | static bool dnotify_should_send_event(struct fsnotify_group *group, |
131 | struct inode *inode, struct vfsmount *mnt, | 131 | struct inode *inode, |
132 | struct fsnotify_mark *inode_mark, | 132 | struct fsnotify_mark *inode_mark, |
133 | struct fsnotify_mark *vfsmount_mark, | 133 | struct fsnotify_mark *vfsmount_mark, |
134 | __u32 mask, void *data, int data_type) | 134 | __u32 mask, void *data, int data_type) |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index ef4fa4a45c94..eb8f73c9c131 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -153,59 +153,20 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
153 | return ret; | 153 | return ret; |
154 | } | 154 | } |
155 | 155 | ||
156 | static bool should_send_vfsmount_event(struct fsnotify_group *group, | ||
157 | struct vfsmount *mnt, | ||
158 | struct inode *inode, | ||
159 | struct fsnotify_mark *mnt_mark, | ||
160 | __u32 mask) | ||
161 | { | ||
162 | struct fsnotify_mark *inode_mark; | ||
163 | |||
164 | pr_debug("%s: group=%p vfsmount=%p mark=%p mask=%x\n", | ||
165 | __func__, group, mnt, mnt_mark, mask); | ||
166 | |||
167 | mask &= mnt_mark->mask; | ||
168 | mask &= ~mnt_mark->ignored_mask; | ||
169 | |||
170 | if (mask) { | ||
171 | inode_mark = fsnotify_find_inode_mark(group, inode); | ||
172 | if (inode_mark) { | ||
173 | mask &= ~inode_mark->ignored_mask; | ||
174 | fsnotify_put_mark(inode_mark); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | return mask; | ||
179 | } | ||
180 | |||
181 | static bool should_send_inode_event(struct fsnotify_group *group, | ||
182 | struct inode *inode, | ||
183 | struct fsnotify_mark *mark, | ||
184 | __u32 mask) | ||
185 | { | ||
186 | pr_debug("%s: group=%p inode=%p mark=%p mask=%x\n", | ||
187 | __func__, group, inode, mark, mask); | ||
188 | |||
189 | /* | ||
190 | * if the event is for a child and this inode doesn't care about | ||
191 | * events on the child, don't send it! | ||
192 | */ | ||
193 | if ((mask & FS_EVENT_ON_CHILD) && | ||
194 | !(mark->mask & FS_EVENT_ON_CHILD)) | ||
195 | return false; | ||
196 | else | ||
197 | return true; | ||
198 | } | ||
199 | |||
200 | static bool fanotify_should_send_event(struct fsnotify_group *group, | 156 | static bool fanotify_should_send_event(struct fsnotify_group *group, |
201 | struct inode *to_tell, | 157 | struct inode *to_tell, |
202 | struct vfsmount *mnt, | ||
203 | struct fsnotify_mark *inode_mark, | 158 | struct fsnotify_mark *inode_mark, |
204 | struct fsnotify_mark *vfsmount_mark, | 159 | struct fsnotify_mark *vfsmnt_mark, |
205 | __u32 mask, void *data, int data_type) | 160 | __u32 event_mask, void *data, int data_type) |
206 | { | 161 | { |
207 | pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x data=%p data_type=%d\n", | 162 | __u32 marks_mask, marks_ignored_mask; |
208 | __func__, group, to_tell, mnt, mask, data, data_type); | 163 | |
164 | pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p " | ||
165 | "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, | ||
166 | inode_mark, vfsmnt_mark, event_mask, data, data_type); | ||
167 | |||
168 | pr_debug("%s: group=%p vfsmount_mark=%p inode_mark=%p mask=%x\n", | ||
169 | __func__, group, vfsmnt_mark, inode_mark, event_mask); | ||
209 | 170 | ||
210 | /* sorry, fanotify only gives a damn about files and dirs */ | 171 | /* sorry, fanotify only gives a damn about files and dirs */ |
211 | if (!S_ISREG(to_tell->i_mode) && | 172 | if (!S_ISREG(to_tell->i_mode) && |
@@ -216,11 +177,30 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, | |||
216 | if (data_type != FSNOTIFY_EVENT_FILE) | 177 | if (data_type != FSNOTIFY_EVENT_FILE) |
217 | return false; | 178 | return false; |
218 | 179 | ||
219 | if (mnt) | 180 | if (inode_mark && vfsmnt_mark) { |
220 | return should_send_vfsmount_event(group, mnt, to_tell, | 181 | marks_mask = (vfsmnt_mark->mask | inode_mark->mask); |
221 | vfsmount_mark, mask); | 182 | marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask); |
222 | else | 183 | } else if (inode_mark) { |
223 | return should_send_inode_event(group, to_tell, inode_mark, mask); | 184 | /* |
185 | * if the event is for a child and this inode doesn't care about | ||
186 | * events on the child, don't send it! | ||
187 | */ | ||
188 | if ((event_mask & FS_EVENT_ON_CHILD) && | ||
189 | !(inode_mark->mask & FS_EVENT_ON_CHILD)) | ||
190 | return false; | ||
191 | marks_mask = inode_mark->mask; | ||
192 | marks_ignored_mask = inode_mark->ignored_mask; | ||
193 | } else if (vfsmnt_mark) { | ||
194 | marks_mask = vfsmnt_mark->mask; | ||
195 | marks_ignored_mask = vfsmnt_mark->ignored_mask; | ||
196 | } else { | ||
197 | BUG(); | ||
198 | } | ||
199 | |||
200 | if (event_mask & marks_mask & ~marks_ignored_mask) | ||
201 | return true; | ||
202 | |||
203 | return false; | ||
224 | } | 204 | } |
225 | 205 | ||
226 | const struct fsnotify_ops fanotify_fsnotify_ops = { | 206 | const struct fsnotify_ops fanotify_fsnotify_ops = { |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 090b64c3b4f9..4d2a82c1ceb1 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -183,7 +183,7 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
183 | if (!inode_test_mask && !vfsmount_test_mask) | 183 | if (!inode_test_mask && !vfsmount_test_mask) |
184 | return 0; | 184 | return 0; |
185 | 185 | ||
186 | if (group->ops->should_send_event(group, to_tell, mnt, inode_mark, | 186 | if (group->ops->should_send_event(group, to_tell, inode_mark, |
187 | vfsmount_mark, mask, data, | 187 | vfsmount_mark, mask, data, |
188 | data_is) == false) | 188 | data_is) == false) |
189 | return 0; | 189 | return 0; |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index e53f49731b6e..5e73eeb2c697 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -142,11 +142,11 @@ static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify | |||
142 | } | 142 | } |
143 | 143 | ||
144 | static bool inotify_should_send_event(struct fsnotify_group *group, struct inode *inode, | 144 | static bool inotify_should_send_event(struct fsnotify_group *group, struct inode *inode, |
145 | struct vfsmount *mnt, struct fsnotify_mark *mark, | 145 | struct fsnotify_mark *inode_mark, |
146 | struct fsnotify_mark *vfsmount_mark, | 146 | struct fsnotify_mark *vfsmount_mark, |
147 | __u32 mask, void *data, int data_type) | 147 | __u32 mask, void *data, int data_type) |
148 | { | 148 | { |
149 | if ((mark->mask & FS_EXCL_UNLINK) && | 149 | if ((inode_mark->mask & FS_EXCL_UNLINK) && |
150 | (data_type == FSNOTIFY_EVENT_FILE)) { | 150 | (data_type == FSNOTIFY_EVENT_FILE)) { |
151 | struct file *file = data; | 151 | struct file *file = data; |
152 | 152 | ||