diff options
| -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 | ||||
| -rw-r--r-- | include/linux/fsnotify_backend.h | 2 | ||||
| -rw-r--r-- | kernel/audit_tree.c | 2 | ||||
| -rw-r--r-- | kernel/audit_watch.c | 2 |
7 files changed, 41 insertions, 61 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 | ||
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index d38f922977f9..9bbfd7204b04 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -92,7 +92,7 @@ struct fsnotify_event_private_data; | |||
| 92 | */ | 92 | */ |
| 93 | struct fsnotify_ops { | 93 | struct fsnotify_ops { |
| 94 | bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode, | 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 | struct fsnotify_mark *vfsmount_mark, | 96 | struct fsnotify_mark *vfsmount_mark, |
| 97 | __u32 mask, void *data, int data_type); | 97 | __u32 mask, void *data, int data_type); |
| 98 | int (*handle_event)(struct fsnotify_group *group, | 98 | int (*handle_event)(struct fsnotify_group *group, |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 781ab7f4e35c..7f18d3a4527e 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
| @@ -921,7 +921,7 @@ static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify | |||
| 921 | } | 921 | } |
| 922 | 922 | ||
| 923 | static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode, | 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 | struct fsnotify_mark *vfsmount_mark, | 925 | struct fsnotify_mark *vfsmount_mark, |
| 926 | __u32 mask, void *data, int data_type) | 926 | __u32 mask, void *data, int data_type) |
| 927 | { | 927 | { |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index a273cf340527..6bf2306be7d6 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
| @@ -503,7 +503,7 @@ void audit_remove_watch_rule(struct audit_krule *krule) | |||
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | static bool audit_watch_should_send_event(struct fsnotify_group *group, struct inode *inode, | 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 | struct fsnotify_mark *vfsmount_mark, | 507 | struct fsnotify_mark *vfsmount_mark, |
| 508 | __u32 mask, void *data, int data_type) | 508 | __u32 mask, void *data, int data_type) |
| 509 | { | 509 | { |
