Fix xfs corrupted when AG size is a multiple of SW
This patch is taken from Linus' kernel repo as it is not in xfsprogs yet. Resolves: rhbz#2192982 Signed-off-by: Pavel Reichl <preichl@redhat.com>
This commit is contained in:
parent
17fdafd9b5
commit
617bf05890
|
@ -0,0 +1,128 @@
|
||||||
|
From 8e698ee72c4ecbbf18264568eb310875839fd601 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||||
|
Date: Tue, 2 May 2023 09:14:36 +1000
|
||||||
|
Subject: [PATCH] xfs: set bnobt/cntbt numrecs correctly when formatting new
|
||||||
|
AGs
|
||||||
|
|
||||||
|
Through generic/300, I discovered that mkfs.xfs creates corrupt
|
||||||
|
filesystems when given these parameters:
|
||||||
|
|
||||||
|
# mkfs.xfs -d size=512M /dev/sda -f -d su=128k,sw=4 --unsupported
|
||||||
|
Filesystems formatted with --unsupported are not supported!!
|
||||||
|
meta-data=/dev/sda isize=512 agcount=8, agsize=16352 blks
|
||||||
|
= sectsz=512 attr=2, projid32bit=1
|
||||||
|
= crc=1 finobt=1, sparse=1, rmapbt=1
|
||||||
|
= reflink=1 bigtime=1 inobtcount=1 nrext64=1
|
||||||
|
data = bsize=4096 blocks=130816, imaxpct=25
|
||||||
|
= sunit=32 swidth=128 blks
|
||||||
|
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
|
||||||
|
log =internal log bsize=4096 blocks=8192, version=2
|
||||||
|
= sectsz=512 sunit=32 blks, lazy-count=1
|
||||||
|
realtime =none extsz=4096 blocks=0, rtextents=0
|
||||||
|
= rgcount=0 rgsize=0 blks
|
||||||
|
Discarding blocks...Done.
|
||||||
|
# xfs_repair -n /dev/sda
|
||||||
|
Phase 1 - find and verify superblock...
|
||||||
|
- reporting progress in intervals of 15 minutes
|
||||||
|
Phase 2 - using internal log
|
||||||
|
- zero log...
|
||||||
|
- 16:30:50: zeroing log - 16320 of 16320 blocks done
|
||||||
|
- scan filesystem freespace and inode maps...
|
||||||
|
agf_freeblks 25, counted 0 in ag 4
|
||||||
|
sb_fdblocks 8823, counted 8798
|
||||||
|
|
||||||
|
The root cause of this problem is the numrecs handling in
|
||||||
|
xfs_freesp_init_recs, which is used to initialize a new AG. Prior to
|
||||||
|
calling the function, we set up the new bnobt block with numrecs == 1
|
||||||
|
and rely on _freesp_init_recs to format that new record. If the last
|
||||||
|
record created has a blockcount of zero, then it sets numrecs = 0.
|
||||||
|
|
||||||
|
That last bit isn't correct if the AG contains the log, the start of the
|
||||||
|
log is not immediately after the initial blocks due to stripe alignment,
|
||||||
|
and the end of the log is perfectly aligned with the end of the AG. For
|
||||||
|
this case, we actually formatted a single bnobt record to handle the
|
||||||
|
free space before the start of the (stripe aligned) log, and incremented
|
||||||
|
arec to try to format a second record. That second record turned out to
|
||||||
|
be unnecessary, so what we really want is to leave numrecs at 1.
|
||||||
|
|
||||||
|
The numrecs handling itself is overly complicated because a different
|
||||||
|
function sets numrecs == 1. Change the bnobt creation code to start
|
||||||
|
with numrecs set to zero and only increment it after successfully
|
||||||
|
formatting a free space extent into the btree block.
|
||||||
|
|
||||||
|
Fixes: f327a00745ff ("xfs: account for log space when formatting new AGs")
|
||||||
|
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||||
|
Reviewed-by: Dave Chinner <dchinner@redhat.com>
|
||||||
|
Signed-off-by: Dave Chinner <david@fromorbit.com>
|
||||||
|
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||||
|
---
|
||||||
|
fs/xfs/libxfs/xfs_ag.c | 19 +++++++++----------
|
||||||
|
1 file changed, 9 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
|
||||||
|
index 1b078bbbf225..9b373a0c7aaf 100644
|
||||||
|
--- a//libxfs/xfs_ag.c
|
||||||
|
+++ b//libxfs/xfs_ag.c
|
||||||
|
@@ -495,10 +495,12 @@ xfs_freesp_init_recs(
|
||||||
|
ASSERT(start >= mp->m_ag_prealloc_blocks);
|
||||||
|
if (start != mp->m_ag_prealloc_blocks) {
|
||||||
|
/*
|
||||||
|
- * Modify first record to pad stripe align of log
|
||||||
|
+ * Modify first record to pad stripe align of log and
|
||||||
|
+ * bump the record count.
|
||||||
|
*/
|
||||||
|
arec->ar_blockcount = cpu_to_be32(start -
|
||||||
|
mp->m_ag_prealloc_blocks);
|
||||||
|
+ be16_add_cpu(&block->bb_numrecs, 1);
|
||||||
|
nrec = arec + 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -509,7 +511,6 @@ xfs_freesp_init_recs(
|
||||||
|
be32_to_cpu(arec->ar_startblock) +
|
||||||
|
be32_to_cpu(arec->ar_blockcount));
|
||||||
|
arec = nrec;
|
||||||
|
- be16_add_cpu(&block->bb_numrecs, 1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Change record start to after the internal log
|
||||||
|
@@ -518,15 +519,13 @@ xfs_freesp_init_recs(
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Calculate the record block count and check for the case where
|
||||||
|
- * the log might have consumed all available space in the AG. If
|
||||||
|
- * so, reset the record count to 0 to avoid exposure of an invalid
|
||||||
|
- * record start block.
|
||||||
|
+ * Calculate the block count of this record; if it is nonzero,
|
||||||
|
+ * increment the record count.
|
||||||
|
*/
|
||||||
|
arec->ar_blockcount = cpu_to_be32(id->agsize -
|
||||||
|
be32_to_cpu(arec->ar_startblock));
|
||||||
|
- if (!arec->ar_blockcount)
|
||||||
|
- block->bb_numrecs = 0;
|
||||||
|
+ if (arec->ar_blockcount)
|
||||||
|
+ be16_add_cpu(&block->bb_numrecs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -538,7 +537,7 @@ xfs_bnoroot_init(
|
||||||
|
struct xfs_buf *bp,
|
||||||
|
struct aghdr_init_data *id)
|
||||||
|
{
|
||||||
|
- xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 1, id->agno);
|
||||||
|
+ xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 0, id->agno);
|
||||||
|
xfs_freesp_init_recs(mp, bp, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -548,7 +547,7 @@ xfs_cntroot_init(
|
||||||
|
struct xfs_buf *bp,
|
||||||
|
struct aghdr_init_data *id)
|
||||||
|
{
|
||||||
|
- xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 1, id->agno);
|
||||||
|
+ xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 0, id->agno);
|
||||||
|
xfs_freesp_init_recs(mp, bp, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Summary: Utilities for managing the XFS filesystem
|
Summary: Utilities for managing the XFS filesystem
|
||||||
Name: xfsprogs
|
Name: xfsprogs
|
||||||
Version: 5.19.0
|
Version: 5.19.0
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
License: GPL+ and LGPLv2+
|
License: GPL+ and LGPLv2+
|
||||||
URL: https://xfs.wiki.kernel.org
|
URL: https://xfs.wiki.kernel.org
|
||||||
Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz
|
Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz
|
||||||
|
@ -34,6 +34,7 @@ Patch8: xfsprogs-5.19.0-xfs-fix-sb-write-verify-for-lazysbcount.patch
|
||||||
Patch9: xfsprogs-5.19.0-xfs-get-rid-of-assert-from-xfs_btree_islastblock.patch
|
Patch9: xfsprogs-5.19.0-xfs-get-rid-of-assert-from-xfs_btree_islastblock.patch
|
||||||
Patch10: xfsprogs-5.19.0-xfs-removed-useless-condition-in-function-xfs_attr_n.patch
|
Patch10: xfsprogs-5.19.0-xfs-removed-useless-condition-in-function-xfs_attr_n.patch
|
||||||
Patch11: xfsprogs-5.19.0-xfs_repair-retain-superblock-buffer-to-avoid-write-h.patch
|
Patch11: xfsprogs-5.19.0-xfs_repair-retain-superblock-buffer-to-avoid-write-h.patch
|
||||||
|
Patch12: xfsprogs-kernel-xfs-set-bnobt-cntbt-numrecs-correctly-when-formattin.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
A set of commands to use the XFS filesystem, including mkfs.xfs.
|
A set of commands to use the XFS filesystem, including mkfs.xfs.
|
||||||
|
@ -145,6 +146,10 @@ install -m 0644 %{SOURCE3} %{buildroot}%{mkfsdir}
|
||||||
%{_libdir}/*.so
|
%{_libdir}/*.so
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri May 26 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-2
|
||||||
|
- Fix xfs corrupted when AG size is a multiple of stripe width
|
||||||
|
- Related: rhbz#2192982
|
||||||
|
|
||||||
* Tue Jan 10 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-1
|
* Tue Jan 10 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-1
|
||||||
- New upstream release
|
- New upstream release
|
||||||
- Tolerate tiny (<300MB) filesystems
|
- Tolerate tiny (<300MB) filesystems
|
||||||
|
|
Loading…
Reference in New Issue