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 | */ |
