]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: check summary counters
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 26 Sep 2019 17:42:04 +0000 (13:42 -0400)
committerEric Sandeen <sandeen@redhat.com>
Thu, 26 Sep 2019 17:42:04 +0000 (13:42 -0400)
Teach scrub to ask the kernel to check and repair summary counters
during phase 7.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
scrub/phase4.c
scrub/phase7.c
scrub/repair.c
scrub/scrub.c
scrub/scrub.h

index 589777f61cb3fd1080c800d7e13c7d0af95c5f9f..25fedc8391552a26ca2872a6edd306fa9b60f7e0 100644 (file)
@@ -107,6 +107,18 @@ bool
 xfs_repair_fs(
        struct scrub_ctx                *ctx)
 {
+       bool                            moveon;
+
+       /*
+        * Check the summary counters early.  Normally we do this during phase
+        * seven, but some of the cross-referencing requires fairly-accurate
+        * counters, so counter repairs have to be put on the list now so that
+        * they get fixed before we stop retrying unfixed metadata repairs.
+        */
+       moveon = xfs_scrub_fs_summary(ctx, &ctx->action_lists[0]);
+       if (!moveon)
+               return false;
+
        return xfs_process_action_items(ctx);
 }
 
index f82b60d6d66b793f16319670d0ad6a6f0859ad46..308b8bb3072696c7428841ae61b94bfa17ec6a81 100644 (file)
@@ -9,10 +9,13 @@
 #include <sys/statvfs.h>
 #include "libfrog/paths.h"
 #include "libfrog/ptvar.h"
+#include "list.h"
 #include "xfs_scrub.h"
 #include "common.h"
+#include "scrub.h"
 #include "fscounters.h"
 #include "spacemap.h"
+#include "repair.h"
 
 /* Phase 7: Check summary counters. */
 
@@ -91,6 +94,7 @@ xfs_scan_summary(
        struct scrub_ctx        *ctx)
 {
        struct summary_counts   totalcount = {0};
+       struct xfs_action_list  alist;
        struct ptvar            *ptvar;
        unsigned long long      used_data;
        unsigned long long      used_rt;
@@ -110,6 +114,16 @@ xfs_scan_summary(
        int                     ip;
        int                     error;
 
+       /* Check and fix the fs summary counters. */
+       xfs_action_list_init(&alist);
+       moveon = xfs_scrub_fs_summary(ctx, &alist);
+       if (!moveon)
+               return false;
+       moveon = xfs_action_list_process(ctx, ctx->mnt.fd, &alist,
+                       ALP_COMPLAIN_IF_UNFIXED | ALP_NOPROGRESS);
+       if (!moveon)
+               return moveon;
+
        /* Flush everything out to disk before we start counting. */
        error = syncfs(ctx->mnt.fd);
        if (error) {
index 0e5afb200e94bea523d3e1bde62efd50566586b9..04a9dccf604483ce293e8aeba0d7061c3ce103df 100644 (file)
@@ -84,6 +84,9 @@ xfs_action_item_priority(
        case XFS_SCRUB_TYPE_GQUOTA:
        case XFS_SCRUB_TYPE_PQUOTA:
                return PRIO(aitem, XFS_SCRUB_TYPE_UQUOTA);
+       case XFS_SCRUB_TYPE_FSCOUNTERS:
+               /* This should always go after AG headers no matter what. */
+               return PRIO(aitem, INT_MAX);
        }
        abort();
 }
index 2557da2accd8adb34e45c2eb3264879698946675..d7a6b49b9b6ae551ca835a938bbe91e5fc6d045e 100644 (file)
@@ -388,6 +388,18 @@ xfs_scrub_fs_metadata(
        return xfs_scrub_all_types(ctx, XFROG_SCRUB_TYPE_FS, 0, alist);
 }
 
+/* Scrub FS summary metadata. */
+bool
+xfs_scrub_fs_summary(
+       struct scrub_ctx                *ctx,
+       struct xfs_action_list          *alist)
+{
+       int                             ret;
+
+       ret = xfs_scrub_meta_type(ctx, XFS_SCRUB_TYPE_FSCOUNTERS, 0, alist);
+       return ret == 0;
+}
+
 /* How many items do we have to check? */
 unsigned int
 xfs_scrub_estimate_ag_work(
index 7e28b522d1892d0c2c5d6f398644a2ceef436775..d407abb0b147dc298e1e5b53c16fb074da9b59d4 100644 (file)
@@ -25,6 +25,8 @@ bool xfs_scrub_ag_metadata(struct scrub_ctx *ctx, xfs_agnumber_t agno,
                struct xfs_action_list *alist);
 bool xfs_scrub_fs_metadata(struct scrub_ctx *ctx,
                struct xfs_action_list *alist);
+bool xfs_scrub_fs_summary(struct scrub_ctx *ctx,
+               struct xfs_action_list *alist);
 
 bool xfs_can_scrub_fs_metadata(struct scrub_ctx *ctx);
 bool xfs_can_scrub_inode(struct scrub_ctx *ctx);