slub: Move node determination out of hotpath
[pandora-kernel.git] / fs / inode.c
index 239fdc0..5f4e11a 100644 (file)
  *   sb->s_inodes, inode->i_sb_list
  * inode_wb_list_lock protects:
  *   bdi->wb.b_{dirty,io,more_io}, inode->i_wb_list
+ * inode_hash_lock protects:
+ *   inode_hashtable, inode->i_hash
  *
  * Lock ordering:
- * inode_lock
- *   inode->i_lock
  *
  * inode_sb_list_lock
  *   inode->i_lock
  *
  * inode_wb_list_lock
  *   inode->i_lock
+ *
+ * inode_hash_lock
+ *   inode_sb_list_lock
+ *   inode->i_lock
+ *
+ * iunique_lock
+ *   inode_hash_lock
  */
 
 /*
@@ -85,6 +92,8 @@
 
 static unsigned int i_hash_mask __read_mostly;
 static unsigned int i_hash_shift __read_mostly;
+static struct hlist_head *inode_hashtable __read_mostly;
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
 
 /*
  * Each inode can be on two separate lists. One is
@@ -100,15 +109,6 @@ static unsigned int i_hash_shift __read_mostly;
 
 static LIST_HEAD(inode_lru);
 static DEFINE_SPINLOCK(inode_lru_lock);
-static struct hlist_head *inode_hashtable __read_mostly;
-
-/*
- * A simple spinlock to protect the list manipulations.
- *
- * NOTE! You also have to own the lock if you change
- * the i_state of an inode while it is in use..
- */
-DEFINE_SPINLOCK(inode_lock);
 
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_wb_list_lock);
@@ -433,11 +433,11 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
 {
        struct hlist_head *b = inode_hashtable + hash(inode->i_sb, hashval);
 
-       spin_lock(&inode_lock);
+       spin_lock(&inode_hash_lock);
        spin_lock(&inode->i_lock);
        hlist_add_head(&inode->i_hash, b);
        spin_unlock(&inode->i_lock);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_hash_lock);
 }
 EXPORT_SYMBOL(__insert_inode_hash);
 
@@ -449,11 +449,11 @@ EXPORT_SYMBOL(__insert_inode_hash);
  */
 void remove_inode_hash(struct inode *inode)
 {
-       spin_lock(&inode_lock);
+       spin_lock(&inode_hash_lock);
        spin_lock(&inode->i_lock);
        hlist_del_init(&inode->i_hash);
        spin_unlock(&inode->i_lock);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_hash_lock);
 }
 EXPORT_SYMBOL(remove_inode_hash);
 
