fsnotify: add marks to inodes so groups can interpret how to handle those inodes
[safe/jmp/linux-2.6] / fs / inode.c
index 8a47ccd..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>
 
@@ -99,7 +100,7 @@ static DEFINE_MUTEX(iprune_mutex);
  */
 struct inodes_stat_t inodes_stat;
 
-static struct kmem_cache * inode_cachep __read_mostly;
+static struct kmem_cache *inode_cachep __read_mostly;
 
 static void wake_up_inode(struct inode *inode)
 {
@@ -124,7 +125,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
        static struct inode_operations empty_iops;
        static const struct file_operations empty_fops;
 
-       struct address_space * const mapping = &inode->i_data;
+       struct address_space *const mapping = &inode->i_data;
 
        inode->i_sb = sb;
        inode->i_blkbits = sb->s_blocksize_bits;
@@ -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:
@@ -216,10 +221,12 @@ static struct inode *alloc_inode(struct super_block *sb)
        return NULL;
 }
 
-void destroy_inode(struct inode *inode) 
+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,13 +258,15 @@ 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);
 
 static void init_once(void *foo)
 {
-       struct inode * inode = (struct inode *) foo;
+       struct inode *inode = (struct inode *) foo;
 
        inode_init_once(inode);
 }
@@ -265,7 +274,7 @@ static void init_once(void *foo)
 /*
  * inode_lock must be held
  */
