Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+41 -61
+1 -1
fs/notify/dnotify/dnotify.c
··· 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)
+34 -54
fs/notify/fanotify/fanotify.c
··· 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; 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 171 /* sorry, fanotify only gives a damn about files and dirs */ 211 172 if (!S_ISREG(to_tell->i_mode) && ··· 177 216 if (data_type != FSNOTIFY_EVENT_FILE) 178 217 return false; 179 218 180 - if (mnt) 181 - return should_send_vfsmount_event(group, mnt, to_tell, 182 - vfsmount_mark, mask); 183 - else 184 - return should_send_inode_event(group, to_tell, inode_mark, mask); 219 + if (inode_mark && vfsmnt_mark) { 220 + marks_mask = (vfsmnt_mark->mask | inode_mark->mask); 221 + marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask); 222 + } else if (inode_mark) { 223 + /* 224 + * if the event is for a child and this inode doesn't care about 225 + * events on the child, don't send it! 226 + */ 227 + if ((event_mask & FS_EVENT_ON_CHILD) && 228 + !(inode_mark->mask & FS_EVENT_ON_CHILD)) 229 + return false; 230 + marks_mask = inode_mark->mask; 231 + marks_ignored_mask = inode_mark->ignored_mask; 232 + } else if (vfsmnt_mark) { 233 + marks_mask = vfsmnt_mark->mask; 234 + marks_ignored_mask = vfsmnt_mark->ignored_mask; 235 + } else { 236 + BUG(); 237 + } 238 + 239 + if (event_mask & marks_mask & ~marks_ignored_mask) 240 + return true; 241 + 242 + return false; 185 243 } 186 244 187 245 const struct fsnotify_ops fanotify_fsnotify_ops = {
+1 -1
fs/notify/fsnotify.c
··· 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;
+2 -2
fs/notify/inotify/inotify_fsnotify.c
··· 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
+1 -1
include/linux/fsnotify_backend.h
··· 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,
+1 -1
kernel/audit_tree.c
··· 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 {
+1 -1
kernel/audit_watch.c
··· 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 {