]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: add an optimization-only mode
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:18 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:10 +0000 (17:01 -0700)
Add a "preen" mode in which we only optimize filesystem metadata.
Repairs will result in early exits.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
man/man8/xfs_scrub.8
scrub/Makefile
scrub/phase4.c
scrub/repair.c
scrub/scrub.c
scrub/xfs_scrub.c
scrub/xfs_scrub.h

index 6154011271e6f3295e5fd831f9fdd6f61505bc34..1fd122f2a242b0b275e550467d485ff15d2a51fb 100644 (file)
@@ -4,7 +4,7 @@ xfs_scrub \- check and repair the contents of a mounted XFS filesystem
 .SH SYNOPSIS
 .B xfs_scrub
 [
-.B \-abCeMmnTvx
+.B \-abCeMmnpTvx
 ]
 .I mount-point
 .br
@@ -128,6 +128,10 @@ Treat informational messages as warnings.
 This will result in a nonzero return code, and a higher logging level.
 .RE
 .TP
+.B \-p
+Only optimize filesystem metadata.
+If repairs are required, report them and exit.
+.TP
 .BI \-T
 Print timing and memory usage information for each phase.
 .TP
index 7e6882450d542be63dfb492a0638441c7f88b451..885b43e9948daff8ec5e544a184c69c243d18c92 100644 (file)
@@ -16,7 +16,7 @@ LTCOMMAND = xfs_scrub
 INSTALL_SCRUB = install-scrub
 XFS_SCRUB_ALL_PROG = xfs_scrub_all
 XFS_SCRUB_FAIL_PROG = xfs_scrub_fail
-XFS_SCRUB_ARGS = -n
+XFS_SCRUB_ARGS = -p
 XFS_SCRUB_SERVICE_ARGS = -b
 ifeq ($(HAVE_SYSTEMD),yes)
 INSTALL_SCRUB += install-systemd
index 451101811c9bb7b9cb7f2043adc991214f2095dd..88cb53aeac9076359477b3fa0bd1fd947b8bd8b9 100644 (file)
@@ -240,6 +240,12 @@ phase4_func(
            action_list_empty(ctx->file_repair_list))
                return 0;
 
