fsnotify: add marks to inodes so groups can interpret how to handle those inodes
[safe/jmp/linux-2.6] / fs / inode.c
index 0571983..54c63ce 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
 #include <linux/inotify.h>
+#include <linux/fsnotify.h>
 #include <linux/mount.h>
 #include <linux/async.h>
 
@@ -189,6 +190,10 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
        inode->i_private = NULL;
        inode->i_mapping = mapping;
 
+#ifdef CONFIG_FSNOTIFY
+       inode->i_fsnotify_mask = 0;
+#endif
+
        return inode;
 
 out_free_security:
@@ -219,7 +224,9 @@ static struct inode *alloc_inode(struct super_block *sb)
 void destroy_inode(struct inode *inode)
 {
        BUG_ON(inode_has_buffers(inode));
+       ima_inode_free(inode);
        security_inode_free(inode);
+       fsnotify_inode_delete(inode);
        if (inode->i_sb->s_op->destroy_inode)
                inode->i_sb->s_op->destroy_inode(inode);
        else
@@ -251,6 +258,9 @@ void inode_init_once(struct inode *inode)
        INIT_LIST_HEAD(&inode->inotify_watches);
        mutex_init(&inode->inotify_mutex);
 #endif
+#ifdef CONFIG_FSNOTIFY
+       INIT_HLIST_HEAD(&inode->i_fsnotify_mark_entries);
+#endif
 }
 EXPORT_SYMBOL(inode_init_once);
 
@@ -1053,13 +1063,22 @@ int insert_inode_locked(struct inode *inode)
        struct super_block *sb = inode->i_sb;
        ino_t ino = inode->i_ino;
        struct hlist_head *head = inode_hashtable + hash(sb, ino);
-       struct inode *old;
 
        inode->i_state |= I_LOCK|I_NEW;
        while (1) {
+               struct hlist_node *node;
+               struct inode *old = NULL;
                spin_lock(&inode_lock);
-               old = find_inode_fast(sb, head, ino);
-               if (likely(!old)) {
+               hlist_for_each_entry(old, node, head, i_hash) {
+                       if (old->i_ino != ino)
+                               continue;
+                       if (old->i_sb != sb)
+                               continue;
+                       if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+                               continue;
+                       break;
+               }
+               if (likely(!node)) {
                        hlist_add_head(&inode->i_hash, head);
                        spin_unlock(&inode_lock);
                        return 0;
@@ -1081,14 +1100,24 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
 {
        struct super_block *sb = inode->i_sb;
        struct hlist_head *head = inode_hashtable + hash(sb, hashval);
-       struct inode *old;
 
        inode->i_state |= I_LOCK|I_NEW;
 
        while (1) {
+               struct hlist_node *node;
+               struct inode *old = NULL;
+
                spin_lock(&inode_lock);
-               old = find_inode(sb, head, test, data);
-               if (likely(!old)) {
+               hlist_for_each_entry(old, node, head, i_hash) {
+                       if (old->i_sb != sb)
+                               continue;
+                       if (!test(old, data))
+                               continue;
+                       if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+                               continue;
+                       break;
+               }
+               if (likely(!node)) {
                        hlist_add_head(&inode->i_hash, head);
                        spin_unlock(&inode_lock);
                        return 0;