aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/fanotify
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-07-28 10:18:39 -0400
committerEric Paris <eparis@redhat.com>2010-07-28 10:18:55 -0400
commit1968f5eed54ce47bde488fd9a450912e4a2d7138 (patch)
treebcf13b98fda519c240e89cae3de95fc7d9ece715 /fs/notify/fanotify
parentce8f76fb7320297ccbe7c950fd9a2d727dd6a5a0 (diff)
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>
Diffstat (limited to 'fs/notify/fanotify')
-rw-r--r--fs/notify/fanotify/fanotify.c88
1 files changed, 34 insertions, 54 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index ef4fa4a45c9..eb8f73c9c13 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
156static 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
181static 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
200static bool fanotify_should_send_event(struct fsnotify_group *group, 156static 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
226const struct fsnotify_ops fanotify_fsnotify_ops = { 206const struct fsnotify_ops fanotify_fsnotify_ops = {