-void __iget(struct inode * inode)
+void __iget(struct inode *inode)
 {
        if (atomic_read(&inode->i_count)) {
                atomic_inc(&inode->i_count);
@@ -289,12 +298,12 @@ void clear_inode(struct inode *inode)
 {
        might_sleep();
        invalidate_inode_buffers(inode);
-       
+
        BUG_ON(inode->i_data.nrpages);
        BUG_ON(!(inode->i_state & I_FREEING));
        BUG_ON(inode->i_state & I_CLEAR);
        inode_sync_wait(inode);
-       DQUOT_DROP(inode);
+       vfs_dq_drop(inode);
        if (inode->i_sb->s_op->clear_inode)
                inode->i_sb->s_op->clear_inode(inode);
        if (S_ISBLK(inode->i_mode) && inode->i_bdev)
@@ -303,7 +312,6 @@ void clear_inode(struct inode *inode)
                cd_forget(inode);
        inode->i_state = I_CLEAR;
 }
-
 EXPORT_SYMBOL(clear_inode);
 
 /*
@@ -351,8 +359,8 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
 
        next = head->next;
        for (;;) {
-               struct list_head * tmp = next;
-               struct inode * inode;
+               struct list_head *tmp = next;
+               struct inode *inode;
 
                /*
                 * We can reschedule here without worrying about the list's
@@ -366,6 +374,8 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
                if (tmp == head)
                        break;
                inode = list_entry(tmp, struct inode, i_sb_list);
+               if (inode->i_state & I_NEW)
+                       continue;
                invalidate_inode_buffers(inode);
                if (!atomic_read(&inode->i_count)) {
                        list_move(&inode->i_list, dispose);
@@ -389,7 +399,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
  *     fails because there are busy inodes then a non zero value is returned.
  *     If the discard is successful all the inodes have been discarded.
  */
-int invalidate_inodes(struct super_block * sb)
+int invalidate_inodes(struct super_block *sb)
 {
        int busy;
        LIST_HEAD(throw_away);
@@ -405,7 +415,6 @@ int invalidate_inodes(struct super_block * sb)
 
        return busy;
 }
-
 EXPORT_SYMBOL(invalidate_inodes);
 
 static int can_unuse(struct inode *inode)
@@ -502,7 +511,7 @@ static int shrink_icache_memory(int nr, gfp_t gfp_mask)
                 * Nasty deadlock avoidance.  We may hold various FS locks,
                 * and we don't want to recurse into the FS that called us
                 * in clear_inode() and friends..
-                */
+                */
                if (!(gfp_mask & __GFP_FS))
                        return -1;
                prune_icache(nr);
@@ -522,10 +531,13 @@ static void __wait_on_freeing_inode(struct inode *inode);
  * by hand after calling find_inode now! This simplifies iunique and won't
  * add any additional branch in the common code.
  */
-static struct inode * find_inode(struct super_block * sb, struct hlist_head *head, int (*test)(struct inode *, void *), void *data)
+static struct inode *find_inode(struct super_block *sb,
+                               struct hlist_head *head,
+                               int (*test)(struct inode *, void *),
+                               void *data)
 {
        struct hlist_node *node;
-       struct inode * inode = NULL;
+       struct inode *inode = NULL;
 
 repeat:
        hlist_for_each_entry(inode, node, head, i_hash) {
@@ -546,10 +558,11 @@ repeat:
  * find_inode_fast is the fast path version of find_inode, see the comment at
  * iget_locked for details.
  */
-static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head *head, unsigned long ino)
+static struct inode *find_inode_fast(struct super_block *sb,
+                               struct hlist_head *head, unsigned long ino)
 {
        struct hlist_node *node;
-       struct inode * inode = NULL;
+       struct inode *inode = NULL;
 
 repeat:
        hlist_for_each_entry(inode, node, head, i_hash) {
@@ -629,10 +642,10 @@ struct inode *new_inode(struct super_block *sb)
         * here to attempt to avoid that.
         */
        static unsigned int last_ino;
-       struct inode * inode;
+       struct inode *inode;
 
        spin_lock_prefetch(&inode_lock);
-       
+
        inode = alloc_inode(sb);
        if (inode) {
                spin_lock(&inode_lock);
@@ -643,7 +656,6 @@ struct inode *new_inode(struct super_block *sb)
        }
        return inode;
 }
-
 EXPORT_SYMBOL(new_inode);
 
 void unlock_new_inode(struct inode *inode)
@@ -672,7 +684,6 @@ void unlock_new_inode(struct inode *inode)
        inode->i_state &= ~(I_LOCK|I_NEW);
        wake_up_inode(inode);
 }
-
 EXPORT_SYMBOL(unlock_new_inode);
 
 /*
@@ -681,13 +692,17 @@ EXPORT_SYMBOL(unlock_new_inode);
  * We no longer cache the sb_flags in i_flags - see fs.h
  *     -- rmk@arm.uk.linux.org
  */
-static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
+static struct inode *get_new_inode(struct super_block *sb,
+                               struct hlist_head *head,
+                               int (*test)(struct inode *, void *),
+                               int (*set)(struct inode *, void *),
+                               void *data)
 {
-       struct inode * inode;
+       struct inode *inode;
 
        inode = alloc_inode(sb);
        if (inode) {
-               struct inode * old;
+               struct inode *old;
 
                spin_lock(&inode_lock);
                /* We released the lock, so.. */
@@ -729,13 +744,14 @@ set_failed:
  * get_new_inode_fast is the fast path version of get_new_inode, see the
  * comment at iget_locked for details.
  */
-static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_head *head, unsigned long ino)
+static struct inode *get_new_inode_fast(struct super_block *sb,
+                               struct hlist_head *head, unsigned long ino)
 {
-       struct inode * inode;
+       struct inode *inode;
 
        inode = alloc_inode(sb);
        if (inode) {
-               struct inode * old;
+               struct inode *old;
 
                spin_lock(&inode_lock);
                /* We released the lock, so.. */
@@ -821,7 +837,6 @@ struct inode *igrab(struct inode *inode)
        spin_unlock(&inode_lock);
        return inode;
 }
-
 EXPORT_SYMBOL(igrab);
 
 /**
@@ -922,7 +937,6 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
 
        return ifind(sb, head, test, data, 0);
 }
-
 EXPORT_SYMBOL(ilookup5_nowait);
 
 /**
@@ -951,7 +965,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
 
        return ifind(sb, head, test, data, 1);
 }
-
 EXPORT_SYMBOL(ilookup5);
 
 /**
@@ -974,7 +987,6 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
 
        return ifind_fast(sb, head, ino);
 }
-
 EXPORT_SYMBOL(ilookup);
 
 /**
@@ -1013,7 +1025,6 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
         */
        return get_new_inode(sb, head, test, set, data);
 }
-
 EXPORT_SYMBOL(iget5_locked);
 
 /**
@@ -1045,7 +1056,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
         */
        return get_new_inode_fast(sb, head, ino);
 }
-
 EXPORT_SYMBOL(iget_locked);
 
 int insert_inode_locked(struct inode *inode)
@@ -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;
@@ -1074,7 +1093,6 @@ int insert_inode_locked(struct inode *inode)
                iput(old);
        }
 }
-
 EXPORT_SYMBOL(insert_inode_locked);
 
 int insert_inode_locked4(struct inode *inode, unsigned long hashval,
@@ -1082,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;
@@ -1104,7 +1132,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
                iput(old);
        }
 }
