aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/fsnotify.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-12-17 21:24:33 -0500
committerEric Paris <eparis@redhat.com>2010-07-28 09:59:00 -0400
commite898386146deb49a0b45ff1887d9da149c003209 (patch)
tree6238ddb50919383139e7937c75a21524faacf03d /fs/notify/fsnotify.c
parentb9e4e3bd0495fea9e8f8e712889c9cd8ffa43c94 (diff)
fsnotify: clear ignored mask on modify
On inode modification we clear the ignored mask for all of the marks on the inode. This allows userspace to ignore accesses to inodes until there is something different. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs/notify/fsnotify.c')
-rw-r--r--fs/notify/fsnotify.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 7f14ddc3efc2..3ad940d0bac1 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -140,6 +140,33 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
140} 140}
141EXPORT_SYMBOL_GPL(__fsnotify_parent); 141EXPORT_SYMBOL_GPL(__fsnotify_parent);
142 142
143void __fsnotify_flush_ignored_mask(struct inode *inode, void *data, int data_is)
144{
145 struct fsnotify_mark *mark;
146 struct hlist_node *node;
147
148 if (!hlist_empty(&inode->i_fsnotify_marks)) {
149 spin_lock(&inode->i_lock);
150 hlist_for_each_entry(mark, node, &inode->i_fsnotify_marks, i.i_list) {
151 mark->ignored_mask = 0;
152 }
153 spin_unlock(&inode->i_lock);
154 }
155
156 if (data_is == FSNOTIFY_EVENT_PATH) {
157 struct vfsmount *mnt;
158
159 mnt = ((struct path *)data)->mnt;
160 if (mnt && !hlist_empty(&mnt->mnt_fsnotify_marks)) {
161 spin_lock(&mnt->mnt_root->d_lock);
162 hlist_for_each_entry(mark, node, &mnt->mnt_fsnotify_marks, m.m_list) {
163 mark->ignored_mask = 0;
164 }
165 spin_unlock(&mnt->mnt_root->d_lock);
166 }
167 }
168}
169
143static void send_to_group(struct fsnotify_group *group, struct inode *to_tell, 170static void send_to_group(struct fsnotify_group *group, struct inode *to_tell,
144 struct vfsmount *mnt, __u32 mask, void *data, 171 struct vfsmount *mnt, __u32 mask, void *data,
145 int data_is, u32 cookie, const char *file_name, 172 int data_is, u32 cookie, const char *file_name,
@@ -170,6 +197,7 @@ static bool needed_by_vfsmount(__u32 test_mask, struct vfsmount *mnt)
170 197
171 return (test_mask & mnt->mnt_fsnotify_mask); 198 return (test_mask & mnt->mnt_fsnotify_mask);
172} 199}
200
173/* 201/*
174 * This is the main call to fsnotify. The VFS calls into hook specific functions 202 * This is the main call to fsnotify. The VFS calls into hook specific functions
175 * in linux/fsnotify.h. Those functions then in turn call here. Here will call 203 * in linux/fsnotify.h. Those functions then in turn call here. Here will call
@@ -190,6 +218,9 @@ void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const
190 list_empty(&fsnotify_vfsmount_groups)) 218 list_empty(&fsnotify_vfsmount_groups))
191 return; 219 return;
192 220
221 if (mask & FS_MODIFY)
222 __fsnotify_flush_ignored_mask(to_tell, data, data_is);
223
193 /* if none of the directed listeners or vfsmount listeners care */ 224 /* if none of the directed listeners or vfsmount listeners care */
194 if (!(test_mask & fsnotify_inode_mask) && 225 if (!(test_mask & fsnotify_inode_mask) &&
195 !(test_mask & fsnotify_vfsmount_mask)) 226 !(test_mask & fsnotify_vfsmount_mask))