+       if (ctx->mode == SCRUB_MODE_PREEN && ctx->corruptions_found) {
+               str_info(ctx, ctx->mntpoint,
+ _("Corruptions found; will not optimize.  Re-run without -p.\n"));
+               return 0;
+       }
+
        /*
         * Check the resource usage counters early.  Normally we do this during
         * phase 7, but some of the cross-referencing requires fairly accurate
index 2883f98af4ab94b360de167ecf3bdfc9795459a5..0258210722ba44f018fed609566c0bcf6355fb93 100644 (file)
@@ -651,7 +651,9 @@ repair_item_class(
        unsigned int                    scrub_type;
        int                             error = 0;
 
-       if (ctx->mode < SCRUB_MODE_REPAIR)
+       if (ctx->mode == SCRUB_MODE_DRY_RUN)
+               return 0;
+       if (ctx->mode == SCRUB_MODE_PREEN && !(repair_mask & SCRUB_ITEM_PREEN))
                return 0;
 
        /*
index 2b6b6274e382bd38ae57b2341092cd547ee278b0..1b0609e7418bd85f563cc999904974a5ce973487 100644 (file)
@@ -174,7 +174,7 @@ _("Filesystem is shut down, aborting."));
         * repair if desired, otherwise complain.
         */
        if (is_corrupt(&meta) || xref_disagrees(&meta)) {
-               if (ctx->mode < SCRUB_MODE_REPAIR) {
+               if (ctx->mode != SCRUB_MODE_REPAIR) {
                        /* Dry-run mode, so log an error and forget it. */
                        str_corrupt(ctx, descr_render(&dsc),
 _("Repairs are required."));
@@ -192,7 +192,7 @@ _("Repairs are required."));
         * otherwise complain.
         */
        if (is_unoptimized(&meta)) {
-               if (ctx->mode != SCRUB_MODE_REPAIR) {
+               if (ctx->mode == SCRUB_MODE_DRY_RUN) {
                        /* Dry-run mode, so log an error and forget it. */
                        if (group != XFROG_SCRUB_GROUP_INODE) {
                                /* AG or FS metadata, always warn. */
index d7cef115deea4ef40901caae5caeb0baef62ea01..bb316f73e02c102fc22993e38c974f28a02666e4 100644 (file)
@@ -183,6 +183,7 @@ usage(void)
        fprintf(stderr, _("  -k           Do not FITRIM the free space.\n"));
        fprintf(stderr, _("  -m path      Path to /etc/mtab.\n"));
        fprintf(stderr, _("  -n           Dry run.  Do not modify anything.\n"));
+       fprintf(stderr, _("  -p           Only optimize, do not fix corruptions.\n"));
        fprintf(stderr, _("  -T           Display timing/usage information.\n"));
        fprintf(stderr, _("  -v           Verbose output.\n"));
        fprintf(stderr, _("  -V           Print version.\n"));
@@ -463,6 +464,11 @@ run_scrub_phases(
                        sp->descr = _("Repair filesystem.");
                        sp->fn = phase4_func;
                        sp->must_run = true;
+               } else if (sp->fn == REPAIR_DUMMY_FN &&
+                          ctx->mode == SCRUB_MODE_PREEN) {
+                       sp->descr = _("Optimize filesystem.");
+                       sp->fn = phase4_func;
+                       sp->must_run = true;
                }
 
                /* Skip certain phases unless they're turned on. */
@@ -601,7 +607,7 @@ report_outcome(
        if (ctx->scrub_setup_succeeded && actionable_errors > 0) {
                char            *msg;
 
-               if (ctx->mode == SCRUB_MODE_DRY_RUN)
+               if (ctx->mode != SCRUB_MODE_REPAIR)
                        msg = _("%s: Re-run xfs_scrub without -n.\n");
                else
                        msg = _("%s: Unmount and run xfs_repair.\n");
@@ -725,7 +731,7 @@ main(
        pthread_mutex_init(&ctx.lock, NULL);
        ctx.mode = SCRUB_MODE_REPAIR;
        ctx.error_action = ERRORS_CONTINUE;
-       while ((c = getopt(argc, argv, "a:bC:de:kM:m:no:TvxV")) != EOF) {
+       while ((c = getopt(argc, argv, "a:bC:de:kM:m:no:pTvxV")) != EOF) {
                switch (c) {
                case 'a':
                        ctx.max_errors = cvt_u64(optarg, 10);
@@ -776,11 +782,22 @@ main(
                        mtab = optarg;
                        break;
                case 'n':
+                       if (ctx.mode != SCRUB_MODE_REPAIR) {
+                               fprintf(stderr, _("Cannot use -n with -p.\n"));
+                               usage();
+                       }
                        ctx.mode = SCRUB_MODE_DRY_RUN;
                        break;
                case 'o':
                        parse_o_opts(&ctx, optarg);
                        break;
+               case 'p':
+                       if (ctx.mode != SCRUB_MODE_REPAIR) {
+                               fprintf(stderr, _("Cannot use -p with -n.\n"));
+                               usage();
+                       }
+                       ctx.mode = SCRUB_MODE_PREEN;
+                       break;
                case 'T':
                        display_rusage = true;
                        break;
index b0aa9fcc67b72651219af35a50c279f595cd01e7..4d9a028921b55e52bcfadf51907457392cea5a3e 100644 (file)
@@ -27,6 +27,7 @@ extern bool                   info_is_warning;
 
 enum scrub_mode {
        SCRUB_MODE_DRY_RUN,
+       SCRUB_MODE_PREEN,
        SCRUB_MODE_REPAIR,
 };