Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[sfrench/cifs-2.6.git] / fs / inode.c
index f97de0aeb3b69dcd320668ccbf6bbeb6e9d57932..27ee1af50d02c6537febbaed5cf7bd60debc832d 100644 (file)
@@ -99,6 +99,15 @@ struct inodes_stat_t inodes_stat;
 
 static struct kmem_cache * inode_cachep __read_mostly;
 
+static void wake_up_inode(struct inode *inode)
+{
+       /*
+        * Prevent speculative execution through spin_unlock(&inode_lock);
+        */
+       smp_mb();
+       wake_up_bit(&inode->i_state, __I_LOCK);
+}
+
 static struct inode *alloc_inode(struct super_block *sb)
 {
        static const struct address_space_operations empty_aops;
@@ -215,7 +224,7 @@ void inode_init_once(struct inode *inode)
 
 EXPORT_SYMBOL(inode_init_once);
 
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
 {
        struct inode * inode = (struct inode *) foo;
 
@@ -232,7 +241,7 @@ void __iget(struct inode * inode)
                return;
        }
        atomic_inc(&inode->i_count);
-       if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+       if (!(inode->i_state & (I_DIRTY|I_SYNC)))
                list_move(&inode->i_list, &inode_in_use);
        inodes_stat.nr_unused--;
 }
@@ -253,7 +262,7 @@ void clear_inode(struct inode *inode)
        BUG_ON(inode->i_data.nrpages);
        BUG_ON(!(inode->i_state & I_FREEING));
        BUG_ON(inode->i_state & I_CLEAR);
-       wait_on_inode(inode);
+       inode_sync_wait(inode);
        DQUOT_DROP(inode);
        if (inode->i_sb->s_op->clear_inode)
                inode->i_sb->s_op->clear_inode(inode);
@@ -568,16 +577,16 @@ EXPORT_SYMBOL(new_inode);
 void unlock_new_inode(struct inode *inode)
 {
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-       struct file_system_type *type = inode->i_sb->s_type;
-       /*
-        * ensure nobody is actually holding i_mutex
-        */
-       mutex_destroy(&inode->i_mutex);
-       mutex_init(&inode->i_mutex);
-       if (inode->i_mode & S_IFDIR)
+       if (inode->i_mode & S_IFDIR) {
+               struct file_system_type *type = inode->i_sb->s_type;
+
+               /*
+                * ensure nobody is actually holding i_mutex
+                */
+               mutex_destroy(&inode->i_mutex);
+               mutex_init(&inode->i_mutex);
                lockdep_set_class(&inode->i_mutex, &type->i_mutex_dir_key);
-       else
-               lockdep_set_class(&inode->i_mutex, &type->i_mutex_key);
+       }
 #endif
        /*
         * This is special!  We do not need the spinlock
@@ -919,8 +928,6 @@ EXPORT_SYMBOL(ilookup);
  * @set:       callback used to initialize a new struct inode
  * @data:      opaque data pointer to pass to @test and @set
  *
- * This is iget() without the read_inode() portion of get_new_inode().
- *
  * iget5_locked() uses ifind() to search for the inode specified by @hashval
  * and @data in the inode cache and if present it is returned with an increased
  * reference count. This is a generalized version of iget_locked() for file
@@ -957,8 +964,6 @@ EXPORT_SYMBOL(iget5_locked);
  * @sb:                super block of file system
  * @ino:       inode number to get
  *
- * This is iget() without the read_inode() portion of get_new_inode_fast().
- *
  * iget_locked() uses ifind_fast() to search for the inode specified by @ino in
  * the inode cache and if present it is returned with an increased reference
  * count. This is for file systems where the inode number is sufficient for
@@ -1071,7 +1076,7 @@ static void generic_forget_inode(struct inode *inode)
        struct super_block *sb = inode->i_sb;
 
        if (!hlist_unhashed(&inode->i_hash)) {
-               if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+               if (!(inode->i_state & (I_DIRTY|I_SYNC)))
                        list_move(&inode->i_list, &inode_unused);
                inodes_stat.nr_unused++;
                if (sb->s_flags & MS_ACTIVE) {
@@ -1194,42 +1199,37 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
        struct inode *inode = dentry->d_inode;
        struct timespec now;
 
-       if (inode->i_flags & S_NOATIME)
+       if (mnt_want_write(mnt))
                return;
+       if (inode->i_flags & S_NOATIME)
+               goto out;
        if (IS_NOATIME(inode))
-               return;
+               goto out;
        if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))
-               return;
+               goto out;
 
-       /*
-        * We may have a NULL vfsmount when coming from NFSD
-        */
-       if (mnt) {
-               if (mnt->mnt_flags & MNT_NOATIME)
-                       return;
-               if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
-                       return;
-
-               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)
-                               return;
-               }
+       if (mnt->mnt_flags & MNT_NOATIME)
+               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 (timespec_equal(&inode->i_atime, &now))
-               return;
+               goto out;
 
        inode->i_atime = now;
        mark_inode_dirty_sync(inode);
+out:
+       mnt_drop_write(mnt);
 }
 EXPORT_SYMBOL(touch_atime);
 
@@ -1250,10 +1250,13 @@ void file_update_time(struct file *file)
        struct inode *inode = file->f_path.dentry->d_inode;
        struct timespec now;
        int sync_it = 0;
+       int err;
 
        if (IS_NOCMTIME(inode))
                return;
-       if (IS_RDONLY(inode))
+
+       err = mnt_want_write(file->f_path.mnt);
+       if (err)
                return;
 
        now = current_fs_time(inode->i_sb);
@@ -1267,8 +1270,14 @@ void file_update_time(struct file *file)
                sync_it = 1;
        }
 
+       if (IS_I_VERSION(inode)) {
+               inode_inc_iversion(inode);
+               sync_it = 1;
+       }
+
        if (sync_it)
                mark_inode_dirty_sync(inode);
+       mnt_drop_write(file->f_path.mnt);
 }
 
 EXPORT_SYMBOL(file_update_time);
@@ -1314,15 +1323,6 @@ static void __wait_on_freeing_inode(struct inode *inode)
        spin_lock(&inode_lock);
 }
 
-void wake_up_inode(struct inode *inode)
-{
-       /*
-        * Prevent speculative execution through spin_unlock(&inode_lock);
-        */
-       smp_mb();
-       wake_up_bit(&inode->i_state, __I_LOCK);
-}
-
 /*
  * We rarely want to lock two inodes that do not have a parent/child
  * relationship (such as directory, child inode) simultaneously. The
@@ -1396,7 +1396,7 @@ void __init inode_init_early(void)
                INIT_HLIST_HEAD(&inode_hashtable[loop]);
 }
 
-void __init inode_init(unsigned long mempages)
+void __init inode_init(void)
 {
        int loop;