aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c73
1 files changed, 30 insertions, 43 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index d7bf38c8cd1c..aeb9d72ebf6e 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -25,13 +25,10 @@
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h" 27#include "xfs_dir2.h"
28#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
33#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 32#include "xfs_dinode.h"
36#include "xfs_inode.h" 33#include "xfs_inode.h"
37#include "xfs_btree.h" 34#include "xfs_btree.h"
@@ -268,10 +265,10 @@ xfs_sb_validate_fsb_count(
268 265
269#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ 266#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */
270 if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) 267 if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX)
271 return E2BIG; 268 return EFBIG;
272#else /* Limited by UINT_MAX of sectors */ 269#else /* Limited by UINT_MAX of sectors */
273 if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) 270 if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX)
274 return E2BIG; 271 return EFBIG;
275#endif 272#endif
276 return 0; 273 return 0;
277} 274}
@@ -393,7 +390,7 @@ xfs_mount_validate_sb(
393 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { 390 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
394 xfs_fs_mount_cmn_err(flags, 391 xfs_fs_mount_cmn_err(flags,
395 "file system too large to be mounted on this system."); 392 "file system too large to be mounted on this system.");
396 return XFS_ERROR(E2BIG); 393 return XFS_ERROR(EFBIG);
397 } 394 }
398 395
399 if (unlikely(sbp->sb_inprogress)) { 396 if (unlikely(sbp->sb_inprogress)) {
@@ -413,17 +410,6 @@ xfs_mount_validate_sb(
413 return 0; 410 return 0;
414} 411}
415 412
416STATIC void
417xfs_initialize_perag_icache(
418 xfs_perag_t *pag)
419{
420 if (!pag->pag_ici_init) {
421 rwlock_init(&pag->pag_ici_lock);
422 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
423 pag->pag_ici_init = 1;
424 }
425}
426
427int 413int
428xfs_initialize_perag( 414xfs_initialize_perag(
429 xfs_mount_t *mp, 415 xfs_mount_t *mp,
@@ -436,13 +422,8 @@ xfs_initialize_perag(
436 xfs_agino_t agino; 422 xfs_agino_t agino;
437 xfs_ino_t ino; 423 xfs_ino_t ino;
438 xfs_sb_t *sbp = &mp->m_sb; 424 xfs_sb_t *sbp = &mp->m_sb;
439 xfs_ino_t max_inum = XFS_MAXINUMBER_32;
440 int error = -ENOMEM; 425 int error = -ENOMEM;
441 426
442 /* Check to see if the filesystem can overflow 32 bit inodes */
443 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
444 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
445
446 /* 427 /*
447 * Walk the current per-ag tree so we don't try to initialise AGs 428 * Walk the current per-ag tree so we don't try to initialise AGs
448 * that already exist (growfs case). Allocate and insert all the 429 * that already exist (growfs case). Allocate and insert all the
@@ -456,11 +437,18 @@ xfs_initialize_perag(
456 } 437 }
457 if (!first_initialised) 438 if (!first_initialised)
458 first_initialised = index; 439 first_initialised = index;
440
459 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); 441 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
460 if (!pag) 442 if (!pag)
461 goto out_unwind; 443 goto out_unwind;
444 pag->pag_agno = index;
445 pag->pag_mount = mp;
446 rwlock_init(&pag->pag_ici_lock);
447 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
448
462 if (radix_tree_preload(GFP_NOFS)) 449 if (radix_tree_preload(GFP_NOFS))
463 goto out_unwind; 450 goto out_unwind;
451
464 spin_lock(&mp->m_perag_lock); 452 spin_lock(&mp->m_perag_lock);
465 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { 453 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
466 BUG(); 454 BUG();
@@ -469,25 +457,26 @@ xfs_initialize_perag(
469 error = -EEXIST; 457 error = -EEXIST;
470 goto out_unwind; 458 goto out_unwind;
471 } 459 }
472 pag->pag_agno = index;
473 pag->pag_mount = mp;
474 spin_unlock(&mp->m_perag_lock); 460 spin_unlock(&mp->m_perag_lock);
475 radix_tree_preload_end(); 461 radix_tree_preload_end();
476 } 462 }
477 463
478 /* Clear the mount flag if no inode can overflow 32 bits 464 /*
479 * on this filesystem, or if specifically requested.. 465 * If we mount with the inode64 option, or no inode overflows
466 * the legacy 32-bit address space clear the inode32 option.
480 */ 467 */
481 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { 468 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
469 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
470
471 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
482 mp->m_flags |= XFS_MOUNT_32BITINODES; 472 mp->m_flags |= XFS_MOUNT_32BITINODES;
483 } else { 473 else
484 mp->m_flags &= ~XFS_MOUNT_32BITINODES; 474 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
485 }
486 475
487 /* If we can overflow then setup the ag headers accordingly */
488 if (mp->m_flags & XFS_MOUNT_32BITINODES) { 476 if (mp->m_flags & XFS_MOUNT_32BITINODES) {
489 /* Calculate how much should be reserved for inodes to 477 /*
490 * meet the max inode percentage. 478 * Calculate how much should be reserved for inodes to meet
479 * the max inode percentage.
491 */ 480 */
492 if (mp->m_maxicount) { 481 if (mp->m_maxicount) {
493 __uint64_t icount; 482 __uint64_t icount;
@@ -500,30 +489,28 @@ xfs_initialize_perag(
500 } else { 489 } else {
501 max_metadata = agcount; 490 max_metadata = agcount;
502 } 491 }
492
503 for (index = 0; index < agcount; index++) { 493 for (index = 0; index < agcount; index++) {
504 ino = XFS_AGINO_TO_INO(mp, index, agino); 494 ino = XFS_AGINO_TO_INO(mp, index, agino);
505 if (ino > max_inum) { 495 if (ino > XFS_MAXINUMBER_32) {
506 index++; 496 index++;
507 break; 497 break;
508 } 498 }
509 499
510 /* This ag is preferred for inodes */
511 pag = xfs_perag_get(mp, index); 500 pag = xfs_perag_get(mp, index);
512 pag->pagi_inodeok = 1; 501 pag->pagi_inodeok = 1;
513 if (index < max_metadata) 502 if (index < max_metadata)
514 pag->pagf_metadata = 1; 503 pag->pagf_metadata = 1;
515 xfs_initialize_perag_icache(pag);
516 xfs_perag_put(pag); 504 xfs_perag_put(pag);
517 } 505 }
518 } else { 506 } else {
519 /* Setup default behavior for smaller filesystems */
520 for (index = 0; index < agcount; index++) { 507 for (index = 0; index < agcount; index++) {
521 pag = xfs_perag_get(mp, index); 508 pag = xfs_perag_get(mp, index);
522 pag->pagi_inodeok = 1; 509 pag->pagi_inodeok = 1;
523 xfs_initialize_perag_icache(pag);
524 xfs_perag_put(pag); 510 xfs_perag_put(pag);
525 } 511 }
526 } 512 }
513
527 if (maxagi) 514 if (maxagi)
528 *maxagi = index; 515 *maxagi = index;
529 return 0; 516 return 0;
@@ -1009,7 +996,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1009 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); 996 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
1010 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { 997 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
1011 cmn_err(CE_WARN, "XFS: size check 1 failed"); 998 cmn_err(CE_WARN, "XFS: size check 1 failed");
1012 return XFS_ERROR(E2BIG); 999 return XFS_ERROR(EFBIG);
1013 } 1000 }
1014 error = xfs_read_buf(mp, mp->m_ddev_targp, 1001 error = xfs_read_buf(mp, mp->m_ddev_targp,
1015 d - XFS_FSS_TO_BB(mp, 1), 1002 d - XFS_FSS_TO_BB(mp, 1),
@@ -1019,7 +1006,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1019 } else { 1006 } else {
1020 cmn_err(CE_WARN, "XFS: size check 2 failed"); 1007 cmn_err(CE_WARN, "XFS: size check 2 failed");
1021 if (error == ENOSPC) 1008 if (error == ENOSPC)
1022 error = XFS_ERROR(E2BIG); 1009 error = XFS_ERROR(EFBIG);
1023 return error; 1010 return error;
1024 } 1011 }
1025 1012
@@ -1027,7 +1014,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1027 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); 1014 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
1028 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { 1015 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
1029 cmn_err(CE_WARN, "XFS: size check 3 failed"); 1016 cmn_err(CE_WARN, "XFS: size check 3 failed");
1030 return XFS_ERROR(E2BIG); 1017 return XFS_ERROR(EFBIG);
1031 } 1018 }
1032 error = xfs_read_buf(mp, mp->m_logdev_targp, 1019 error = xfs_read_buf(mp, mp->m_logdev_targp,
1033 d - XFS_FSB_TO_BB(mp, 1), 1020 d - XFS_FSB_TO_BB(mp, 1),
@@ -1037,7 +1024,7 @@ xfs_check_sizes(xfs_mount_t *mp)
1037 } else { 1024 } else {
1038 cmn_err(CE_WARN, "XFS: size check 3 failed"); 1025 cmn_err(CE_WARN, "XFS: size check 3 failed");
1039 if (error == ENOSPC) 1026 if (error == ENOSPC)
1040 error = XFS_ERROR(E2BIG); 1027 error = XFS_ERROR(EFBIG);
1041 return error; 1028 return error;
1042 } 1029 }
1043 } 1030 }
@@ -1254,7 +1241,7 @@ xfs_mountfs(
1254 * Allocate and initialize the per-ag data. 1241 * Allocate and initialize the per-ag data.
1255 */ 1242 */
1256 spin_lock_init(&mp->m_perag_lock); 1243 spin_lock_init(&mp->m_perag_lock);
1257 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS); 1244 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
1258 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); 1245 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
1259 if (error) { 1246 if (error) {
1260 cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error); 1247 cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error);
@@ -1310,7 +1297,7 @@ xfs_mountfs(
1310 * Get and sanity-check the root inode. 1297 * Get and sanity-check the root inode.
1311 * Save the pointer to it in the mount structure. 1298 * Save the pointer to it in the mount structure.
1312 */ 1299 */
1313 error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); 1300 error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip);
1314 if (error) { 1301 if (error) {
1315 cmn_err(CE_WARN, "XFS: failed to read root inode"); 1302 cmn_err(CE_WARN, "XFS: failed to read root inode");
1316 goto out_log_dealloc; 1303 goto out_log_dealloc;