diff options
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index f6900022f69e..060b177146e8 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -100,31 +100,39 @@ static int fanotify_handle_event(struct fsnotify_group *group, struct fsnotify_e | |||
100 | } | 100 | } |
101 | 101 | ||
102 | static bool should_send_vfsmount_event(struct fsnotify_group *group, struct vfsmount *mnt, | 102 | static bool should_send_vfsmount_event(struct fsnotify_group *group, struct vfsmount *mnt, |
103 | __u32 mask) | 103 | struct inode *inode, __u32 mask) |
104 | { | 104 | { |
105 | struct fsnotify_mark *fsn_mark; | 105 | struct fsnotify_mark *mnt_mark; |
106 | bool send; | 106 | struct fsnotify_mark *inode_mark; |
107 | 107 | ||
108 | pr_debug("%s: group=%p vfsmount=%p mask=%x\n", | 108 | pr_debug("%s: group=%p vfsmount=%p mask=%x\n", |
109 | __func__, group, mnt, mask); | 109 | __func__, group, mnt, mask); |
110 | 110 | ||
111 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); | 111 | mnt_mark = fsnotify_find_vfsmount_mark(group, mnt); |
112 | if (!fsn_mark) | 112 | if (!mnt_mark) |
113 | return false; | 113 | return false; |
114 | 114 | ||
115 | send = (mask & fsn_mark->mask); | 115 | mask &= mnt_mark->mask; |
116 | mask &= ~mnt_mark->ignored_mask; | ||
117 | |||
118 | if (mask) { | ||
119 | inode_mark = fsnotify_find_inode_mark(group, inode); | ||
120 | if (inode_mark) { | ||
121 | mask &= ~inode_mark->ignored_mask; | ||
122 | fsnotify_put_mark(inode_mark); | ||
123 | } | ||
124 | } | ||
116 | 125 | ||
117 | /* find took a reference */ | 126 | /* find took a reference */ |
118 | fsnotify_put_mark(fsn_mark); | 127 | fsnotify_put_mark(mnt_mark); |
119 | 128 | ||
120 | return send; | 129 | return mask; |
121 | } | 130 | } |
122 | 131 | ||
123 | static bool should_send_inode_event(struct fsnotify_group *group, struct inode *inode, | 132 | static bool should_send_inode_event(struct fsnotify_group *group, struct inode *inode, |
124 | __u32 mask) | 133 | __u32 mask) |
125 | { | 134 | { |
126 | struct fsnotify_mark *fsn_mark; | 135 | struct fsnotify_mark *fsn_mark; |
127 | bool send; | ||
128 | 136 | ||
129 | pr_debug("%s: group=%p inode=%p mask=%x\n", | 137 | pr_debug("%s: group=%p inode=%p mask=%x\n", |
130 | __func__, group, inode, mask); | 138 | __func__, group, inode, mask); |
@@ -137,20 +145,21 @@ static bool should_send_inode_event(struct fsnotify_group *group, struct inode * | |||
137 | * events on the child, don't send it! */ | 145 | * events on the child, don't send it! */ |
138 | if ((mask & FS_EVENT_ON_CHILD) && | 146 | if ((mask & FS_EVENT_ON_CHILD) && |
139 | !(fsn_mark->mask & FS_EVENT_ON_CHILD)) { | 147 | !(fsn_mark->mask & FS_EVENT_ON_CHILD)) { |
140 | send = false; | 148 | mask = 0; |
141 | } else { | 149 | } else { |
142 | /* | 150 | /* |
143 | * We care about children, but do we care about this particular | 151 | * We care about children, but do we care about this particular |
144 | * type of event? | 152 | * type of event? |
145 | */ | 153 | */ |
146 | mask = (mask & ~FS_EVENT_ON_CHILD); | 154 | mask &= ~FS_EVENT_ON_CHILD; |
147 | send = (fsn_mark->mask & mask); | 155 | mask &= fsn_mark->mask; |
156 | mask &= ~fsn_mark->ignored_mask; | ||
148 | } | 157 | } |
149 | 158 | ||
150 | /* find took a reference */ | 159 | /* find took a reference */ |
151 | fsnotify_put_mark(fsn_mark); | 160 | fsnotify_put_mark(fsn_mark); |
152 | 161 | ||
153 | return send; | 162 | return mask; |
154 | } | 163 | } |
155 | 164 | ||
156 | static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *to_tell, | 165 | static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *to_tell, |
@@ -170,7 +179,7 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, struct inod | |||
170 | return false; | 179 | return false; |
171 | 180 | ||
172 | if (mnt) | 181 | if (mnt) |
173 | return should_send_vfsmount_event(group, mnt, mask); | 182 | return should_send_vfsmount_event(group, mnt, to_tell, mask); |
174 | else | 183 | else |
175 | return should_send_inode_event(group, to_tell, mask); | 184 | return should_send_inode_event(group, to_tell, mask); |
176 | } | 185 | } |