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