Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / fs / xfs / scrub / dabtree.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <darrick.wong@oracle.com>
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_log_format.h"
13 #include "xfs_trans.h"
14 #include "xfs_inode.h"
15 #include "xfs_dir2.h"
16 #include "xfs_dir2_priv.h"
17 #include "xfs_attr_leaf.h"
18 #include "scrub/scrub.h"
19 #include "scrub/common.h"
20 #include "scrub/trace.h"
21 #include "scrub/dabtree.h"
22
23 /* Directory/Attribute Btree */
24
25 /*
26  * Check for da btree operation errors.  See the section about handling
27  * operational errors in common.c.
28  */
29 bool
30 xchk_da_process_error(
31         struct xchk_da_btree    *ds,
32         int                     level,
33         int                     *error)
34 {
35         struct xfs_scrub        *sc = ds->sc;
36
37         if (*error == 0)
38                 return true;
39
40         switch (*error) {
41         case -EDEADLOCK:
42                 /* Used to restart an op with deadlock avoidance. */
43                 trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
44                 break;
45         case -EFSBADCRC:
46         case -EFSCORRUPTED:
47                 /* Note the badness but don't abort. */
48                 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
49                 *error = 0;
50                 /* fall through */
51         default:
52                 trace_xchk_file_op_error(sc, ds->dargs.whichfork,
53                                 xfs_dir2_da_to_db(ds->dargs.geo,
54                                         ds->state->path.blk[level].blkno),
55                                 *error, __return_address);
56                 break;
57         }
58         return false;
59 }
60
61 /*
62  * Check for da btree corruption.  See the section about handling
63  * operational errors in common.c.
64  */
65 void
66 xchk_da_set_corrupt(
67         struct xchk_da_btree    *ds,
68         int                     level)
69 {
70         struct xfs_scrub        *sc = ds->sc;
71
72         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
73
74         trace_xchk_fblock_error(sc, ds->dargs.whichfork,
75                         xfs_dir2_da_to_db(ds->dargs.geo,
76                                 ds->state->path.blk[level].blkno),
77                         __return_address);
78 }
79
80 /* Find an entry at a certain level in a da btree. */
81 STATIC void *
82 xchk_da_btree_entry(
83         struct xchk_da_btree    *ds,
84         int                     level,
85         int                     rec)
86 {
87         char                    *ents;
88         struct xfs_da_state_blk *blk;
89         void                    *baddr;
90
91         /* Dispatch the entry finding function. */
92         blk = &ds->state->path.blk[level];
93         baddr = blk->bp->b_addr;
94         switch (blk->magic) {
95         case XFS_ATTR_LEAF_MAGIC:
96         case XFS_ATTR3_LEAF_MAGIC:
97                 ents = (char *)xfs_attr3_leaf_entryp(baddr);
98                 return ents + (rec * sizeof(struct xfs_attr_leaf_entry));
99         case XFS_DIR2_LEAFN_MAGIC:
100         case XFS_DIR3_LEAFN_MAGIC:
101                 ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
102                 return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
103         case XFS_DIR2_LEAF1_MAGIC:
104         case XFS_DIR3_LEAF1_MAGIC:
105                 ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
106                 return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
107         case XFS_DA_NODE_MAGIC:
108         case XFS_DA3_NODE_MAGIC:
109                 ents = (char *)ds->dargs.dp->d_ops->node_tree_p(baddr);
110                 return ents + (rec * sizeof(struct xfs_da_node_entry));
111         }
112
113         return NULL;
114 }
115
116 /* Scrub a da btree hash (key). */
117 int
118 xchk_da_btree_hash(
119         struct xchk_da_btree            *ds,
120         int                             level,
121         __be32                          *hashp)
122 {
123         struct xfs_da_state_blk         *blks;
124         struct xfs_da_node_entry        *entry;
125         xfs_dahash_t                    hash;
126         xfs_dahash_t                    parent_hash;
127
128         /* Is this hash in order? */
129         hash = be32_to_cpu(*hashp);
130         if (hash < ds->hashes[level])
131                 xchk_da_set_corrupt(ds, level);
132         ds->hashes[level] = hash;
133
134         if (level == 0)
135                 return 0;
136
137         /* Is this hash no larger than the parent hash? */
138         blks = ds->state->path.blk;
139         entry = xchk_da_btree_entry(ds, level - 1, blks[level - 1].index);
140         parent_hash = be32_to_cpu(entry->hashval);
141         if (parent_hash < hash)
142                 xchk_da_set_corrupt(ds, level);
143
144         return 0;
145 }
146
147 /*
148  * Check a da btree pointer.  Returns true if it's ok to use this
149  * pointer.
150  */
151 STATIC bool
152 xchk_da_btree_ptr_ok(
153         struct xchk_da_btree    *ds,
154         int                     level,
155         xfs_dablk_t             blkno)
156 {
157         if (blkno < ds->lowest || (ds->highest != 0 && blkno >= ds->highest)) {
158                 xchk_da_set_corrupt(ds, level);
159                 return false;
160         }
161
162         return true;
163 }
164
165 /*
166  * The da btree scrubber can handle leaf1 blocks as a degenerate
167  * form of leafn blocks.  Since the regular da code doesn't handle
168  * leaf1, we must multiplex the verifiers.
169  */
170 static void
171 xchk_da_btree_read_verify(
172         struct xfs_buf          *bp)
173 {
174         struct xfs_da_blkinfo   *info = bp->b_addr;
175
176         switch (be16_to_cpu(info->magic)) {
177         case XFS_DIR2_LEAF1_MAGIC:
178         case XFS_DIR3_LEAF1_MAGIC:
179                 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
180                 bp->b_ops->verify_read(bp);
181                 return;
182         default:
183                 /*
184                  * xfs_da3_node_buf_ops already know how to handle
185                  * DA*_NODE, ATTR*_LEAF, and DIR*_LEAFN blocks.
186                  */
187                 bp->b_ops = &xfs_da3_node_buf_ops;
188                 bp->b_ops->verify_read(bp);
189                 return;
190         }
191 }
192 static void
193 xchk_da_btree_write_verify(
194         struct xfs_buf          *bp)
195 {
196         struct xfs_da_blkinfo   *info = bp->b_addr;
197
198         switch (be16_to_cpu(info->magic)) {
199         case XFS_DIR2_LEAF1_MAGIC:
200         case XFS_DIR3_LEAF1_MAGIC:
201                 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
202                 bp->b_ops->verify_write(bp);
203                 return;
204         default:
205                 /*
206                  * xfs_da3_node_buf_ops already know how to handle
207                  * DA*_NODE, ATTR*_LEAF, and DIR*_LEAFN blocks.
208                  */
209                 bp->b_ops = &xfs_da3_node_buf_ops;
210                 bp->b_ops->verify_write(bp);
211                 return;
212         }
213 }
214 static void *
215 xchk_da_btree_verify(
216         struct xfs_buf          *bp)
217 {
218         struct xfs_da_blkinfo   *info = bp->b_addr;
219
220         switch (be16_to_cpu(info->magic)) {
221         case XFS_DIR2_LEAF1_MAGIC:
222         case XFS_DIR3_LEAF1_MAGIC:
223                 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
224                 return bp->b_ops->verify_struct(bp);
225         default:
226                 bp->b_ops = &xfs_da3_node_buf_ops;
227                 return bp->b_ops->verify_struct(bp);
228         }
229 }
230
231 static const struct xfs_buf_ops xchk_da_btree_buf_ops = {
232         .name = "xchk_da_btree",
233         .verify_read = xchk_da_btree_read_verify,
234         .verify_write = xchk_da_btree_write_verify,
235         .verify_struct = xchk_da_btree_verify,
236 };
237
238 /* Check a block's sibling. */
239 STATIC int
240 xchk_da_btree_block_check_sibling(
241         struct xchk_da_btree    *ds,
242         int                     level,
243         int                     direction,
244         xfs_dablk_t             sibling)
245 {
246         int                     retval;
247         int                     error;
248
249         memcpy(&ds->state->altpath, &ds->state->path,
250                         sizeof(ds->state->altpath));
251
252         /*
253          * If the pointer is null, we shouldn't be able to move the upper
254          * level pointer anywhere.
255          */
256         if (sibling == 0) {
257                 error = xfs_da3_path_shift(ds->state, &ds->state->altpath,
258                                 direction, false, &retval);
259                 if (error == 0 && retval == 0)
260                         xchk_da_set_corrupt(ds, level);
261                 error = 0;
262                 goto out;
263         }
264
265         /* Move the alternate cursor one block in the direction given. */
266         error = xfs_da3_path_shift(ds->state, &ds->state->altpath,
267                         direction, false, &retval);
268         if (!xchk_da_process_error(ds, level, &error))
269                 return error;
270         if (retval) {
271                 xchk_da_set_corrupt(ds, level);
272                 return error;
273         }
274         if (ds->state->altpath.blk[level].bp)
275                 xchk_buffer_recheck(ds->sc,
276                                 ds->state->altpath.blk[level].bp);
277
278         /* Compare upper level pointer to sibling pointer. */
279         if (ds->state->altpath.blk[level].blkno != sibling)
280                 xchk_da_set_corrupt(ds, level);
281         if (ds->state->altpath.blk[level].bp) {
282                 xfs_trans_brelse(ds->dargs.trans,
283                                 ds->state->altpath.blk[level].bp);
284                 ds->state->altpath.blk[level].bp = NULL;
285         }
286 out:
287         return error;
288 }
289
290 /* Check a block's sibling pointers. */
291 STATIC int
292 xchk_da_btree_block_check_siblings(
293         struct xchk_da_btree    *ds,
294         int                     level,
295         struct xfs_da_blkinfo   *hdr)
296 {
297         xfs_dablk_t             forw;
298         xfs_dablk_t             back;
299         int                     error = 0;
300
301         forw = be32_to_cpu(hdr->forw);
302         back = be32_to_cpu(hdr->back);
303
304         /* Top level blocks should not have sibling pointers. */
305         if (level == 0) {
306                 if (forw != 0 || back != 0)
307                         xchk_da_set_corrupt(ds, level);
308                 return 0;
309         }
310
311         /*
312          * Check back (left) and forw (right) pointers.  These functions
313          * absorb error codes for us.
314          */
315         error = xchk_da_btree_block_check_sibling(ds, level, 0, back);
316         if (error)
317                 goto out;
318         error = xchk_da_btree_block_check_sibling(ds, level, 1, forw);
319
320 out:
321         memset(&ds->state->altpath, 0, sizeof(ds->state->altpath));
322         return error;
323 }
324
325 /* Load a dir/attribute block from a btree. */
326 STATIC int
327 xchk_da_btree_block(
328         struct xchk_da_btree            *ds,
329         int                             level,
330         xfs_dablk_t                     blkno)
331 {
332         struct xfs_da_state_blk         *blk;
333         struct xfs_da_intnode           *node;
334         struct xfs_da_node_entry        *btree;
335         struct xfs_da3_blkinfo          *hdr3;
336         struct xfs_da_args              *dargs = &ds->dargs;
337         struct xfs_inode                *ip = ds->dargs.dp;
338         xfs_ino_t                       owner;
339         int                             *pmaxrecs;
340         struct xfs_da3_icnode_hdr       nodehdr;
341         int                             error = 0;
342
343         blk = &ds->state->path.blk[level];
344         ds->state->path.active = level + 1;
345
346         /* Release old block. */
347         if (blk->bp) {
348                 xfs_trans_brelse(dargs->trans, blk->bp);
349                 blk->bp = NULL;
350         }
351
352         /* Check the pointer. */
353         blk->blkno = blkno;
354         if (!xchk_da_btree_ptr_ok(ds, level, blkno))
355                 goto out_nobuf;
356
357         /* Read the buffer. */
358         error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, -2,
359                         &blk->bp, dargs->whichfork,
360                         &xchk_da_btree_buf_ops);
361         if (!xchk_da_process_error(ds, level, &error))
362                 goto out_nobuf;
363         if (blk->bp)
364                 xchk_buffer_recheck(ds->sc, blk->bp);
365
366         /*
367          * We didn't find a dir btree root block, which means that
368          * there's no LEAF1/LEAFN tree (at least not where it's supposed
369          * to be), so jump out now.
370          */
371         if (ds->dargs.whichfork == XFS_DATA_FORK && level == 0 &&
372                         blk->bp == NULL)
373                 goto out_nobuf;
374
375         /* It's /not/ ok for attr trees not to have a da btree. */
376         if (blk->bp == NULL) {
377                 xchk_da_set_corrupt(ds, level);
378                 goto out_nobuf;
379         }
380
381         hdr3 = blk->bp->b_addr;
382         blk->magic = be16_to_cpu(hdr3->hdr.magic);
383         pmaxrecs = &ds->maxrecs[level];
384
385         /* We only started zeroing the header on v5 filesystems. */
386         if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb) && hdr3->hdr.pad)
387                 xchk_da_set_corrupt(ds, level);
388
389         /* Check the owner. */
390         if (xfs_sb_version_hascrc(&ip->i_mount->m_sb)) {
391                 owner = be64_to_cpu(hdr3->owner);
392                 if (owner != ip->i_ino)
393                         xchk_da_set_corrupt(ds, level);
394         }
395
396         /* Check the siblings. */
397         error = xchk_da_btree_block_check_siblings(ds, level, &hdr3->hdr);
398         if (error)
399                 goto out;
400
401         /* Interpret the buffer. */
402         switch (blk->magic) {
403         case XFS_ATTR_LEAF_MAGIC:
404         case XFS_ATTR3_LEAF_MAGIC:
405                 xfs_trans_buf_set_type(dargs->trans, blk->bp,
406                                 XFS_BLFT_ATTR_LEAF_BUF);
407                 blk->magic = XFS_ATTR_LEAF_MAGIC;
408                 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, pmaxrecs);
409                 if (ds->tree_level != 0)
410                         xchk_da_set_corrupt(ds, level);
411                 break;
412         case XFS_DIR2_LEAFN_MAGIC:
413         case XFS_DIR3_LEAFN_MAGIC:
414                 xfs_trans_buf_set_type(dargs->trans, blk->bp,
415                                 XFS_BLFT_DIR_LEAFN_BUF);
416                 blk->magic = XFS_DIR2_LEAFN_MAGIC;
417                 blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs);
418                 if (ds->tree_level != 0)
419                         xchk_da_set_corrupt(ds, level);
420                 break;
421         case XFS_DIR2_LEAF1_MAGIC:
422         case XFS_DIR3_LEAF1_MAGIC:
423                 xfs_trans_buf_set_type(dargs->trans, blk->bp,
424                                 XFS_BLFT_DIR_LEAF1_BUF);
425                 blk->magic = XFS_DIR2_LEAF1_MAGIC;
426                 blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs);
427                 if (ds->tree_level != 0)
428                         xchk_da_set_corrupt(ds, level);
429                 break;
430         case XFS_DA_NODE_MAGIC:
431         case XFS_DA3_NODE_MAGIC:
432                 xfs_trans_buf_set_type(dargs->trans, blk->bp,
433                                 XFS_BLFT_DA_NODE_BUF);
434                 blk->magic = XFS_DA_NODE_MAGIC;
435                 node = blk->bp->b_addr;
436                 ip->d_ops->node_hdr_from_disk(&nodehdr, node);
437                 btree = ip->d_ops->node_tree_p(node);
438                 *pmaxrecs = nodehdr.count;
439                 blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval);
440                 if (level == 0) {
441                         if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
442                                 xchk_da_set_corrupt(ds, level);
443                                 goto out_freebp;
444                         }
445                         ds->tree_level = nodehdr.level;
446                 } else {
447                         if (ds->tree_level != nodehdr.level) {
448                                 xchk_da_set_corrupt(ds, level);
449                                 goto out_freebp;
450                         }
451                 }
452
453                 /* XXX: Check hdr3.pad32 once we know how to fix it. */
454                 break;
455         default:
456                 xchk_da_set_corrupt(ds, level);
457                 goto out_freebp;
458         }
459
460 out:
461         return error;
462 out_freebp:
463         xfs_trans_brelse(dargs->trans, blk->bp);
464         blk->bp = NULL;
465 out_nobuf:
466         blk->blkno = 0;
467         return error;
468 }
469
470 /* Visit all nodes and leaves of a da btree. */
471 int
472 xchk_da_btree(
473         struct xfs_scrub                *sc,
474         int                             whichfork,
475         xchk_da_btree_rec_fn            scrub_fn,
476         void                            *private)
477 {
478         struct xchk_da_btree            ds = {};
479         struct xfs_mount                *mp = sc->mp;
480         struct xfs_da_state_blk         *blks;
481         struct xfs_da_node_entry        *key;
482         void                            *rec;
483         xfs_dablk_t                     blkno;
484         int                             level;
485         int                             error;
486
487         /* Skip short format data structures; no btree to scan. */
488         if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
489             XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE)
490                 return 0;
491
492         /* Set up initial da state. */
493         ds.dargs.dp = sc->ip;
494         ds.dargs.whichfork = whichfork;
495         ds.dargs.trans = sc->tp;
496         ds.dargs.op_flags = XFS_DA_OP_OKNOENT;
497         ds.state = xfs_da_state_alloc();
498         ds.state->args = &ds.dargs;
499         ds.state->mp = mp;
500         ds.sc = sc;
501         ds.private = private;
502         if (whichfork == XFS_ATTR_FORK) {
503                 ds.dargs.geo = mp->m_attr_geo;
504                 ds.lowest = 0;
505                 ds.highest = 0;
506         } else {
507                 ds.dargs.geo = mp->m_dir_geo;
508                 ds.lowest = ds.dargs.geo->leafblk;
509                 ds.highest = ds.dargs.geo->freeblk;
510         }
511         blkno = ds.lowest;
512         level = 0;
513
514         /* Find the root of the da tree, if present. */
515         blks = ds.state->path.blk;
516         error = xchk_da_btree_block(&ds, level, blkno);
517         if (error)
518                 goto out_state;
519         /*
520          * We didn't find a block at ds.lowest, which means that there's
521          * no LEAF1/LEAFN tree (at least not where it's supposed to be),
522          * so jump out now.
523          */
524         if (blks[level].bp == NULL)
525                 goto out_state;
526
527         blks[level].index = 0;
528         while (level >= 0 && level < XFS_DA_NODE_MAXDEPTH) {
529                 /* Handle leaf block. */
530                 if (blks[level].magic != XFS_DA_NODE_MAGIC) {
531                         /* End of leaf, pop back towards the root. */
532                         if (blks[level].index >= ds.maxrecs[level]) {
533                                 if (level > 0)
534                                         blks[level - 1].index++;
535                                 ds.tree_level++;
536                                 level--;
537                                 continue;
538                         }
539
540                         /* Dispatch record scrubbing. */
541                         rec = xchk_da_btree_entry(&ds, level,
542                                         blks[level].index);
543                         error = scrub_fn(&ds, level, rec);
544                         if (error)
545                                 break;
546                         if (xchk_should_terminate(sc, &error) ||
547                             (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
548                                 break;
549
550                         blks[level].index++;
551                         continue;
552                 }
553
554
555                 /* End of node, pop back towards the root. */
556                 if (blks[level].index >= ds.maxrecs[level]) {
557                         if (level > 0)
558                                 blks[level - 1].index++;
559                         ds.tree_level++;
560                         level--;
561                         continue;
562                 }
563
564                 /* Hashes in order for scrub? */
565                 key = xchk_da_btree_entry(&ds, level, blks[level].index);
566                 error = xchk_da_btree_hash(&ds, level, &key->hashval);
567                 if (error)
568                         goto out;
569
570                 /* Drill another level deeper. */
571                 blkno = be32_to_cpu(key->before);
572                 level++;
573                 if (level >= XFS_DA_NODE_MAXDEPTH) {
574                         /* Too deep! */
575                         xchk_da_set_corrupt(&ds, level - 1);
576                         break;
577                 }
578                 ds.tree_level--;
579                 error = xchk_da_btree_block(&ds, level, blkno);
580                 if (error)
581                         goto out;
582                 if (blks[level].bp == NULL)
583                         goto out;
584
585                 blks[level].index = 0;
586         }
587
588 out:
589         /* Release all the buffers we're tracking. */
590         for (level = 0; level < XFS_DA_NODE_MAXDEPTH; level++) {
591                 if (blks[level].bp == NULL)
592                         continue;
593                 xfs_trans_brelse(sc->tp, blks[level].bp);
594                 blks[level].bp = NULL;
595         }
596
597 out_state:
598         xfs_da_state_free(ds.state);
599         return error;
600 }