Merge branch 'master' into for-linus
[safe/jmp/linux-2.6] / fs / xfs / xfs_mount.c
index d7bf38c..d59f4e8 100644 (file)
@@ -268,10 +268,10 @@ xfs_sb_validate_fsb_count(
 
 #if XFS_BIG_BLKNOS     /* Limited by ULONG_MAX of page cache index */
        if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX)
-               return E2BIG;
+               return EFBIG;
 #else                  /* Limited by UINT_MAX of sectors */
        if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX)
-               return E2BIG;
+               return EFBIG;
 #endif
        return 0;
 }
@@ -393,7 +393,7 @@ xfs_mount_validate_sb(
            xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
                xfs_fs_mount_cmn_err(flags,
                        "file system too large to be mounted on this system.");
-               return XFS_ERROR(E2BIG);
+               return XFS_ERROR(EFBIG);
        }
 
        if (unlikely(sbp->sb_inprogress)) {
@@ -413,17 +413,6 @@ xfs_mount_validate_sb(
        return 0;
 }
 
-STATIC void
-xfs_initialize_perag_icache(
-       xfs_perag_t     *pag)
-{
-       if (!pag->pag_ici_init) {
-               rwlock_init(&pag->pag_ici_lock);
-               INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
-               pag->pag_ici_init = 1;
-       }
-}
-
 int
 xfs_initialize_perag(
        xfs_mount_t     *mp,
@@ -436,13 +425,8 @@ xfs_initialize_perag(
        xfs_agino_t     agino;
        xfs_ino_t       ino;
        xfs_sb_t        *sbp = &mp->m_sb;
-       xfs_ino_t       max_inum = XFS_MAXINUMBER_32;
        int             error = -ENOMEM;
 
-       /* Check to see if the filesystem can overflow 32 bit inodes */
-       agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
-       ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
-
        /*
         * Walk the current per-ag tree so we don't try to initialise AGs
         * that already exist (growfs case). Allocate and insert all the
@@ -456,11 +440,18 @@ xfs_initialize_perag(
                }
                if (!first_initialised)
                        first_initialised = index;
+
                pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
                if (!pag)
                        goto out_unwind;
+               pag->pag_agno = index;
+               pag->pag_mount = mp;
+               rwlock_init(&pag->pag_ici_lock);
+               INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
+
                if (radix_tree_preload(GFP_NOFS))
                        goto out_unwind;
+
                spin_lock(&mp->m_perag_lock);
                if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
                        BUG();
@@ -469,25 +460,26 @@ xfs_initialize_perag(
                        error = -EEXIST;
                        goto out_unwind;
                }
-               pag->pag_agno = index;
-               pag->pag_mount = mp;
                spin_unlock(&mp->m_perag_lock);
                radix_tree_preload_end();
        }
 
-       /* Clear the mount flag if no inode can overflow 32 bits
-        * on this filesystem, or if specifically requested..
+       /*
+        * If we mount with the inode64 option, or no inode overflows
+        * the legacy 32-bit address space clear the inode32 option.
         */
-       if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) {
+       agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
+       ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
+
+       if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
                mp->m_flags |= XFS_MOUNT_32BITINODES;
-       } else {
+       else
                mp->m_flags &= ~XFS_MOUNT_32BITINODES;
-       }
 
-       /* If we can overflow then setup the ag headers accordingly */
        if (mp->m_flags & XFS_MOUNT_32BITINODES) {
-               /* Calculate how much should be reserved for inodes to
-                * meet the max inode percentage.
+               /*
+                * Calculate how much should be reserved for inodes to meet
+                * the max inode percentage.
                 */
                if (mp->m_maxicount) {
                        __uint64_t      icount;
@@ -500,30 +492,28 @@ xfs_initialize_perag(
                } else {
                        max_metadata = agcount;
                }
+
                for (index = 0; index < agcount; index++) {
                        ino = XFS_AGINO_TO_INO(mp, index, agino);
-                       if (ino > max_inum) {
+                       if (ino > XFS_MAXINUMBER_32) {
                                index++;
                                break;
                        }
 
-                       /* This ag is preferred for inodes */
                        pag = xfs_perag_get(mp, index);
                        pag->pagi_inodeok = 1;
                        if (index < max_metadata)
                                pag->pagf_metadata = 1;
-                       xfs_initialize_perag_icache(pag);
                        xfs_perag_put(pag);
                }
        } else {
-               /* Setup default behavior for smaller filesystems */
                for (index = 0; index < agcount; index++) {
                        pag = xfs_perag_get(mp, index);
                        pag->pagi_inodeok = 1;
-                       xfs_initialize_perag_icache(pag);
                        xfs_perag_put(pag);
                }
        }
+
        if (maxagi)
                *maxagi = index;
        return 0;
@@ -1009,7 +999,7 @@ xfs_check_sizes(xfs_mount_t *mp)
        d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
        if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
                cmn_err(CE_WARN, "XFS: size check 1 failed");
-               return XFS_ERROR(E2BIG);
+               return XFS_ERROR(EFBIG);
        }
        error = xfs_read_buf(mp, mp->m_ddev_targp,
                             d - XFS_FSS_TO_BB(mp, 1),
@@ -1019,7 +1009,7 @@ xfs_check_sizes(xfs_mount_t *mp)
        } else {
                cmn_err(CE_WARN, "XFS: size check 2 failed");
                if (error == ENOSPC)
-                       error = XFS_ERROR(E2BIG);
+                       error = XFS_ERROR(EFBIG);
                return error;
        }
 
@@ -1027,7 +1017,7 @@ xfs_check_sizes(xfs_mount_t *mp)
                d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
                if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
                        cmn_err(CE_WARN, "XFS: size check 3 failed");
-                       return XFS_ERROR(E2BIG);
+                       return XFS_ERROR(EFBIG);
                }
                error = xfs_read_buf(mp, mp->m_logdev_targp,
                                     d - XFS_FSB_TO_BB(mp, 1),
@@ -1037,7 +1027,7 @@ xfs_check_sizes(xfs_mount_t *mp)
                } else {
                        cmn_err(CE_WARN, "XFS: size check 3 failed");
                        if (error == ENOSPC)
-                               error = XFS_ERROR(E2BIG);
+                               error = XFS_ERROR(EFBIG);
                        return error;
                }
        }
@@ -1254,7 +1244,7 @@ xfs_mountfs(
         * Allocate and initialize the per-ag data.
         */
        spin_lock_init(&mp->m_perag_lock);
-       INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS);
+       INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
        error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
        if (error) {
                cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error);