[PATCH 6/7] xfs_repair: try not to trash qflags on metadir filesystems

Darrick J. Wong
2024-12-07T00:19:34Z

From: Darrick J. Wong <djwong@kernel.org>

Try to preserve the accounting and enforcement quota flags when
repairing filesystems.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
repair/agheader.c | 3 ++-
repair/phase4.c | 20 ++++++++++++++++++++
repair/sb.c | 3 +++
3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/repair/agheader.c b/repair/agheader.c
index e6fca07c6cb4c9..89a23a869a02e4 100644
--- a/repair/agheader.c
+++ b/repair/agheader.c
@@ -642,7 +642,8 @@ verify_set_agheader(xfs_mount_t *mp, struct xfs_buf *sbuf, xfs_sb_t *sb,
sb->sb_fdblocks = 0;
sb->sb_frextents = 0;

- sb->sb_qflags = 0;
+ if (!xfs_has_metadir(mp))
+ sb->sb_qflags = 0;
}

rval |= XR_AG_SB;
diff --git a/repair/phase4.c b/repair/phase4.c
index a4183c557a1891..728d9ed84cdc7a 100644
--- a/repair/phase4.c
+++ b/repair/phase4.c
@@ -71,6 +71,26 @@ quotino_check(
static void
quota_sb_check(xfs_mount_t *mp)
{
+ if (xfs_has_metadir(mp)) {
+ /*
+ * Metadir filesystems try to preserve the quota accounting
+ * and enforcement flags so that users don't have to remember
+ * to supply quota mount options. Phase 1 discovered the
+ * QUOTABIT flag (fs_quotas) and phase 2 discovered the quota
+ * inodes from the metadir for us.
+ *
+ * If QUOTABIT wasn't set but we found quota inodes, signal
+ * phase 5 to add the feature bit for us. We do not ever
+ * downgrade the filesystem.
+ */
+ if (!fs_quotas &&
+ (has_quota_inode(XFS_DQTYPE_USER) ||
+ has_quota_inode(XFS_DQTYPE_GROUP) ||
+ has_quota_inode(XFS_DQTYPE_PROJ)))
+ fs_quotas = 1;
+ return;
+ }
+
/*
* if the sb says we have quotas and we lost both,
* signal a superblock downgrade. that will cause
diff --git a/repair/sb.c b/repair/sb.c
index d52ab2ffeaf28c..0e4827e046780b 100644
--- a/repair/sb.c
+++ b/repair/sb.c
@@ -233,6 +233,9 @@ find_secondary_sb(xfs_sb_t *rsb)
if (!retval)
retval = __find_secondary_sb(rsb, XFS_AG_MIN_BYTES, BSIZE);

+ if (retval && xfs_sb_version_hasmetadir(rsb))
+ do_warn(_("quota accounting and enforcement flags lost\n"));
+
return retval;
}