]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/phase2.c
xfsprogs: convert to SPDX license tags
[thirdparty/xfsprogs-dev.git] / scrub / phase2.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2018 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
5 */
6 #include "xfs.h"
7 #include <stdint.h>
8 #include <sys/types.h>
9 #include <sys/statvfs.h>
10 #include "list.h"
11 #include "path.h"
12 #include "workqueue.h"
13 #include "xfs_scrub.h"
14 #include "common.h"
15 #include "scrub.h"
16
17 /* Phase 2: Check internal metadata. */
18
19 /* Scrub each AG's metadata btrees. */
20 static void
21 xfs_scan_ag_metadata(
22 struct workqueue *wq,
23 xfs_agnumber_t agno,
24 void *arg)
25 {
26 struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
27 bool *pmoveon = arg;
28 bool moveon;
29 char descr[DESCR_BUFSZ];
30
31 snprintf(descr, DESCR_BUFSZ, _("AG %u"), agno);
32
33 /*
34 * First we scrub and fix the AG headers, because we need
35 * them to work well enough to check the AG btrees.
36 */
37 moveon = xfs_scrub_ag_headers(ctx, agno);
38 if (!moveon)
39 goto err;
40
41 /* Now scrub the AG btrees. */
42 moveon = xfs_scrub_ag_metadata(ctx, agno);
43 if (!moveon)
44 goto err;
45
46 return;
47 err:
48 *pmoveon = false;
49 }
50
51 /* Scrub whole-FS metadata btrees. */
52 static void
53 xfs_scan_fs_metadata(
54 struct workqueue *wq,
55 xfs_agnumber_t agno,
56 void *arg)
57 {
58 struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
59 bool *pmoveon = arg;
60 bool moveon;
61
62 moveon = xfs_scrub_fs_metadata(ctx);
63 if (!moveon)
64 *pmoveon = false;
65 }
66
67 /* Scan all filesystem metadata. */
68 bool
69 xfs_scan_metadata(
70 struct scrub_ctx *ctx)
71 {
72 struct workqueue wq;
73 xfs_agnumber_t agno;
74 bool moveon = true;
75 int ret;
76
77 ret = workqueue_create(&wq, (struct xfs_mount *)ctx,
78 scrub_nproc_workqueue(ctx));
79 if (ret) {
80 str_info(ctx, ctx->mntpoint, _("Could not create workqueue."));
81 return false;
82 }
83
84 /*
85 * In case we ever use the primary super scrubber to perform fs
86 * upgrades (followed by a full scrub), do that before we launch
87 * anything else.
88 */
89 moveon = xfs_scrub_primary_super(ctx);
90 if (!moveon)
91 return moveon;
92
93 for (agno = 0; moveon && agno < ctx->geo.agcount; agno++) {
94 ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon);
95 if (ret) {
96 moveon = false;
97 str_info(ctx, ctx->mntpoint,
98 _("Could not queue AG %u scrub work."), agno);
99 goto out;
100 }
101 }
102
103 if (!moveon)
104 goto out;
105
106 ret = workqueue_add(&wq, xfs_scan_fs_metadata, 0, &moveon);
107 if (ret) {
108 moveon = false;
109 str_info(ctx, ctx->mntpoint,
110 _("Could not queue filesystem scrub work."));
111 goto out;
112 }
113
114 out:
115 workqueue_destroy(&wq);
116 return moveon;
117 }
118
119 /* Estimate how much work we're going to do. */
120 bool
121 xfs_estimate_metadata_work(
122 struct scrub_ctx *ctx,
123 uint64_t *items,
124 unsigned int *nr_threads,
125 int *rshift)
126 {
127 *items = xfs_scrub_estimate_ag_work(ctx);
128 *nr_threads = scrub_nproc(ctx);
129 *rshift = 0;
130 return true;
131 }