Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Copyright (C) 2018-2023 Oracle. All Rights Reserved.
4 : * Author: Darrick J. Wong <djwong@kernel.org>
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_trans_resv.h"
11 : #include "xfs_mount.h"
12 : #include "xfs_btree.h"
13 : #include "xfs_btree_staging.h"
14 : #include "xfs_log_format.h"
15 : #include "xfs_trans.h"
16 : #include "xfs_sb.h"
17 : #include "xfs_alloc.h"
18 : #include "xfs_alloc_btree.h"
19 : #include "xfs_ialloc.h"
20 : #include "xfs_ialloc_btree.h"
21 : #include "xfs_rmap.h"
22 : #include "xfs_rmap_btree.h"
23 : #include "xfs_refcount_btree.h"
24 : #include "xfs_ag.h"
25 : #include "xfs_inode.h"
26 : #include "xfs_iunlink_item.h"
27 : #include "scrub/scrub.h"
28 : #include "scrub/common.h"
29 : #include "scrub/trace.h"
30 : #include "scrub/repair.h"
31 : #include "scrub/bitmap.h"
32 : #include "scrub/reap.h"
33 : #include "scrub/xfile.h"
34 : #include "scrub/xfarray.h"
35 :
36 : /* Superblock */
37 :
38 : /* Repair the superblock. */
39 : int
40 149519 : xrep_superblock(
41 : struct xfs_scrub *sc)
42 : {
43 149519 : struct xfs_mount *mp = sc->mp;
44 149519 : struct xfs_buf *bp;
45 149519 : xfs_agnumber_t agno;
46 149519 : int error;
47 :
48 : /* Don't try to repair AG 0's sb; let xfs_repair deal with it. */
49 149519 : agno = sc->sm->sm_agno;
50 149519 : if (agno == 0)
51 : return -EOPNOTSUPP;
52 :
53 146017 : error = xfs_sb_get_secondary(mp, sc->tp, agno, &bp);
54 146016 : if (error)
55 : return error;
56 :
57 : /* Last chance to abort before we start committing fixes. */
58 146016 : if (xchk_should_terminate(sc, &error))
59 0 : return error;
60 :
61 : /* Copy AG 0's superblock to this one. */
62 146014 : xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
63 146017 : xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
64 :
65 : /*
66 : * Don't write out a secondary super with NEEDSREPAIR or log incompat
67 : * features set, since both are ignored when set on a secondary.
68 : */
69 146017 : if (xfs_has_crc(mp)) {
70 146017 : struct xfs_dsb *sb = bp->b_addr;
71 :
72 146017 : sb->sb_features_incompat &=
73 : ~cpu_to_be32(XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR);
74 146017 : sb->sb_features_log_incompat = 0;
75 : }
76 :
77 : /* Write this to disk. */
78 146017 : xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_SB_BUF);
79 146017 : xfs_trans_log_buf(sc->tp, bp, 0, BBTOB(bp->b_length) - 1);
80 146015 : return error;
81 : }
82 :
83 : /* AGF */
84 :
85 : struct xrep_agf_allocbt {
86 : struct xfs_scrub *sc;
87 : xfs_agblock_t freeblks;
88 : xfs_agblock_t longest;
89 : };
90 :
91 : /* Record free space shape information. */
92 : STATIC int
93 172085064 : xrep_agf_walk_allocbt(
94 : struct xfs_btree_cur *cur,
95 : const struct xfs_alloc_rec_incore *rec,
96 : void *priv)
97 : {
98 172085064 : struct xrep_agf_allocbt *raa = priv;
99 172085064 : int error = 0;
100 :
101 172085064 : if (xchk_should_terminate(raa->sc, &error))
102 0 : return error;
103 :
104 172085132 : raa->freeblks += rec->ar_blockcount;
105 172085132 : if (rec->ar_blockcount > raa->longest)
106 411212 : raa->longest = rec->ar_blockcount;
107 172085132 : return error;
108 : }
109 :
110 : /* Does this AGFL block look sane? */
111 : STATIC int
112 529961 : xrep_agf_check_agfl_block(
113 : struct xfs_mount *mp,
114 : xfs_agblock_t agbno,
115 : void *priv)
116 : {
117 529961 : struct xfs_scrub *sc = priv;
118 :
119 529961 : if (!xfs_verify_agbno(sc->sa.pag, agbno))
120 0 : return -EFSCORRUPTED;
121 : return 0;
122 : }
123 :
124 : /*
125 : * Offset within the xrep_find_ag_btree array for each btree type. Avoid the
126 : * XFS_BTNUM_ names here to avoid creating a sparse array.
127 : */
128 : enum {
129 : XREP_AGF_BNOBT = 0,
130 : XREP_AGF_CNTBT,
131 : XREP_AGF_RMAPBT,
132 : XREP_AGF_REFCOUNTBT,
133 : XREP_AGF_END,
134 : XREP_AGF_MAX
135 : };
136 :
137 : /* Check a btree root candidate. */
138 : static inline bool
139 : xrep_check_btree_root(
140 : struct xfs_scrub *sc,
141 : struct xrep_find_ag_btree *fab)
142 : {
143 253472 : return xfs_verify_agbno(sc->sa.pag, fab->root) &&
144 385754 : fab->height <= fab->maxlevels;
145 : }
146 :
147 : /*
148 : * Given the btree roots described by *fab, find the roots, check them for
149 : * sanity, and pass the root data back out via *fab.
150 : *
151 : * This is /also/ a chicken and egg problem because we have to use the rmapbt
152 : * (rooted in the AGF) to find the btrees rooted in the AGF. We also have no
153 : * idea if the btrees make any sense. If we hit obvious corruptions in those
154 : * btrees we'll bail out.
155 : */
156 : STATIC int
157 60595 : xrep_agf_find_btrees(
158 : struct xfs_scrub *sc,
159 : struct xfs_buf *agf_bp,
160 : struct xrep_find_ag_btree *fab,
161 : struct xfs_buf *agfl_bp)
162 : {
163 60595 : struct xfs_agf *old_agf = agf_bp->b_addr;
164 60595 : int error;
165 :
166 : /* Go find the root data. */
167 60595 : error = xrep_find_ag_btree_roots(sc, agf_bp, fab, agfl_bp);
168 60595 : if (error)
169 : return error;
170 :
171 : /* We must find the bnobt, cntbt, and rmapbt roots. */
172 181785 : if (!xrep_check_btree_root(sc, &fab[XREP_AGF_BNOBT]) ||
173 60595 : !xrep_check_btree_root(sc, &fab[XREP_AGF_CNTBT]) ||
174 : !xrep_check_btree_root(sc, &fab[XREP_AGF_RMAPBT]))
175 : return -EFSCORRUPTED;
176 :
177 : /*
178 : * We relied on the rmapbt to reconstruct the AGF. If we get a
179 : * different root then something's seriously wrong.
180 : */
181 60595 : if (fab[XREP_AGF_RMAPBT].root !=
182 60595 : be32_to_cpu(old_agf->agf_roots[XFS_BTNUM_RMAPi]))
183 : return -EFSCORRUPTED;
184 :
185 : /* We must find the refcountbt root if that feature is enabled. */
186 121190 : if (xfs_has_reflink(sc->mp) &&
187 : !xrep_check_btree_root(sc, &fab[XREP_AGF_REFCOUNTBT]))
188 0 : return -EFSCORRUPTED;
189 :
190 : return 0;
191 : }
192 :
193 : /*
194 : * Reinitialize the AGF header, making an in-core copy of the old contents so
195 : * that we know which in-core state needs to be reinitialized.
196 : */
197 : STATIC void
198 60595 : xrep_agf_init_header(
199 : struct xfs_scrub *sc,
200 : struct xfs_buf *agf_bp,
201 : struct xfs_agf *old_agf)
202 : {
203 60595 : struct xfs_mount *mp = sc->mp;
204 60595 : struct xfs_perag *pag = sc->sa.pag;
205 60595 : struct xfs_agf *agf = agf_bp->b_addr;
206 :
207 121190 : memcpy(old_agf, agf, sizeof(*old_agf));
208 60595 : memset(agf, 0, BBTOB(agf_bp->b_length));
209 60595 : agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
210 60595 : agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
211 60595 : agf->agf_seqno = cpu_to_be32(pag->pag_agno);
212 60595 : agf->agf_length = cpu_to_be32(pag->block_count);
213 60595 : agf->agf_flfirst = old_agf->agf_flfirst;
214 60595 : agf->agf_fllast = old_agf->agf_fllast;
215 60595 : agf->agf_flcount = old_agf->agf_flcount;
216 60595 : if (xfs_has_crc(mp))
217 60595 : uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
218 :
219 : /* Mark the incore AGF data stale until we're done fixing things. */
220 121190 : ASSERT(xfs_perag_initialised_agf(pag));
221 60595 : clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
222 60595 : }
223 :
224 : /* Set btree root information in an AGF. */
225 : STATIC void
226 60595 : xrep_agf_set_roots(
227 : struct xfs_scrub *sc,
228 : struct xfs_agf *agf,
229 : struct xrep_find_ag_btree *fab)
230 : {
231 121190 : agf->agf_roots[XFS_BTNUM_BNOi] =
232 60595 : cpu_to_be32(fab[XREP_AGF_BNOBT].root);
233 121190 : agf->agf_levels[XFS_BTNUM_BNOi] =
234 60595 : cpu_to_be32(fab[XREP_AGF_BNOBT].height);
235 :
236 121190 : agf->agf_roots[XFS_BTNUM_CNTi] =
237 60595 : cpu_to_be32(fab[XREP_AGF_CNTBT].root);
238 121190 : agf->agf_levels[XFS_BTNUM_CNTi] =
239 60595 : cpu_to_be32(fab[XREP_AGF_CNTBT].height);
240 :
241 121190 : agf->agf_roots[XFS_BTNUM_RMAPi] =
242 60595 : cpu_to_be32(fab[XREP_AGF_RMAPBT].root);
243 121190 : agf->agf_levels[XFS_BTNUM_RMAPi] =
244 60595 : cpu_to_be32(fab[XREP_AGF_RMAPBT].height);
245 :
246 60595 : if (xfs_has_reflink(sc->mp)) {
247 121190 : agf->agf_refcount_root =
248 60595 : cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].root);
249 60595 : agf->agf_refcount_level =
250 60595 : cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].height);
251 : }
252 60595 : }
253 :
254 : /* Update all AGF fields which derive from btree contents. */
255 : STATIC int
256 60595 : xrep_agf_calc_from_btrees(
257 : struct xfs_scrub *sc,
258 : struct xfs_buf *agf_bp)
259 : {
260 60595 : struct xrep_agf_allocbt raa = { .sc = sc };
261 60595 : struct xfs_btree_cur *cur = NULL;
262 60595 : struct xfs_agf *agf = agf_bp->b_addr;
263 60595 : struct xfs_mount *mp = sc->mp;
264 60595 : xfs_agblock_t btreeblks;
265 60595 : xfs_agblock_t blocks;
266 60595 : int error;
267 :
268 : /* Update the AGF counters from the bnobt. */
269 60595 : cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
270 : sc->sa.pag, XFS_BTNUM_BNO);
271 60595 : error = xfs_alloc_query_all(cur, xrep_agf_walk_allocbt, &raa);
272 60595 : if (error)
273 0 : goto err;
274 60595 : error = xfs_btree_count_blocks(cur, &blocks);
275 60595 : if (error)
276 0 : goto err;
277 60595 : xfs_btree_del_cursor(cur, error);
278 60595 : btreeblks = blocks - 1;
279 60595 : agf->agf_freeblks = cpu_to_be32(raa.freeblks);
280 60595 : agf->agf_longest = cpu_to_be32(raa.longest);
281 :
282 : /* Update the AGF counters from the cntbt. */
283 60595 : cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
284 : sc->sa.pag, XFS_BTNUM_CNT);
285 60595 : error = xfs_btree_count_blocks(cur, &blocks);
286 60595 : if (error)
287 0 : goto err;
288 60595 : xfs_btree_del_cursor(cur, error);
289 60595 : btreeblks += blocks - 1;
290 :
291 : /* Update the AGF counters from the rmapbt. */
292 60595 : cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag);
293 60595 : error = xfs_btree_count_blocks(cur, &blocks);
294 60595 : if (error)
295 0 : goto err;
296 60595 : xfs_btree_del_cursor(cur, error);
297 60595 : agf->agf_rmap_blocks = cpu_to_be32(blocks);
298 60595 : btreeblks += blocks - 1;
299 :
300 60595 : agf->agf_btreeblks = cpu_to_be32(btreeblks);
301 :
302 : /* Update the AGF counters from the refcountbt. */
303 60595 : if (xfs_has_reflink(mp)) {
304 60595 : cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp,
305 : sc->sa.pag);
306 60595 : error = xfs_btree_count_blocks(cur, &blocks);
307 60595 : if (error)
308 0 : goto err;
309 60595 : xfs_btree_del_cursor(cur, error);
310 121190 : agf->agf_refcount_blocks = cpu_to_be32(blocks);
311 : }
312 :
313 : return 0;
314 0 : err:
315 0 : xfs_btree_del_cursor(cur, error);
316 0 : return error;
317 : }
318 :
319 : /* Commit the new AGF and reinitialize the incore state. */
320 : STATIC int
321 60595 : xrep_agf_commit_new(
322 : struct xfs_scrub *sc,
323 : struct xfs_buf *agf_bp)
324 : {
325 60595 : struct xfs_perag *pag;
326 60595 : struct xfs_agf *agf = agf_bp->b_addr;
327 :
328 : /* Trigger fdblocks recalculation */
329 60595 : xfs_force_summary_recalc(sc->mp);
330 :
331 : /* Write this to disk. */
332 60595 : xfs_trans_buf_set_type(sc->tp, agf_bp, XFS_BLFT_AGF_BUF);
333 60595 : xfs_trans_log_buf(sc->tp, agf_bp, 0, BBTOB(agf_bp->b_length) - 1);
334 :
335 : /* Now reinitialize the in-core counters we changed. */
336 60595 : pag = sc->sa.pag;
337 60595 : pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
338 60595 : pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
339 60595 : pag->pagf_longest = be32_to_cpu(agf->agf_longest);
340 60595 : pag->pagf_levels[XFS_BTNUM_BNOi] =
341 60595 : be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
342 60595 : pag->pagf_levels[XFS_BTNUM_CNTi] =
343 60595 : be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
344 60595 : pag->pagf_levels[XFS_BTNUM_RMAPi] =
345 60595 : be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
346 60595 : pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
347 60595 : set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
348 :
349 60595 : return 0;
350 : }
351 :
352 : /* Repair the AGF. v5 filesystems only. */
353 : int
354 64504 : xrep_agf(
355 : struct xfs_scrub *sc)
356 : {
357 64504 : struct xrep_find_ag_btree fab[XREP_AGF_MAX] = {
358 : [XREP_AGF_BNOBT] = {
359 : .rmap_owner = XFS_RMAP_OWN_AG,
360 : .buf_ops = &xfs_bnobt_buf_ops,
361 64504 : .maxlevels = sc->mp->m_alloc_maxlevels,
362 : },
363 : [XREP_AGF_CNTBT] = {
364 : .rmap_owner = XFS_RMAP_OWN_AG,
365 : .buf_ops = &xfs_cntbt_buf_ops,
366 : .maxlevels = sc->mp->m_alloc_maxlevels,
367 : },
368 : [XREP_AGF_RMAPBT] = {
369 : .rmap_owner = XFS_RMAP_OWN_AG,
370 : .buf_ops = &xfs_rmapbt_buf_ops,
371 64504 : .maxlevels = sc->mp->m_rmap_maxlevels,
372 : },
373 : [XREP_AGF_REFCOUNTBT] = {
374 : .rmap_owner = XFS_RMAP_OWN_REFC,
375 : .buf_ops = &xfs_refcountbt_buf_ops,
376 64504 : .maxlevels = sc->mp->m_refc_maxlevels,
377 : },
378 : [XREP_AGF_END] = {
379 : .buf_ops = NULL,
380 : },
381 : };
382 64504 : struct xfs_agf old_agf;
383 64504 : struct xfs_mount *mp = sc->mp;
384 64504 : struct xfs_buf *agf_bp;
385 64504 : struct xfs_buf *agfl_bp;
386 64504 : struct xfs_agf *agf;
387 64504 : int error;
388 :
389 : /* We require the rmapbt to rebuild anything. */
390 64504 : if (!xfs_has_rmapbt(mp))
391 : return -EOPNOTSUPP;
392 :
393 : /*
394 : * Make sure we have the AGF buffer, as scrub might have decided it
395 : * was corrupt after xfs_alloc_read_agf failed with -EFSCORRUPTED.
396 : */
397 121190 : error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
398 60595 : XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
399 : XFS_AGF_DADDR(mp)),
400 : XFS_FSS_TO_BB(mp, 1), 0, &agf_bp, NULL);
401 60595 : if (error)
402 : return error;
403 60595 : agf_bp->b_ops = &xfs_agf_buf_ops;
404 60595 : agf = agf_bp->b_addr;
405 :
406 : /*
407 : * Load the AGFL so that we can screen out OWN_AG blocks that are on
408 : * the AGFL now; these blocks might have once been part of the
409 : * bno/cnt/rmap btrees but are not now. This is a chicken and egg
410 : * problem: the AGF is corrupt, so we have to trust the AGFL contents
411 : * because we can't do any serious cross-referencing with any of the
412 : * btrees rooted in the AGF. If the AGFL contents are obviously bad
413 : * then we'll bail out.
414 : */
415 60595 : error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &agfl_bp);
416 60595 : if (error)
417 : return error;
418 :
419 : /*
420 : * Spot-check the AGFL blocks; if they're obviously corrupt then
421 : * there's nothing we can do but bail out.
422 : */
423 60595 : error = xfs_agfl_walk(sc->mp, agf_bp->b_addr, agfl_bp,
424 : xrep_agf_check_agfl_block, sc);
425 60595 : if (error)
426 : return error;
427 :
428 : /*
429 : * Find the AGF btree roots. This is also a chicken-and-egg situation;
430 : * see the function for more details.
431 : */
432 60595 : error = xrep_agf_find_btrees(sc, agf_bp, fab, agfl_bp);
433 60595 : if (error)
434 : return error;
435 :
436 : /* Last chance to abort before we start committing fixes. */
437 60595 : if (xchk_should_terminate(sc, &error))
438 0 : return error;
439 :
440 : /* Start rewriting the header and implant the btrees we found. */
441 60595 : xrep_agf_init_header(sc, agf_bp, &old_agf);
442 60595 : xrep_agf_set_roots(sc, agf, fab);
443 60595 : error = xrep_agf_calc_from_btrees(sc, agf_bp);
444 60595 : if (error)
445 0 : goto out_revert;
446 :
447 : /* Commit the changes and reinitialize incore state. */
448 60595 : return xrep_agf_commit_new(sc, agf_bp);
449 :
450 : out_revert:
451 : /* Mark the incore AGF state stale and revert the AGF. */
452 0 : clear_bit(XFS_AGSTATE_AGF_INIT, &sc->sa.pag->pag_opstate);
453 0 : memcpy(agf, &old_agf, sizeof(old_agf));
454 0 : return error;
455 : }
456 :
457 : /* AGFL */
458 :
459 : struct xrep_agfl {
460 : /* Bitmap of alleged AGFL blocks that we're not going to add. */
461 : struct xagb_bitmap crossed;
462 :
463 : /* Bitmap of other OWN_AG metadata blocks. */
464 : struct xagb_bitmap agmetablocks;
465 :
466 : /* Bitmap of free space. */
467 : struct xagb_bitmap *freesp;
468 :
469 : /* rmapbt cursor for finding crosslinked blocks */
470 : struct xfs_btree_cur *rmap_cur;
471 :
472 : struct xfs_scrub *sc;
473 : };
474 :
475 : /* Record all OWN_AG (free space btree) information from the rmap data. */
476 : STATIC int
477 1797157236 : xrep_agfl_walk_rmap(
478 : struct xfs_btree_cur *cur,
479 : const struct xfs_rmap_irec *rec,
480 : void *priv)
481 : {
482 1797157236 : struct xrep_agfl *ra = priv;
483 1797157236 : int error = 0;
484 :
485 1797157236 : if (xchk_should_terminate(ra->sc, &error))
486 0 : return error;
487 :
488 : /* Record all the OWN_AG blocks. */
489 1797157267 : if (rec->rm_owner == XFS_RMAP_OWN_AG) {
490 26558028 : error = xagb_bitmap_set(ra->freesp, rec->rm_startblock,
491 13279014 : rec->rm_blockcount);
492 13279014 : if (error)
493 : return error;
494 : }
495 :
496 1797157267 : return xagb_bitmap_set_btcur_path(&ra->agmetablocks, cur);
497 : }
498 :
499 : /* Strike out the blocks that are cross-linked according to the rmapbt. */
500 : STATIC int
501 414542 : xrep_agfl_check_extent(
502 : uint64_t start,
503 : uint64_t len,
504 : void *priv)
505 : {
506 414542 : struct xrep_agfl *ra = priv;
507 414542 : xfs_agblock_t agbno = start;
508 414542 : xfs_agblock_t last_agbno = agbno + len - 1;
509 414542 : int error;
510 :
511 896608 : while (agbno <= last_agbno) {
512 482066 : bool other_owners;
513 :
514 482066 : error = xfs_rmap_has_other_keys(ra->rmap_cur, agbno, 1,
515 : &XFS_RMAP_OINFO_AG, &other_owners);
516 482066 : if (error)
517 0 : return error;
518 :
519 482066 : if (other_owners) {
520 0 : error = xagb_bitmap_set(&ra->crossed, agbno, 1);
521 0 : if (error)
522 0 : return error;
523 : }
524 :
525 482066 : if (xchk_should_terminate(ra->sc, &error))
526 0 : return error;
527 482066 : agbno++;
528 : }
529 :
530 : return 0;
531 : }
532 :
533 : /*
534 : * Map out all the non-AGFL OWN_AG space in this AG so that we can deduce
535 : * which blocks belong to the AGFL.
536 : *
537 : * Compute the set of old AGFL blocks by subtracting from the list of OWN_AG
538 : * blocks the list of blocks owned by all other OWN_AG metadata (bnobt, cntbt,
539 : * rmapbt). These are the old AGFL blocks, so return that list and the number
540 : * of blocks we're actually going to put back on the AGFL.
541 : */
542 : STATIC int
543 54447 : xrep_agfl_collect_blocks(
544 : struct xfs_scrub *sc,
545 : struct xfs_buf *agf_bp,
546 : struct xagb_bitmap *agfl_extents,
547 : xfs_agblock_t *flcount)
548 : {
549 54447 : struct xrep_agfl ra;
550 54447 : struct xfs_mount *mp = sc->mp;
551 54447 : struct xfs_btree_cur *cur;
552 54447 : int error;
553 :
554 54447 : ra.sc = sc;
555 54447 : ra.freesp = agfl_extents;
556 54447 : xagb_bitmap_init(&ra.agmetablocks);
557 54447 : xagb_bitmap_init(&ra.crossed);
558 :
559 : /* Find all space used by the free space btrees & rmapbt. */
560 54447 : cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag);
561 54447 : error = xfs_rmap_query_all(cur, xrep_agfl_walk_rmap, &ra);
562 54447 : xfs_btree_del_cursor(cur, error);
563 54447 : if (error)
564 0 : goto out_bmp;
565 :
566 : /* Find all blocks currently being used by the bnobt. */
567 54447 : cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
568 : sc->sa.pag, XFS_BTNUM_BNO);
569 54447 : error = xagb_bitmap_set_btblocks(&ra.agmetablocks, cur);
570 54447 : xfs_btree_del_cursor(cur, error);
571 54447 : if (error)
572 0 : goto out_bmp;
573 :
574 : /* Find all blocks currently being used by the cntbt. */
575 54447 : cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
576 : sc->sa.pag, XFS_BTNUM_CNT);
577 54447 : error = xagb_bitmap_set_btblocks(&ra.agmetablocks, cur);
578 54447 : xfs_btree_del_cursor(cur, error);
579 54447 : if (error)
580 0 : goto out_bmp;
581 :
582 : /*
583 : * Drop the freesp meta blocks that are in use by btrees.
584 : * The remaining blocks /should/ be AGFL blocks.
585 : */
586 54447 : error = xagb_bitmap_disunion(agfl_extents, &ra.agmetablocks);
587 54447 : if (error)
588 0 : goto out_bmp;
589 :
590 : /* Strike out the blocks that are cross-linked. */
591 54447 : ra.rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag);
592 54447 : error = xagb_bitmap_walk(agfl_extents, xrep_agfl_check_extent, &ra);
593 54447 : xfs_btree_del_cursor(ra.rmap_cur, error);
594 54447 : if (error)
595 0 : goto out_bmp;
596 54447 : error = xagb_bitmap_disunion(agfl_extents, &ra.crossed);
597 54447 : if (error)
598 0 : goto out_bmp;
599 :
600 : /*
601 : * Calculate the new AGFL size. If we found more blocks than fit in
602 : * the AGFL we'll free them later.
603 : */
604 54447 : *flcount = min_t(uint64_t, xagb_bitmap_hweight(agfl_extents),
605 : xfs_agfl_size(mp));
606 :
607 54447 : out_bmp:
608 54447 : xagb_bitmap_destroy(&ra.crossed);
609 54447 : xagb_bitmap_destroy(&ra.agmetablocks);
610 54447 : return error;
611 : }
612 :
613 : /* Update the AGF and reset the in-core state. */
614 : STATIC void
615 54447 : xrep_agfl_update_agf(
616 : struct xfs_scrub *sc,
617 : struct xfs_buf *agf_bp,
618 : xfs_agblock_t flcount)
619 : {
620 54447 : struct xfs_agf *agf = agf_bp->b_addr;
621 :
622 54447 : ASSERT(flcount <= xfs_agfl_size(sc->mp));
623 :
624 : /* Trigger fdblocks recalculation */
625 54447 : xfs_force_summary_recalc(sc->mp);
626 :
627 : /* Update the AGF counters. */
628 108894 : if (xfs_perag_initialised_agf(sc->sa.pag)) {
629 54447 : sc->sa.pag->pagf_flcount = flcount;
630 54447 : clear_bit(XFS_AGSTATE_AGFL_NEEDS_RESET,
631 54447 : &sc->sa.pag->pag_opstate);
632 : }
633 54447 : agf->agf_flfirst = cpu_to_be32(0);
634 54447 : agf->agf_flcount = cpu_to_be32(flcount);
635 54447 : if (flcount)
636 108894 : agf->agf_fllast = cpu_to_be32(flcount - 1);
637 : else
638 0 : agf->agf_fllast = cpu_to_be32(xfs_agfl_size(sc->mp) - 1);
639 :
640 54447 : xfs_alloc_log_agf(sc->tp, agf_bp,
641 : XFS_AGF_FLFIRST | XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
642 54447 : }
643 :
644 : struct xrep_agfl_fill {
645 : struct xagb_bitmap used_extents;
646 : struct xfs_scrub *sc;
647 : __be32 *agfl_bno;
648 : xfs_agblock_t flcount;
649 : unsigned int fl_off;
650 : };
651 :
652 : /* Fill the AGFL with whatever blocks are in this extent. */
653 : static int
654 414542 : xrep_agfl_fill(
655 : uint64_t start,
656 : uint64_t len,
657 : void *priv)
658 : {
659 414542 : struct xrep_agfl_fill *af = priv;
660 414542 : struct xfs_scrub *sc = af->sc;
661 414542 : xfs_agblock_t agbno = start;
662 414542 : int error;
663 :
664 414542 : trace_xrep_agfl_insert(sc->sa.pag, agbno, len);
665 :
666 896608 : while (agbno < start + len && af->fl_off < af->flcount)
667 482066 : af->agfl_bno[af->fl_off++] = cpu_to_be32(agbno++);
668 :
669 414542 : error = xagb_bitmap_set(&af->used_extents, start, agbno - 1);
670 414542 : if (error)
671 : return error;
672 :
673 414542 : if (af->fl_off == af->flcount)
674 54447 : return -ECANCELED;
675 :
676 : return 0;
677 : }
678 :
679 : /* Write out a totally new AGFL. */
680 : STATIC int
681 54447 : xrep_agfl_init_header(
682 : struct xfs_scrub *sc,
683 : struct xfs_buf *agfl_bp,
684 : struct xagb_bitmap *agfl_extents,
685 : xfs_agblock_t flcount)
686 : {
687 54447 : struct xrep_agfl_fill af = {
688 : .sc = sc,
689 : .flcount = flcount,
690 : };
691 54447 : struct xfs_mount *mp = sc->mp;
692 54447 : struct xfs_agfl *agfl;
693 54447 : int error;
694 :
695 54447 : ASSERT(flcount <= xfs_agfl_size(mp));
696 :
697 : /*
698 : * Start rewriting the header by setting the bno[] array to
699 : * NULLAGBLOCK, then setting AGFL header fields.
700 : */
701 54447 : agfl = XFS_BUF_TO_AGFL(agfl_bp);
702 54447 : memset(agfl, 0xFF, BBTOB(agfl_bp->b_length));
703 54447 : agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
704 54447 : agfl->agfl_seqno = cpu_to_be32(sc->sa.pag->pag_agno);
705 54447 : uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
706 :
707 : /*
708 : * Fill the AGFL with the remaining blocks. If agfl_extents has more
709 : * blocks than fit in the AGFL, they will be freed in a subsequent
710 : * step.
711 : */
712 54447 : xagb_bitmap_init(&af.used_extents);
713 108894 : af.agfl_bno = xfs_buf_to_agfl_bno(agfl_bp),
714 : xagb_bitmap_walk(agfl_extents, xrep_agfl_fill, &af);
715 54447 : error = xagb_bitmap_disunion(agfl_extents, &af.used_extents);
716 54447 : if (error)
717 : return error;
718 :
719 : /* Write new AGFL to disk. */
720 54447 : xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF);
721 54447 : xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1);
722 54447 : xagb_bitmap_destroy(&af.used_extents);
723 54447 : return 0;
724 : }
725 :
726 : /* Repair the AGFL. */
727 : int
728 58356 : xrep_agfl(
729 : struct xfs_scrub *sc)
730 : {
731 58356 : struct xagb_bitmap agfl_extents;
732 58356 : struct xfs_mount *mp = sc->mp;
733 58356 : struct xfs_buf *agf_bp;
734 58356 : struct xfs_buf *agfl_bp;
735 58356 : xfs_agblock_t flcount;
736 58356 : int error;
737 :
738 : /* We require the rmapbt to rebuild anything. */
739 58356 : if (!xfs_has_rmapbt(mp))
740 : return -EOPNOTSUPP;
741 :
742 54447 : xagb_bitmap_init(&agfl_extents);
743 :
744 : /*
745 : * Read the AGF so that we can query the rmapbt. We hope that there's
746 : * nothing wrong with the AGF, but all the AG header repair functions
747 : * have this chicken-and-egg problem.
748 : */
749 54447 : error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp);
750 54447 : if (error)
751 : return error;
752 :
753 : /*
754 : * Make sure we have the AGFL buffer, as scrub might have decided it
755 : * was corrupt after xfs_alloc_read_agfl failed with -EFSCORRUPTED.
756 : */
757 108894 : error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
758 54447 : XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
759 : XFS_AGFL_DADDR(mp)),
760 : XFS_FSS_TO_BB(mp, 1), 0, &agfl_bp, NULL);
761 54447 : if (error)
762 : return error;
763 54447 : agfl_bp->b_ops = &xfs_agfl_buf_ops;
764 :
765 : /* Gather all the extents we're going to put on the new AGFL. */
766 54447 : error = xrep_agfl_collect_blocks(sc, agf_bp, &agfl_extents, &flcount);
767 54447 : if (error)
768 0 : goto err;
769 :
770 : /* Last chance to abort before we start committing fixes. */
771 54447 : if (xchk_should_terminate(sc, &error))
772 0 : goto err;
773 :
774 : /*
775 : * Update AGF and AGFL. We reset the global free block counter when
776 : * we adjust the AGF flcount (which can fail) so avoid updating any
777 : * buffers until we know that part works.
778 : */
779 54447 : xrep_agfl_update_agf(sc, agf_bp, flcount);
780 54447 : error = xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount);
781 54447 : if (error)
782 0 : goto err;
783 :
784 : /*
785 : * Ok, the AGFL should be ready to go now. Roll the transaction to
786 : * make the new AGFL permanent before we start using it to return
787 : * freespace overflow to the freespace btrees.
788 : */
789 54447 : sc->sa.agf_bp = agf_bp;
790 54447 : error = xrep_roll_ag_trans(sc);
791 54447 : if (error)
792 0 : goto err;
793 :
794 : /* Dump any AGFL overflow. */
795 54447 : error = xrep_reap_agblocks(sc, &agfl_extents, &XFS_RMAP_OINFO_AG,
796 : XFS_AG_RESV_AGFL);
797 54447 : err:
798 54447 : xagb_bitmap_destroy(&agfl_extents);
799 54447 : return error;
800 : }
801 :
802 : /* AGI */
803 :
804 : /*
805 : * Offset within the xrep_find_ag_btree array for each btree type. Avoid the
806 : * XFS_BTNUM_ names here to avoid creating a sparse array.
807 : */
808 : enum {
809 : XREP_AGI_INOBT = 0,
810 : XREP_AGI_FINOBT,
811 : XREP_AGI_END,
812 : XREP_AGI_MAX
813 : };
814 :
815 : #define XREP_AGI_LOOKUP_BATCH 32
816 :
817 : struct xrep_agi {
818 : struct xfs_scrub *sc;
819 :
820 : /* AGI buffer, tracked separately */
821 : struct xfs_buf *agi_bp;
822 :
823 : /* context for finding btree roots */
824 : struct xrep_find_ag_btree fab[XREP_AGI_MAX];
825 :
826 : /* old AGI contents in case we have to revert */
827 : struct xfs_agi old_agi;
828 :
829 : /* bitmap of which inodes are unlinked */
830 : struct xbitmap iunlink_bmp;
831 :
832 : /* heads of the unlinked inode bucket lists */
833 : xfs_agino_t iunlink_heads[XFS_AGI_UNLINKED_BUCKETS];
834 :
835 : /* scratchpad for batched lookups of the radix tree */
836 : struct xfs_inode *lookup_batch[XREP_AGI_LOOKUP_BATCH];
837 :
838 : /* Map of ino -> next_ino for unlinked inode processing. */
839 : struct xfarray *iunlink_next;
840 :
841 : /* Map of ino -> prev_ino for unlinked inode processing. */
842 : struct xfarray *iunlink_prev;
843 : };
844 :
845 : static void
846 71687 : xrep_agi_buf_cleanup(
847 : void *buf)
848 : {
849 71687 : struct xrep_agi *ragi = buf;
850 :
851 71687 : xfarray_destroy(ragi->iunlink_prev);
852 71687 : xfarray_destroy(ragi->iunlink_next);
853 71687 : xbitmap_destroy(&ragi->iunlink_bmp);
854 71687 : }
855 :
856 : /*
857 : * Given the inode btree roots described by *fab, find the roots, check them
858 : * for sanity, and pass the root data back out via *fab.
859 : */
860 : STATIC int
861 71687 : xrep_agi_find_btrees(
862 : struct xrep_agi *ragi)
863 : {
864 71687 : struct xfs_scrub *sc = ragi->sc;
865 71687 : struct xrep_find_ag_btree *fab = ragi->fab;
866 71687 : struct xfs_buf *agf_bp;
867 71687 : struct xfs_mount *mp = sc->mp;
868 71687 : int error;
869 :
870 : /* Read the AGF. */
871 71687 : error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp);
872 71687 : if (error)
873 : return error;
874 :
875 : /* Find the btree roots. */
876 71687 : error = xrep_find_ag_btree_roots(sc, agf_bp, fab, NULL);
877 71687 : if (error)
878 : return error;
879 :
880 : /* We must find the inobt root. */
881 143374 : if (!xrep_check_btree_root(sc, &fab[XREP_AGI_INOBT]))
882 : return -EFSCORRUPTED;
883 :
884 : /* We must find the finobt root if that feature is enabled. */
885 143374 : if (xfs_has_finobt(mp) &&
886 : !xrep_check_btree_root(sc, &fab[XREP_AGI_FINOBT]))
887 0 : return -EFSCORRUPTED;
888 :
889 : return 0;
890 : }
891 :
892 : /*
893 : * Reinitialize the AGI header, making an in-core copy of the old contents so
894 : * that we know which in-core state needs to be reinitialized.
895 : */
896 : STATIC void
897 71687 : xrep_agi_init_header(
898 : struct xrep_agi *ragi)
899 : {
900 71687 : struct xfs_scrub *sc = ragi->sc;
901 71687 : struct xfs_buf *agi_bp = ragi->agi_bp;
902 71687 : struct xfs_agi *old_agi = &ragi->old_agi;
903 71687 : struct xfs_agi *agi = agi_bp->b_addr;
904 71687 : struct xfs_perag *pag = sc->sa.pag;
905 71687 : struct xfs_mount *mp = sc->mp;
906 :
907 143374 : memcpy(old_agi, agi, sizeof(*old_agi));
908 71687 : memset(agi, 0, BBTOB(agi_bp->b_length));
909 71687 : agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
910 71687 : agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
911 71687 : agi->agi_seqno = cpu_to_be32(pag->pag_agno);
912 71687 : agi->agi_length = cpu_to_be32(pag->block_count);
913 71687 : agi->agi_newino = cpu_to_be32(NULLAGINO);
914 71687 : agi->agi_dirino = cpu_to_be32(NULLAGINO);
915 71687 : if (xfs_has_crc(mp))
916 71687 : uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
917 :
918 : /* Mark the incore AGF data stale until we're done fixing things. */
919 143374 : ASSERT(xfs_perag_initialised_agi(pag));
920 71687 : clear_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate);
921 71687 : }
922 :
923 : /* Set btree root information in an AGI. */
924 : STATIC void
925 71687 : xrep_agi_set_roots(
926 : struct xrep_agi *ragi)
927 : {
928 71687 : struct xfs_scrub *sc = ragi->sc;
929 71687 : struct xfs_agi *agi = ragi->agi_bp->b_addr;
930 71687 : struct xrep_find_ag_btree *fab = ragi->fab;
931 :
932 71687 : agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root);
933 71687 : agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height);
934 :
935 71687 : if (xfs_has_finobt(sc->mp)) {
936 71687 : agi->agi_free_root = cpu_to_be32(fab[XREP_AGI_FINOBT].root);
937 143374 : agi->agi_free_level = cpu_to_be32(fab[XREP_AGI_FINOBT].height);
938 : }
939 71687 : }
940 :
941 : /* Update the AGI counters. */
942 : STATIC int
943 71687 : xrep_agi_calc_from_btrees(
944 : struct xrep_agi *ragi)
945 : {
946 71687 : struct xfs_scrub *sc = ragi->sc;
947 71687 : struct xfs_buf *agi_bp = ragi->agi_bp;
948 71687 : struct xfs_btree_cur *cur;
949 71687 : struct xfs_agi *agi = agi_bp->b_addr;
950 71687 : struct xfs_mount *mp = sc->mp;
951 71687 : xfs_agino_t count;
952 71687 : xfs_agino_t freecount;
953 71687 : int error;
954 :
955 71687 : cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp, XFS_BTNUM_INO);
956 71687 : error = xfs_ialloc_count_inodes(cur, &count, &freecount);
957 71687 : if (error)
958 0 : goto err;
959 71687 : if (xfs_has_inobtcounts(mp)) {
960 71687 : xfs_agblock_t blocks;
961 :
962 71687 : error = xfs_btree_count_blocks(cur, &blocks);
963 71687 : if (error)
964 0 : goto err;
965 143374 : agi->agi_iblocks = cpu_to_be32(blocks);
966 : }
967 71687 : xfs_btree_del_cursor(cur, error);
968 :
969 71687 : agi->agi_count = cpu_to_be32(count);
970 71687 : agi->agi_freecount = cpu_to_be32(freecount);
971 :
972 71687 : if (xfs_has_finobt(mp) && xfs_has_inobtcounts(mp)) {
973 71687 : xfs_agblock_t blocks;
974 :
975 71687 : cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp,
976 : XFS_BTNUM_FINO);
977 71687 : error = xfs_btree_count_blocks(cur, &blocks);
978 71687 : if (error)
979 0 : goto err;
980 71687 : xfs_btree_del_cursor(cur, error);
981 143374 : agi->agi_fblocks = cpu_to_be32(blocks);
982 : }
983 :
984 : return 0;
985 0 : err:
986 0 : xfs_btree_del_cursor(cur, error);
987 0 : return error;
988 : }
989 :
990 : /*
991 : * Record a forwards unlinked chain pointer from agino -> next_agino in our
992 : * staging information.
993 : */
994 : static inline int
995 867 : xrep_iunlink_store_next(
996 : struct xrep_agi *ragi,
997 : xfs_agino_t agino,
998 : xfs_agino_t next_agino)
999 : {
1000 867 : ASSERT(next_agino != 0);
1001 :
1002 867 : return xfarray_store(ragi->iunlink_next, agino, &next_agino);
1003 : }
1004 :
1005 : /*
1006 : * Record a backwards unlinked chain pointer from prev_ino <- agino in our
1007 : * staging information.
1008 : */
1009 : static inline int
1010 867 : xrep_iunlink_store_prev(
1011 : struct xrep_agi *ragi,
1012 : xfs_agino_t agino,
1013 : xfs_agino_t prev_agino)
1014 : {
1015 867 : ASSERT(prev_agino != 0);
1016 :
1017 867 : return xfarray_store(ragi->iunlink_prev, agino, &prev_agino);
1018 : }
1019 :
1020 : /* Load this inode into memory and add it to the incore unlinked list. */
1021 : STATIC int
1022 0 : xrep_iunlink_reload_inode(
1023 : struct xrep_agi *ragi,
1024 : xfs_agino_t prev_agino,
1025 : xfs_agino_t agino,
1026 : struct xfs_inode **ipp)
1027 : {
1028 0 : struct xfs_scrub *sc = ragi->sc;
1029 0 : xfs_ino_t ino;
1030 0 : int error;
1031 :
1032 0 : ino = XFS_AGINO_TO_INO(sc->mp, sc->sa.pag->pag_agno, agino);
1033 0 : error = xchk_iget(ragi->sc, ino, ipp);
1034 0 : if (error)
1035 : return error;
1036 :
1037 0 : trace_xrep_iunlink_reload(*ipp, prev_agino);
1038 :
1039 : /* If this is a linked inode, stop processing the chain. */
1040 0 : if (VFS_I(*ipp)->i_nlink != 0) {
1041 0 : error = -EFSCORRUPTED;
1042 0 : goto rele;
1043 : }
1044 :
1045 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_prev agno 0x%x agino 0x%x prev ???? -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, prev_agino);
1046 0 : (*ipp)->i_prev_unlinked = prev_agino;
1047 :
1048 : /*
1049 : * Drop the inode reference that we just took. We hold the AGI, so
1050 : * this inode cannot move off the unlinked list and hence cannot be
1051 : * reclaimed.
1052 : */
1053 0 : rele:
1054 0 : xchk_irele(sc, *ipp);
1055 0 : return 0;
1056 : }
1057 :
1058 : /*
1059 : * Walk an AGI unlinked bucket's list to load incore any unlinked inodes that
1060 : * still existed at mount time. This can happen if iunlink processing fails
1061 : * during log recovery.
1062 : */
1063 : STATIC int
1064 4587968 : xrep_iunlink_walk_ondisk_bucket(
1065 : struct xrep_agi *ragi,
1066 : unsigned int bucket)
1067 : {
1068 4587968 : struct xfs_scrub *sc = ragi->sc;
1069 4587968 : struct xfs_inode *ip;
1070 4587968 : struct xfs_agi *agi = sc->sa.agi_bp->b_addr;
1071 4587968 : xfs_agino_t prev_agino = NULLAGINO;
1072 4587968 : xfs_agino_t next_agino;
1073 4587968 : int error = 0;
1074 :
1075 4587968 : next_agino = be32_to_cpu(agi->agi_unlinked[bucket]);
1076 4588835 : while (next_agino != NULLAGINO) {
1077 867 : if (xchk_should_terminate(ragi->sc, &error))
1078 0 : return error;
1079 :
1080 867 : trace_xrep_iunlink_walk_ondisk_bucket(sc->sa.pag, bucket,
1081 : prev_agino, next_agino);
1082 :
1083 867 : ip = xfs_iunlink_lookup(sc->sa.pag, next_agino);
1084 867 : if (!ip) {
1085 : /*
1086 : * This unlinked inode wasn't incore. Try to load it
1087 : * and link it into the incore list.
1088 : */
1089 0 : error = xrep_iunlink_reload_inode(ragi, prev_agino,
1090 : next_agino, &ip);
1091 0 : if (error) {
1092 : /*
1093 : * Inode cannot be resuscitated? Terminate the
1094 : * chain. We have other ways to find the rest
1095 : * of the inode(s) that might have been in this
1096 : * chain.
1097 : */
1098 : break;
1099 : }
1100 : }
1101 :
1102 867 : next_agino = ip->i_next_unlinked;
1103 : }
1104 :
1105 : return 0;
1106 : }
1107 :
1108 : /* Decide if this is an unlinked inode in this AG. */
1109 : STATIC bool
1110 749592062 : xrep_iunlink_igrab(
1111 : struct xfs_perag *pag,
1112 : struct xfs_inode *ip)
1113 : {
1114 749592062 : struct xfs_mount *mp = pag->pag_mount;
1115 :
1116 749592062 : if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
1117 : return false;
1118 :
1119 749591817 : if (!xfs_inode_on_unlinked_list(ip))
1120 749591148 : return false;
1121 :
1122 : return true;
1123 : }
1124 :
1125 : /*
1126 : * Mark the given inode in the lookup batch in our unlinked inode bitmap, and
1127 : * remember if this inode is the start of the unlinked chain.
1128 : */
1129 : STATIC int
1130 867 : xrep_iunlink_visit(
1131 : struct xrep_agi *ragi,
1132 : unsigned int batch_idx)
1133 : {
1134 867 : struct xfs_mount *mp = ragi->sc->mp;
1135 867 : struct xfs_inode *ip = ragi->lookup_batch[batch_idx];
1136 867 : xfs_agino_t agino;
1137 867 : unsigned int bucket;
1138 867 : int error;
1139 :
1140 867 : ASSERT(XFS_INO_TO_AGNO(mp, ip->i_ino) == ragi->sc->sa.pag->pag_agno);
1141 867 : ASSERT(xfs_inode_on_unlinked_list(ip));
1142 :
1143 867 : agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
1144 867 : bucket = agino % XFS_AGI_UNLINKED_BUCKETS;
1145 :
1146 867 : trace_xrep_iunlink_visit(ragi->sc->sa.pag, ragi->iunlink_heads[bucket],
1147 : ip);
1148 :
1149 867 : error = xbitmap_set(&ragi->iunlink_bmp, agino, 1);
1150 867 : if (error)
1151 : return error;
1152 :
1153 867 : if (ip->i_prev_unlinked == NULLAGINO) {
1154 867 : if (ragi->iunlink_heads[bucket] == NULLAGINO)
1155 867 : ragi->iunlink_heads[bucket] = agino;
1156 : }
1157 :
1158 : return 0;
1159 : }
1160 :
1161 : /*
1162 : * Find all incore unlinked inodes so that we can rebuild the unlinked buckets.
1163 : * We hold the AGI so there should not be any modifications to the unlinked
1164 : * list.
1165 : */
1166 : STATIC int
1167 71687 : xrep_iunlink_mark_inodes(
1168 : struct xrep_agi *ragi)
1169 : {
1170 71687 : struct xfs_perag *pag = ragi->sc->sa.pag;
1171 71687 : struct xfs_mount *mp = pag->pag_mount;
1172 71687 : uint32_t first_index = 0;
1173 71687 : bool done = false;
1174 71687 : unsigned int nr_found = 0;
1175 :
1176 23530809 : do {
1177 23530809 : unsigned int i;
1178 23530809 : int error = 0;
1179 :
1180 23530809 : if (xchk_should_terminate(ragi->sc, &error))
1181 71687 : return error;
1182 :
1183 23530810 : rcu_read_lock();
1184 :
1185 23530810 : nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
1186 23530810 : (void **)&ragi->lookup_batch, first_index,
1187 : XREP_AGI_LOOKUP_BATCH);
1188 23530809 : if (!nr_found) {
1189 71687 : rcu_read_unlock();
1190 71687 : return 0;
1191 : }
1192 :
1193 773051169 : for (i = 0; i < nr_found; i++) {
1194 749592047 : struct xfs_inode *ip = ragi->lookup_batch[i];
1195 :
1196 749592047 : if (done || !xrep_iunlink_igrab(pag, ip))
1197 749591176 : ragi->lookup_batch[i] = NULL;
1198 :
1199 : /*
1200 : * Update the index for the next lookup. Catch
1201 : * overflows into the next AG range which can occur if
1202 : * we have inodes in the last block of the AG and we
1203 : * are currently pointing to the last inode.
1204 : *
1205 : * Because we may see inodes that are from the wrong AG
1206 : * due to RCU freeing and reallocation, only update the
1207 : * index if it lies in this AG. It was a race that lead
1208 : * us to see this inode, so another lookup from the
1209 : * same index will not find it again.
1210 : */
1211 749592047 : if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
1212 46 : continue;
1213 749592001 : first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
1214 749592001 : if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
1215 0 : done = true;
1216 : }
1217 :
1218 : /* unlock now we've grabbed the inodes. */
1219 23459122 : rcu_read_unlock();
1220 :
1221 796510439 : for (i = 0; i < nr_found; i++) {
1222 749592195 : if (!ragi->lookup_batch[i])
1223 749591328 : continue;
1224 867 : error = xrep_iunlink_visit(ragi, i);
1225 867 : if (error)
1226 0 : return error;
1227 : }
1228 23459122 : } while (!done);
1229 :
1230 : return 0;
1231 : }
1232 :
1233 : /*
1234 : * Walk an iunlink bucket's inode list. For each inode that should be on this
1235 : * chain, clear its entry in in iunlink_bmp because it's ok and we don't need
1236 : * to touch it further.
1237 : */
1238 : STATIC int
1239 4587968 : xrep_iunlink_clear_bucket_chain(
1240 : struct xrep_agi *ragi,
1241 : unsigned int bucket)
1242 : {
1243 4587968 : struct xfs_scrub *sc = ragi->sc;
1244 4587968 : struct xfs_inode *ip;
1245 4587968 : xfs_agino_t prev_agino = NULLAGINO;
1246 4587968 : xfs_agino_t next_agino = ragi->iunlink_heads[bucket];
1247 4587968 : int error = 0;
1248 :
1249 4588835 : while (next_agino != NULLAGINO) {
1250 867 : if (xchk_should_terminate(ragi->sc, &error))
1251 0 : return error;
1252 :
1253 867 : trace_xrep_iunlink_clear_bucket_chain(sc->sa.pag, bucket,
1254 : prev_agino, next_agino);
1255 :
1256 : /* Find the next inode in the chain. */
1257 867 : ip = xfs_iunlink_lookup(sc->sa.pag, next_agino);
1258 867 : if (!ip) {
1259 : /* Inode not incore? Terminate the chain. */
1260 : next_agino = NULLAGINO;
1261 : break;
1262 : }
1263 :
1264 867 : if (next_agino % XFS_AGI_UNLINKED_BUCKETS != bucket ||
1265 : !xfs_inode_on_unlinked_list(ip)) {
1266 : /*
1267 : * Inode is in the wrong bucket or isn't unlinked.
1268 : * Advance the list, but pretend we didn't see this
1269 : * inode.
1270 : */
1271 0 : next_agino = ip->i_next_unlinked;
1272 0 : continue;
1273 : }
1274 :
1275 : /*
1276 : * Otherwise, this inode's unlinked pointers are ok. Clear it
1277 : * from the unlinked bitmap since we're done with it, and make
1278 : * sure the chain is still correct.
1279 : */
1280 867 : error = xbitmap_clear(&ragi->iunlink_bmp, next_agino, 1);
1281 867 : if (error)
1282 0 : return error;
1283 :
1284 : /* Remember the previous inode's next pointer. */
1285 867 : if (prev_agino != NULLAGINO) {
1286 0 : error = xrep_iunlink_store_next(ragi, prev_agino,
1287 : next_agino);
1288 0 : if (error)
1289 0 : return error;
1290 : }
1291 :
1292 : /* Remember this inode's previous pointer. */
1293 867 : error = xrep_iunlink_store_prev(ragi, next_agino, prev_agino);
1294 867 : if (error)
1295 0 : return error;
1296 :
1297 : /* Advance the list and remember this inode. */
1298 867 : prev_agino = next_agino;
1299 867 : next_agino = ip->i_next_unlinked;
1300 : }
1301 :
1302 : /* Update the previous inode's next pointer. */
1303 4587968 : if (prev_agino != NULLAGINO) {
1304 867 : error = xrep_iunlink_store_next(ragi, prev_agino, next_agino);
1305 867 : if (error)
1306 0 : return error;
1307 : }
1308 :
1309 : return 0;
1310 : }
1311 :
1312 : /* Reinsert this unlinked inode into the head of the staged bucket list. */
1313 : STATIC int
1314 0 : xrep_iunlink_add_to_bucket(
1315 : struct xrep_agi *ragi,
1316 : xfs_agino_t agino)
1317 : {
1318 0 : xfs_agino_t current_head;
1319 0 : unsigned int bucket;
1320 0 : int error;
1321 :
1322 0 : bucket = agino % XFS_AGI_UNLINKED_BUCKETS;
1323 :
1324 : /* Point this inode at the current head of the bucket list. */
1325 0 : current_head = ragi->iunlink_heads[bucket];
1326 0 : error = xrep_iunlink_store_next(ragi, agino, current_head);
1327 0 : if (error)
1328 : return error;
1329 :
1330 : /* Remember the head inode's previous pointer. */
1331 0 : if (current_head != NULLAGINO) {
1332 0 : error = xrep_iunlink_store_prev(ragi, current_head, agino);
1333 0 : if (error)
1334 : return error;
1335 : }
1336 :
1337 0 : ragi->iunlink_heads[bucket] = agino;
1338 0 : return 0;
1339 : }
1340 :
1341 : /* Reinsert unlinked inodes into the staged iunlink buckets. */
1342 : STATIC int
1343 0 : xrep_iunlink_add_lost_inodes(
1344 : uint64_t start,
1345 : uint64_t len,
1346 : void *priv)
1347 : {
1348 0 : struct xrep_agi *ragi = priv;
1349 0 : int error;
1350 :
1351 0 : while (len > 0) {
1352 0 : error = xrep_iunlink_add_to_bucket(ragi, start);
1353 0 : if (error)
1354 0 : return error;
1355 :
1356 0 : start++;
1357 0 : len--;
1358 : }
1359 :
1360 : return 0;
1361 : }
1362 :
1363 : /*
1364 : * Figure out the iunlink bucket values and find inodes that need to be
1365 : * reinserted into the list.
1366 : */
1367 : STATIC int
1368 71687 : xrep_iunlink_rebuild_buckets(
1369 : struct xrep_agi *ragi)
1370 : {
1371 71687 : unsigned int i;
1372 71687 : int error;
1373 :
1374 : /*
1375 : * Walk the ondisk AGI unlinked list to find inodes that are on the
1376 : * list but aren't in memory. This can happen if a past log recovery
1377 : * tried to clear the iunlinked list but failed. Our scan rebuilds the
1378 : * unlinked list using incore inodes, so we must load and link them
1379 : * properly.
1380 : */
1381 4659655 : for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
1382 4587968 : error = xrep_iunlink_walk_ondisk_bucket(ragi, i);
1383 4587968 : if (error)
1384 0 : return error;
1385 : }
1386 :
1387 : /* Record all the incore unlinked inodes in iunlink_bmp. */
1388 71687 : error = xrep_iunlink_mark_inodes(ragi);
1389 71687 : if (error)
1390 : return error;
1391 :
1392 : /*
1393 : * Clear from iunlink_bmp all the unlinked inodes that are correctly
1394 : * linked into their incore inode bucket lists. After this call,
1395 : * iunlink_bmp will contain unlinked inodes that are not in the correct
1396 : * list.
1397 : */
1398 4659655 : for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
1399 4587968 : error = xrep_iunlink_clear_bucket_chain(ragi, i);
1400 4587968 : if (error)
1401 0 : return error;
1402 : }
1403 :
1404 : /*
1405 : * Any unlinked inodes that we didn't find through the bucket list
1406 : * walk (or was ignored by the walk) must be inserted into the bucket
1407 : * list. Stage this in memory for now.
1408 : */
1409 71687 : return xbitmap_walk(&ragi->iunlink_bmp,
1410 : xrep_iunlink_add_lost_inodes, ragi);
1411 : }
1412 :
1413 : /* Update i_next_iunlinked for the inode @agino. */
1414 : STATIC int
1415 867 : xrep_iunlink_relink_next(
1416 : struct xrep_agi *ragi,
1417 : xfarray_idx_t idx,
1418 : xfs_agino_t next_agino)
1419 : {
1420 867 : struct xfs_scrub *sc = ragi->sc;
1421 867 : struct xfs_perag *pag = sc->sa.pag;
1422 867 : struct xfs_inode *ip;
1423 867 : xfarray_idx_t agino = idx - 1;
1424 867 : bool want_rele = false;
1425 867 : int error = 0;
1426 :
1427 867 : ip = xfs_iunlink_lookup(pag, agino);
1428 867 : if (!ip) {
1429 0 : xfs_ino_t ino;
1430 0 : xfs_agino_t prev_agino;
1431 :
1432 : /*
1433 : * No inode exists in cache. Load it off the disk so that we
1434 : * can reinsert it into the incore unlinked list.
1435 : */
1436 0 : ino = XFS_AGINO_TO_INO(sc->mp, pag->pag_agno, agino);
1437 0 : error = xchk_iget(sc, ino, &ip);
1438 0 : if (error)
1439 0 : return -EFSCORRUPTED;
1440 :
1441 0 : want_rele = true;
1442 :
1443 : /* Set the backward pointer since this just came off disk. */
1444 0 : error = xfarray_load(ragi->iunlink_prev, agino, &prev_agino);
1445 0 : if (error)
1446 0 : goto out_rele;
1447 :
1448 0 : trace_xrep_iunlink_relink_prev(ip, prev_agino);
1449 0 : ip->i_prev_unlinked = prev_agino;
1450 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_prev agno 0x%x agino 0x%llx prev 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_prev_unlinked, prev_agino);
1451 : }
1452 :
1453 : /* Update the forward pointer. */
1454 867 : if (ip->i_next_unlinked != next_agino) {
1455 0 : error = xfs_iunlink_log_inode(sc->tp, ip, pag, next_agino);
1456 0 : if (error)
1457 0 : goto out_rele;
1458 :
1459 0 : trace_xrep_iunlink_relink_next(ip, next_agino);
1460 0 : ip->i_next_unlinked = next_agino;
1461 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_next agno 0x%x agino 0x%llx next 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_next_unlinked, next_agino);
1462 : }
1463 :
1464 867 : out_rele:
1465 : /*
1466 : * The iunlink lookup doesn't igrab because we hold the AGI buffer lock
1467 : * and the inode cannot be reclaimed. However, if we used iget to load
1468 : * a missing inode, we must irele it here.
1469 : */
1470 867 : if (want_rele)
1471 0 : xchk_irele(sc, ip);
1472 : return error;
1473 : }
1474 :
1475 : /* Update i_prev_iunlinked for the inode @agino. */
1476 : STATIC int
1477 867 : xrep_iunlink_relink_prev(
1478 : struct xrep_agi *ragi,
1479 : xfarray_idx_t idx,
1480 : xfs_agino_t prev_agino)
1481 : {
1482 867 : struct xfs_scrub *sc = ragi->sc;
1483 867 : struct xfs_perag *pag = sc->sa.pag;
1484 867 : struct xfs_inode *ip;
1485 867 : xfarray_idx_t agino = idx - 1;
1486 867 : bool want_rele = false;
1487 867 : int error = 0;
1488 :
1489 867 : ASSERT(prev_agino != 0);
1490 :
1491 867 : ip = xfs_iunlink_lookup(pag, agino);
1492 867 : if (!ip) {
1493 0 : xfs_ino_t ino;
1494 0 : xfs_agino_t next_agino;
1495 :
1496 : /*
1497 : * No inode exists in cache. Load it off the disk so that we
1498 : * can reinsert it into the incore unlinked list.
1499 : */
1500 0 : ino = XFS_AGINO_TO_INO(sc->mp, pag->pag_agno, agino);
1501 0 : error = xchk_iget(sc, ino, &ip);
1502 0 : if (error)
1503 0 : return -EFSCORRUPTED;
1504 :
1505 0 : want_rele = true;
1506 :
1507 : /* Set the forward pointer since this just came off disk. */
1508 0 : error = xfarray_load(ragi->iunlink_prev, agino, &next_agino);
1509 0 : if (error)
1510 0 : goto out_rele;
1511 :
1512 0 : error = xfs_iunlink_log_inode(sc->tp, ip, pag, next_agino);
1513 0 : if (error)
1514 0 : goto out_rele;
1515 :
1516 0 : trace_xrep_iunlink_relink_next(ip, next_agino);
1517 0 : ip->i_next_unlinked = next_agino;
1518 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_next agno 0x%x agino 0x%llx next 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_next_unlinked, next_agino);
1519 : }
1520 :
1521 : /* Update the backward pointer. */
1522 867 : if (ip->i_prev_unlinked != prev_agino) {
1523 0 : trace_xrep_iunlink_relink_prev(ip, prev_agino);
1524 0 : ip->i_prev_unlinked = prev_agino;
1525 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_prev agno 0x%x agino 0x%llx prev 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_prev_unlinked, prev_agino);
1526 : }
1527 :
1528 867 : out_rele:
1529 : /*
1530 : * The iunlink lookup doesn't igrab because we hold the AGI buffer lock
1531 : * and the inode cannot be reclaimed. However, if we used iget to load
1532 : * a missing inode, we must irele it here.
1533 : */
1534 867 : if (want_rele)
1535 0 : xchk_irele(sc, ip);
1536 : return error;
1537 : }
1538 :
1539 : /* Log all the iunlink updates we need to finish regenerating the AGI. */
1540 : STATIC int
1541 71687 : xrep_iunlink_commit(
1542 : struct xrep_agi *ragi)
1543 : {
1544 71687 : struct xfs_agi *agi = ragi->agi_bp->b_addr;
1545 71687 : xfarray_idx_t idx = XFARRAY_CURSOR_INIT;
1546 71687 : xfs_agino_t agino;
1547 71687 : unsigned int i;
1548 71687 : int error;
1549 :
1550 : /* Fix all the forward links */
1551 72554 : while ((error = xfarray_iter(ragi->iunlink_next, &idx, &agino)) == 1) {
1552 867 : error = xrep_iunlink_relink_next(ragi, idx, agino);
1553 867 : if (error) {
1554 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_forw failed agno 0x%x agino 0x%llx new_next 0x%x err %d", ragi->sc->sa.pag->pag_agno, idx - 1, agino, error);
1555 0 : return error;
1556 : }
1557 : }
1558 :
1559 : /* Fix all the back links */
1560 71687 : idx = XFARRAY_CURSOR_INIT;
1561 72554 : while ((error = xfarray_iter(ragi->iunlink_prev, &idx, &agino)) == 1) {
1562 867 : error = xrep_iunlink_relink_prev(ragi, idx, agino);
1563 867 : if (error) {
1564 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_back failed agno 0x%x agino 0x%llx new_prev 0x%x err %d", ragi->sc->sa.pag->pag_agno, idx - 1, agino, error);
1565 0 : return error;
1566 : }
1567 : }
1568 :
1569 : /* Copy the staged iunlink buckets to the new AGI. */
1570 4659655 : for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
1571 4587968 : trace_xrep_iunlink_commit_bucket(ragi->sc->sa.pag, i,
1572 : ragi->iunlink_heads[i]);
1573 :
1574 9175936 : if (ragi->old_agi.agi_unlinked[i] != cpu_to_be32(ragi->iunlink_heads[i]))
1575 0 : xfs_emerg(ragi->sc->mp, "IUNLINK relink_buct agno 0x%x bucket %u head 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, i, be32_to_cpu(ragi->old_agi.agi_unlinked[i]), ragi->iunlink_heads[i]);
1576 9175936 : agi->agi_unlinked[i] = cpu_to_be32(ragi->iunlink_heads[i]);
1577 : }
1578 :
1579 : return 0;
1580 : }
1581 :
1582 : /* Trigger reinitialization of the in-core data. */
1583 : STATIC int
1584 71687 : xrep_agi_commit_new(
1585 : struct xrep_agi *ragi)
1586 : {
1587 71687 : struct xfs_scrub *sc = ragi->sc;
1588 71687 : struct xfs_buf *agi_bp = ragi->agi_bp;
1589 71687 : struct xfs_perag *pag;
1590 71687 : struct xfs_agi *agi = agi_bp->b_addr;
1591 :
1592 : /* Trigger inode count recalculation */
1593 71687 : xfs_force_summary_recalc(sc->mp);
1594 :
1595 : /* Write this to disk. */
1596 71687 : xfs_trans_buf_set_type(sc->tp, agi_bp, XFS_BLFT_AGI_BUF);
1597 71687 : xfs_trans_log_buf(sc->tp, agi_bp, 0, BBTOB(agi_bp->b_length) - 1);
1598 :
1599 : /* Now reinitialize the in-core counters if necessary. */
1600 71687 : pag = sc->sa.pag;
1601 71687 : pag->pagi_count = be32_to_cpu(agi->agi_count);
1602 71687 : pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
1603 71687 : set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate);
1604 :
1605 71687 : return 0;
1606 : }
1607 :
1608 : /* Repair the AGI. */
1609 : int
1610 75596 : xrep_agi(
1611 : struct xfs_scrub *sc)
1612 : {
1613 75596 : struct xrep_agi *ragi;
1614 75596 : struct xfs_mount *mp = sc->mp;
1615 75596 : char *descr;
1616 75596 : unsigned int i;
1617 75596 : int error;
1618 :
1619 : /* We require the rmapbt to rebuild anything. */
1620 75596 : if (!xfs_has_rmapbt(mp))
1621 : return -EOPNOTSUPP;
1622 :
1623 71687 : sc->buf = kzalloc(sizeof(struct xrep_agi), XCHK_GFP_FLAGS);
1624 71687 : if (!sc->buf)
1625 : return -ENOMEM;
1626 71687 : ragi = sc->buf;
1627 71687 : ragi->sc = sc;
1628 :
1629 71687 : ragi->fab[XREP_AGI_INOBT] = (struct xrep_find_ag_btree){
1630 : .rmap_owner = XFS_RMAP_OWN_INOBT,
1631 : .buf_ops = &xfs_inobt_buf_ops,
1632 71687 : .maxlevels = M_IGEO(sc->mp)->inobt_maxlevels,
1633 : };
1634 71687 : ragi->fab[XREP_AGI_FINOBT] = (struct xrep_find_ag_btree){
1635 : .rmap_owner = XFS_RMAP_OWN_INOBT,
1636 : .buf_ops = &xfs_finobt_buf_ops,
1637 71687 : .maxlevels = M_IGEO(sc->mp)->inobt_maxlevels,
1638 : };
1639 71687 : ragi->fab[XREP_AGI_END] = (struct xrep_find_ag_btree){
1640 : .buf_ops = NULL,
1641 : };
1642 :
1643 4659655 : for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
1644 4587968 : ragi->iunlink_heads[i] = NULLAGINO;
1645 :
1646 71687 : xbitmap_init(&ragi->iunlink_bmp);
1647 71687 : sc->buf_cleanup = xrep_agi_buf_cleanup;
1648 :
1649 71687 : descr = xchk_xfile_ag_descr(sc, "iunlinked next pointers");
1650 71687 : error = xfarray_create(descr, 0, sizeof(xfs_agino_t),
1651 : &ragi->iunlink_next);
1652 71687 : kfree(descr);
1653 71687 : if (error)
1654 : return error;
1655 :
1656 71687 : descr = xchk_xfile_ag_descr(sc, "iunlinked prev pointers");
1657 71687 : error = xfarray_create(descr, 0, sizeof(xfs_agino_t),
1658 : &ragi->iunlink_prev);
1659 71687 : kfree(descr);
1660 71687 : if (error)
1661 : return error;
1662 :
1663 : /*
1664 : * Make sure we have the AGI buffer, as scrub might have decided it
1665 : * was corrupt after xfs_ialloc_read_agi failed with -EFSCORRUPTED.
1666 : */
1667 143374 : error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
1668 71687 : XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
1669 : XFS_AGI_DADDR(mp)),
1670 : XFS_FSS_TO_BB(mp, 1), 0, &ragi->agi_bp, NULL);
1671 71687 : if (error)
1672 : return error;
1673 71687 : ragi->agi_bp->b_ops = &xfs_agi_buf_ops;
1674 :
1675 : /* Find the AGI btree roots. */
1676 71687 : error = xrep_agi_find_btrees(ragi);
1677 71687 : if (error)
1678 : return error;
1679 :
1680 71687 : error = xrep_iunlink_rebuild_buckets(ragi);
1681 71687 : if (error)
1682 : return error;
1683 :
1684 : /* Last chance to abort before we start committing fixes. */
1685 71687 : if (xchk_should_terminate(sc, &error))
1686 0 : return error;
1687 :
1688 : /* Start rewriting the header and implant the btrees we found. */
1689 71687 : xrep_agi_init_header(ragi);
1690 71687 : xrep_agi_set_roots(ragi);
1691 71687 : error = xrep_agi_calc_from_btrees(ragi);
1692 71687 : if (error)
1693 0 : goto out_revert;
1694 71687 : error = xrep_iunlink_commit(ragi);
1695 71687 : if (error)
1696 0 : goto out_revert;
1697 :
1698 : /* Reinitialize in-core state. */
1699 71687 : return xrep_agi_commit_new(ragi);
1700 :
1701 0 : out_revert:
1702 : /* Mark the incore AGI state stale and revert the AGI. */
1703 0 : clear_bit(XFS_AGSTATE_AGI_INIT, &sc->sa.pag->pag_opstate);
1704 0 : memcpy(ragi->agi_bp->b_addr, &ragi->old_agi, sizeof(struct xfs_agi));
1705 0 : return error;
1706 : }
|