759349ccca26fe353bf92dad6c95495360d04406
[platform/kernel/linux-rpi.git] / fs / xfs / scrub / rmap.c
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_rmap.h"
14 #include "xfs_refcount.h"
15 #include "xfs_ag.h"
16 #include "xfs_bit.h"
17 #include "scrub/scrub.h"
18 #include "scrub/common.h"
19 #include "scrub/btree.h"
20 #include "scrub/bitmap.h"
21
22 /*
23  * Set us up to scrub reverse mapping btrees.
24  */
25 int
26 xchk_setup_ag_rmapbt(
27         struct xfs_scrub        *sc)
28 {
29         if (xchk_need_intent_drain(sc))
30                 xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN);
31
32         return xchk_setup_ag_btree(sc, false);
33 }
34
35 /* Reverse-mapping scrubber. */
36
37 struct xchk_rmap {
38         /*
39          * The furthest-reaching of the rmapbt records that we've already
40          * processed.  This enables us to detect overlapping records for space
41          * allocations that cannot be shared.
42          */
43         struct xfs_rmap_irec    overlap_rec;
44
45         /*
46          * The previous rmapbt record, so that we can check for two records
47          * that could be one.
48          */
49         struct xfs_rmap_irec    prev_rec;
50
51         /* Bitmaps containing all blocks for each type of AG metadata. */
52         struct xagb_bitmap      fs_owned;
53         struct xagb_bitmap      log_owned;
54
55         /* Did we complete the AG space metadata bitmaps? */
56         bool                    bitmaps_complete;
57 };
58
59 /* Cross-reference a rmap against the refcount btree. */
60 STATIC void
61 xchk_rmapbt_xref_refc(
62         struct xfs_scrub        *sc,
63         struct xfs_rmap_irec    *irec)
64 {
65         xfs_agblock_t           fbno;
66         xfs_extlen_t            flen;
67         bool                    non_inode;
68         bool                    is_bmbt;
69         bool                    is_attr;
70         bool                    is_unwritten;
71         int                     error;
72
73         if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm))
74                 return;
75
76         non_inode = XFS_RMAP_NON_INODE_OWNER(irec->rm_owner);
77         is_bmbt = irec->rm_flags & XFS_RMAP_BMBT_BLOCK;
78         is_attr = irec->rm_flags & XFS_RMAP_ATTR_FORK;
79         is_unwritten = irec->rm_flags & XFS_RMAP_UNWRITTEN;
80
81         /* If this is shared, must be a data fork extent. */
82         error = xfs_refcount_find_shared(sc->sa.refc_cur, irec->rm_startblock,
83                         irec->rm_blockcount, &fbno, &flen, false);
84         if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur))
85                 return;
86         if (flen != 0 && (non_inode || is_attr || is_bmbt || is_unwritten))
87                 xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
88 }
89
90 /* Cross-reference with the other btrees. */
91 STATIC void
92 xchk_rmapbt_xref(
93         struct xfs_scrub        *sc,
94         struct xfs_rmap_irec    *irec)
95 {
96         xfs_agblock_t           agbno = irec->rm_startblock;
97         xfs_extlen_t            len = irec->rm_blockcount;
98
99         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
100                 return;
101
102         xchk_xref_is_used_space(sc, agbno, len);
103         if (irec->rm_owner == XFS_RMAP_OWN_INODES)
104                 xchk_xref_is_inode_chunk(sc, agbno, len);
105         else
106                 xchk_xref_is_not_inode_chunk(sc, agbno, len);
107         if (irec->rm_owner == XFS_RMAP_OWN_COW)
108                 xchk_xref_is_cow_staging(sc, irec->rm_startblock,
109                                 irec->rm_blockcount);
110         else
111                 xchk_rmapbt_xref_refc(sc, irec);
112 }
113
114 /*
115  * Check for bogus UNWRITTEN flags in the rmapbt node block keys.
116  *
117  * In reverse mapping records, the file mapping extent state
118  * (XFS_RMAP_OFF_UNWRITTEN) is a record attribute, not a key field.  It is not
119  * involved in lookups in any way.  In older kernels, the functions that
120  * convert rmapbt records to keys forgot to filter out the extent state bit,
121  * even though the key comparison functions have filtered the flag correctly.
122  * If we spot an rmap key with the unwritten bit set in rm_offset, we should
123  * mark the btree as needing optimization to rebuild the btree without those
124  * flags.
125  */
126 STATIC void
127 xchk_rmapbt_check_unwritten_in_keyflags(
128         struct xchk_btree       *bs)
129 {
130         struct xfs_scrub        *sc = bs->sc;
131         struct xfs_btree_cur    *cur = bs->cur;
132         struct xfs_btree_block  *keyblock;
133         union xfs_btree_key     *lkey, *hkey;
134         __be64                  badflag = cpu_to_be64(XFS_RMAP_OFF_UNWRITTEN);
135         unsigned int            level;
136
137         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_PREEN)
138                 return;
139
140         for (level = 1; level < cur->bc_nlevels; level++) {
141                 struct xfs_buf  *bp;
142                 unsigned int    ptr;
143
144                 /* Only check the first time we've seen this node block. */
145                 if (cur->bc_levels[level].ptr > 1)
146                         continue;
147
148                 keyblock = xfs_btree_get_block(cur, level, &bp);
149                 for (ptr = 1; ptr <= be16_to_cpu(keyblock->bb_numrecs); ptr++) {
150                         lkey = xfs_btree_key_addr(cur, ptr, keyblock);
151
152                         if (lkey->rmap.rm_offset & badflag) {
153                                 xchk_btree_set_preen(sc, cur, level);
154                                 break;
155                         }
156
157                         hkey = xfs_btree_high_key_addr(cur, ptr, keyblock);
158                         if (hkey->rmap.rm_offset & badflag) {
159                                 xchk_btree_set_preen(sc, cur, level);
160                                 break;
161                         }
162                 }
163         }
164 }
165
166 static inline bool
167 xchk_rmapbt_is_shareable(
168         struct xfs_scrub                *sc,
169         const struct xfs_rmap_irec      *irec)
170 {
171         if (!xfs_has_reflink(sc->mp))
172                 return false;
173         if (XFS_RMAP_NON_INODE_OWNER(irec->rm_owner))
174                 return false;
175         if (irec->rm_flags & (XFS_RMAP_BMBT_BLOCK | XFS_RMAP_ATTR_FORK |
176                               XFS_RMAP_UNWRITTEN))
177                 return false;
178         return true;
179 }
180
181 /* Flag failures for records that overlap but cannot. */
182 STATIC void
183 xchk_rmapbt_check_overlapping(
184         struct xchk_btree               *bs,
185         struct xchk_rmap                *cr,
186         const struct xfs_rmap_irec      *irec)
187 {
188         xfs_agblock_t                   pnext, inext;
189
190         if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
191                 return;
192
193         /* No previous record? */
194         if (cr->overlap_rec.rm_blockcount == 0)
195                 goto set_prev;
196
197         /* Do overlap_rec and irec overlap? */
198         pnext = cr->overlap_rec.rm_startblock + cr->overlap_rec.rm_blockcount;
199         if (pnext <= irec->rm_startblock)
200                 goto set_prev;
201
202         /* Overlap is only allowed if both records are data fork mappings. */
203         if (!xchk_rmapbt_is_shareable(bs->sc, &cr->overlap_rec) ||
204             !xchk_rmapbt_is_shareable(bs->sc, irec))
205                 xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
206
207         /* Save whichever rmap record extends furthest. */
208         inext = irec->rm_startblock + irec->rm_blockcount;
209         if (pnext > inext)
210                 return;
211
212 set_prev:
213         memcpy(&cr->overlap_rec, irec, sizeof(struct xfs_rmap_irec));
214 }
215
216 /* Decide if two reverse-mapping records can be merged. */
217 static inline bool
218 xchk_rmap_mergeable(
219         struct xchk_rmap                *cr,
220         const struct xfs_rmap_irec      *r2)
221 {
222         const struct xfs_rmap_irec      *r1 = &cr->prev_rec;
223
224         /* Ignore if prev_rec is not yet initialized. */
225         if (cr->prev_rec.rm_blockcount == 0)
226                 return false;
227
228         if (r1->rm_owner != r2->rm_owner)
229                 return false;
230         if (r1->rm_startblock + r1->rm_blockcount != r2->rm_startblock)
231                 return false;
232         if ((unsigned long long)r1->rm_blockcount + r2->rm_blockcount >
233             XFS_RMAP_LEN_MAX)
234                 return false;
235         if (XFS_RMAP_NON_INODE_OWNER(r2->rm_owner))
236                 return true;
237         /* must be an inode owner below here */
238         if (r1->rm_flags != r2->rm_flags)
239                 return false;
240         if (r1->rm_flags & XFS_RMAP_BMBT_BLOCK)
241                 return true;
242         return r1->rm_offset + r1->rm_blockcount == r2->rm_offset;
243 }
244
245 /* Flag failures for records that could be merged. */
246 STATIC void
247 xchk_rmapbt_check_mergeable(
248         struct xchk_btree               *bs,
249         struct xchk_rmap                *cr,
250         const struct xfs_rmap_irec      *irec)
251 {
252         if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
253                 return;
254
255         if (xchk_rmap_mergeable(cr, irec))
256                 xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
257
258         memcpy(&cr->prev_rec, irec, sizeof(struct xfs_rmap_irec));
259 }
260
261 /* Compare an rmap for AG metadata against the metadata walk. */
262 STATIC int
263 xchk_rmapbt_mark_bitmap(
264         struct xchk_btree               *bs,
265         struct xchk_rmap                *cr,
266         const struct xfs_rmap_irec      *irec)
267 {
268         struct xfs_scrub                *sc = bs->sc;
269         struct xagb_bitmap              *bmp = NULL;
270         xfs_extlen_t                    fsbcount = irec->rm_blockcount;
271
272         /*
273          * Skip corrupt records.  It is essential that we detect records in the
274          * btree that cannot overlap but do, flag those as CORRUPT, and skip
275          * the bitmap comparison to avoid generating false XCORRUPT reports.
276          */
277         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
278                 return 0;
279
280         /*
281          * If the AG metadata walk didn't complete, there's no point in
282          * comparing against partial results.
283          */
284         if (!cr->bitmaps_complete)
285                 return 0;
286
287         switch (irec->rm_owner) {
288         case XFS_RMAP_OWN_FS:
289                 bmp = &cr->fs_owned;
290                 break;
291         case XFS_RMAP_OWN_LOG:
292                 bmp = &cr->log_owned;
293                 break;
294         }
295
296         if (!bmp)
297                 return 0;
298
299         if (xagb_bitmap_test(bmp, irec->rm_startblock, &fsbcount)) {
300                 /*
301                  * The start of this reverse mapping corresponds to a set
302                  * region in the bitmap.  If the mapping covers more area than
303                  * the set region, then it covers space that wasn't found by
304                  * the AG metadata walk.
305                  */
306                 if (fsbcount < irec->rm_blockcount)
307                         xchk_btree_xref_set_corrupt(bs->sc,
308                                         bs->sc->sa.rmap_cur, 0);
309         } else {
310                 /*
311                  * The start of this reverse mapping does not correspond to a
312                  * completely set region in the bitmap.  The region wasn't
313                  * fully set by walking the AG metadata, so this is a
314                  * cross-referencing corruption.
315                  */
316                 xchk_btree_xref_set_corrupt(bs->sc, bs->sc->sa.rmap_cur, 0);
317         }
318
319         /* Unset the region so that we can detect missing rmap records. */
320         return xagb_bitmap_clear(bmp, irec->rm_startblock, irec->rm_blockcount);
321 }
322
323 /* Scrub an rmapbt record. */
324 STATIC int
325 xchk_rmapbt_rec(
326         struct xchk_btree       *bs,
327         const union xfs_btree_rec *rec)
328 {
329         struct xchk_rmap        *cr = bs->private;
330         struct xfs_rmap_irec    irec;
331
332         if (xfs_rmap_btrec_to_irec(rec, &irec) != NULL ||
333             xfs_rmap_check_irec(bs->cur, &irec) != NULL) {
334                 xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
335                 return 0;
336         }
337
338         xchk_rmapbt_check_unwritten_in_keyflags(bs);
339         xchk_rmapbt_check_mergeable(bs, cr, &irec);
340         xchk_rmapbt_check_overlapping(bs, cr, &irec);
341         xchk_rmapbt_xref(bs->sc, &irec);
342
343         return xchk_rmapbt_mark_bitmap(bs, cr, &irec);
344 }
345
346 /*
347  * Set up bitmaps mapping all the AG metadata to compare with the rmapbt
348  * records.
349  */
350 STATIC int
351 xchk_rmapbt_walk_ag_metadata(
352         struct xfs_scrub        *sc,
353         struct xchk_rmap        *cr)
354 {
355         struct xfs_mount        *mp = sc->mp;
356         int                     error;
357
358         /* OWN_FS: AG headers */
359         error = xagb_bitmap_set(&cr->fs_owned, XFS_SB_BLOCK(mp),
360                         XFS_AGFL_BLOCK(mp) - XFS_SB_BLOCK(mp) + 1);
361         if (error)
362                 goto out;
363
364         /* OWN_LOG: Internal log */
365         if (xfs_ag_contains_log(mp, sc->sa.pag->pag_agno)) {
366                 error = xagb_bitmap_set(&cr->log_owned,
367                                 XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart),
368                                 mp->m_sb.sb_logblocks);
369                 if (error)
370                         goto out;
371         }
372
373 out:
374         /*
375          * If there's an error, set XFAIL and disable the bitmap
376          * cross-referencing checks, but proceed with the scrub anyway.
377          */
378         if (error)
379                 xchk_btree_xref_process_error(sc, sc->sa.rmap_cur,
380                                 sc->sa.rmap_cur->bc_nlevels - 1, &error);
381         else
382                 cr->bitmaps_complete = true;
383         return 0;
384 }
385
386 /*
387  * Check for set regions in the bitmaps; if there are any, the rmap records do
388  * not describe all the AG metadata.
389  */
390 STATIC void
391 xchk_rmapbt_check_bitmaps(
392         struct xfs_scrub        *sc,
393         struct xchk_rmap        *cr)
394 {
395         struct xfs_btree_cur    *cur = sc->sa.rmap_cur;
396         unsigned int            level;
397
398         if (sc->sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
399                                 XFS_SCRUB_OFLAG_XFAIL))
400                 return;
401         if (!cur)
402                 return;
403         level = cur->bc_nlevels - 1;
404
405         /*
406          * Any bitmap with bits still set indicates that the reverse mapping
407          * doesn't cover the entire primary structure.
408          */
409         if (xagb_bitmap_hweight(&cr->fs_owned) != 0)
410                 xchk_btree_xref_set_corrupt(sc, cur, level);
411
412         if (xagb_bitmap_hweight(&cr->log_owned) != 0)
413                 xchk_btree_xref_set_corrupt(sc, cur, level);
414 }
415
416 /* Scrub the rmap btree for some AG. */
417 int
418 xchk_rmapbt(
419         struct xfs_scrub        *sc)
420 {
421         struct xchk_rmap        *cr;
422         int                     error;
423
424         cr = kzalloc(sizeof(struct xchk_rmap), XCHK_GFP_FLAGS);
425         if (!cr)
426                 return -ENOMEM;
427
428         xagb_bitmap_init(&cr->fs_owned);
429         xagb_bitmap_init(&cr->log_owned);
430
431         error = xchk_rmapbt_walk_ag_metadata(sc, cr);
432         if (error)
433                 goto out;
434
435         error = xchk_btree(sc, sc->sa.rmap_cur, xchk_rmapbt_rec,
436                         &XFS_RMAP_OINFO_AG, cr);
437         if (error)
438                 goto out;
439
440         xchk_rmapbt_check_bitmaps(sc, cr);
441
442 out:
443         xagb_bitmap_destroy(&cr->log_owned);
444         xagb_bitmap_destroy(&cr->fs_owned);
445         kfree(cr);
446         return error;
447 }
448
449 /* xref check that the extent is owned only by a given owner */
450 void
451 xchk_xref_is_only_owned_by(
452         struct xfs_scrub                *sc,
453         xfs_agblock_t                   bno,
454         xfs_extlen_t                    len,
455         const struct xfs_owner_info     *oinfo)
456 {
457         struct xfs_rmap_matches         res;
458         int                             error;
459
460         if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
461                 return;
462
463         error = xfs_rmap_count_owners(sc->sa.rmap_cur, bno, len, oinfo, &res);
464         if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
465                 return;
466         if (res.matches != 1)
467                 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
468         if (res.bad_non_owner_matches)
469                 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
470         if (res.non_owner_matches)
471                 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
472 }
473
474 /* xref check that the extent is not owned by a given owner */
475 void
476 xchk_xref_is_not_owned_by(
477         struct xfs_scrub                *sc,
478         xfs_agblock_t                   bno,
479         xfs_extlen_t                    len,
480         const struct xfs_owner_info     *oinfo)
481 {
482         struct xfs_rmap_matches         res;
483         int                             error;
484
485         if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
486                 return;
487
488         error = xfs_rmap_count_owners(sc->sa.rmap_cur, bno, len, oinfo, &res);
489         if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
490                 return;
491         if (res.matches != 0)
492                 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
493         if (res.bad_non_owner_matches)
494                 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
495 }
496
497 /* xref check that the extent has no reverse mapping at all */
498 void
499 xchk_xref_has_no_owner(
500         struct xfs_scrub        *sc,
501         xfs_agblock_t           bno,
502         xfs_extlen_t            len)
503 {
504         enum xbtree_recpacking  outcome;
505         int                     error;
506
507         if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
508                 return;
509
510         error = xfs_rmap_has_records(sc->sa.rmap_cur, bno, len, &outcome);
511         if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
512                 return;
513         if (outcome != XBTREE_RECPACKING_EMPTY)
514                 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
515 }