]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
fsnotify: clear ignored mask on modify
authorEric Paris <eparis@redhat.com>
Fri, 18 Dec 2009 02:24:33 +0000 (21:24 -0500)
committerEric Paris <eparis@redhat.com>
Wed, 28 Jul 2010 13:59:00 +0000 (09:59 -0400)
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>
fs/notify/fsnotify.c

index 7f14ddc3efc2249a6ab3c475e1fbedc63b39a993..3ad940d0bac145a531ddae9318d1a4d7eb7c4d81 100644 (file)
@@ -140,6 +140,33 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
 }
 EXPORT_SYMBOL_GPL(__fsnotify_parent);
 
+void __fsnotify_flush_ignored_mask(struct inode *inode, void *data, int data_is)
+{
+       struct fsnotify_mark *mark;
+       struct hlist_node *node;
+
+       if (!hlist_empty(&inode->i_fsnotify_marks)) {
+               spin_lock(&inode->i_lock);
+               hlist_for_each_entry(mark, node, &inode->i_fsnotify_marks, i.i_list) {
+                       mark->ignored_mask = 0;
+               }
+               spin_unlock(&inode->i_lock);
+       }
+
+       if (data_is == FSNOTIFY_EVENT_PATH) {
+               struct vfsmount *mnt;
+
+               mnt = ((struct path *)data)->mnt;
+               if (mnt && !hlist_empty(&mnt->mnt_fsnotify_marks)) {
+                       spin_lock(&mnt->mnt_root->d_lock);
+                       hlist_for_each_entry(mark, node, &mnt->mnt_fsnotify_marks, m.m_list) {
+                               mark->ignored_mask = 0;
+                       }
+                       spin_unlock(&mnt->mnt_root->d_lock);
+               }
+       }
+}
+
 static void send_to_group(struct fsnotify_group *group, struct inode *to_tell,
                          struct vfsmount *mnt, __u32 mask, void *data,
                          int data_is, u32 cookie, const char *file_name,
@@ -170,6 +197,7 @@ static bool needed_by_vfsmount(__u32 test_mask, struct vfsmount *mnt)
 
        return (test_mask & mnt->mnt_fsnotify_mask);
 }
+
 /*
  * This is the main call to fsnotify.  The VFS calls into hook specific functions
  * 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
            list_empty(&fsnotify_vfsmount_groups))
                 return;
  
+       if (mask & FS_MODIFY)
+               __fsnotify_flush_ignored_mask(to_tell, data, data_is);
+
        /* if none of the directed listeners or vfsmount listeners care */
        if (!(test_mask & fsnotify_inode_mask) &&
            !(test_mask & fsnotify_vfsmount_mask))