diff mbox series

[5/7] xfs_repair: check the force-align flag

Message ID 20230929095342.2976587-6-john.g.garry@oracle.com (mailing list archive)
State New, archived
Headers show
Series xfsprogs: Enable extent forcealign feature | expand

Commit Message

John Garry Sept. 29, 2023, 9:53 a.m. UTC
From: "Darrick J. Wong" <djwong@kernel.org>

Make sure the flag isn't set incorrectly.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 repair/dinode.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
diff mbox series

Patch

diff --git a/repair/dinode.c b/repair/dinode.c
index e534a01b5009..a9de2ee73ef4 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2262,6 +2262,69 @@  _("Bad extent size hint %u on inode %" PRIu64 ", "),
 	}
 }
 
+static void
+validate_forcealign(
+	struct xfs_mount	*mp,
+	struct xfs_dinode	*dino,
+	xfs_ino_t		lino,
+	int			*dirty)
+{
+	uint16_t		mode;
+	uint16_t		flags;
+	uint64_t		flags2;
+	
+	mode = be16_to_cpu(dino->di_mode);
+	flags = be16_to_cpu(dino->di_flags);
+	flags2 = be64_to_cpu(dino->di_flags2);
+
+	if (!(flags2 & XFS_DIFLAG2_FORCEALIGN))
+		return;
+
+	if (!xfs_has_forcealign(mp)) {
+		do_warn(
+ _("Filesystem does not support forcealign flag set on inode %" PRIu64 ", "),
+					lino);
+		goto zap;
+	}
+
+	if (!S_ISDIR(mode) && !S_ISREG(mode)) {
+		do_warn(
+ _("Cannot have forcealign inode flag set on non-dir non-regular file inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	if (flags & XFS_DIFLAG_REALTIME) {
+		do_warn(
+ _("Cannot have forcealign inode flag set on realtime inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	if (dino->di_extsize == 0) {
+		do_warn(
+ _("Cannot have forcealign inode flag set without an extent size hint on inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	if (dino->di_cowextsize != 0) {
+		do_warn(
+ _("Cannot have forcealign inode flag set with nonzero CoW extent size hint on inode %" PRIu64 "\n"),
+					lino);
+		goto zap;
+	}
+
+	return;
+zap:
+	if (!no_modify) {
+		do_warn(_("clearing flag\n"));
+		dino->di_flags2 &= ~cpu_to_be64(XFS_DIFLAG2_FORCEALIGN);
+		*dirty = 1;
+	} else
+		do_warn(_("would clear flag\n"));
+}
+
 /*
  * returns 0 if the inode is ok, 1 if the inode is corrupt
  * check_dups can be set to 1 *only* when called by the
@@ -2833,6 +2896,9 @@  _("Bad CoW extent size %u on inode %" PRIu64 ", "),
 			do_warn(_("would reset to zero\n"));
 	}
 
+	if (dino->di_version >= 3)
+		validate_forcealign(mp, dino, lino, dirty);
+
 	/* nsec fields cannot be larger than 1 billion */
 	check_nsec("atime", lino, dino, &dino->di_atime, dirty);
 	check_nsec("mtime", lino, dino, &dino->di_mtime, dirty);