[PATCH 2/2] xfs: Bypass sb alignment checks when custom values are used

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux