diff options
author | Eric Sandeen <sandeen@sandeen.net> | 2008-04-09 22:19:34 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-10 02:25:26 -0400 |
commit | e6957ea48429aeda4f5d51af4238231d44b0dc4a (patch) | |
tree | 860c95c0e9446191262bb44ad436d38afb8cb7d6 /fs/xfs | |
parent | ee1c090825bf2f1cb9712489c234eabf69a9a78f (diff) |
[XFS] Ensure "both" features2 slots are consistent
Since older kernels may look in the sb_bad_features2 slot for flags,
rather than zeroing it out on fixup, we should make it equal to the
sb_features2 value.
Also, if the ATTR2 flag was not found prior to features2 fixup, it was not
set in the mount flags, so re-check after the fixup so that the current
session will use the feature.
Also fix up the comments to reflect these changes.
SGI-PV: 980085
SGI-Modid: xfs-linux-melb:xfs-kern:30778a
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_mount.c | 37 | ||||
-rw-r--r-- | fs/xfs/xfs_sb.h | 7 |
2 files changed, 29 insertions, 15 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 4e93c02faf24..8ed164eb9544 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -972,23 +972,35 @@ xfs_mountfs( | |||
972 | xfs_mount_common(mp, sbp); | 972 | xfs_mount_common(mp, sbp); |
973 | 973 | ||
974 | /* | 974 | /* |
975 | * Check for a bad features2 field alignment. This happened on | 975 | * Check for a mismatched features2 values. Older kernels |
976 | * some platforms due to xfs_sb_t not being 64bit size aligned | 976 | * read & wrote into the wrong sb offset for sb_features2 |
977 | * when sb_features was added and hence the compiler put it in | 977 | * on some platforms due to xfs_sb_t not being 64bit size aligned |
978 | * the wrong place. | 978 | * when sb_features2 was added, which made older superblock |
979 | * reading/writing routines swap it as a 64-bit value. | ||
979 | * | 980 | * |
980 | * If we detect a bad field, we or the set bits into the existing | 981 | * For backwards compatibility, we make both slots equal. |
981 | * features2 field in case it has already been modified and we | 982 | * |
982 | * don't want to lose any features. Zero the bad one and mark | 983 | * If we detect a mismatched field, we OR the set bits into the |
983 | * the two fields as needing updates once the transaction subsystem | 984 | * existing features2 field in case it has already been modified; we |
984 | * is online. | 985 | * don't want to lose any features. We then update the bad location |
986 | * with the ORed value so that older kernels will see any features2 | ||
987 | * flags, and mark the two fields as needing updates once the | ||
988 | * transaction subsystem is online. | ||
985 | */ | 989 | */ |
986 | if (xfs_sb_has_bad_features2(sbp)) { | 990 | if (xfs_sb_has_mismatched_features2(sbp)) { |
987 | cmn_err(CE_WARN, | 991 | cmn_err(CE_WARN, |
988 | "XFS: correcting sb_features alignment problem"); | 992 | "XFS: correcting sb_features alignment problem"); |
989 | sbp->sb_features2 |= sbp->sb_bad_features2; | 993 | sbp->sb_features2 |= sbp->sb_bad_features2; |
990 | sbp->sb_bad_features2 = 0; | 994 | sbp->sb_bad_features2 = sbp->sb_features2; |
991 | update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; | 995 | update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; |
996 | |||
997 | /* | ||
998 | * Re-check for ATTR2 in case it was found in bad_features2 | ||
999 | * slot. | ||
1000 | */ | ||
1001 | if (xfs_sb_version_hasattr2(&mp->m_sb)) | ||
1002 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
1003 | |||
992 | } | 1004 | } |
993 | 1005 | ||
994 | /* | 1006 | /* |
@@ -1896,7 +1908,8 @@ xfs_uuid_unmount( | |||
1896 | 1908 | ||
1897 | /* | 1909 | /* |
1898 | * Used to log changes to the superblock unit and width fields which could | 1910 | * Used to log changes to the superblock unit and width fields which could |
1899 | * be altered by the mount options. Only the first superblock is updated. | 1911 | * be altered by the mount options, as well as any potential sb_features2 |
1912 | * fixup. Only the first superblock is updated. | ||
1900 | */ | 1913 | */ |
1901 | STATIC void | 1914 | STATIC void |
1902 | xfs_mount_log_sb( | 1915 | xfs_mount_log_sb( |
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index b1a83f8ec044..d904efe7f871 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h | |||
@@ -320,11 +320,12 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp) | |||
320 | #endif /* __KERNEL__ */ | 320 | #endif /* __KERNEL__ */ |
321 | 321 | ||
322 | /* | 322 | /* |
323 | * Detect a bad features2 field | 323 | * Detect a mismatched features2 field. Older kernels read/wrote |
324 | * this into the wrong slot, so to be safe we keep them in sync. | ||
324 | */ | 325 | */ |
325 | static inline int xfs_sb_has_bad_features2(xfs_sb_t *sbp) | 326 | static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp) |
326 | { | 327 | { |
327 | return (sbp->sb_bad_features2 != 0); | 328 | return (sbp->sb_bad_features2 != sbp->sb_features2); |
328 | } | 329 | } |
329 | 330 | ||
330 | static inline unsigned xfs_sb_version_tonew(unsigned v) | 331 | static inline unsigned xfs_sb_version_tonew(unsigned v) |