diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 107 |
1 files changed, 23 insertions, 84 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index d3d38836f87f..4fa80e63eea2 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -408,11 +408,11 @@ xfs_update_alignment(xfs_mount_t *mp) | |||
408 | if (xfs_sb_version_hasdalign(sbp)) { | 408 | if (xfs_sb_version_hasdalign(sbp)) { |
409 | if (sbp->sb_unit != mp->m_dalign) { | 409 | if (sbp->sb_unit != mp->m_dalign) { |
410 | sbp->sb_unit = mp->m_dalign; | 410 | sbp->sb_unit = mp->m_dalign; |
411 | mp->m_update_flags |= XFS_SB_UNIT; | 411 | mp->m_update_sb = true; |
412 | } | 412 | } |
413 | if (sbp->sb_width != mp->m_swidth) { | 413 | if (sbp->sb_width != mp->m_swidth) { |
414 | sbp->sb_width = mp->m_swidth; | 414 | sbp->sb_width = mp->m_swidth; |
415 | mp->m_update_flags |= XFS_SB_WIDTH; | 415 | mp->m_update_sb = true; |
416 | } | 416 | } |
417 | } else { | 417 | } else { |
418 | xfs_warn(mp, | 418 | xfs_warn(mp, |
@@ -583,38 +583,19 @@ int | |||
583 | xfs_mount_reset_sbqflags( | 583 | xfs_mount_reset_sbqflags( |
584 | struct xfs_mount *mp) | 584 | struct xfs_mount *mp) |
585 | { | 585 | { |
586 | int error; | ||
587 | struct xfs_trans *tp; | ||
588 | |||
589 | mp->m_qflags = 0; | 586 | mp->m_qflags = 0; |
590 | 587 | ||
591 | /* | 588 | /* It is OK to look at sb_qflags in the mount path without m_sb_lock. */ |
592 | * It is OK to look at sb_qflags here in mount path, | ||
593 | * without m_sb_lock. | ||
594 | */ | ||
595 | if (mp->m_sb.sb_qflags == 0) | 589 | if (mp->m_sb.sb_qflags == 0) |
596 | return 0; | 590 | return 0; |
597 | spin_lock(&mp->m_sb_lock); | 591 | spin_lock(&mp->m_sb_lock); |
598 | mp->m_sb.sb_qflags = 0; | 592 | mp->m_sb.sb_qflags = 0; |
599 | spin_unlock(&mp->m_sb_lock); | 593 | spin_unlock(&mp->m_sb_lock); |
600 | 594 | ||
601 | /* | 595 | if (!xfs_fs_writable(mp, SB_FREEZE_WRITE)) |
602 | * If the fs is readonly, let the incore superblock run | ||
603 | * with quotas off but don't flush the update out to disk | ||
604 | */ | ||
605 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
606 | return 0; | 596 | return 0; |
607 | 597 | ||
608 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); | 598 | return xfs_sync_sb(mp, false); |
609 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0); | ||
610 | if (error) { | ||
611 | xfs_trans_cancel(tp, 0); | ||
612 | xfs_alert(mp, "%s: Superblock update failed!", __func__); | ||
613 | return error; | ||
614 | } | ||
615 | |||
616 | xfs_mod_sb(tp, XFS_SB_QFLAGS); | ||
617 | return xfs_trans_commit(tp, 0); | ||
618 | } | 599 | } |
619 | 600 | ||
620 | __uint64_t | 601 | __uint64_t |
@@ -659,26 +640,25 @@ xfs_mountfs( | |||
659 | xfs_sb_mount_common(mp, sbp); | 640 | xfs_sb_mount_common(mp, sbp); |
660 | 641 | ||
661 | /* | 642 | /* |
662 | * Check for a mismatched features2 values. Older kernels | 643 | * Check for a mismatched features2 values. Older kernels read & wrote |
663 | * read & wrote into the wrong sb offset for sb_features2 | 644 | * into the wrong sb offset for sb_features2 on some platforms due to |
664 | * on some platforms due to xfs_sb_t not being 64bit size aligned | 645 | * xfs_sb_t not being 64bit size aligned when sb_features2 was added, |
665 | * when sb_features2 was added, which made older superblock | 646 | * which made older superblock reading/writing routines swap it as a |
666 | * reading/writing routines swap it as a 64-bit value. | 647 | * 64-bit value. |
667 | * | 648 | * |
668 | * For backwards compatibility, we make both slots equal. | 649 | * For backwards compatibility, we make both slots equal. |
669 | * | 650 | * |
670 | * If we detect a mismatched field, we OR the set bits into the | 651 | * If we detect a mismatched field, we OR the set bits into the existing |
671 | * existing features2 field in case it has already been modified; we | 652 | * features2 field in case it has already been modified; we don't want |
672 | * don't want to lose any features. We then update the bad location | 653 | * to lose any features. We then update the bad location with the ORed |
673 | * with the ORed value so that older kernels will see any features2 | 654 | * value so that older kernels will see any features2 flags. The |
674 | * flags, and mark the two fields as needing updates once the | 655 | * superblock writeback code ensures the new sb_features2 is copied to |
675 | * transaction subsystem is online. | 656 | * sb_bad_features2 before it is logged or written to disk. |
676 | */ | 657 | */ |
677 | if (xfs_sb_has_mismatched_features2(sbp)) { | 658 | if (xfs_sb_has_mismatched_features2(sbp)) { |
678 | xfs_warn(mp, "correcting sb_features alignment problem"); | 659 | xfs_warn(mp, "correcting sb_features alignment problem"); |
679 | sbp->sb_features2 |= sbp->sb_bad_features2; | 660 | sbp->sb_features2 |= sbp->sb_bad_features2; |
680 | sbp->sb_bad_features2 = sbp->sb_features2; | 661 | mp->m_update_sb = true; |
681 | mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; | ||
682 | 662 | ||
683 | /* | 663 | /* |
684 | * Re-check for ATTR2 in case it was found in bad_features2 | 664 | * Re-check for ATTR2 in case it was found in bad_features2 |
@@ -692,17 +672,17 @@ xfs_mountfs( | |||
692 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | 672 | if (xfs_sb_version_hasattr2(&mp->m_sb) && |
693 | (mp->m_flags & XFS_MOUNT_NOATTR2)) { | 673 | (mp->m_flags & XFS_MOUNT_NOATTR2)) { |
694 | xfs_sb_version_removeattr2(&mp->m_sb); | 674 | xfs_sb_version_removeattr2(&mp->m_sb); |
695 | mp->m_update_flags |= XFS_SB_FEATURES2; | 675 | mp->m_update_sb = true; |
696 | 676 | ||
697 | /* update sb_versionnum for the clearing of the morebits */ | 677 | /* update sb_versionnum for the clearing of the morebits */ |
698 | if (!sbp->sb_features2) | 678 | if (!sbp->sb_features2) |
699 | mp->m_update_flags |= XFS_SB_VERSIONNUM; | 679 | mp->m_update_sb = true; |
700 | } | 680 | } |
701 | 681 | ||
702 | /* always use v2 inodes by default now */ | 682 | /* always use v2 inodes by default now */ |
703 | if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) { | 683 | if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) { |
704 | mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT; | 684 | mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT; |
705 | mp->m_update_flags |= XFS_SB_VERSIONNUM; | 685 | mp->m_update_sb = true; |
706 | } | 686 | } |
707 | 687 | ||
708 | /* | 688 | /* |
@@ -895,8 +875,8 @@ xfs_mountfs( | |||
895 | * the next remount into writeable mode. Otherwise we would never | 875 | * the next remount into writeable mode. Otherwise we would never |
896 | * perform the update e.g. for the root filesystem. | 876 | * perform the update e.g. for the root filesystem. |
897 | */ | 877 | */ |
898 | if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { | 878 | if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
899 | error = xfs_mount_log_sb(mp, mp->m_update_flags); | 879 | error = xfs_sync_sb(mp, false); |
900 | if (error) { | 880 | if (error) { |
901 | xfs_warn(mp, "failed to write sb changes"); | 881 | xfs_warn(mp, "failed to write sb changes"); |
902 | goto out_rtunmount; | 882 | goto out_rtunmount; |
@@ -1103,9 +1083,6 @@ xfs_fs_writable( | |||
1103 | int | 1083 | int |
1104 | xfs_log_sbcount(xfs_mount_t *mp) | 1084 | xfs_log_sbcount(xfs_mount_t *mp) |
1105 | { | 1085 | { |
1106 | xfs_trans_t *tp; | ||
1107 | int error; | ||
1108 | |||
1109 | /* allow this to proceed during the freeze sequence... */ | 1086 | /* allow this to proceed during the freeze sequence... */ |
1110 | if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE)) | 1087 | if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE)) |
1111 | return 0; | 1088 | return 0; |
@@ -1119,17 +1096,7 @@ xfs_log_sbcount(xfs_mount_t *mp) | |||
1119 | if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) | 1096 | if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) |
1120 | return 0; | 1097 | return 0; |
1121 | 1098 | ||
1122 | tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); | 1099 | return xfs_sync_sb(mp, true); |
1123 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); | ||
1124 | if (error) { | ||
1125 | xfs_trans_cancel(tp, 0); | ||
1126 | return error; | ||
1127 | } | ||
1128 | |||
1129 | xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); | ||
1130 | xfs_trans_set_sync(tp); | ||
1131 | error = xfs_trans_commit(tp, 0); | ||
1132 | return error; | ||
1133 | } | 1100 | } |
1134 | 1101 | ||
1135 | /* | 1102 | /* |
@@ -1423,34 +1390,6 @@ xfs_freesb( | |||
1423 | } | 1390 | } |
1424 | 1391 | ||
1425 | /* | 1392 | /* |
1426 | * Used to log changes to the superblock unit and width fields which could | ||
1427 | * be altered by the mount options, as well as any potential sb_features2 | ||
1428 | * fixup. Only the first superblock is updated. | ||
1429 | */ | ||
1430 | int | ||
1431 | xfs_mount_log_sb( | ||
1432 | xfs_mount_t *mp, | ||
1433 | __int64_t fields) | ||
1434 | { | ||
1435 | xfs_trans_t *tp; | ||
1436 | int error; | ||
1437 | |||
1438 | ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | | ||
1439 | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2 | | ||
1440 | XFS_SB_VERSIONNUM)); | ||
1441 | |||
1442 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); | ||
1443 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); | ||
1444 | if (error) { | ||
1445 | xfs_trans_cancel(tp, 0); | ||
1446 | return error; | ||
1447 | } | ||
1448 | xfs_mod_sb(tp, fields); | ||
1449 | error = xfs_trans_commit(tp, 0); | ||
1450 | return error; | ||
1451 | } | ||
1452 | |||
1453 | /* | ||
1454 | * If the underlying (data/log/rt) device is readonly, there are some | 1393 | * If the underlying (data/log/rt) device is readonly, there are some |
1455 | * operations that cannot proceed. | 1394 | * operations that cannot proceed. |
1456 | */ | 1395 | */ |