diff options
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 5 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 12 | ||||
-rw-r--r-- | include/linux/fanotify.h | 10 |
3 files changed, 25 insertions, 2 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 8d98e1f5817b..b04f88eed09e 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -131,6 +131,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
131 | BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW); | 131 | BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW); |
132 | BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM); | 132 | BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM); |
133 | BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); | 133 | BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); |
134 | BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR); | ||
134 | 135 | ||
135 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 136 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
136 | 137 | ||
@@ -195,6 +196,10 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, | |||
195 | BUG(); | 196 | BUG(); |
196 | } | 197 | } |
197 | 198 | ||
199 | if (S_ISDIR(path->dentry->d_inode->i_mode) && | ||
200 | (marks_ignored_mask & FS_ISDIR)) | ||
201 | return false; | ||
202 | |||
198 | if (event_mask & marks_mask & ~marks_ignored_mask) | 203 | if (event_mask & marks_mask & ~marks_ignored_mask) |
199 | return true; | 204 | return true; |
200 | 205 | ||
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index a7d9369482d5..ff1a908c9708 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -570,6 +570,12 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, | |||
570 | if (flags & FAN_MARK_IGNORED_SURV_MODIFY) | 570 | if (flags & FAN_MARK_IGNORED_SURV_MODIFY) |
571 | fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; | 571 | fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; |
572 | } | 572 | } |
573 | |||
574 | if (!(flags & FAN_MARK_ONDIR)) { | ||
575 | __u32 tmask = fsn_mark->ignored_mask | FAN_ONDIR; | ||
576 | fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask); | ||
577 | } | ||
578 | |||
573 | spin_unlock(&fsn_mark->lock); | 579 | spin_unlock(&fsn_mark->lock); |
574 | 580 | ||
575 | return mask & ~oldmask; | 581 | return mask & ~oldmask; |
@@ -766,6 +772,12 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
766 | default: | 772 | default: |
767 | return -EINVAL; | 773 | return -EINVAL; |
768 | } | 774 | } |
775 | |||
776 | if (mask & FAN_ONDIR) { | ||
777 | flags |= FAN_MARK_ONDIR; | ||
778 | mask &= ~FAN_ONDIR; | ||
779 | } | ||
780 | |||
769 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 781 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
770 | if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD)) | 782 | if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD)) |
771 | #else | 783 | #else |
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 7592a366a57b..5e0400a80c33 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h | |||
@@ -10,13 +10,15 @@ | |||
10 | #define FAN_CLOSE_NOWRITE 0x00000010 /* Writtable file closed */ | 10 | #define FAN_CLOSE_NOWRITE 0x00000010 /* Writtable file closed */ |
11 | #define FAN_OPEN 0x00000020 /* File was opened */ | 11 | #define FAN_OPEN 0x00000020 /* File was opened */ |
12 | 12 | ||
13 | #define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ | ||
14 | |||
15 | #define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ | 13 | #define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ |
16 | 14 | ||
17 | #define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ | 15 | #define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ |
18 | #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ | 16 | #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ |
19 | 17 | ||
18 | #define FAN_ONDIR 0x40000000 /* event occurred against dir */ | ||
19 | |||
20 | #define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ | ||
21 | |||
20 | /* helper events */ | 22 | /* helper events */ |
21 | #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ | 23 | #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ |
22 | 24 | ||
@@ -47,6 +49,10 @@ | |||
47 | #define FAN_MARK_IGNORED_MASK 0x00000020 | 49 | #define FAN_MARK_IGNORED_MASK 0x00000020 |
48 | #define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 | 50 | #define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 |
49 | #define FAN_MARK_FLUSH 0x00000080 | 51 | #define FAN_MARK_FLUSH 0x00000080 |
52 | #ifdef __KERNEL__ | ||
53 | /* not valid from userspace, only kernel internal */ | ||
54 | #define FAN_MARK_ONDIR 0x00000100 | ||
55 | #endif | ||
50 | 56 | ||
51 | #define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ | 57 | #define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ |
52 | FAN_MARK_REMOVE |\ | 58 | FAN_MARK_REMOVE |\ |