]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/phase4.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
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
;
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
, ctx
->mnt
.fd
, 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
, ctx
->mnt
.fd
, 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
);
98 pthread_mutex_lock(&ctx
->lock
);
99 if (ctx
->corruptions_found
== 0 && ctx
->unfixable_errors
== 0 &&
104 pthread_mutex_unlock(&ctx
->lock
);
109 /* Fix everything that needs fixing. */
112 struct scrub_ctx
*ctx
)
117 * Check the summary counters early. Normally we do this during phase
118 * seven, but some of the cross-referencing requires fairly-accurate
119 * counters, so counter repairs have to be put on the list now so that
120 * they get fixed before we stop retrying unfixed metadata repairs.
122 ret
= xfs_scrub_fs_summary(ctx
, &ctx
->action_lists
[0]);
126 return repair_everything(ctx
);
129 /* Estimate how much work we're going to do. */
132 struct scrub_ctx
*ctx
,
134 unsigned int *nr_threads
,
138 size_t need_fixing
= 0;
140 for (agno
= 0; agno
< ctx
->mnt
.fsgeom
.agcount
; agno
++)
141 need_fixing
+= action_list_length(&ctx
->action_lists
[agno
]);
143 *items
= need_fixing
;
144 *nr_threads
= scrub_nproc(ctx
) + 1;