102 lines
2.5 KiB
Diff
102 lines
2.5 KiB
Diff
From 2a14aafc618a9878d45240c4f0c1f0c7dc8f3d6b Mon Sep 17 00:00:00 2001
|
|
From: "Darrick J. Wong" <djwong@kernel.org>
|
|
Date: Fri, 29 Sep 2023 09:53:40 +0000
|
|
Subject: [PATCH 05/11] xfs_repair: check the force-align flag
|
|
|
|
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 --git a/repair/dinode.c b/repair/dinode.c
|
|
index f39ab2d..7747070 100644
|
|
--- a/repair/dinode.c
|
|
+++ b/repair/dinode.c
|
|
@@ -2229,6 +2229,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_sb_version_hasforcealign(&mp->m_sb)) {
|
|
+ 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
|
|
@@ -2764,6 +2827,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);
|
|
--
|
|
2.33.0
|
|
|