]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/phase3.c
libxfs: refactor manage_zones()
[thirdparty/xfsprogs-dev.git] / repair / phase3.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
6b803e5a 7#include "libxfs.h"
1164bde5
DC
8#include "threads.h"
9#include "prefetch.h"
2bd0ea18
NS
10#include "avl.h"
11#include "globals.h"
12#include "agheader.h"
13#include "incore.h"
14#include "protos.h"
15#include "err_protos.h"
16#include "dinode.h"
06fbdda9 17#include "progress.h"
bd758142 18#include "bmap.h"
8100dd79 19#include "threads.h"
2bd0ea18 20
62b00e63
CH
21static void
22process_agi_unlinked(
23 struct xfs_mount *mp,
24 xfs_agnumber_t agno)
2bd0ea18 25{
62b00e63
CH
26 struct xfs_buf *bp;
27 struct xfs_agi *agip;
28 xfs_agnumber_t i;
29 int agi_dirty = 0;
2bd0ea18 30
9440d84d
NS
31 bp = libxfs_readbuf(mp->m_dev,
32 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
75c8b434 33 mp->m_sb.sb_sectsize/BBSIZE, 0, &xfs_agi_buf_ops);
507f4e33 34 if (!bp)
5d1b7f0f 35 do_error(_("cannot read agi block %" PRId64 " for ag %u\n"),
9440d84d 36 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), agno);
2bd0ea18
NS
37
38 agip = XFS_BUF_TO_AGI(bp);
39
62b00e63 40 ASSERT(be32_to_cpu(agip->agi_seqno) == agno);
2bd0ea18
NS
41
42 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
62b00e63
CH
43 if (agip->agi_unlinked[i] != cpu_to_be32(NULLAGINO)) {
44 agip->agi_unlinked[i] = cpu_to_be32(NULLAGINO);
45 agi_dirty = 1;
2bd0ea18
NS
46 }
47 }
48
62b00e63 49 if (agi_dirty)
2bd0ea18
NS
50 libxfs_writebuf(bp, 0);
51 else
52 libxfs_putbuf(bp);
53}
54
2556c98b
BN
55static void
56process_ag_func(
62843f36 57 struct workqueue *wq,
2556c98b
BN
58 xfs_agnumber_t agno,
59 void *arg)
3b6ac903
MV
60{
61 /*
62 * turn on directory processing (inode discovery) and
63 * attribute processing (extra_attr_check)
64 */
2556c98b 65 wait_for_inode_prefetch(arg);
3b6ac903 66 do_log(_(" - agno = %d\n"), agno);
62843f36 67 process_aginodes(wq->wq_ctx, arg, agno, 1, 0, 1);
bd758142 68 blkmap_free_final();
2556c98b
BN
69 cleanup_inode_prefetch(arg);
70}
71
72static void
73process_ags(
74 xfs_mount_t *mp)
75{
1164bde5 76 do_inode_prefetch(mp, ag_stride, process_ag_func, false, false);
3b6ac903
MV
77}
78
8100dd79
DC
79static void
80do_uncertain_aginodes(
62843f36
DW
81 struct workqueue *wq,
82 xfs_agnumber_t agno,
83 void *arg)
8100dd79 84{
62843f36 85 int *count = arg;
8100dd79 86
62843f36 87 *count = process_uncertain_aginodes(wq->wq_ctx, agno);
8100dd79
DC
88
89#ifdef XR_INODE_TRACE
90 fprintf(stderr,
91 "\t\t phase 3 - ag %d process_uncertain_inodes returns %d\n",
92 *count, j);
93#endif
94
95 PROG_RPT_INC(prog_rpt_done[agno], 1);
96}
97
2bd0ea18 98void
8100dd79
DC
99phase3(
100 struct xfs_mount *mp,
101 int scan_threads)
2bd0ea18 102{
8100dd79
DC
103 int i, j;
104 int *counts;
62843f36 105 struct workqueue wq;
2bd0ea18 106
507f4e33 107 do_log(_("Phase 3 - for each AG...\n"));
2bd0ea18 108 if (!no_modify)
507f4e33 109 do_log(_(" - scan and clear agi unlinked lists...\n"));
2bd0ea18 110 else
507f4e33 111 do_log(_(" - scan (but don't clear) agi unlinked lists...\n"));
2bd0ea18 112
14f8b681 113 set_progress_msg(PROG_FMT_AGI_UNLINKED, (uint64_t) glob_agcount);
06fbdda9 114
62b00e63
CH
115 /* first clear the agi unlinked AGI list */
116 if (!no_modify) {
117 for (i = 0; i < mp->m_sb.sb_agcount; i++)
118 process_agi_unlinked(mp, i);
119 }
120
121 /* now look at possibly bogus inodes */
2bd0ea18 122 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
2bd0ea18 123 check_uncertain_aginodes(mp, i);
06fbdda9 124 PROG_RPT_INC(prog_rpt_done[i], 1);
2bd0ea18 125 }
06fbdda9 126 print_final_rpt();
2bd0ea18
NS
127
128 /* ok, now that the tree's ok, let's take a good look */
129
507f4e33
NS
130 do_log(_(
131 " - process known inodes and perform inode discovery...\n"));
2bd0ea18 132
14f8b681 133 set_progress_msg(PROG_FMT_PROCESS_INO, (uint64_t) mp->m_sb.sb_icount);
2556c98b
BN
134
135 process_ags(mp);
136
06fbdda9 137 print_final_rpt();
2bd0ea18
NS
138
139 /*
140 * process newly discovered inode chunks
141 */
507f4e33 142 do_log(_(" - process newly discovered inodes...\n"));
14f8b681 143 set_progress_msg(PROG_FMT_NEW_INODES, (uint64_t) glob_agcount);
8100dd79
DC
144
145 counts = calloc(sizeof(*counts), mp->m_sb.sb_agcount);
146 if (!counts) {
147 do_abort(_("no memory for uncertain inode counts\n"));
148 return;
149 }
150
2bd0ea18
NS
151 do {
152 /*
153 * have to loop until no ag has any uncertain
154 * inodes
155 */
156 j = 0;
8100dd79
DC
157 memset(counts, 0, mp->m_sb.sb_agcount * sizeof(*counts));
158
159 create_work_queue(&wq, mp, scan_threads);
160
161 for (i = 0; i < mp->m_sb.sb_agcount; i++)
162 queue_work(&wq, do_uncertain_aginodes, i, &counts[i]);
163
164 destroy_work_queue(&wq);
165
166 /* tally up the counts */
167 for (i = 0; i < mp->m_sb.sb_agcount; i++)
168 j += counts[i];
169
2bd0ea18 170 } while (j != 0);
8100dd79
DC
171
172 free(counts);
173
06fbdda9 174 print_final_rpt();
2bd0ea18 175}