aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 99bab1e372b1..4e93c02faf24 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -44,7 +44,7 @@
44#include "xfs_quota.h" 44#include "xfs_quota.h"
45#include "xfs_fsops.h" 45#include "xfs_fsops.h"
46 46
47STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); 47STATIC void xfs_mount_log_sb(xfs_mount_t *, __int64_t);
48STATIC int xfs_uuid_mount(xfs_mount_t *); 48STATIC int xfs_uuid_mount(xfs_mount_t *);
49STATIC void xfs_uuid_unmount(xfs_mount_t *mp); 49STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
50STATIC void xfs_unmountfs_wait(xfs_mount_t *); 50STATIC void xfs_unmountfs_wait(xfs_mount_t *);
@@ -119,6 +119,7 @@ static const struct {
119 { offsetof(xfs_sb_t, sb_logsectsize),0 }, 119 { offsetof(xfs_sb_t, sb_logsectsize),0 },
120 { offsetof(xfs_sb_t, sb_logsunit), 0 }, 120 { offsetof(xfs_sb_t, sb_logsunit), 0 },
121 { offsetof(xfs_sb_t, sb_features2), 0 }, 121 { offsetof(xfs_sb_t, sb_features2), 0 },
122 { offsetof(xfs_sb_t, sb_bad_features2), 0 },
122 { sizeof(xfs_sb_t), 0 } 123 { sizeof(xfs_sb_t), 0 }
123}; 124};
124 125
@@ -449,6 +450,7 @@ xfs_sb_from_disk(
449 to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); 450 to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
450 to->sb_logsunit = be32_to_cpu(from->sb_logsunit); 451 to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
451 to->sb_features2 = be32_to_cpu(from->sb_features2); 452 to->sb_features2 = be32_to_cpu(from->sb_features2);
453 to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
452} 454}
453 455
454/* 456/*
@@ -970,6 +972,26 @@ xfs_mountfs(
970 xfs_mount_common(mp, sbp); 972 xfs_mount_common(mp, sbp);
971 973
972 /* 974 /*
975 * Check for a bad features2 field alignment. This happened on
976 * some platforms due to xfs_sb_t not being 64bit size aligned
977 * when sb_features was added and hence the compiler put it in
978 * the wrong place.
979 *
980 * If we detect a bad field, we or the set bits into the existing
981 * features2 field in case it has already been modified and we
982 * don't want to lose any features. Zero the bad one and mark
983 * the two fields as needing updates once the transaction subsystem
984 * is online.
985 */
986 if (xfs_sb_has_bad_features2(sbp)) {
987 cmn_err(CE_WARN,
988 "XFS: correcting sb_features alignment problem");
989 sbp->sb_features2 |= sbp->sb_bad_features2;
990 sbp->sb_bad_features2 = 0;
991 update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
992 }
993
994 /*
973 * Check if sb_agblocks is aligned at stripe boundary 995 * Check if sb_agblocks is aligned at stripe boundary
974 * If sb_agblocks is NOT aligned turn off m_dalign since 996 * If sb_agblocks is NOT aligned turn off m_dalign since
975 * allocator alignment is within an ag, therefore ag has 997 * allocator alignment is within an ag, therefore ag has
@@ -1159,11 +1181,10 @@ xfs_mountfs(
1159 } 1181 }
1160 1182
1161 /* 1183 /*
1162 * If fs is not mounted readonly, then update the superblock 1184 * If fs is not mounted readonly, then update the superblock changes.
1163 * unit and width changes.
1164 */ 1185 */
1165 if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) 1186 if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY))
1166 xfs_mount_log_sbunit(mp, update_flags); 1187 xfs_mount_log_sb(mp, update_flags);
1167 1188
1168 /* 1189 /*
1169 * Initialise the XFS quota management subsystem for this mount 1190 * Initialise the XFS quota management subsystem for this mount
@@ -1878,13 +1899,14 @@ xfs_uuid_unmount(
1878 * be altered by the mount options. Only the first superblock is updated. 1899 * be altered by the mount options. Only the first superblock is updated.
1879 */ 1900 */
1880STATIC void 1901STATIC void
1881xfs_mount_log_sbunit( 1902xfs_mount_log_sb(
1882 xfs_mount_t *mp, 1903 xfs_mount_t *mp,
1883 __int64_t fields) 1904 __int64_t fields)
1884{ 1905{
1885 xfs_trans_t *tp; 1906 xfs_trans_t *tp;
1886 1907
1887 ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID)); 1908 ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
1909 XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2));
1888 1910
1889 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); 1911 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
1890 if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, 1912 if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,