diff options
author | Darrick J. Wong <djwong@kernel.org> | 2023-08-10 07:48:11 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2023-08-10 07:48:11 -0700 |
commit | 5c83df2e54b6af870e3e02ccd2a8ecd54e36668c (patch) | |
tree | c4b49211e25b038da0ab4b0ca0132857ef972462 /fs/xfs/scrub | |
parent | 8336a64eb75cba4cc4749d9c4770fef53afdc1ad (diff) | |
download | linux-5c83df2e54b6af870e3e02ccd2a8ecd54e36668c.tar.gz linux-5c83df2e54b6af870e3e02ccd2a8ecd54e36668c.tar.bz2 linux-5c83df2e54b6af870e3e02ccd2a8ecd54e36668c.zip |
xfs: allow userspace to rebuild metadata structures
Add a new (superuser-only) flag to the online metadata repair ioctl to
force it to rebuild structures, even if they're not broken. We will use
this to move metadata structures out of the way during a free space
defragmentation operation.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/scrub')
-rw-r--r-- | fs/xfs/scrub/scrub.c | 11 | ||||
-rw-r--r-- | fs/xfs/scrub/trace.h | 3 |
2 files changed, 12 insertions, 2 deletions
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index aade9d3b0283..e92129d74462 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -409,6 +409,11 @@ xchk_validate_inputs( goto out; } + /* No rebuild without repair. */ + if ((sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) && + !(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)) + return -EINVAL; + /* * We only want to repair read-write v5+ filesystems. Defer the check * for ops->repair until after our scrub confirms that we need to @@ -537,8 +542,12 @@ retry_op: !(sc->flags & XREP_ALREADY_FIXED)) { bool needs_fix = xchk_needs_repair(sc->sm); + /* Userspace asked us to rebuild the structure regardless. */ + if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) + needs_fix = true; + /* Let debug users force us into the repair routines. */ - if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR)) + if (XFS_TEST_ERROR(needs_fix, mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR)) needs_fix = true; /* diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 98f6773f3ec1..fca99e831466 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -98,7 +98,8 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_FSCOUNTERS); { XFS_SCRUB_OFLAG_XCORRUPT, "xcorrupt" }, \ { XFS_SCRUB_OFLAG_INCOMPLETE, "incomplete" }, \ { XFS_SCRUB_OFLAG_WARNING, "warning" }, \ - { XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED, "norepair" } + { XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED, "norepair" }, \ + { XFS_SCRUB_IFLAG_FORCE_REBUILD, "rebuild" } #define XFS_SCRUB_STATE_STRINGS \ { XCHK_TRY_HARDER, "try_harder" }, \ |