Commit 1968f5eed54ce47bde488fd9a450912e4a2d7138
1 parent
ce8f76fb73
Exists in
master
and in
4 other branches
fanotify: use both marks when possible
fanotify currently, when given a vfsmount_mark will look up (if it exists) the corresponding inode mark. This patch drops that lookup and uses the mark provided. Signed-off-by: Eric Paris <eparis@redhat.com>
Showing 7 changed files with 41 additions and 61 deletions Side-by-side Diff
fs/notify/dnotify/dnotify.c
... | ... | @@ -128,7 +128,7 @@ |
128 | 128 | * userspace notification for that pair. |
129 | 129 | */ |
130 | 130 | static bool dnotify_should_send_event(struct fsnotify_group *group, |
131 | - struct inode *inode, struct vfsmount *mnt, | |
131 | + struct inode *inode, | |
132 | 132 | struct fsnotify_mark *inode_mark, |
133 | 133 | struct fsnotify_mark *vfsmount_mark, |
134 | 134 | __u32 mask, void *data, int data_type) |
fs/notify/fanotify/fanotify.c
... | ... | @@ -153,60 +153,21 @@ |
153 | 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 | 156 | static bool fanotify_should_send_event(struct fsnotify_group *group, |
201 | 157 | struct inode *to_tell, |
202 | - struct vfsmount *mnt, | |
203 | 158 | struct fsnotify_mark *inode_mark, |
204 | - struct fsnotify_mark *vfsmount_mark, | |
205 | - __u32 mask, void *data, int data_type) | |
159 | + struct fsnotify_mark *vfsmnt_mark, | |
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", | |
208 | - __func__, group, to_tell, mnt, mask, data, data_type); | |
162 | + __u32 marks_mask, marks_ignored_mask; | |
209 | 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); | |
170 | + | |
210 | 171 | /* sorry, fanotify only gives a damn about files and dirs */ |
211 | 172 | if (!S_ISREG(to_tell->i_mode) && |
212 | 173 | !S_ISDIR(to_tell->i_mode)) |
... | ... | @@ -216,11 +177,30 @@ |
216 | 177 | if (data_type != FSNOTIFY_EVENT_FILE) |
217 | 178 | return false; |
218 | 179 | |
219 | - if (mnt) | |
220 | - return should_send_vfsmount_event(group, mnt, to_tell, | |
221 | - vfsmount_mark, mask); | |
222 | - else | |
223 | - return should_send_inode_event(group, to_tell, inode_mark, mask); | |
180 | + if (inode_mark && vfsmnt_mark) { | |
181 | + marks_mask = (vfsmnt_mark->mask | inode_mark->mask); | |
182 | + marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask); | |
183 | + } else if (inode_mark) { | |
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 | 206 | const struct fsnotify_ops fanotify_fsnotify_ops = { |
fs/notify/fsnotify.c
... | ... | @@ -183,7 +183,7 @@ |
183 | 183 | if (!inode_test_mask && !vfsmount_test_mask) |
184 | 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 | 187 | vfsmount_mark, mask, data, |
188 | 188 | data_is) == false) |
189 | 189 | return 0; |
fs/notify/inotify/inotify_fsnotify.c
... | ... | @@ -142,11 +142,11 @@ |
142 | 142 | } |
143 | 143 | |
144 | 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 | 146 | struct fsnotify_mark *vfsmount_mark, |
147 | 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 | 150 | (data_type == FSNOTIFY_EVENT_FILE)) { |
151 | 151 | struct file *file = data; |
152 | 152 |
include/linux/fsnotify_backend.h
... | ... | @@ -92,7 +92,7 @@ |
92 | 92 | */ |
93 | 93 | struct fsnotify_ops { |
94 | 94 | bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode, |
95 | - struct vfsmount *mnt, struct fsnotify_mark *inode_mark, | |
95 | + struct fsnotify_mark *inode_mark, | |
96 | 96 | struct fsnotify_mark *vfsmount_mark, |
97 | 97 | __u32 mask, void *data, int data_type); |
98 | 98 | int (*handle_event)(struct fsnotify_group *group, |
kernel/audit_tree.c
... | ... | @@ -921,7 +921,7 @@ |
921 | 921 | } |
922 | 922 | |
923 | 923 | static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode, |
924 | - struct vfsmount *mnt, struct fsnotify_mark *inode_mark, | |
924 | + struct fsnotify_mark *inode_mark, | |
925 | 925 | struct fsnotify_mark *vfsmount_mark, |
926 | 926 | __u32 mask, void *data, int data_type) |
927 | 927 | { |
kernel/audit_watch.c
... | ... | @@ -503,7 +503,7 @@ |
503 | 503 | } |
504 | 504 | |
505 | 505 | static bool audit_watch_should_send_event(struct fsnotify_group *group, struct inode *inode, |
506 | - struct vfsmount *mnt, struct fsnotify_mark *inode_mark, | |
506 | + struct fsnotify_mark *inode_mark, | |
507 | 507 | struct fsnotify_mark *vfsmount_mark, |
508 | 508 | __u32 mask, void *data, int data_type) |
509 | 509 | { |