diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 73 |
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 | ||
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 | 413 | int |
428 | xfs_initialize_perag( | 414 | xfs_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; |