This patch introduces a new mount flag: XFS_MOUNT_ALIGN that is set when custom alignment values are set, making easier to identify when user passes custom alignment options via mount command line. Then use this flag to bypass on-disk alignment checks. This is useful specifically for users which had filesystems created with wrong alignment provided by buggy storage, which, after commit fa4ca9c5574605, these filesystems won't be mountable anymore. But, using custom alignment settings, there is no need to check those values, once the alignment used will be the one provided during mount time, avoiding the issues in the allocator caused by bad alignment values anyway. This at least give a chance for users to remount their filesystems on newer kernels, without needing to reformat it. Signed-off-by: Carlos Maiolino <cmaiolino@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_sb.c | 30 +++++++++++++++++++----------- fs/xfs/xfs_mount.h | 2 ++ fs/xfs/xfs_super.c | 1 + 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 4df87546bd40..72dae95a5e4a 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -360,19 +360,27 @@ xfs_validate_sb_common( } } - if (sbp->sb_unit) { - if (!xfs_sb_version_hasdalign(sbp) || - sbp->sb_unit > sbp->sb_width || - (sbp->sb_width % sbp->sb_unit) != 0) { - xfs_notice(mp, "SB stripe unit sanity check failed"); + /* + * Ignore superblock alignment checks if sunit/swidth mount options + * were used or alignment turned off. + * The custom alignment validation will happen later on xfs_mountfs() + */ + if (!(mp->m_flags & XFS_MOUNT_ALIGN) && + !(mp->m_flags & XFS_MOUNT_NOALIGN)) { + if (sbp->sb_unit) { + if (!xfs_sb_version_hasdalign(sbp) || + sbp->sb_unit > sbp->sb_width || + (sbp->sb_width % sbp->sb_unit) != 0) { + xfs_notice(mp, "SB stripe unit sanity check failed"); + return -EFSCORRUPTED; + } + } else if (xfs_sb_version_hasdalign(sbp)) { + xfs_notice(mp, "SB stripe alignment sanity check failed"); + return -EFSCORRUPTED; + } else if (sbp->sb_width) { + xfs_notice(mp, "SB stripe width sanity check failed"); return -EFSCORRUPTED; } - } else if (xfs_sb_version_hasdalign(sbp)) { - xfs_notice(mp, "SB stripe alignment sanity check failed"); - return -EFSCORRUPTED; - } else if (sbp->sb_width) { - xfs_notice(mp, "SB stripe width sanity check failed"); - return -EFSCORRUPTED; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 6552473ab117..3b650795fbc3 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -233,6 +233,8 @@ typedef struct xfs_mount { operations, typically for disk errors in metadata */ #define XFS_MOUNT_DISCARD (1ULL << 5) /* discard unused blocks */ +#define XFS_MOUNT_ALIGN (1ULL << 6) /* Custom alignment set via + mount */ #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment allocations */ #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 580072b19e8a..981e69845620 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1214,6 +1214,7 @@ xfs_fc_parse_param( return 0; case Opt_sunit: mp->m_dalign = result.uint_32; + mp->m_flags |= XFS_MOUNT_ALIGN; return 0; case Opt_swidth: mp->m_swidth = result.uint_32; -- 2.26.2