]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: allow userspace to rebuild metadata structures
authorDarrick J. Wong <djwong@kernel.org>
Thu, 10 Aug 2023 14:48:11 +0000 (07:48 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 10 Aug 2023 14:48:11 +0000 (07:48 -0700)
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>
fs/xfs/libxfs/xfs_fs.h
fs/xfs/scrub/scrub.c
fs/xfs/scrub/trace.h

index 2cbf9ea39b8cc4cbd6420ebd721d6e3045c3ed38..6360073865dbc3136e3655e1b493a53ca4310dd3 100644 (file)
@@ -743,7 +743,11 @@ struct xfs_scrub_metadata {
  */
 #define XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED (1u << 7)
 
-#define XFS_SCRUB_FLAGS_IN     (XFS_SCRUB_IFLAG_REPAIR)
+/* i: Rebuild the data structure. */
+#define XFS_SCRUB_IFLAG_FORCE_REBUILD  (1u << 8)
+
+#define XFS_SCRUB_FLAGS_IN     (XFS_SCRUB_IFLAG_REPAIR | \
+                                XFS_SCRUB_IFLAG_FORCE_REBUILD)
 #define XFS_SCRUB_FLAGS_OUT    (XFS_SCRUB_OFLAG_CORRUPT | \
                                 XFS_SCRUB_OFLAG_PREEN | \
                                 XFS_SCRUB_OFLAG_XFAIL | \
index aade9d3b028395cc3208f2ed82527ffe9bdf0f2d..e92129d74462b390cfab9f219db4715a5b253bd7 100644 (file)
@@ -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;
 
                /*
index 98f6773f3ec12be7f4ded0e2644f36ba1b3b00dc..fca99e8314660528bfca52393d7055f3fc8e1325 100644 (file)
@@ -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" }, \