]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/phase4.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
10 #include <sys/statvfs.h>
12 #include "libfrog/paths.h"
13 #include "libfrog/workqueue.h"
14 #include "xfs_scrub.h"
21 /* Phase 4: Repair filesystem. */
23 /* Fix all the problems in our per-AG list. */
30 struct scrub_ctx
*ctx
= (struct scrub_ctx
*)wq
->wq_ctx
;
32 struct action_list
*alist
;
33 unsigned long long unfixed
;
34 unsigned long long new_unfixed
;
35 unsigned int flags
= 0;
38 alist
= &ctx
->action_lists
[agno
];
39 unfixed
= action_list_length(alist
);
41 /* Repair anything broken until we fail to make progress. */
43 ret
= action_list_process(ctx
, -1, alist
, flags
);
48 new_unfixed
= action_list_length(alist
);
49 if (new_unfixed
== unfixed
)
51 unfixed
= new_unfixed
;
54 } while (unfixed
> 0);
56 /* Try once more, but this time complain if we can't fix things. */
57 flags
|= ALP_COMPLAIN_IF_UNFIXED
;
58 ret
= action_list_process(ctx
, -1, alist
, flags
);
63 /* Process all the action items. */
66 struct scrub_ctx
*ctx
)
73 ret
= -workqueue_create(&wq
, (struct xfs_mount
*)ctx
,
74 scrub_nproc_workqueue(ctx
));
76 str_liberror(ctx
, ret
, _("creating repair workqueue"));
79 for (agno
= 0; !aborted
&& agno
< ctx
->mnt
.fsgeom
.agcount
; agno
++) {
80 if (action_list_length(&ctx
->action_lists
[agno
]) == 0)
83 ret
= -workqueue_add(&wq
, repair_ag
, agno
, &aborted
);
85 str_liberror(ctx
, ret
, _("queueing repair work"));
90 ret
= -workqueue_terminate(&wq
);
92 str_liberror(ctx
, ret
, _("finishing repair work"));
93 workqueue_destroy(&wq
);
101 /* Decide if we have any repair work to do. */
104 struct scrub_ctx
*ctx
)
108 for (agno
= 0; agno
< ctx
->mnt
.fsgeom
.agcount
; agno
++) {
109 if (action_list_length(&ctx
->action_lists
[agno
]) > 0)
116 /* Trim the unused areas of the filesystem if the caller asked us to. */
119 struct scrub_ctx
*ctx
)
126 /* Fix everything that needs fixing. */
129 struct scrub_ctx
*ctx
)
133 if (!have_action_items(ctx
))
137 * Check the summary counters early. Normally we do this during phase
138 * seven, but some of the cross-referencing requires fairly-accurate
139 * counters, so counter repairs have to be put on the list now so that
140 * they get fixed before we stop retrying unfixed metadata repairs.
142 ret
= scrub_fs_summary(ctx
, &ctx
->action_lists
[0]);
146 ret
= repair_everything(ctx
);
151 * If errors remain on the filesystem, do not trim anything. We don't
152 * have any threads running, so it's ok to skip the ctx lock here.
154 if (ctx
->corruptions_found
|| ctx
->unfixable_errors
!= 0)
158 trim_filesystem(ctx
);
162 /* Estimate how much work we're going to do. */
165 struct scrub_ctx
*ctx
,
167 unsigned int *nr_threads
,
171 unsigned long long need_fixing
= 0;
173 for (agno
= 0; agno
< ctx
->mnt
.fsgeom
.agcount
; agno
++)
174 need_fixing
+= action_list_length(&ctx
->action_lists
[agno
]);
176 *items
= need_fixing
;
177 *nr_threads
= scrub_nproc(ctx
) + 1;