@@ -778,11 +778,15 @@ static struct inode *find_inode(struct super_block *sb,
 
 repeat:
        hlist_for_each_entry(inode, node, head, i_hash) {
-               if (inode->i_sb != sb)
+               spin_lock(&inode->i_lock);
+               if (inode->i_sb != sb) {
+                       spin_unlock(&inode->i_lock);
                        continue;
-               if (!test(inode, data))
+               }
+               if (!test(inode, data)) {
+                       spin_unlock(&inode->i_lock);
                        continue;
-               spin_lock(&inode->i_lock);
+               }
                if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
                        __wait_on_freeing_inode(inode);
                        goto repeat;
@@ -806,11 +810,15 @@ static struct inode *find_inode_fast(struct super_block *sb,
 
 repeat:
        hlist_for_each_entry(inode, node, head, i_hash) {
-               if (inode->i_ino != ino)
+               spin_lock(&inode->i_lock);
+               if (inode->i_ino != ino) {
+                       spin_unlock(&inode->i_lock);
                        continue;
-               if (inode->i_sb != sb)
+               }
+               if (inode->i_sb != sb) {
+                       spin_unlock(&inode->i_lock);
                        continue;
-               spin_lock(&inode->i_lock);
+               }
                if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
                        __wait_on_freeing_inode(inode);
                        goto repeat;
@@ -923,25 +931,47 @@ void unlock_new_inode(struct inode *inode)
 }
 EXPORT_SYMBOL(unlock_new_inode);
 
-/*
- * This is called without the inode lock held.. Be careful.
+/**
+ * iget5_locked - obtain an inode from a mounted file system
+ * @sb:                super block of file system
+ * @hashval:   hash value (usually inode number) to get
+ * @test:      callback used for comparisons between inodes
+ * @set:       callback used to initialize a new struct inode
+ * @data:      opaque data pointer to pass to @test and @set
+ *
+ * Search for the inode specified by @hashval and @data in the inode cache,
+ * and if present it is return it with an increased reference count. This is
+ * a generalized version of iget_locked() for file systems where the inode
+ * number is not sufficient for unique identification of an inode.
+ *
+ * If the inode is not in cache, allocate a new inode and return it locked,
+ * hashed, and with the I_NEW flag set. The file system gets to fill it in
+ * before unlocking it via unlock_new_inode().
  *
- * We no longer cache the sb_flags in i_flags - see fs.h
- *     -- rmk@arm.uk.linux.org
+ * Note both @test and @set are called with the inode_hash_lock held, so can't
+ * sleep.
  */
-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 *iget5_locked(struct super_block *sb, unsigned long hashval,
+               int (*test)(struct inode *, void *),
+               int (*set)(struct inode *, void *), void *data)
 {
+       struct hlist_head *head = inode_hashtable + hash(sb, hashval);
        struct inode *inode;
 
+       spin_lock(&inode_hash_lock);
+       inode = find_inode(sb, head, test, data);
+       spin_unlock(&inode_hash_lock);
+
+       if (inode) {
+               wait_on_inode(inode);
+               return inode;
+       }
+
        inode = alloc_inode(sb);
        if (inode) {
                struct inode *old;
 
-               spin_lock(&inode_lock);
+               spin_lock(&inode_hash_lock);
                /* We released the lock, so.. */
                old = find_inode(sb, head, test, data);
                if (!old) {
@@ -953,7 +983,7 @@ static struct inode *get_new_inode(struct super_block *sb,
                        hlist_add_head(&inode->i_hash, head);
                        spin_unlock(&inode->i_lock);
                        inode_sb_list_add(inode);
-                       spin_unlock(&inode_lock);
+                       spin_unlock(&inode_hash_lock);
 
                        /* Return the locked inode with I_NEW set, the
                         * caller is responsible for filling in the contents
@@ -966,7 +996,7 @@ static struct inode *get_new_inode(struct super_block *sb,
                 * us. Use the old inode instead of the one we just
                 * allocated.
                 */
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_hash_lock);
                destroy_inode(inode);
                inode = old;
                wait_on_inode(inode);
@@ -974,25 +1004,43 @@ static struct inode *get_new_inode(struct super_block *sb,
        return inode;
 
 set_failed:
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_hash_lock);
        destroy_inode(inode);
        return NULL;
 }
+EXPORT_SYMBOL(iget5_locked);
 
-/*
- * get_new_inode_fast is the fast path version of get_new_inode, see the
- * comment at iget_locked for details.
+/**
+ * iget_locked - obtain an inode from a mounted file system
+ * @sb:                super block of file system
+ * @ino:       inode number to get
+ *
+ * Search for the inode specified by @ino in the inode cache and if present
+ * return it with an increased reference count. This is for file systems
+ * where the inode number is sufficient for unique identification of an inode.
+ *
+ * If the inode is not in cache, allocate a new inode and return it locked,
+ * hashed, and with the I_NEW flag set.  The file system gets to fill it in
+ * before unlocking it via unlock_new_inode().
  */
-static struct inode *get_new_inode_fast(struct super_block *sb,
-                               struct hlist_head *head, unsigned long ino)
+struct inode *iget_locked(struct super_block *sb, unsigned long ino)
 {
+       struct hlist_head *head = inode_hashtable + hash(sb, ino);
        struct inode *inode;
 
+       spin_lock(&inode_hash_lock);
+       inode = find_inode_fast(sb, head, ino);
+       spin_unlock(&inode_hash_lock);
+       if (inode) {
+               wait_on_inode(inode);
+               return inode;
+       }
+
        inode = alloc_inode(sb);
        if (inode) {
                struct inode *old;
 
-               spin_lock(&inode_lock);
+               spin_lock(&inode_hash_lock);
                /* We released the lock, so.. */
                old = find_inode_fast(sb, head, ino);
                if (!old) {
@@ -1002,7 +1050,7 @@ static struct inode *get_new_inode_fast(struct super_block *sb,
                        hlist_add_head(&inode->i_hash, head);
                        spin_unlock(&inode->i_lock);
                        inode_sb_list_add(inode);
-                       spin_unlock(&inode_lock);
+                       spin_unlock(&inode_hash_lock);
 
                        /* Return the locked inode with I_NEW set, the
                         * caller is responsible for filling in the contents
@@ -1015,13 +1063,14 @@ static struct inode *get_new_inode_fast(struct super_block *sb,
                 * us. Use the old inode instead of the one we just
                 * allocated.
                 */
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_hash_lock);
                destroy_inode(inode);
                inode = old;
                wait_on_inode(inode);
        }
        return inode;
 }
+EXPORT_SYMBOL(iget_locked);
 
 /*
  * search the inode cache for a matching inode number.
@@ -1036,10 +1085,14 @@ static int test_inode_iunique(struct super_block *sb, unsigned long ino)
        struct hlist_node *node;
        struct inode *inode;
 
+       spin_lock(&inode_hash_lock);
        hlist_for_each_entry(inode, node, b, i_hash) {
-               if (inode->i_ino == ino && inode->i_sb == sb)
+               if (inode->i_ino == ino && inode->i_sb == sb) {
+                       spin_unlock(&inode_hash_lock);
                        return 0;
+               }
        }
+       spin_unlock(&inode_hash_lock);
 
        return 1;
 }
@@ -1069,7 +1122,6 @@ ino_t iunique(struct super_block *sb, ino_t max_reserved)
        static unsigned int counter;
        ino_t res;
 
-       spin_lock(&inode_lock);
        spin_lock(&iunique_lock);
        do {
                if (counter <= max_reserved)
@@ -1077,7 +1129,6 @@ ino_t iunique(struct super_block *sb, ino_t max_reserved)
                res = counter++;
        } while (!test_inode_iunique(sb, res));
        spin_unlock(&iunique_lock);
-       spin_unlock(&inode_lock);
 
        return res;
 }
@@ -1102,74 +1153,6 @@ struct inode *igrab(struct inode *inode)
 }
 EXPORT_SYMBOL(igrab);
 
-/**
- * ifind - internal function, you want ilookup5() or iget5().
- * @sb:                super block of file system to search
- * @head:       the head of the list to search
- * @test:      callback used for comparisons between inodes
- * @data:      opaque data pointer to pass to @test
- * @wait:      if true wait for the inode to be unlocked, if false do not
- *
- * ifind() searches for the inode specified by @data in the inode
- * cache. This is a generalized version of ifind_fast() for file systems where
- * the inode number is not sufficient for unique identification of an inode.
- *
- * If the inode is in the cache, the inode is returned with an incremented
- * reference count.
- *
- * Otherwise NULL is returned.
- *
- * Note, @test is called with the inode_lock held, so can't sleep.
- */
-static struct inode *ifind(struct super_block *sb,
-               struct hlist_head *head, int (*test)(struct inode *, void *),
-               void *data, const int wait)
-{
-       struct inode *inode;
-
-       spin_lock(&inode_lock);
-       inode = find_inode(sb, head, test, data);
-       if (inode) {
-               spin_unlock(&inode_lock);
-               if (likely(wait))
-                       wait_on_inode(inode);
-               return inode;
-       }
-       spin_unlock(&inode_lock);
-       return NULL;
-}
-
-/**
- * ifind_fast - internal function, you want ilookup() or iget().
- * @sb:                super block of file system to search
- * @head:       head of the list to search
- * @ino:       inode number to search for
- *
- * ifind_fast() searches for the inode @ino in the inode cache. This is for
- * file systems where the inode number is sufficient for unique identification
- * of an inode.
- *
- * If the inode is in the cache, the inode is returned with an incremented
- * reference count.
- *
- * Otherwise NULL is returned.
- */
-static struct inode *ifind_fast(struct super_block *sb,
-               struct hlist_head *head, unsigned long ino)
-{
-       struct inode *inode;
-
-       spin_lock(&inode_lock);
-       inode = find_inode_fast(sb, head, ino);
-       if (inode) {
-               spin_unlock(&inode_lock);
-               wait_on_inode(inode);
-               return inode;
-       }
-       spin_unlock(&inode_lock);
-       return NULL;
-}
-
 /**
  * ilookup5_nowait - search for an inode in the inode cache
  * @sb:                super block of file system to search
@@ -1177,26 +1160,26 @@ static struct inode *ifind_fast(struct super_block *sb,
  * @test:      callback used for comparisons between inodes
  * @data:      opaque data pointer to pass to @test
  *
- * ilookup5() uses ifind() to search for the inode specified by @hashval and
- * @data in the inode cache. This is a generalized version of ilookup() for
- * file systems where the inode number is not sufficient for unique
- * identification of an inode.
- *
+ * Search for the inode specified by @hashval and @data in the inode cache.
  * If the inode is in the cache, the inode is returned with an incremented
- * reference count.  Note, the inode lock is not waited upon so you have to be
- * very careful what you do with the returned inode.  You probably should be
- * using ilookup5() instead.
+ * reference count.
  *
- * Otherwise NULL is returned.
+ * Note: I_NEW is not waited upon so you have to be very careful what you do
+ * with the returned inode.  You probably should be using ilookup5() instead.
  *
- * Note, @test is called with the inode_lock held, so can't sleep.
+ * Note2: @test is called with the inode_hash_lock held, so can't sleep.
  */
 struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
                int (*test)(struct inode *, void *), void *data)
 {
        struct hlist_head *head = inode_hashtable + hash(sb, hashval);
+       struct inode *inode;
+
+       spin_lock(&inode_hash_lock);
+       inode = find_inode(sb, head, test, data);
+       spin_unlock(&inode_hash_lock);
 
-       return ifind(sb, head, test, data, 0);
+       return inode;
 }
 EXPORT_SYMBOL(ilookup5_nowait);
 
@@ -1207,24 +1190,24 @@ EXPORT_SYMBOL(ilookup5_nowait);
  * @test:      callback used for comparisons between inodes
  * @data:      opaque data pointer to pass to @test
  *
- * ilookup5() uses ifind() to search for the inode specified by @hashval and
- * @data in the inode cache. This is a generalized version of ilookup() for
- * file systems where the inode number is not sufficient for unique
- * identification of an inode.
- *
- * If the inode is in the cache, the inode lock is waited upon and the inode is
+ * Search for the inode specified by @hashval and @data in the inode cache,
+ * and if the inode is in the cache, return the inode with an incremented
+ * reference count.  Waits on I_NEW before returning the inode.
  * returned with an incremented reference count.
  *
- * Otherwise NULL is returned.
+ * This is a generalized version of ilookup() for file systems where the
+ * inode number is not sufficient for unique identification of an inode.
  *
- * Note, @test is called with the inode_lock held, so can't sleep.
+ * Note: @test is called with the inode_hash_lock held, so can't sleep.
  */
 struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
                int (*test)(struct inode *, void *), void *data)
 {
-       struct hlist_head *head = inode_hashtable + hash(sb, hashval);
+       struct inode *inode = ilookup5_nowait(sb, hashval, test, data);
 
-       return ifind(sb, head, test, data, 1);
+       if (inode)
+               wait_on_inode(inode);
+       return inode;
 }
 EXPORT_SYMBOL(ilookup5);
 
@@ -1233,91 +1216,23 @@ EXPORT_SYMBOL(ilookup5);
  * @sb:                super block of file system to search
  * @ino:       inode number to search for
  *
- * ilookup() uses ifind_fast() to search for the inode @ino in the inode cache.
- * This is for file systems where the inode number is sufficient for unique
- * identification of an inode.
- *
- * If the inode is in the cache, the inode is returned with an incremented
- * reference count.
- *
- * Otherwise NULL is returned.
+ * Search for the inode @ino in the inode cache, and if the inode is in the
+ * cache, the inode is returned with an incremented reference count.
  */
 struct inode *ilookup(struct super_block *sb, unsigned long ino)
 {
        struct hlist_head *head = inode_hashtable + hash(sb, ino);
-
-       return ifind_fast(sb, head, ino);
-}
-EXPORT_SYMBOL(ilookup);
-
-/**
- * iget5_locked - obtain an inode from a mounted file system
- * @sb:                super block of file system
- * @hashval:   hash value (usually inode number) to get
- * @test:      callback used for comparisons between inodes
- * @set:       callback used to initialize a new struct inode
- * @data:      opaque data pointer to pass to @test and @set
- *
- * 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
- * systems where the inode number is not sufficient for unique identification
- * of an inode.
- *
- * If the inode is not in cache, get_new_inode() is called to allocate a new
- * inode and this is returned locked, hashed, and with the I_NEW flag set. The
- * file system gets to fill it in before unlocking it via unlock_new_inode().
- *
- * Note both @test and @set are called with the inode_lock held, so can't sleep.
- */
-struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
-               int (*test)(struct inode *, void *),
-               int (*set)(struct inode *, void *), void *data)
-{
-       struct hlist_head *head = inode_hashtable + hash(sb, hashval);
        struct inode *inode;
 
-       inode = ifind(sb, head, test, data, 1);
-       if (inode)
-               return inode;
-       /*
-        * get_new_inode() will do the right thing, re-trying the search
-        * in case it had to block at any point.
-        */
-       return get_new_inode(sb, head, test, set, data);
-}
-EXPORT_SYMBOL(iget5_locked);
-
-/**
- * iget_locked - obtain an inode from a mounted file system
- * @sb:                super block of file system
- * @ino:       inode number to get
- *
- * 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
- * unique identification of an inode.
- *
- * If the inode is not in cache, get_new_inode_fast() is called to allocate a
- * new inode and this is returned locked, hashed, and with the I_NEW flag set.
- * The file system gets to fill it in before unlocking it via
- * unlock_new_inode().
- */
-struct inode *iget_locked(struct super_block *sb, unsigned long ino)
-{
-       struct hlist_head *head = inode_hashtable + hash(sb, ino);
-       struct inode *inode;
+       spin_lock(&inode_hash_lock);
+       inode = find_inode_fast(sb, head, ino);
+       spin_unlock(&inode_hash_lock);
 
-       inode = ifind_fast(sb, head, ino);
        if (inode)
-               return inode;
-       /*
-        * get_new_inode_fast() will do the right thing, re-trying the search
-        * in case it had to block at any point.
-        */
-       return get_new_inode_fast(sb, head, ino);
+               wait_on_inode(inode);
+       return inode;
 }
-EXPORT_SYMBOL(iget_locked);
+EXPORT_SYMBOL(ilookup);
 
 int insert_inode_locked(struct inode *inode)
 {
@@ -1328,7 +1243,7 @@ int insert_inode_locked(struct inode *inode)
        while (1) {
                struct hlist_node *node;
                struct inode *old = NULL;
-               spin_lock(&inode_lock);
+               spin_lock(&inode_hash_lock);
                hlist_for_each_entry(old, node, head, i_hash) {
                        if (old->i_ino != ino)
                                continue;
@@ -1346,12 +1261,12 @@ int insert_inode_locked(struct inode *inode)
                        inode->i_state |= I_NEW;
                        hlist_add_head(&inode->i_hash, head);
                        spin_unlock(&inode->i_lock);
-                       spin_unlock(&inode_lock);
+                       spin_unlock(&inode_hash_lock);
                        return 0;
                }
                __iget(old);
                spin_unlock(&old->i_lock);
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_hash_lock);
                wait_on_inode(old);
                if (unlikely(!inode_unhashed(old))) {
                        iput(old);
@@ -1372,7 +1287,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
                struct hlist_node *node;
                struct inode *old = NULL;
 
-               spin_lock(&inode_lock);
+               spin_lock(&inode_hash_lock);
                hlist_for_each_entry(old, node, head, i_hash) {
                        if (old->i_sb != sb)
                                continue;
@@ -1390,12 +1305,12 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
                        inode->i_state |= I_NEW;
                        hlist_add_head(&inode->i_hash, head);
                        spin_unlock(&inode->i_lock);
-                       spin_unlock(&inode_lock);
+                       spin_unlock(&inode_hash_lock);
                        return 0;
                }
                __iget(old);
                spin_unlock(&old->i_lock);
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_hash_lock);
                wait_on_inode(old);
                if (unlikely(!inode_unhashed(old))) {
                        iput(old);
@@ -1674,10 +1589,10 @@ static void __wait_on_freeing_inode(struct inode *inode)
        wq = bit_waitqueue(&inode->i_state, __I_NEW);
        prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
        spin_unlock(&inode->i_lock);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_hash_lock);
        schedule();
        finish_wait(wq, &wait.wait);
-       spin_lock(&inode_lock);
+       spin_lock(&inode_hash_lock);
 }
 
 static __initdata unsigned long ihash_entries;