[PATCHSET 09/10] xfs_repair: support more than 4 billion records

Darrick J. Wong
2024-03-13T01:49:24Z

Hi all,

I started looking through all the places where XFS has to deal with the
rc_refcount attribute of refcount records, and noticed that offline
repair doesn't handle the situation where there are more than 2^32
reverse mappings in an AG, or that there are more than 2^32 owners of a
particular piece of AG space. I've estimated that it would take several
months to produce a filesystem with this many records, but we really
ought to do better at handling them than crashing or (worse) not
crashing and writing out corrupt btrees due to integer truncation.

Once I started using the bmap_inflate debugger command to create extreme
reflink scenarios, I noticed that the memory usage of xfs_repair was
astronomical. This I observed to be due to the fact that it allocates a
single huge block mapping array for all files on the system, even though
it only uses that array for data and attr forks that map metadata blocks
(e.g. directories, xattrs, symlinks) and does not use it for regular
data files.

So I got rid of the 2^31-1 limits on the block map array and turned off
the block mapping for regular data files. This doesn't answer the
question of what to do if there are a lot of extents, but it kicks the
can down the road until someone creates a maximally sized xattr tree,
which so far nobody's ever stuck to long enough to complain about.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=repair-support-4bn-records
---
Commits in this patchset:
* xfs_db: add a bmbt inflation command
* xfs_repair: slab and bag structs need to track more than 2^32 items
* xfs_repair: support more than 2^32 rmapbt records per AG
* xfs_repair: support more than 2^32 owners per physical block
* xfs_repair: clean up lock resources
* xfs_repair: constrain attr fork extent count
* xfs_repair: don't create block maps for data files
* xfs_repair: support more than INT_MAX block maps
---
db/Makefile | 65 +++++-
db/bmap_inflate.c | 564 +++++++++++++++++++++++++++++++++++++++++++++++++++++
db/command.c | 1
db/command.h | 1
man/man8/xfs_db.8 | 23 ++
repair/bmap.c | 26 +-
repair/bmap.h | 9 -
repair/dinode.c | 12 +
repair/dir2.c | 2
repair/incore.c | 9 +
repair/rmap.c | 26 +-
repair/rmap.h | 4
repair/slab.c | 36 ++-
repair/slab.h | 36 ++-
14 files changed, 735 insertions(+), 79 deletions(-)
create mode 100644 db/bmap_inflate.c