]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/phase2.c
edf66df6a7fa9c0243a2f9d8f403d72bc4783000
[thirdparty/xfsprogs-dev.git] / scrub / phase2.c
1 /*
2 * Copyright (C) 2018 Oracle. All Rights Reserved.
3 *
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it would be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <stdbool.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/statvfs.h>
26 #include "xfs.h"
27 #include "list.h"
28 #include "path.h"
29 #include "workqueue.h"
30 #include "xfs_scrub.h"
31 #include "common.h"
32 #include "scrub.h"
33
34 /* Phase 2: Check internal metadata. */
35
36 /* Scrub each AG's metadata btrees. */
37 static void
38 xfs_scan_ag_metadata(
39 struct workqueue *wq,
40 xfs_agnumber_t agno,
41 void *arg)
42 {
43 struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
44 bool *pmoveon = arg;
45 bool moveon;
46 char descr[DESCR_BUFSZ];
47
48 snprintf(descr, DESCR_BUFSZ, _("AG %u"), agno);
49
50 /*
51 * First we scrub and fix the AG headers, because we need
52 * them to work well enough to check the AG btrees.
53 */
54 moveon = xfs_scrub_ag_headers(ctx, agno);
55 if (!moveon)
56 goto err;
57
58 /* Now scrub the AG btrees. */
59 moveon = xfs_scrub_ag_metadata(ctx, agno);
60 if (!moveon)
61 goto err;
62
63 return;
64 err:
65 *pmoveon = false;
66 }
67
68 /* Scrub whole-FS metadata btrees. */
69 static void
70 xfs_scan_fs_metadata(
71 struct workqueue *wq,
72 xfs_agnumber_t agno,
73 void *arg)
74 {
75 struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
76 bool *pmoveon = arg;
77 bool moveon;
78
79 moveon = xfs_scrub_fs_metadata(ctx);
80 if (!moveon)
81 *pmoveon = false;
82 }
83
84 /* Scan all filesystem metadata. */
85 bool
86 xfs_scan_metadata(
87 struct scrub_ctx *ctx)
88 {
89 struct workqueue wq;
90 xfs_agnumber_t agno;
91 bool moveon = true;
92 int ret;
93
94 ret = workqueue_create(&wq, (struct xfs_mount *)ctx,
95 scrub_nproc_workqueue(ctx));
96 if (ret) {
97 str_info(ctx, ctx->mntpoint, _("Could not create workqueue."));
98 return false;
99 }
100
101 /*
102 * In case we ever use the primary super scrubber to perform fs
103 * upgrades (followed by a full scrub), do that before we launch
104 * anything else.
105 */
106 moveon = xfs_scrub_primary_super(ctx);
107 if (!moveon)
108 return moveon;
109
110 for (agno = 0; moveon && agno < ctx->geo.agcount; agno++) {
111 ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon);
112 if (ret) {
113 moveon = false;
114 str_info(ctx, ctx->mntpoint,
115 _("Could not queue AG %u scrub work."), agno);
116 goto out;
117 }
118 }
119
120 if (!moveon)
121 goto out;
122
123 ret = workqueue_add(&wq, xfs_scan_fs_metadata, 0, &moveon);
124 if (ret) {
125 moveon = false;
126 str_info(ctx, ctx->mntpoint,
127 _("Could not queue filesystem scrub work."));
128 goto out;
129 }
130
131 out:
132 workqueue_destroy(&wq);
133 return moveon;
134 }
135
136 /* Estimate how much work we're going to do. */
137 bool
138 xfs_estimate_metadata_work(
139 struct scrub_ctx *ctx,
140 uint64_t *items,
141 unsigned int *nr_threads,
142 int *rshift)
143 {
144 *items = xfs_scrub_estimate_ag_work(ctx);
145 *nr_threads = scrub_nproc(ctx);
146 *rshift = 0;
147 return true;
148 }