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_bit.h"
14 : #include "xfs_log_format.h"
15 : #include "xfs_trans.h"
16 : #include "xfs_inode.h"
17 : #include "xfs_alloc.h"
18 : #include "xfs_bmap.h"
19 : #include "xfs_bmap_btree.h"
20 : #include "xfs_rmap.h"
21 : #include "xfs_rmap_btree.h"
22 : #include "scrub/scrub.h"
23 : #include "scrub/common.h"
24 : #include "scrub/btree.h"
25 : #include "xfs_ag.h"
26 :
27 : /* Set us up with an inode's bmap. */
28 : int
29 1054534192 : xchk_setup_inode_bmap(
30 : struct xfs_scrub *sc)
31 : {
32 1054534192 : int error;
33 :
34 1054534192 : if (xchk_need_intent_drain(sc))
35 0 : xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN);
36 :
37 1054534192 : error = xchk_iget_for_scrubbing(sc);
38 1055145201 : if (error)
39 5297974 : goto out;
40 :
41 1049847227 : sc->ilock_flags = XFS_IOLOCK_EXCL;
42 1049847227 : xfs_ilock(sc->ip, XFS_IOLOCK_EXCL);
43 :
44 : /*
45 : * We don't want any ephemeral data/cow fork updates sitting around
46 : * while we inspect block mappings, so wait for directio to finish
47 : * and flush dirty data if we have delalloc reservations.
48 : */
49 1049137389 : if (S_ISREG(VFS_I(sc->ip)->i_mode) &&
50 409798334 : sc->sm->sm_type != XFS_SCRUB_TYPE_BMBTA) {
51 263972441 : struct address_space *mapping = VFS_I(sc->ip)->i_mapping;
52 :
53 263972441 : sc->ilock_flags |= XFS_MMAPLOCK_EXCL;
54 263972441 : xfs_ilock(sc->ip, XFS_MMAPLOCK_EXCL);
55 :
56 264072049 : inode_dio_wait(VFS_I(sc->ip));
57 :
58 : /*
59 : * Try to flush all incore state to disk before we examine the
60 : * space mappings for the data fork. Leave accumulated errors
61 : * in the mapping for the writer threads to consume.
62 : *
63 : * On ENOSPC or EIO writeback errors, we continue into the
64 : * extent mapping checks because write failures do not
65 : * necessarily imply anything about the correctness of the file
66 : * metadata. The metadata and the file data could be on
67 : * completely separate devices; a media failure might only
68 : * affect a subset of the disk, etc. We can handle delalloc
69 : * extents in the scrubber, so leaving them in memory is fine.
70 : */
71 263798089 : error = filemap_fdatawrite(mapping);
72 263767157 : if (!error)
73 263773041 : error = filemap_fdatawait_keep_errors(mapping);
74 263903943 : if (error && (error != -ENOSPC && error != -EIO))
75 0 : goto out;
76 : }
77 :
78 : /* Got the inode, lock it and we're ready to go. */
79 1049068891 : error = xchk_trans_alloc(sc, 0);
80 1047665894 : if (error)
81 0 : goto out;
82 1047665894 : sc->ilock_flags |= XFS_ILOCK_EXCL;
83 1047665894 : xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
84 :
85 1054421878 : out:
86 : /* scrub teardown will unlock and release the inode */
87 1054421878 : return error;
88 : }
89 :
90 : /*
91 : * Inode fork block mapping (BMBT) scrubber.
92 : * More complex than the others because we have to scrub
93 : * all the extents regardless of whether or not the fork
94 : * is in btree format.
95 : */
96 :
97 : struct xchk_bmap_info {
98 : struct xfs_scrub *sc;
99 :
100 : /* Incore extent tree cursor */
101 : struct xfs_iext_cursor icur;
102 :
103 : /* Previous fork mapping that we examined */
104 : struct xfs_bmbt_irec prev_rec;
105 :
106 : /* Is this a realtime fork? */
107 : bool is_rt;
108 :
109 : /* May mappings point to shared space? */
110 : bool is_shared;
111 :
112 : /* Was the incore extent tree loaded? */
113 : bool was_loaded;
114 :
115 : /* Which inode fork are we checking? */
116 : int whichfork;
117 : };
118 :
119 : /* Look for a corresponding rmap for this irec. */
120 : static inline bool
121 258066803 : xchk_bmap_get_rmap(
122 : struct xchk_bmap_info *info,
123 : struct xfs_bmbt_irec *irec,
124 : xfs_agblock_t agbno,
125 : uint64_t owner,
126 : struct xfs_rmap_irec *rmap)
127 : {
128 258066803 : xfs_fileoff_t offset;
129 258066803 : unsigned int rflags = 0;
130 258066803 : int has_rmap;
131 258066803 : int error;
132 :
133 258066803 : if (info->whichfork == XFS_ATTR_FORK)
134 557848 : rflags |= XFS_RMAP_ATTR_FORK;
135 258066803 : if (irec->br_state == XFS_EXT_UNWRITTEN)
136 22429251 : rflags |= XFS_RMAP_UNWRITTEN;
137 :
138 : /*
139 : * CoW staging extents are owned (on disk) by the refcountbt, so
140 : * their rmaps do not have offsets.
141 : */
142 258066803 : if (info->whichfork == XFS_COW_FORK)
143 : offset = 0;
144 : else
145 255825007 : offset = irec->br_startoff;
146 :
147 : /*
148 : * If the caller thinks this could be a shared bmbt extent (IOWs,
149 : * any data fork extent of a reflink inode) then we have to use the
150 : * range rmap lookup to make sure we get the correct owner/offset.
151 : */
152 258066803 : if (info->is_shared) {
153 117769344 : error = xfs_rmap_lookup_le_range(info->sc->sa.rmap_cur, agbno,
154 : owner, offset, rflags, rmap, &has_rmap);
155 : } else {
156 140297459 : error = xfs_rmap_lookup_le(info->sc->sa.rmap_cur, agbno,
157 : owner, offset, rflags, rmap, &has_rmap);
158 : }
159 258066005 : if (!xchk_should_check_xref(info->sc, &error, &info->sc->sa.rmap_cur))
160 : return false;
161 :
162 258028298 : if (!has_rmap)
163 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
164 : irec->br_startoff);
165 258028298 : return has_rmap;
166 : }
167 :
168 : /* Make sure that we have rmapbt records for this data/attr fork extent. */
169 : STATIC void
170 277018561 : xchk_bmap_xref_rmap(
171 : struct xchk_bmap_info *info,
172 : struct xfs_bmbt_irec *irec,
173 : xfs_agblock_t agbno)
174 : {
175 277018561 : struct xfs_rmap_irec rmap;
176 277018561 : unsigned long long rmap_end;
177 277018561 : uint64_t owner = info->sc->ip->i_ino;
178 :
179 277018561 : if (!info->sc->sa.rmap_cur || xchk_skip_xref(info->sc->sm))
180 21188835 : return;
181 :
182 : /* Find the rmap record for this irec. */
183 255829726 : if (!xchk_bmap_get_rmap(info, irec, agbno, owner, &rmap))
184 : return;
185 :
186 : /*
187 : * The rmap must be an exact match for this incore file mapping record,
188 : * which may have arisen from multiple ondisk records.
189 : */
190 255804756 : if (rmap.rm_startblock != agbno)
191 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
192 : irec->br_startoff);
193 :
194 255804756 : rmap_end = (unsigned long long)rmap.rm_startblock + rmap.rm_blockcount;
195 255804756 : if (rmap_end != agbno + irec->br_blockcount)
196 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
197 : irec->br_startoff);
198 :
199 : /* Check the logical offsets. */
200 255804756 : if (rmap.rm_offset != irec->br_startoff)
201 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
202 : irec->br_startoff);
203 :
204 255804756 : rmap_end = (unsigned long long)rmap.rm_offset + rmap.rm_blockcount;
205 255804756 : if (rmap_end != irec->br_startoff + irec->br_blockcount)
206 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
207 : irec->br_startoff);
208 :
209 : /* Check the owner */
210 255804756 : if (rmap.rm_owner != owner)
211 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
212 : irec->br_startoff);
213 :
214 : /*
215 : * Check for discrepancies between the unwritten flag in the irec and
216 : * the rmap. Note that the (in-memory) CoW fork distinguishes between
217 : * unwritten and written extents, but we don't track that in the rmap
218 : * records because the blocks are owned (on-disk) by the refcountbt,
219 : * which doesn't track unwritten state.
220 : */
221 255804756 : if (!!(irec->br_state == XFS_EXT_UNWRITTEN) !=
222 255804756 : !!(rmap.rm_flags & XFS_RMAP_UNWRITTEN))
223 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
224 : irec->br_startoff);
225 :
226 255804756 : if (!!(info->whichfork == XFS_ATTR_FORK) !=
227 255804756 : !!(rmap.rm_flags & XFS_RMAP_ATTR_FORK))
228 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
229 : irec->br_startoff);
230 255804756 : if (rmap.rm_flags & XFS_RMAP_BMBT_BLOCK)
231 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
232 : irec->br_startoff);
233 : }
234 :
235 : /* Make sure that we have rmapbt records for this COW fork extent. */
236 : STATIC void
237 2251711 : xchk_bmap_xref_rmap_cow(
238 : struct xchk_bmap_info *info,
239 : struct xfs_bmbt_irec *irec,
240 : xfs_agblock_t agbno)
241 : {
242 2251711 : struct xfs_rmap_irec rmap;
243 2251711 : unsigned long long rmap_end;
244 2251711 : uint64_t owner = XFS_RMAP_OWN_COW;
245 :
246 2251711 : if (!info->sc->sa.rmap_cur || xchk_skip_xref(info->sc->sm))
247 0 : return;
248 :
249 : /* Find the rmap record for this irec. */
250 2251711 : if (!xchk_bmap_get_rmap(info, irec, agbno, owner, &rmap))
251 : return;
252 :
253 : /*
254 : * CoW staging extents are owned by the refcount btree, so the rmap
255 : * can start before and end after the physical space allocated to this
256 : * mapping. There are no offsets to check.
257 : */
258 2251562 : if (rmap.rm_startblock > agbno)
259 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
260 : irec->br_startoff);
261 :
262 2251562 : rmap_end = (unsigned long long)rmap.rm_startblock + rmap.rm_blockcount;
263 2251562 : if (rmap_end < agbno + irec->br_blockcount)
264 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
265 : irec->br_startoff);
266 :
267 : /* Check the owner */
268 2251562 : if (rmap.rm_owner != owner)
269 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
270 : irec->br_startoff);
271 :
272 : /*
273 : * No flags allowed. Note that the (in-memory) CoW fork distinguishes
274 : * between unwritten and written extents, but we don't track that in
275 : * the rmap records because the blocks are owned (on-disk) by the
276 : * refcountbt, which doesn't track unwritten state.
277 : */
278 2251562 : if (rmap.rm_flags & XFS_RMAP_ATTR_FORK)
279 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
280 : irec->br_startoff);
281 2251562 : if (rmap.rm_flags & XFS_RMAP_BMBT_BLOCK)
282 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
283 : irec->br_startoff);
284 2251562 : if (rmap.rm_flags & XFS_RMAP_UNWRITTEN)
285 0 : xchk_fblock_xref_set_corrupt(info->sc, info->whichfork,
286 : irec->br_startoff);
287 : }
288 :
289 : /* Cross-reference a single rtdev extent record. */
290 : STATIC void
291 263353786 : xchk_bmap_rt_iextent_xref(
292 : struct xfs_inode *ip,
293 : struct xchk_bmap_info *info,
294 : struct xfs_bmbt_irec *irec)
295 : {
296 263353786 : xchk_xref_is_used_rt_space(info->sc, irec->br_startblock,
297 263353786 : irec->br_blockcount);
298 263444099 : }
299 :
300 : /* Cross-reference a single datadev extent record. */
301 : STATIC void
302 279229524 : xchk_bmap_iextent_xref(
303 : struct xfs_inode *ip,
304 : struct xchk_bmap_info *info,
305 : struct xfs_bmbt_irec *irec)
306 : {
307 279229524 : struct xfs_owner_info oinfo;
308 279229524 : struct xfs_mount *mp = info->sc->mp;
309 279229524 : xfs_agnumber_t agno;
310 279229524 : xfs_agblock_t agbno;
311 279229524 : xfs_extlen_t len;
312 279229524 : int error;
313 :
314 279229524 : agno = XFS_FSB_TO_AGNO(mp, irec->br_startblock);
315 279229524 : agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock);
316 279217267 : len = irec->br_blockcount;
317 :
318 279217267 : error = xchk_ag_init_existing(info->sc, agno, &info->sc->sa);
319 279297511 : if (!xchk_fblock_process_error(info->sc, info->whichfork,
320 : irec->br_startoff, &error))
321 0 : goto out_free;
322 :
323 279228704 : xchk_xref_is_used_space(info->sc, agbno, len);
324 279213013 : xchk_xref_is_not_inode_chunk(info->sc, agbno, len);
325 279300410 : switch (info->whichfork) {
326 275611838 : case XFS_DATA_FORK:
327 275611838 : xchk_bmap_xref_rmap(info, irec, agbno);
328 275554755 : if (!xfs_is_reflink_inode(info->sc->ip)) {
329 157780619 : xfs_rmap_ino_owner(&oinfo, info->sc->ip->i_ino,
330 : info->whichfork, irec->br_startoff);
331 157780619 : xchk_xref_is_only_owned_by(info->sc, agbno,
332 157780619 : irec->br_blockcount, &oinfo);
333 157820100 : xchk_xref_is_not_shared(info->sc, agbno,
334 157820100 : irec->br_blockcount);
335 : }
336 275590695 : xchk_xref_is_not_cow_staging(info->sc, agbno,
337 275590695 : irec->br_blockcount);
338 275590695 : break;
339 1436666 : case XFS_ATTR_FORK:
340 1436666 : xchk_bmap_xref_rmap(info, irec, agbno);
341 1434124 : xfs_rmap_ino_owner(&oinfo, info->sc->ip->i_ino,
342 : info->whichfork, irec->br_startoff);
343 1434124 : xchk_xref_is_only_owned_by(info->sc, agbno, irec->br_blockcount,
344 : &oinfo);
345 1434792 : xchk_xref_is_not_shared(info->sc, agbno,
346 1434792 : irec->br_blockcount);
347 1434692 : xchk_xref_is_not_cow_staging(info->sc, agbno,
348 1434692 : irec->br_blockcount);
349 1434692 : break;
350 2251906 : case XFS_COW_FORK:
351 2251906 : xchk_bmap_xref_rmap_cow(info, irec, agbno);
352 2251631 : xchk_xref_is_only_owned_by(info->sc, agbno, irec->br_blockcount,
353 : &XFS_RMAP_OINFO_COW);
354 2251879 : xchk_xref_is_cow_staging(info->sc, agbno,
355 2251879 : irec->br_blockcount);
356 2251858 : xchk_xref_is_not_shared(info->sc, agbno,
357 2251858 : irec->br_blockcount);
358 2251858 : break;
359 : }
360 :
361 279264555 : out_free:
362 279264555 : xchk_ag_free(info->sc, &info->sc->sa);
363 279322680 : }
364 :
365 : /*
366 : * Directories and attr forks should never have blocks that can't be addressed
367 : * by a xfs_dablk_t.
368 : */
369 : STATIC void
370 542454345 : xchk_bmap_dirattr_extent(
371 : struct xfs_inode *ip,
372 : struct xchk_bmap_info *info,
373 : struct xfs_bmbt_irec *irec)
374 : {
375 542454345 : struct xfs_mount *mp = ip->i_mount;
376 542454345 : xfs_fileoff_t off;
377 :
378 542454345 : if (!S_ISDIR(VFS_I(ip)->i_mode) && info->whichfork != XFS_ATTR_FORK)
379 : return;
380 :
381 2660780 : if (!xfs_verify_dablk(mp, irec->br_startoff))
382 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
383 : irec->br_startoff);
384 :
385 2657620 : off = irec->br_startoff + irec->br_blockcount - 1;
386 2657620 : if (!xfs_verify_dablk(mp, off))
387 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork, off);
388 : }
389 :
390 : /* Scrub a single extent record. */
391 : STATIC void
392 542532201 : xchk_bmap_iextent(
393 : struct xfs_inode *ip,
394 : struct xchk_bmap_info *info,
395 : struct xfs_bmbt_irec *irec)
396 : {
397 542532201 : struct xfs_mount *mp = info->sc->mp;
398 :
399 : /*
400 : * Check for out-of-order extents. This record could have come
401 : * from the incore list, for which there is no ordering check.
402 : */
403 542532201 : if (irec->br_startoff < info->prev_rec.br_startoff +
404 542532201 : info->prev_rec.br_blockcount)
405 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
406 : irec->br_startoff);
407 :
408 542532201 : if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount))
409 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
410 : irec->br_startoff);
411 :
412 542448538 : xchk_bmap_dirattr_extent(ip, info, irec);
413 :
414 : /* Make sure the extent points to a valid place. */
415 805880607 : if (info->is_rt &&
416 263297557 : !xfs_verify_rtext(mp, irec->br_startblock, irec->br_blockcount))
417 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
418 : irec->br_startoff);
419 821822568 : if (!info->is_rt &&
420 279212193 : !xfs_verify_fsbext(mp, irec->br_startblock, irec->br_blockcount))
421 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
422 : irec->br_startoff);
423 :
424 : /* We don't allow unwritten extents on attr forks. */
425 542610375 : if (irec->br_state == XFS_EXT_UNWRITTEN &&
426 93531568 : info->whichfork == XFS_ATTR_FORK)
427 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
428 : irec->br_startoff);
429 :
430 542610375 : if (info->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
431 : return;
432 :
433 542610375 : if (info->is_rt)
434 263360055 : xchk_bmap_rt_iextent_xref(ip, info, irec);
435 : else
436 279250320 : xchk_bmap_iextent_xref(ip, info, irec);
437 : }
438 :
439 : /* Scrub a bmbt record. */
440 : STATIC int
441 304068556 : xchk_bmapbt_rec(
442 : struct xchk_btree *bs,
443 : const union xfs_btree_rec *rec)
444 : {
445 304068556 : struct xfs_bmbt_irec irec;
446 304068556 : struct xfs_bmbt_irec iext_irec;
447 304068556 : struct xfs_iext_cursor icur;
448 304068556 : struct xchk_bmap_info *info = bs->private;
449 304068556 : struct xfs_inode *ip = bs->cur->bc_ino.ip;
450 304068556 : struct xfs_buf *bp = NULL;
451 304068556 : struct xfs_btree_block *block;
452 304068556 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, info->whichfork);
453 304065494 : uint64_t owner;
454 304065494 : int i;
455 :
456 : /*
457 : * Check the owners of the btree blocks up to the level below
458 : * the root since the verifiers don't do that.
459 : */
460 304065494 : if (xfs_has_crc(bs->cur->bc_mp) &&
461 304066528 : bs->cur->bc_levels[0].ptr == 1) {
462 10242981 : for (i = 0; i < bs->cur->bc_nlevels - 1; i++) {
463 5470022 : block = xfs_btree_get_block(bs->cur, i, &bp);
464 5470189 : owner = be64_to_cpu(block->bb_u.l.bb_owner);
465 5470189 : if (owner != ip->i_ino)
466 0 : xchk_fblock_set_corrupt(bs->sc,
467 : info->whichfork, 0);
468 : }
469 : }
470 :
471 : /*
472 : * Check that the incore extent tree contains an extent that matches
473 : * this one exactly. We validate those cached bmaps later, so we don't
474 : * need to check them here. If the incore extent tree was just loaded
475 : * from disk by the scrubber, we assume that its contents match what's
476 : * on disk (we still hold the ILOCK) and skip the equivalence check.
477 : */
478 304065661 : if (!info->was_loaded)
479 : return 0;
480 :
481 301752061 : xfs_bmbt_disk_get_all(&rec->bmbt, &irec);
482 301751710 : if (xfs_bmap_validate_extent(ip, info->whichfork, &irec) != NULL) {
483 0 : xchk_fblock_set_corrupt(bs->sc, info->whichfork,
484 : irec.br_startoff);
485 0 : return 0;
486 : }
487 :
488 301752585 : if (!xfs_iext_lookup_extent(ip, ifp, irec.br_startoff, &icur,
489 301773532 : &iext_irec) ||
490 301773532 : irec.br_startoff != iext_irec.br_startoff ||
491 301776880 : irec.br_startblock != iext_irec.br_startblock ||
492 301777842 : irec.br_blockcount != iext_irec.br_blockcount ||
493 301778169 : irec.br_state != iext_irec.br_state)
494 0 : xchk_fblock_set_corrupt(bs->sc, info->whichfork,
495 : irec.br_startoff);
496 : return 0;
497 : }
498 :
499 : /* Scan the btree records. */
500 : STATIC int
501 3984524 : xchk_bmap_btree(
502 : struct xfs_scrub *sc,
503 : int whichfork,
504 : struct xchk_bmap_info *info)
505 : {
506 3984524 : struct xfs_owner_info oinfo;
507 3984524 : struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, whichfork);
508 3984124 : struct xfs_mount *mp = sc->mp;
509 3984124 : struct xfs_inode *ip = sc->ip;
510 3984124 : struct xfs_btree_cur *cur;
511 3984124 : int error;
512 :
513 : /* Load the incore bmap cache if it's not loaded. */
514 3984124 : info->was_loaded = !xfs_need_iread_extents(ifp);
515 :
516 3984136 : error = xfs_iread_extents(sc->tp, ip, whichfork);
517 3984461 : if (!xchk_fblock_process_error(sc, whichfork, 0, &error))
518 0 : goto out;
519 :
520 : /* Check the btree structure. */
521 3984395 : cur = xfs_bmbt_init_cursor(mp, sc->tp, ip, whichfork);
522 3985145 : xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork);
523 3985145 : error = xchk_btree(sc, cur, xchk_bmapbt_rec, &oinfo, info);
524 3985278 : xfs_btree_del_cursor(cur, error);
525 3985286 : out:
526 3985286 : return error;
527 : }
528 :
529 : struct xchk_bmap_check_rmap_info {
530 : struct xfs_scrub *sc;
531 : int whichfork;
532 : struct xfs_iext_cursor icur;
533 : };
534 :
535 : /* Can we find bmaps that fit this rmap? */
536 : STATIC int
537 35119627545 : xchk_bmap_check_rmap(
538 : struct xfs_btree_cur *cur,
539 : const struct xfs_rmap_irec *rec,
540 : void *priv)
541 : {
542 35119627545 : struct xfs_bmbt_irec irec;
543 35119627545 : struct xfs_rmap_irec check_rec;
544 35119627545 : struct xchk_bmap_check_rmap_info *sbcri = priv;
545 35119627545 : struct xfs_ifork *ifp;
546 35119627545 : struct xfs_scrub *sc = sbcri->sc;
547 35119627545 : bool have_map;
548 :
549 : /* Is this even the right fork? */
550 35119627545 : if (rec->rm_owner != sc->ip->i_ino)
551 : return 0;
552 334065 : if ((sbcri->whichfork == XFS_ATTR_FORK) ^
553 334065 : !!(rec->rm_flags & XFS_RMAP_ATTR_FORK))
554 : return 0;
555 0 : if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK)
556 : return 0;
557 :
558 : /* Now look up the bmbt record. */
559 0 : ifp = xfs_ifork_ptr(sc->ip, sbcri->whichfork);
560 0 : if (!ifp) {
561 0 : xchk_fblock_set_corrupt(sc, sbcri->whichfork,
562 0 : rec->rm_offset);
563 0 : goto out;
564 : }
565 0 : have_map = xfs_iext_lookup_extent(sc->ip, ifp, rec->rm_offset,
566 : &sbcri->icur, &irec);
567 0 : if (!have_map)
568 0 : xchk_fblock_set_corrupt(sc, sbcri->whichfork,
569 0 : rec->rm_offset);
570 : /*
571 : * bmap extent record lengths are constrained to 2^21 blocks in length
572 : * because of space constraints in the on-disk metadata structure.
573 : * However, rmap extent record lengths are constrained only by AG
574 : * length, so we have to loop through the bmbt to make sure that the
575 : * entire rmap is covered by bmbt records.
576 : */
577 0 : check_rec = *rec;
578 0 : while (have_map) {
579 0 : if (irec.br_startoff != check_rec.rm_offset)
580 0 : xchk_fblock_set_corrupt(sc, sbcri->whichfork,
581 : check_rec.rm_offset);
582 0 : if (irec.br_startblock != XFS_AGB_TO_FSB(sc->mp,
583 : cur->bc_ag.pag->pag_agno,
584 : check_rec.rm_startblock))
585 0 : xchk_fblock_set_corrupt(sc, sbcri->whichfork,
586 : check_rec.rm_offset);
587 0 : if (irec.br_blockcount > check_rec.rm_blockcount)
588 0 : xchk_fblock_set_corrupt(sc, sbcri->whichfork,
589 : check_rec.rm_offset);
590 0 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
591 : break;
592 0 : check_rec.rm_startblock += irec.br_blockcount;
593 0 : check_rec.rm_offset += irec.br_blockcount;
594 0 : check_rec.rm_blockcount -= irec.br_blockcount;
595 0 : if (check_rec.rm_blockcount == 0)
596 : break;
597 0 : have_map = xfs_iext_next_extent(ifp, &sbcri->icur, &irec);
598 0 : if (!have_map)
599 0 : xchk_fblock_set_corrupt(sc, sbcri->whichfork,
600 : check_rec.rm_offset);
601 : }
602 :
603 0 : out:
604 0 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
605 0 : return -ECANCELED;
606 : return 0;
607 : }
608 :
609 : /* Make sure each rmap has a corresponding bmbt entry. */
610 : STATIC int
611 1775500 : xchk_bmap_check_ag_rmaps(
612 : struct xfs_scrub *sc,
613 : int whichfork,
614 : struct xfs_perag *pag)
615 : {
616 1775500 : struct xchk_bmap_check_rmap_info sbcri;
617 1775500 : struct xfs_btree_cur *cur;
618 1775500 : struct xfs_buf *agf;
619 1775500 : int error;
620 :
621 1775500 : error = xfs_alloc_read_agf(pag, sc->tp, 0, &agf);
622 1775501 : if (error)
623 : return error;
624 :
625 1775503 : cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, agf, pag);
626 :
627 1775520 : sbcri.sc = sc;
628 1775520 : sbcri.whichfork = whichfork;
629 1775520 : error = xfs_rmap_query_all(cur, xchk_bmap_check_rmap, &sbcri);
630 1775511 : if (error == -ECANCELED)
631 0 : error = 0;
632 :
633 1775511 : xfs_btree_del_cursor(cur, error);
634 1775518 : xfs_trans_brelse(sc->tp, agf);
635 1775518 : return error;
636 : }
637 :
638 : /*
639 : * Decide if we want to walk every rmap btree in the fs to make sure that each
640 : * rmap for this file fork has corresponding bmbt entries.
641 : */
642 : static bool
643 183666888 : xchk_bmap_want_check_rmaps(
644 : struct xchk_bmap_info *info)
645 : {
646 183666888 : struct xfs_scrub *sc = info->sc;
647 183666888 : struct xfs_ifork *ifp;
648 :
649 183666888 : if (!xfs_has_rmapbt(sc->mp))
650 : return false;
651 82916525 : if (info->whichfork == XFS_COW_FORK)
652 : return false;
653 75871297 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
654 : return false;
655 :
656 : /* Don't support realtime rmap checks yet. */
657 75871297 : if (info->is_rt)
658 : return false;
659 :
660 : /*
661 : * The inode repair code zaps broken inode forks by resetting them back
662 : * to EXTENTS format and zero extent records. If we encounter a fork
663 : * in this state along with evidence that the fork isn't supposed to be
664 : * empty, we need to scan the reverse mappings to decide if we're going
665 : * to rebuild the fork. Data forks with nonzero file size are scanned.
666 : * xattr forks are never empty of content, so they are always scanned.
667 : */
668 75856199 : ifp = xfs_ifork_ptr(sc->ip, info->whichfork);
669 75849758 : if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && ifp->if_nextents == 0) {
670 44391279 : if (info->whichfork == XFS_DATA_FORK &&
671 44353177 : i_size_read(VFS_I(sc->ip)) == 0)
672 : return false;
673 :
674 365670 : return true;
675 : }
676 :
677 : return false;
678 : }
679 :
680 : /* Make sure each rmap has a corresponding bmbt entry. */
681 : STATIC int
682 365670 : xchk_bmap_check_rmaps(
683 : struct xfs_scrub *sc,
684 : int whichfork)
685 : {
686 365670 : struct xfs_perag *pag;
687 365670 : xfs_agnumber_t agno;
688 365670 : int error;
689 :
690 2141189 : for_each_perag(sc->mp, agno, pag) {
691 1775506 : error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag);
692 1775519 : if (error ||
693 1775519 : (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
694 0 : xfs_perag_rele(pag);
695 0 : return error;
696 : }
697 : }
698 :
699 : return 0;
700 : }
701 :
702 : /* Scrub a delalloc reservation from the incore extent map tree. */
703 : STATIC void
704 1023 : xchk_bmap_iextent_delalloc(
705 : struct xfs_inode *ip,
706 : struct xchk_bmap_info *info,
707 : struct xfs_bmbt_irec *irec)
708 : {
709 1023 : struct xfs_mount *mp = info->sc->mp;
710 :
711 : /*
712 : * Check for out-of-order extents. This record could have come
713 : * from the incore list, for which there is no ordering check.
714 : */
715 1023 : if (irec->br_startoff < info->prev_rec.br_startoff +
716 1023 : info->prev_rec.br_blockcount)
717 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
718 : irec->br_startoff);
719 :
720 1023 : if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount))
721 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
722 : irec->br_startoff);
723 :
724 : /* Make sure the extent points to a valid place. */
725 1023 : if (irec->br_blockcount > XFS_MAX_BMBT_EXTLEN)
726 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
727 : irec->br_startoff);
728 1023 : }
729 :
730 : /* Decide if this individual fork mapping is ok. */
731 : static bool
732 : xchk_bmap_iext_mapping(
733 : struct xchk_bmap_info *info,
734 : const struct xfs_bmbt_irec *irec)
735 : {
736 : /* There should never be a "hole" extent in either extent list. */
737 542625296 : if (irec->br_startblock == HOLESTARTBLOCK)
738 : return false;
739 542625296 : if (irec->br_blockcount > XFS_MAX_BMBT_EXTLEN)
740 : return false;
741 : return true;
742 : }
743 :
744 : /* Are these two mappings contiguous with each other? */
745 : static inline bool
746 456772375 : xchk_are_bmaps_contiguous(
747 : const struct xfs_bmbt_irec *b1,
748 : const struct xfs_bmbt_irec *b2)
749 : {
750 : /* Don't try to combine unallocated mappings. */
751 913547455 : if (!xfs_bmap_is_real_extent(b1))
752 : return false;
753 913523716 : if (!xfs_bmap_is_real_extent(b2))
754 : return false;
755 :
756 : /* Does b2 come right after b1 in the logical and physical range? */
757 456771504 : if (b1->br_startoff + b1->br_blockcount != b2->br_startoff)
758 : return false;
759 187631177 : if (b1->br_startblock + b1->br_blockcount != b2->br_startblock)
760 : return false;
761 41579649 : if (b1->br_state != b2->br_state)
762 41580369 : return false;
763 : return true;
764 : }
765 :
766 : /*
767 : * Walk the incore extent records, accumulating consecutive contiguous records
768 : * into a single incore mapping. Returns true if @irec has been set to a
769 : * mapping or false if there are no more mappings. Caller must ensure that
770 : * @info.icur is zeroed before the first call.
771 : */
772 : static bool
773 726184556 : xchk_bmap_iext_iter(
774 : struct xchk_bmap_info *info,
775 : struct xfs_bmbt_irec *irec)
776 : {
777 726184556 : struct xfs_bmbt_irec got;
778 726184556 : struct xfs_ifork *ifp;
779 726184556 : unsigned int nr = 0;
780 :
781 726184556 : ifp = xfs_ifork_ptr(info->sc->ip, info->whichfork);
782 :
783 : /* Advance to the next iextent record and check the mapping. */
784 725790180 : xfs_iext_next(ifp, &info->icur);
785 725909853 : if (!xfs_iext_get_extent(ifp, &info->icur, irec))
786 : return false;
787 :
788 542625162 : if (!xchk_bmap_iext_mapping(info, irec)) {
789 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
790 : irec->br_startoff);
791 0 : return false;
792 : }
793 : nr++;
794 :
795 : /*
796 : * Iterate subsequent iextent records and merge them with the one
797 : * that we just read, if possible.
798 : */
799 542625296 : while (xfs_iext_peek_next_extent(ifp, &info->icur, &got)) {
800 456654832 : if (!xchk_are_bmaps_contiguous(irec, &got))
801 : break;
802 :
803 134 : if (!xchk_bmap_iext_mapping(info, &got)) {
804 0 : xchk_fblock_set_corrupt(info->sc, info->whichfork,
805 : got.br_startoff);
806 0 : return false;
807 : }
808 134 : nr++;
809 :
810 134 : irec->br_blockcount += got.br_blockcount;
811 134 : xfs_iext_next(ifp, &info->icur);
812 : }
813 :
814 : /*
815 : * If the merged mapping could be expressed with fewer bmbt records
816 : * than we actually found, notify the user that this fork could be
817 : * optimized. CoW forks only exist in memory so we ignore them.
818 : */
819 542425404 : if (nr > 1 && info->whichfork != XFS_COW_FORK &&
820 87 : howmany_64(irec->br_blockcount, XFS_MAX_BMBT_EXTLEN) < nr)
821 0 : xchk_ino_set_preen(info->sc, info->sc->ip->i_ino);
822 :
823 : return true;
824 : }
825 :
826 : /*
827 : * Scrub an inode fork's block mappings.
828 : *
829 : * First we scan every record in every btree block, if applicable.
830 : * Then we unconditionally scan the incore extent cache.
831 : */
832 : STATIC int
833 763325591 : xchk_bmap(
834 : struct xfs_scrub *sc,
835 : int whichfork)
836 : {
837 763325591 : struct xfs_bmbt_irec irec;
838 763325591 : struct xchk_bmap_info info = { NULL };
839 763325591 : struct xfs_mount *mp = sc->mp;
840 763325591 : struct xfs_inode *ip = sc->ip;
841 763325591 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
842 764115636 : xfs_fileoff_t endoff;
843 764115636 : int error = 0;
844 :
845 : /* Non-existent forks can be ignored. */
846 764115636 : if (!ifp)
847 358575095 : goto out;
848 :
849 405540541 : info.is_rt = whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip);
850 405540541 : info.whichfork = whichfork;
851 405540541 : info.is_shared = whichfork == XFS_DATA_FORK && xfs_is_reflink_inode(ip);
852 405540541 : info.sc = sc;
853 :
854 405540541 : switch (whichfork) {
855 : case XFS_COW_FORK:
856 : /* No CoW forks on non-reflink inodes/filesystems. */
857 7045852 : if (!xfs_is_reflink_inode(ip)) {
858 0 : xchk_ino_set_corrupt(sc, sc->ip->i_ino);
859 0 : goto out;
860 : }
861 : break;
862 : case XFS_ATTR_FORK:
863 18905600 : if (!xfs_has_attr(mp) && !xfs_has_attr2(mp))
864 0 : xchk_ino_set_corrupt(sc, sc->ip->i_ino);
865 : break;
866 379589089 : default:
867 379589089 : ASSERT(whichfork == XFS_DATA_FORK);
868 : break;
869 : }
870 :
871 : /* Check the fork values */
872 405540541 : switch (ifp->if_format) {
873 221920234 : case XFS_DINODE_FMT_UUID:
874 : case XFS_DINODE_FMT_DEV:
875 : case XFS_DINODE_FMT_LOCAL:
876 : /* No mappings to check. */
877 221920234 : if (whichfork == XFS_COW_FORK)
878 0 : xchk_fblock_set_corrupt(sc, whichfork, 0);
879 221920234 : goto out;
880 : case XFS_DINODE_FMT_EXTENTS:
881 : break;
882 3984566 : case XFS_DINODE_FMT_BTREE:
883 3984566 : if (whichfork == XFS_COW_FORK) {
884 0 : xchk_fblock_set_corrupt(sc, whichfork, 0);
885 0 : goto out;
886 : }
887 :
888 3984566 : error = xchk_bmap_btree(sc, whichfork, &info);
889 3985233 : if (error)
890 4 : goto out;
891 : break;
892 0 : default:
893 0 : xchk_fblock_set_corrupt(sc, whichfork, 0);
894 0 : goto out;
895 : }
896 :
897 183620970 : if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
898 0 : goto out;
899 :
900 : /* Find the offset of the last extent in the mapping. */
901 183620970 : error = xfs_bmap_last_offset(ip, &endoff, whichfork);
902 183613511 : if (!xchk_fblock_process_error(sc, whichfork, 0, &error))
903 0 : goto out;
904 :
905 : /*
906 : * Scrub extent records. We use a special iterator function here that
907 : * combines adjacent mappings if they are logically and physically
908 : * contiguous. For large allocations that require multiple bmbt
909 : * records, this reduces the number of cross-referencing calls, which
910 : * reduces runtime. Cross referencing with the rmap is simpler because
911 : * the rmap must match the combined mapping exactly.
912 : */
913 726389346 : while (xchk_bmap_iext_iter(&info, &irec)) {
914 542408415 : if (xchk_should_terminate(sc, &error) ||
915 542442510 : (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
916 40 : goto out;
917 :
918 542442510 : if (irec.br_startoff >= endoff) {
919 0 : xchk_fblock_set_corrupt(sc, whichfork,
920 : irec.br_startoff);
921 0 : goto out;
922 : }
923 :
924 542442510 : if (isnullstartblock(irec.br_startblock))
925 1023 : xchk_bmap_iextent_delalloc(ip, &info, &irec);
926 : else
927 542441487 : xchk_bmap_iextent(ip, &info, &irec);
928 542844960 : memcpy(&info.prev_rec, &irec, sizeof(struct xfs_bmbt_irec));
929 : }
930 :
931 183747514 : if (xchk_bmap_want_check_rmaps(&info)) {
932 365670 : error = xchk_bmap_check_rmaps(sc, whichfork);
933 365680 : if (!xchk_fblock_xref_process_error(sc, whichfork, 0, &error))
934 : goto out;
935 : }
936 183664115 : out:
937 764159488 : return error;
938 : }
939 :
940 : /* Scrub an inode's data fork. */
941 : int
942 379527146 : xchk_bmap_data(
943 : struct xfs_scrub *sc)
944 : {
945 379527146 : return xchk_bmap(sc, XFS_DATA_FORK);
946 : }
947 :
948 : /* Scrub an inode's attr fork. */
949 : int
950 377586958 : xchk_bmap_attr(
951 : struct xfs_scrub *sc)
952 : {
953 377586958 : return xchk_bmap(sc, XFS_ATTR_FORK);
954 : }
955 :
956 : /* Scrub an inode's CoW fork. */
957 : int
958 293620667 : xchk_bmap_cow(
959 : struct xfs_scrub *sc)
960 : {
961 293620667 : if (!xfs_is_reflink_inode(sc->ip))
962 : return -ENOENT;
963 :
964 7047182 : return xchk_bmap(sc, XFS_COW_FORK);
965 : }
|