]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/xfs_iget.c
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / fs / xfs / xfs_iget.c
index b53854325266efb6e55f46cc26f0f6de0d481ce2..b73d216ecaf939aa4df49f8a89a6cff9e2fafd16 100644 (file)
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -52,7 +50,7 @@ void
 xfs_ihash_init(xfs_mount_t *mp)
 {
        __uint64_t      icount;
-       uint            i, flags = KM_SLEEP | KM_MAYFAIL;
+       uint            i;
 
        if (!mp->m_ihsize) {
                icount = mp->m_maxicount ? mp->m_maxicount :
@@ -63,14 +61,13 @@ xfs_ihash_init(xfs_mount_t *mp)
                                        (64 * NBPP) / sizeof(xfs_ihash_t));
        }
 
-       while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize *
-                                               sizeof(xfs_ihash_t), flags))) {
-               if ((mp->m_ihsize >>= 1) <= NBPP)
-                       flags = KM_SLEEP;
-       }
-       for (i = 0; i < mp->m_ihsize; i++) {
+       mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize,
+                                        NBPC * sizeof(xfs_ihash_t),
+                                        mp->m_ihsize * sizeof(xfs_ihash_t),
+                                        KM_SLEEP | KM_MAYFAIL | KM_LARGE);
+       mp->m_ihsize /= sizeof(xfs_ihash_t);
+       for (i = 0; i < mp->m_ihsize; i++)
                rwlock_init(&(mp->m_ihash[i].ih_lock));
-       }
 }
 
 /*
@@ -79,7 +76,7 @@ xfs_ihash_init(xfs_mount_t *mp)
 void
 xfs_ihash_free(xfs_mount_t *mp)
 {
-       kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t));
+       kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t));
        mp->m_ihash = NULL;
 }
 
@@ -97,7 +94,7 @@ xfs_chash_init(xfs_mount_t *mp)
        mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
        mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
                                                 * sizeof(xfs_chash_t),
-                                                KM_SLEEP);
+                                                KM_SLEEP | KM_LARGE);
        for (i = 0; i < mp->m_chsize; i++) {
                spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
        }
@@ -186,7 +183,7 @@ xfs_ihash_promote(
  */
 STATIC int
 xfs_iget_core(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        xfs_mount_t     *mp,
        xfs_trans_t     *tp,
        xfs_ino_t       ino,
@@ -198,7 +195,7 @@ xfs_iget_core(
        xfs_ihash_t     *ih;
        xfs_inode_t     *ip;
        xfs_inode_t     *iq;
-       vnode_t         *inode_vp;
+       bhv_vnode_t     *inode_vp;
        ulong           version;
        int             error;
        /* REFERENCED */
@@ -246,7 +243,9 @@ again:
 
                                XFS_STATS_INC(xs_ig_found);
 
+                               spin_lock(&ip->i_flags_lock);
                                ip->i_flags &= ~XFS_IRECLAIMABLE;
+                               spin_unlock(&ip->i_flags_lock);
                                version = ih->ih_version;
                                read_unlock(&ih->ih_lock);
                                xfs_ihash_promote(ih, ip, version);
@@ -292,15 +291,17 @@ again:
 
 finish_inode:
                        if (ip->i_d.di_mode == 0) {
-                               if (!(flags & IGET_CREATE))
+                               if (!(flags & XFS_IGET_CREATE))
                                        return ENOENT;
                                xfs_iocore_inode_reinit(ip);
                        }
-       
+
                        if (lock_flags != 0)
                                xfs_ilock(ip, lock_flags);
 
+                       spin_lock(&ip->i_flags_lock);
                        ip->i_flags &= ~XFS_ISTALE;
+                       spin_unlock(&ip->i_flags_lock);
 
                        vn_trace_exit(vp, "xfs_iget.found",
                                                (inst_t *)__return_address);
@@ -322,21 +323,20 @@ finish_inode:
         * Read the disk inode attributes into a new inode structure and get
         * a new vnode for it. This should also initialize i_ino and i_mount.
         */
-       error = xfs_iread(mp, tp, ino, &ip, bno);
-       if (error) {
+       error = xfs_iread(mp, tp, ino, &ip, bno,
+                         (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
+       if (error)
                return error;
-       }
 
        vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
 
        xfs_inode_lock_init(ip, vp);
        xfs_iocore_inode_init(ip);
 
-       if (lock_flags != 0) {
+       if (lock_flags)
                xfs_ilock(ip, lock_flags);
-       }
-               
-       if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) {
+
+       if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
                xfs_idestroy(ip);
                return ENOENT;
        }
@@ -371,7 +371,9 @@ finish_inode:
        ih->ih_next = ip;
        ip->i_udquot = ip->i_gdquot = NULL;
        ih->ih_version++;
+       spin_lock(&ip->i_flags_lock);
        ip->i_flags |= XFS_INEW;
+       spin_unlock(&ip->i_flags_lock);
 
        write_unlock(&ih->ih_lock);
 
@@ -468,7 +470,7 @@ finish_inode:
         * If we have a real type for an on-disk inode, we can set ops(&unlock)
         * now.  If it's a new inode being created, xfs_ialloc will handle it.
         */
-       VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
+       bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
 
        return 0;
 }
@@ -489,7 +491,7 @@ xfs_iget(
        xfs_daddr_t     bno)
 {
        struct inode    *inode;
-       vnode_t         *vp = NULL;
+       bhv_vnode_t     *vp = NULL;
        int             error;
 
        XFS_STATS_INC(xs_ig_attempts);
@@ -543,14 +545,14 @@ retry:
 void
 xfs_inode_lock_init(
        xfs_inode_t     *ip,
-       vnode_t         *vp)
+       bhv_vnode_t     *vp)
 {
        mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
                     "xfsino", (long)vp->v_number);
        mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number);
        init_waitqueue_head(&ip->i_ipin_wait);
        atomic_set(&ip->i_pincount, 0);
-       init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number);
+       initnsema(&ip->i_flock, 1, "xfsfino");
 }
 
 /*
@@ -603,12 +605,10 @@ void
 xfs_iput(xfs_inode_t   *ip,
         uint           lock_flags)
 {
-       vnode_t *vp = XFS_ITOV(ip);
+       bhv_vnode_t     *vp = XFS_ITOV(ip);
 
        vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
-
        xfs_iunlock(ip, lock_flags);
-
        VN_RELE(vp);
 }
 
@@ -619,7 +619,7 @@ void
 xfs_iput_new(xfs_inode_t       *ip,
             uint               lock_flags)
 {
-       vnode_t         *vp = XFS_ITOV(ip);
+       bhv_vnode_t     *vp = XFS_ITOV(ip);
        struct inode    *inode = vn_to_inode(vp);
 
        vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
@@ -645,7 +645,7 @@ xfs_iput_new(xfs_inode_t    *ip,
 void
 xfs_ireclaim(xfs_inode_t *ip)
 {
-       vnode_t         *vp;
+       bhv_vnode_t     *vp;
 
        /*
         * Remove from old hash list and mount list.
@@ -1033,6 +1033,6 @@ xfs_iflock_nowait(xfs_inode_t *ip)
 void
 xfs_ifunlock(xfs_inode_t *ip)
 {
-       ASSERT(valusema(&(ip->i_flock)) <= 0);
+       ASSERT(issemalocked(&(ip->i_flock)));
        vsema(&(ip->i_flock));
 }