Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Copyright (C) 2017-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_log_format.h"
14 : #include "xfs_trans.h"
15 : #include "xfs_inode.h"
16 : #include "xfs_ialloc.h"
17 : #include "xfs_ialloc_btree.h"
18 : #include "xfs_icache.h"
19 : #include "xfs_rmap.h"
20 : #include "scrub/scrub.h"
21 : #include "scrub/common.h"
22 : #include "scrub/btree.h"
23 : #include "scrub/trace.h"
24 : #include "xfs_ag.h"
25 :
26 : /*
27 : * Set us up to scrub inode btrees.
28 : * If we detect a discrepancy between the inobt and the inode,
29 : * try again after forcing logged inode cores out to disk.
30 : */
31 : int
32 802164 : xchk_setup_ag_iallocbt(
33 : struct xfs_scrub *sc)
34 : {
35 802164 : if (xchk_need_intent_drain(sc))
36 14475 : xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN);
37 802164 : return xchk_setup_ag_btree(sc, sc->flags & XCHK_TRY_HARDER);
38 : }
39 :
40 : /* Inode btree scrubber. */
41 :
42 : struct xchk_iallocbt {
43 : /* Number of inodes we see while scanning inobt. */
44 : unsigned long long inodes;
45 :
46 : /* Expected next startino, for big block filesystems. */
47 : xfs_agino_t next_startino;
48 :
49 : /* Expected end of the current inode cluster. */
50 : xfs_agino_t next_cluster_ino;
51 : };
52 :
53 : /*
54 : * Does the finobt have a record for this inode with the same hole/free state?
55 : * This is a bit complicated because of the following:
56 : *
57 : * - The finobt need not have a record if all inodes in the inobt record are
58 : * allocated.
59 : * - The finobt need not have a record if all inodes in the inobt record are
60 : * free.
61 : * - The finobt need not have a record if the inobt record says this is a hole.
62 : * This likely doesn't happen in practice.
63 : */
64 : STATIC int
65 2775828566 : xchk_inobt_xref_finobt(
66 : struct xfs_scrub *sc,
67 : struct xfs_inobt_rec_incore *irec,
68 : xfs_agino_t agino,
69 : bool free,
70 : bool hole)
71 : {
72 2775828566 : struct xfs_inobt_rec_incore frec;
73 2775828566 : struct xfs_btree_cur *cur = sc->sa.fino_cur;
74 2775828566 : bool ffree, fhole;
75 2775828566 : unsigned int frec_idx, fhole_idx;
76 2775828566 : int has_record;
77 2775828566 : int error;
78 :
79 2775828566 : ASSERT(cur->bc_btnum == XFS_BTNUM_FINO);
80 :
81 2775828566 : error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has_record);
82 2775978681 : if (error)
83 : return error;
84 2775978681 : if (!has_record)
85 2131318419 : goto no_record;
86 :
87 644660262 : error = xfs_inobt_get_rec(cur, &frec, &has_record);
88 644686689 : if (!has_record)
89 : return -EFSCORRUPTED;
90 :
91 644686689 : if (frec.ir_startino + XFS_INODES_PER_CHUNK <= agino)
92 621833944 : goto no_record;
93 :
94 : /* There's a finobt record; free and hole status must match. */
95 22852745 : frec_idx = agino - frec.ir_startino;
96 22852745 : ffree = frec.ir_free & (1ULL << frec_idx);
97 22852745 : fhole_idx = frec_idx / XFS_INODES_PER_HOLEMASK_BIT;
98 22852745 : fhole = frec.ir_holemask & (1U << fhole_idx);
99 :
100 22852745 : if (ffree != free)
101 0 : xchk_btree_xref_set_corrupt(sc, cur, 0);
102 22852745 : if (fhole != hole)
103 0 : xchk_btree_xref_set_corrupt(sc, cur, 0);
104 : return 0;
105 :
106 2753152363 : no_record:
107 : /* inobt record is fully allocated */
108 2753152363 : if (irec->ir_free == 0)
109 : return 0;
110 :
111 : /* inobt record is totally unallocated */
112 839968925 : if (irec->ir_free == XFS_INOBT_ALL_FREE)
113 : return 0;
114 :
115 : /* inobt record says this is a hole */
116 839968925 : if (hole)
117 : return 0;
118 :
119 : /* finobt doesn't care about allocated inodes */
120 839968925 : if (!free)
121 : return 0;
122 :
123 0 : xchk_btree_xref_set_corrupt(sc, cur, 0);
124 0 : return 0;
125 : }
126 :
127 : /*
128 : * Make sure that each inode of this part of an inobt record has the same
129 : * sparse and free status as the finobt.
130 : */
131 : STATIC void
132 241120153 : xchk_inobt_chunk_xref_finobt(
133 : struct xfs_scrub *sc,
134 : struct xfs_inobt_rec_incore *irec,
135 : xfs_agino_t agino,
136 : unsigned int nr_inodes)
137 : {
138 241120153 : xfs_agino_t i;
139 241120153 : unsigned int rec_idx;
140 241120153 : int error;
141 :
142 241120153 : ASSERT(sc->sm->sm_type == XFS_SCRUB_TYPE_INOBT);
143 :
144 241120153 : if (!sc->sa.fino_cur || xchk_skip_xref(sc->sm))
145 11 : return;
146 :
147 241120142 : for (i = agino, rec_idx = agino - irec->ir_startino;
148 3016794794 : i < agino + nr_inodes;
149 2775674652 : i++, rec_idx++) {
150 2775671526 : bool free, hole;
151 2775671526 : unsigned int hole_idx;
152 :
153 2775671526 : free = irec->ir_free & (1ULL << rec_idx);
154 2775671526 : hole_idx = rec_idx / XFS_INODES_PER_HOLEMASK_BIT;
155 2775671526 : hole = irec->ir_holemask & (1U << hole_idx);
156 :
157 2775671526 : error = xchk_inobt_xref_finobt(sc, irec, i, free, hole);
158 2775743874 : if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur))
159 : return;
160 : }
161 : }
162 :
163 : /*
164 : * Does the inobt have a record for this inode with the same hole/free state?
165 : * The inobt must always have a record if there's a finobt record.
166 : */
167 : STATIC int
168 26515475 : xchk_finobt_xref_inobt(
169 : struct xfs_scrub *sc,
170 : struct xfs_inobt_rec_incore *frec,
171 : xfs_agino_t agino,
172 : bool ffree,
173 : bool fhole)
174 : {
175 26515475 : struct xfs_inobt_rec_incore irec;
176 26515475 : struct xfs_btree_cur *cur = sc->sa.ino_cur;
177 26515475 : bool free, hole;
178 26515475 : unsigned int rec_idx, hole_idx;
179 26515475 : int has_record;
180 26515475 : int error;
181 :
182 26515475 : ASSERT(cur->bc_btnum == XFS_BTNUM_INO);
183 :
184 26515475 : error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has_record);
185 26514853 : if (error)
186 : return error;
187 26514853 : if (!has_record)
188 0 : goto no_record;
189 :
190 26514853 : error = xfs_inobt_get_rec(cur, &irec, &has_record);
191 26515193 : if (!has_record)
192 : return -EFSCORRUPTED;
193 :
194 26515193 : if (irec.ir_startino + XFS_INODES_PER_CHUNK <= agino)
195 0 : goto no_record;
196 :
197 : /* There's an inobt record; free and hole status must match. */
198 26515193 : rec_idx = agino - irec.ir_startino;
199 26515193 : free = irec.ir_free & (1ULL << rec_idx);
200 26515193 : hole_idx = rec_idx / XFS_INODES_PER_HOLEMASK_BIT;
201 26515193 : hole = irec.ir_holemask & (1U << hole_idx);
202 :
203 26515193 : if (ffree != free)
204 0 : xchk_btree_xref_set_corrupt(sc, cur, 0);
205 26515193 : if (fhole != hole)
206 0 : xchk_btree_xref_set_corrupt(sc, cur, 0);
207 : return 0;
208 :
209 0 : no_record:
210 : /* finobt should never have a record for which the inobt does not */
211 0 : xchk_btree_xref_set_corrupt(sc, cur, 0);
212 0 : return 0;
213 : }
214 :
215 : /*
216 : * Make sure that each inode of this part of an finobt record has the same
217 : * sparse and free status as the inobt.
218 : */
219 : STATIC void
220 1421154 : xchk_finobt_chunk_xref_inobt(
221 : struct xfs_scrub *sc,
222 : struct xfs_inobt_rec_incore *frec,
223 : xfs_agino_t agino,
224 : unsigned int nr_inodes)
225 : {
226 1421154 : xfs_agino_t i;
227 1421154 : unsigned int rec_idx;
228 1421154 : int error;
229 :
230 1421154 : ASSERT(sc->sm->sm_type == XFS_SCRUB_TYPE_FINOBT);
231 :
232 1421154 : if (!sc->sa.ino_cur || xchk_skip_xref(sc->sm))
233 0 : return;
234 :
235 1421154 : for (i = agino, rec_idx = agino - frec->ir_startino;
236 27936170 : i < agino + nr_inodes;
237 26515016 : i++, rec_idx++) {
238 26514990 : bool ffree, fhole;
239 26514990 : unsigned int hole_idx;
240 :
241 26514990 : ffree = frec->ir_free & (1ULL << rec_idx);
242 26514990 : hole_idx = rec_idx / XFS_INODES_PER_HOLEMASK_BIT;
243 26514990 : fhole = frec->ir_holemask & (1U << hole_idx);
244 :
245 26514990 : error = xchk_finobt_xref_inobt(sc, frec, i, ffree, fhole);
246 26515692 : if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur))
247 : return;
248 : }
249 : }
250 :
251 : /* Is this chunk worth checking and cross-referencing? */
252 : STATIC bool
253 242540425 : xchk_iallocbt_chunk(
254 : struct xchk_btree *bs,
255 : struct xfs_inobt_rec_incore *irec,
256 : xfs_agino_t agino,
257 : unsigned int nr_inodes)
258 : {
259 242540425 : struct xfs_scrub *sc = bs->sc;
260 242540425 : struct xfs_mount *mp = bs->cur->bc_mp;
261 242540425 : struct xfs_perag *pag = bs->cur->bc_ag.pag;
262 242540425 : xfs_agblock_t agbno;
263 242540425 : xfs_extlen_t len;
264 :
265 242540425 : agbno = XFS_AGINO_TO_AGBNO(mp, agino);
266 242540425 : len = XFS_B_TO_FSB(mp, nr_inodes * mp->m_sb.sb_inodesize);
267 :
268 242540425 : if (!xfs_verify_agbext(pag, agbno, len))
269 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
270 :
271 242540425 : if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
272 : return false;
273 :
274 242538933 : xchk_xref_is_used_space(sc, agbno, len);
275 242540023 : if (sc->sm->sm_type == XFS_SCRUB_TYPE_INOBT)
276 241118858 : xchk_inobt_chunk_xref_finobt(sc, irec, agino, nr_inodes);
277 : else
278 1421165 : xchk_finobt_chunk_xref_inobt(sc, irec, agino, nr_inodes);
279 242544666 : xchk_xref_is_only_owned_by(sc, agbno, len, &XFS_RMAP_OINFO_INODES);
280 242539747 : xchk_xref_is_not_shared(sc, agbno, len);
281 242539215 : xchk_xref_is_not_cow_staging(sc, agbno, len);
282 242539215 : return true;
283 : }
284 :
285 : /*
286 : * Check that an inode's allocation status matches ir_free in the inobt
287 : * record. First we try querying the in-core inode state, and if the inode
288 : * isn't loaded we examine the on-disk inode directly.
289 : *
290 : * Since there can be 1:M and M:1 mappings between inobt records and inode
291 : * clusters, we pass in the inode location information as an inobt record;
292 : * the index of an inode cluster within the inobt record (as well as the
293 : * cluster buffer itself); and the index of the inode within the cluster.
294 : *
295 : * @irec is the inobt record.
296 : * @irec_ino is the inode offset from the start of the record.
297 : * @dip is the on-disk inode.
298 : */
299 : STATIC int
300 2802354485 : xchk_iallocbt_check_cluster_ifree(
301 : struct xchk_btree *bs,
302 : struct xfs_inobt_rec_incore *irec,
303 : unsigned int irec_ino,
304 : struct xfs_dinode *dip)
305 : {
306 2802354485 : struct xfs_mount *mp = bs->cur->bc_mp;
307 2802354485 : xfs_ino_t fsino;
308 2802354485 : xfs_agino_t agino;
309 2802354485 : bool irec_free;
310 2802354485 : bool ino_inuse;
311 2802354485 : bool freemask_ok;
312 2802354485 : int error = 0;
313 :
314 2802354485 : if (xchk_should_terminate(bs->sc, &error))
315 1 : return error;
316 :
317 : /*
318 : * Given an inobt record and the offset of an inode from the start of
319 : * the record, compute which fs inode we're talking about.
320 : */
321 2801980766 : agino = irec->ir_startino + irec_ino;
322 2801980766 : fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_ag.pag->pag_agno, agino);
323 2801980766 : irec_free = (irec->ir_free & XFS_INOBT_MASK(irec_ino));
324 :
325 2801980766 : if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC ||
326 2801980766 : (dip->di_version >= 3 && be64_to_cpu(dip->di_ino) != fsino)) {
327 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
328 0 : goto out;
329 : }
330 :
331 2801980766 : error = xchk_inode_is_allocated(bs->sc, agino, &ino_inuse);
332 2802502782 : if (error == -ENODATA) {
333 : /* Not cached, just read the disk buffer */
334 51504265 : freemask_ok = irec_free ^ !!(dip->di_mode);
335 51504265 : if (!(bs->sc->flags & XCHK_TRY_HARDER) && !freemask_ok)
336 : return -EDEADLOCK;
337 2750998517 : } else if (error < 0) {
338 : /*
339 : * Inode is only half assembled, or there was an IO error,
340 : * or the verifier failed, so don't bother trying to check.
341 : * The inode scrubber can deal with this.
342 : */
343 0 : goto out;
344 : } else {
345 : /* Inode is all there. */
346 2750998517 : freemask_ok = irec_free ^ ino_inuse;
347 : }
348 2802502782 : if (!freemask_ok)
349 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
350 2802502782 : out:
351 : return 0;
352 : }
353 :
354 : /*
355 : * Check that the holemask and freemask of a hypothetical inode cluster match
356 : * what's actually on disk. If sparse inodes are enabled, the cluster does
357 : * not actually have to map to inodes if the corresponding holemask bit is set.
358 : *
359 : * @cluster_base is the first inode in the cluster within the @irec.
360 : */
361 : STATIC int
362 114096097 : xchk_iallocbt_check_cluster(
363 : struct xchk_btree *bs,
364 : struct xfs_inobt_rec_incore *irec,
365 : unsigned int cluster_base)
366 : {
367 114096097 : struct xfs_imap imap;
368 114096097 : struct xfs_mount *mp = bs->cur->bc_mp;
369 114096097 : struct xfs_buf *cluster_bp;
370 114096097 : unsigned int nr_inodes;
371 114096097 : xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno;
372 114096097 : xfs_agblock_t agbno;
373 114096097 : unsigned int cluster_index;
374 114096097 : uint16_t cluster_mask = 0;
375 114096097 : uint16_t ir_holemask;
376 114096097 : int error = 0;
377 :
378 114096097 : nr_inodes = min_t(unsigned int, XFS_INODES_PER_CHUNK,
379 : M_IGEO(mp)->inodes_per_cluster);
380 :
381 : /* Map this inode cluster */
382 114096097 : agbno = XFS_AGINO_TO_AGBNO(mp, irec->ir_startino + cluster_base);
383 :
384 : /* Compute a bitmask for this cluster that can be used for holemask. */
385 114096097 : for (cluster_index = 0;
386 1026855714 : cluster_index < nr_inodes;
387 912759617 : cluster_index += XFS_INODES_PER_HOLEMASK_BIT)
388 912759617 : cluster_mask |= XFS_INOBT_MASK((cluster_base + cluster_index) /
389 : XFS_INODES_PER_HOLEMASK_BIT);
390 :
391 : /*
392 : * Map the first inode of this cluster to a buffer and offset.
393 : * Be careful about inobt records that don't align with the start of
394 : * the inode buffer when block sizes are large enough to hold multiple
395 : * inode chunks. When this happens, cluster_base will be zero but
396 : * ir_startino can be large enough to make im_boffset nonzero.
397 : */
398 114096097 : ir_holemask = (irec->ir_holemask & cluster_mask);
399 114096097 : imap.im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno);
400 114096097 : imap.im_len = XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster);
401 114096097 : imap.im_boffset = XFS_INO_TO_OFFSET(mp, irec->ir_startino) <<
402 114096097 : mp->m_sb.sb_inodelog;
403 :
404 114096097 : if (imap.im_boffset != 0 && cluster_base != 0) {
405 0 : ASSERT(imap.im_boffset == 0 || cluster_base == 0);
406 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
407 0 : return 0;
408 : }
409 :
410 228192194 : trace_xchk_iallocbt_check_cluster(mp, agno, irec->ir_startino,
411 114096097 : imap.im_blkno, imap.im_len, cluster_base, nr_inodes,
412 : cluster_mask, ir_holemask,
413 114096097 : XFS_INO_TO_OFFSET(mp, irec->ir_startino +
414 : cluster_base));
415 :
416 : /* The whole cluster must be a hole or not a hole. */
417 114097038 : if (ir_holemask != cluster_mask && ir_holemask != 0) {
418 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
419 0 : return 0;
420 : }
421 :
422 : /* If any part of this is a hole, skip it. */
423 114097038 : if (ir_holemask) {
424 26500061 : xchk_xref_is_not_owned_by(bs->sc, agbno,
425 : M_IGEO(mp)->blocks_per_cluster,
426 : &XFS_RMAP_OINFO_INODES);
427 26500061 : return 0;
428 : }
429 :
430 87596977 : xchk_xref_is_only_owned_by(bs->sc, agbno, M_IGEO(mp)->blocks_per_cluster,
431 : &XFS_RMAP_OINFO_INODES);
432 :
433 : /* Grab the inode cluster buffer. */
434 87597292 : error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap, &cluster_bp);
435 87596939 : if (!xchk_btree_xref_process_error(bs->sc, bs->cur, 0, &error))
436 0 : return error;
437 :
438 : /* Check free status of each inode within this cluster. */
439 2890015635 : for (cluster_index = 0; cluster_index < nr_inodes; cluster_index++) {
440 2802416544 : struct xfs_dinode *dip;
441 :
442 2802416544 : if (imap.im_boffset >= BBTOB(cluster_bp->b_length)) {
443 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
444 0 : break;
445 : }
446 :
447 2802416544 : dip = xfs_buf_offset(cluster_bp, imap.im_boffset);
448 2802329134 : error = xchk_iallocbt_check_cluster_ifree(bs, irec,
449 : cluster_base + cluster_index, dip);
450 2802420037 : if (error)
451 : break;
452 2802420036 : imap.im_boffset += mp->m_sb.sb_inodesize;
453 : }
454 :
455 87599092 : xfs_trans_brelse(bs->cur->bc_tp, cluster_bp);
456 87598733 : return error;
457 : }
458 :
459 : /*
460 : * For all the inode clusters that could map to this inobt record, make sure
461 : * that the holemask makes sense and that the allocation status of each inode
462 : * matches the freemask.
463 : */
464 : STATIC int
465 57048476 : xchk_iallocbt_check_clusters(
466 : struct xchk_btree *bs,
467 : struct xfs_inobt_rec_incore *irec)
468 : {
469 57048476 : unsigned int cluster_base;
470 57048476 : int error = 0;
471 :
472 : /*
473 : * For the common case where this inobt record maps to multiple inode
474 : * clusters this will call _check_cluster for each cluster.
475 : *
476 : * For the case that multiple inobt records map to a single cluster,
477 : * this will call _check_cluster once.
478 : */
479 57048476 : for (cluster_base = 0;
480 171145750 : cluster_base < XFS_INODES_PER_CHUNK;
481 114097274 : cluster_base += M_IGEO(bs->sc->mp)->inodes_per_cluster) {
482 114096459 : error = xchk_iallocbt_check_cluster(bs, irec, cluster_base);
483 114097275 : if (error)
484 : break;
485 : }
486 :
487 57049292 : return error;
488 : }
489 :
490 : /*
491 : * Make sure this inode btree record is aligned properly. Because a fs block
492 : * contains multiple inodes, we check that the inobt record is aligned to the
493 : * correct inode, not just the correct block on disk. This results in a finer
494 : * grained corruption check.
495 : */
496 : STATIC void
497 57048207 : xchk_iallocbt_rec_alignment(
498 : struct xchk_btree *bs,
499 : struct xfs_inobt_rec_incore *irec)
500 : {
501 57048207 : struct xfs_mount *mp = bs->sc->mp;
502 57048207 : struct xchk_iallocbt *iabt = bs->private;
503 57048207 : struct xfs_ino_geometry *igeo = M_IGEO(mp);
504 :
505 : /*
506 : * finobt records have different positioning requirements than inobt
507 : * records: each finobt record must have a corresponding inobt record.
508 : * That is checked in the xref function, so for now we only catch the
509 : * obvious case where the record isn't at all aligned properly.
510 : *
511 : * Note that if a fs block contains more than a single chunk of inodes,
512 : * we will have finobt records only for those chunks containing free
513 : * inodes, and therefore expect chunk alignment of finobt records.
514 : * Otherwise, we expect that the finobt record is aligned to the
515 : * cluster alignment as told by the superblock.
516 : */
517 57048207 : if (bs->cur->bc_btnum == XFS_BTNUM_FINO) {
518 481468 : unsigned int imask;
519 :
520 481468 : imask = min_t(unsigned int, XFS_INODES_PER_CHUNK,
521 : igeo->cluster_align_inodes) - 1;
522 481468 : if (irec->ir_startino & imask)
523 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
524 481468 : return;
525 : }
526 :
527 56566739 : if (iabt->next_startino != NULLAGINO) {
528 : /*
529 : * We're midway through a cluster of inodes that is mapped by
530 : * multiple inobt records. Did we get the record for the next
531 : * irec in the sequence?
532 : */
533 0 : if (irec->ir_startino != iabt->next_startino) {
534 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
535 0 : return;
536 : }
537 :
538 0 : iabt->next_startino += XFS_INODES_PER_CHUNK;
539 :
540 : /* Are we done with the cluster? */
541 0 : if (iabt->next_startino >= iabt->next_cluster_ino) {
542 0 : iabt->next_startino = NULLAGINO;
543 0 : iabt->next_cluster_ino = NULLAGINO;
544 : }
545 0 : return;
546 : }
547 :
548 : /* inobt records must be aligned to cluster and inoalignmnt size. */
549 56566739 : if (irec->ir_startino & (igeo->cluster_align_inodes - 1)) {
550 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
551 0 : return;
552 : }
553 :
554 56566739 : if (irec->ir_startino & (igeo->inodes_per_cluster - 1)) {
555 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
556 0 : return;
557 : }
558 :
559 56566739 : if (igeo->inodes_per_cluster <= XFS_INODES_PER_CHUNK)
560 : return;
561 :
562 : /*
563 : * If this is the start of an inode cluster that can be mapped by
564 : * multiple inobt records, the next inobt record must follow exactly
565 : * after this one.
566 : */
567 0 : iabt->next_startino = irec->ir_startino + XFS_INODES_PER_CHUNK;
568 0 : iabt->next_cluster_ino = irec->ir_startino + igeo->inodes_per_cluster;
569 : }
570 :
571 : /* Scrub an inobt/finobt record. */
572 : STATIC int
573 57047738 : xchk_iallocbt_rec(
574 : struct xchk_btree *bs,
575 : const union xfs_btree_rec *rec)
576 : {
577 57047738 : struct xfs_mount *mp = bs->cur->bc_mp;
578 57047738 : struct xchk_iallocbt *iabt = bs->private;
579 57047738 : struct xfs_inobt_rec_incore irec;
580 57047738 : uint64_t holes;
581 57047738 : xfs_agino_t agino;
582 57047738 : int holecount;
583 57047738 : int i;
584 57047738 : int error = 0;
585 57047738 : uint16_t holemask;
586 :
587 57047738 : xfs_inobt_btrec_to_irec(mp, rec, &irec);
588 57047637 : if (xfs_inobt_check_irec(bs->cur, &irec) != NULL) {
589 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
590 0 : return 0;
591 : }
592 :
593 57048578 : agino = irec.ir_startino;
594 :
595 57048578 : xchk_iallocbt_rec_alignment(bs, &irec);
596 57048514 : if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
597 0 : goto out;
598 :
599 57048514 : iabt->inodes += irec.ir_count;
600 :
601 : /* Handle non-sparse inodes */
602 57048514 : if (!xfs_inobt_issparse(irec.ir_holemask)) {
603 30548531 : if (irec.ir_count != XFS_INODES_PER_CHUNK)
604 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
605 :
606 30548531 : if (!xchk_iallocbt_chunk(bs, &irec, agino,
607 : XFS_INODES_PER_CHUNK))
608 0 : goto out;
609 30548931 : goto check_clusters;
610 : }
611 :
612 : /* Check each chunk of a sparse inode cluster. */
613 26499983 : holemask = irec.ir_holemask;
614 26499983 : holecount = 0;
615 26499983 : holes = ~xfs_inobt_irec_to_allocmask(&irec);
616 26500065 : if ((holes & irec.ir_free) != holes ||
617 26500065 : irec.ir_freecount > irec.ir_count)
618 0 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
619 :
620 450494570 : for (i = 0; i < XFS_INOBT_HOLEMASK_BITS; i++) {
621 423994469 : if (holemask & 1)
622 212000709 : holecount += XFS_INODES_PER_HOLEMASK_BIT;
623 211993760 : else if (!xchk_iallocbt_chunk(bs, &irec, agino,
624 : XFS_INODES_PER_HOLEMASK_BIT))
625 0 : goto out;
626 423994504 : holemask >>= 1;
627 423994504 : agino += XFS_INODES_PER_HOLEMASK_BIT;
628 : }
629 :
630 26500101 : if (holecount > XFS_INODES_PER_CHUNK ||
631 26500101 : holecount + irec.ir_count != XFS_INODES_PER_CHUNK)
632 4 : xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
633 :
634 26500098 : check_clusters:
635 57048536 : if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
636 0 : goto out;
637 :
638 57048536 : error = xchk_iallocbt_check_clusters(bs, &irec);
639 57049101 : if (error)
640 1 : goto out;
641 :
642 57049100 : out:
643 : return error;
644 : }
645 :
646 : /*
647 : * Make sure the inode btrees are as large as the rmap thinks they are.
648 : * Don't bother if we're missing btree cursors, as we're already corrupt.
649 : */
650 : STATIC void
651 932035 : xchk_iallocbt_xref_rmap_btreeblks(
652 : struct xfs_scrub *sc,
653 : int which)
654 : {
655 932035 : xfs_filblks_t blocks;
656 932035 : xfs_extlen_t inobt_blocks = 0;
657 932035 : xfs_extlen_t finobt_blocks = 0;
658 932035 : int error;
659 :
660 932035 : if (!sc->sa.ino_cur || !sc->sa.rmap_cur ||
661 914326 : (xfs_has_finobt(sc->mp) && !sc->sa.fino_cur) ||
662 914326 : xchk_skip_xref(sc->sm))
663 17709 : return;
664 :
665 : /* Check that we saw as many inobt blocks as the rmap says. */
666 914326 : error = xfs_btree_count_blocks(sc->sa.ino_cur, &inobt_blocks);
667 914615 : if (!xchk_process_error(sc, 0, 0, &error))
668 : return;
669 :
670 914178 : if (sc->sa.fino_cur) {
671 914178 : error = xfs_btree_count_blocks(sc->sa.fino_cur, &finobt_blocks);
672 915924 : if (!xchk_process_error(sc, 0, 0, &error))
673 : return;
674 : }
675 :
676 915788 : error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur,
677 : &XFS_RMAP_OINFO_INOBT, &blocks);
678 915747 : if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
679 : return;
680 915259 : if (blocks != inobt_blocks + finobt_blocks)
681 0 : xchk_btree_set_corrupt(sc, sc->sa.ino_cur, 0);
682 : }
683 :
684 : /*
685 : * Make sure that the inobt records point to the same number of blocks as
686 : * the rmap says are owned by inodes.
687 : */
688 : STATIC void
689 458948 : xchk_iallocbt_xref_rmap_inodes(
690 : struct xfs_scrub *sc,
691 : int which,
692 : unsigned long long inodes)
693 : {
694 458948 : xfs_filblks_t blocks;
695 458948 : xfs_filblks_t inode_blocks;
696 458948 : int error;
697 :
698 458948 : if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
699 8481 : return;
700 :
701 : /* Check that we saw as many inode blocks as the rmap knows about. */
702 450467 : error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur,
703 : &XFS_RMAP_OINFO_INODES, &blocks);
704 451826 : if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
705 : return;
706 451674 : inode_blocks = XFS_B_TO_FSB(sc->mp, inodes * sc->mp->m_sb.sb_inodesize);
707 451674 : if (blocks != inode_blocks)
708 0 : xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
709 : }
710 :
711 : /* Scrub the inode btrees for some AG. */
712 : STATIC int
713 932156 : xchk_iallocbt(
714 : struct xfs_scrub *sc,
715 : xfs_btnum_t which)
716 : {
717 932156 : struct xfs_btree_cur *cur;
718 932156 : struct xchk_iallocbt iabt = {
719 : .inodes = 0,
720 : .next_startino = NULLAGINO,
721 : .next_cluster_ino = NULLAGINO,
722 : };
723 932156 : int error;
724 :
725 932156 : cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur;
726 932156 : error = xchk_btree(sc, cur, xchk_iallocbt_rec, &XFS_RMAP_OINFO_INOBT,
727 : &iabt);
728 933277 : if (error)
729 : return error;
730 :
731 933209 : xchk_iallocbt_xref_rmap_btreeblks(sc, which);
732 :
733 : /*
734 : * If we're scrubbing the inode btree, inode_blocks is the number of
735 : * blocks pointed to by all the inode chunk records. Therefore, we
736 : * should compare to the number of inode chunk blocks that the rmap
737 : * knows about. We can't do this for the finobt since it only points
738 : * to inode chunks with free inodes.
739 : */
740 932896 : if (which == XFS_BTNUM_INO)
741 459606 : xchk_iallocbt_xref_rmap_inodes(sc, which, iabt.inodes);
742 :
743 : return error;
744 : }
745 :
746 : int
747 459898 : xchk_inobt(
748 : struct xfs_scrub *sc)
749 : {
750 459898 : return xchk_iallocbt(sc, XFS_BTNUM_INO);
751 : }
752 :
753 : int
754 473166 : xchk_finobt(
755 : struct xfs_scrub *sc)
756 : {
757 473166 : return xchk_iallocbt(sc, XFS_BTNUM_FINO);
758 : }
759 :
760 : /* See if an inode btree has (or doesn't have) an inode chunk record. */
761 : static inline void
762 4076351049 : xchk_xref_inode_check(
763 : struct xfs_scrub *sc,
764 : xfs_agblock_t agbno,
765 : xfs_extlen_t len,
766 : struct xfs_btree_cur **icur,
767 : enum xbtree_recpacking expected)
768 : {
769 4076351049 : enum xbtree_recpacking outcome;
770 4076351049 : int error;
771 :
772 4076351049 : if (!(*icur) || xchk_skip_xref(sc->sm))
773 209 : return;
774 :
775 4076350840 : error = xfs_ialloc_has_inodes_at_extent(*icur, agbno, len, &outcome);
776 4076753290 : if (!xchk_should_check_xref(sc, &error, icur))
777 : return;
778 4076616493 : if (outcome != expected)
779 0 : xchk_btree_xref_set_corrupt(sc, *icur, 0);
780 : }
781 :
782 : /* xref check that the extent is not covered by inodes */
783 : void
784 2029699874 : xchk_xref_is_not_inode_chunk(
785 : struct xfs_scrub *sc,
786 : xfs_agblock_t agbno,
787 : xfs_extlen_t len)
788 : {
789 2029699874 : xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur,
790 : XBTREE_RECPACKING_EMPTY);
791 2029981780 : xchk_xref_inode_check(sc, agbno, len, &sc->sa.fino_cur,
792 : XBTREE_RECPACKING_EMPTY);
793 2030099387 : }
794 :
795 : /* xref check that the extent is covered by inodes */
796 : void
797 17440241 : xchk_xref_is_inode_chunk(
798 : struct xfs_scrub *sc,
799 : xfs_agblock_t agbno,
800 : xfs_extlen_t len)
801 : {
802 17440241 : xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur,
803 : XBTREE_RECPACKING_FULL);
804 17441211 : }
|