-
 EXPORT_SYMBOL(insert_inode_locked4);
 
 /**
@@ -1122,7 +1149,6 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
        hlist_add_head(&inode->i_hash, head);
        spin_unlock(&inode_lock);
 }
-
 EXPORT_SYMBOL(__insert_inode_hash);
 
 /**
@@ -1137,7 +1163,6 @@ void remove_inode_hash(struct inode *inode)
        hlist_del_init(&inode->i_hash);
        spin_unlock(&inode_lock);
 }
-
 EXPORT_SYMBOL(remove_inode_hash);
 
 /*
@@ -1168,7 +1193,7 @@ void generic_delete_inode(struct inode *inode)
        if (op->delete_inode) {
                void (*delete)(struct inode *) = op->delete_inode;
                if (!is_bad_inode(inode))
-                       DQUOT_INIT(inode);
+                       vfs_dq_init(inode);
                /* Filesystems implementing their own
                 * s_op->delete_inode are required to call
                 * truncate_inode_pages and clear_inode()
@@ -1185,7 +1210,6 @@ void generic_delete_inode(struct inode *inode)
        BUG_ON(inode->i_state != I_CLEAR);
        destroy_inode(inode);
 }
-
 EXPORT_SYMBOL(generic_delete_inode);
 
 static void generic_forget_inode(struct inode *inode)
@@ -1235,12 +1259,11 @@ void generic_drop_inode(struct inode *inode)
        else
                generic_forget_inode(inode);
 }
-
 EXPORT_SYMBOL_GPL(generic_drop_inode);
 
 /*
  * Called when we're dropping the last reference
- * to an inode. 
+ * to an inode.
  *
  * Call the FS "drop()" function, defaulting to
  * the legacy UNIX filesystem behaviour..
@@ -1260,7 +1283,7 @@ static inline void iput_final(struct inode *inode)
 }
 
 /**
- *     iput    - put an inode 
+ *     iput    - put an inode
  *     @inode: inode to put
  *
  *     Puts an inode, dropping its usage count. If the inode use count hits
@@ -1277,7 +1300,6 @@ void iput(struct inode *inode)
                        iput_final(inode);
        }
 }
-
 EXPORT_SYMBOL(iput);
 
 /**
@@ -1288,10 +1310,10 @@ EXPORT_SYMBOL(iput);
  *     Returns the block number on the device holding the inode that
  *     is the disk block number for the block of the file requested.
  *     That is, asked for block 4 of inode 1 the function will return the
- *     disk block relative to the disk start that holds that block of the 
+ *     disk block relative to the disk start that holds that block of the
  *     file.
  */
-sector_t bmap(struct inode * inode, sector_t block)
+sector_t bmap(struct inode *inode, sector_t block)
 {
        sector_t res = 0;
        if (inode->i_mapping->a_ops->bmap)
@@ -1300,6 +1322,40 @@ sector_t bmap(struct inode * inode, sector_t block)
 }
 EXPORT_SYMBOL(bmap);
 
+/*
+ * With relative atime, only update atime if the previous atime is
+ * earlier than either the ctime or mtime or if at least a day has
+ * passed since the last atime update.
+ */
+static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
+                            struct timespec now)
+{
+
+       if (!(mnt->mnt_flags & MNT_RELATIME))
+               return 1;
+       /*
+        * Is mtime younger than atime? If yes, update atime:
+        */
+       if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
+               return 1;
+       /*
+        * Is ctime younger than atime? If yes, update atime:
+        */
+       if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
+               return 1;
+
+       /*
+        * Is the previous atime value older than a day? If yes,
+        * update atime:
+        */
+       if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
+               return 1;
+       /*
+        * Good, we can skip the atime update:
+        */
+       return 0;
+}
+
 /**
  *     touch_atime     -       update the access time
  *     @mnt: mount the inode is accessed on
@@ -1327,17 +1383,12 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
                goto out;
        if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
                goto out;
-       if (mnt->mnt_flags & MNT_RELATIME) {
-               /*
-                * With relative atime, only update atime if the previous
-                * atime is earlier than either the ctime or mtime.
-                */
-               if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 &&
-                   timespec_compare(&inode->i_ctime, &inode->i_atime) < 0)
-                       goto out;
-       }
 
        now = current_fs_time(inode->i_sb);
+
+       if (!relatime_need_update(mnt, inode, now))
+               goto out;
+
        if (timespec_equal(&inode->i_atime, &now))
                goto out;
 
@@ -1394,7 +1445,6 @@ void file_update_time(struct file *file)
                mark_inode_dirty_sync(inode);
        mnt_drop_write(file->f_path.mnt);
 }
-
 EXPORT_SYMBOL(file_update_time);
 
 int inode_needs_sync(struct inode *inode)
@@ -1405,7 +1455,6 @@ int inode_needs_sync(struct inode *inode)
                return 1;
        return 0;
 }
-
 EXPORT_SYMBOL(inode_needs_sync);
 
 int inode_wait(void *word)
@@ -1439,42 +1488,6 @@ static void __wait_on_freeing_inode(struct inode *inode)
        spin_lock(&inode_lock);
 }
 
-/*
- * We rarely want to lock two inodes that do not have a parent/child
- * relationship (such as directory, child inode) simultaneously. The
- * vast majority of file systems should be able to get along fine
- * without this. Do not use these functions except as a last resort.
- */
-void inode_double_lock(struct inode *inode1, struct inode *inode2)
-{
-       if (inode1 == NULL || inode2 == NULL || inode1 == inode2) {
-               if (inode1)
-                       mutex_lock(&inode1->i_mutex);
-               else if (inode2)
-                       mutex_lock(&inode2->i_mutex);
-               return;
-       }
-
-       if (inode1 < inode2) {
-               mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
-       } else {
-               mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
-       }
-}
-EXPORT_SYMBOL(inode_double_lock);
-
-void inode_double_unlock(struct inode *inode1, struct inode *inode2)
-{
-       if (inode1)
-               mutex_unlock(&inode1->i_mutex);
-
-       if (inode2 && inode2 != inode1)
-               mutex_unlock(&inode2->i_mutex);
-}
-EXPORT_SYMBOL(inode_double_unlock);
-
 static __initdata unsigned long ihash_entries;
 static int __init set_ihash_entries(char *str)
 {