Lines Matching +full:scrubber +full:- +full:done
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2017-2023 Oracle. All Rights Reserved.
45 struct xfs_mount *mp = sc->mp; in xchk_dir_check_ftype()
53 if (xfs_mode_to_ftype(VFS_I(ip)->i_mode) != ftype) in xchk_dir_check_ftype()
72 struct xfs_mount *mp = dp->i_mount; in xchk_dir_actor()
78 offset = xfs_dir2_db_to_da(mp->m_dir_geo, in xchk_dir_actor()
79 xfs_dir2_dataptr_to_db(mp->m_dir_geo, dapos)); in xchk_dir_actor()
87 return -ECANCELED; in xchk_dir_actor()
91 if (!xfs_dir2_namecheck(name->name, name->len)) { in xchk_dir_actor()
93 return -ECANCELED; in xchk_dir_actor()
96 if (!strncmp(".", name->name, name->len)) { in xchk_dir_actor()
98 if (ino != dp->i_ino) in xchk_dir_actor()
100 } else if (!strncmp("..", name->name, name->len)) { in xchk_dir_actor()
105 if (dp->i_ino == mp->m_sb.sb_rootino && ino != dp->i_ino) in xchk_dir_actor()
112 if (error == -ENOENT) in xchk_dir_actor()
113 error = -EFSCORRUPTED; in xchk_dir_actor()
118 return -ECANCELED; in xchk_dir_actor()
125 * If _iget returns -EINVAL or -ENOENT then the child inode number is in xchk_dir_actor()
127 * -EFSCORRUPTED or -EFSBADCRC then the child is corrupt which is a in xchk_dir_actor()
131 if (error == -EINVAL || error == -ENOENT) { in xchk_dir_actor()
132 error = -EFSCORRUPTED; in xchk_dir_actor()
139 xchk_dir_check_ftype(sc, offset, ip, name->type); in xchk_dir_actor()
142 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_dir_actor()
143 return -ECANCELED; in xchk_dir_actor()
154 struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; in xchk_dir_rec()
155 struct xfs_mount *mp = ds->state->mp; in xchk_dir_rec()
156 struct xfs_inode *dp = ds->dargs.dp; in xchk_dir_rec()
157 struct xfs_da_geometry *geo = mp->m_dir_geo; in xchk_dir_rec()
174 ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC || in xchk_dir_rec()
175 blk->magic == XFS_DIR2_LEAFN_MAGIC); in xchk_dir_rec()
177 xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr); in xchk_dir_rec()
178 ent = hdr.ents + blk->index; in xchk_dir_rec()
181 error = xchk_da_btree_hash(ds, level, &ent->hashval); in xchk_dir_rec()
186 ptr = be32_to_cpu(ent->address); in xchk_dir_rec()
195 if (rec_bno >= geo->leafblk) { in xchk_dir_rec()
199 error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, in xchk_dir_rec()
201 if (!xchk_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno, in xchk_dir_rec()
205 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); in xchk_dir_rec()
208 xchk_buffer_recheck(ds->sc, bp); in xchk_dir_rec()
210 if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_dir_rec()
213 dent = bp->b_addr + off; in xchk_dir_rec()
216 iter_off = geo->data_entry_offset; in xchk_dir_rec()
217 end = xfs_dir3_data_end_offset(geo, bp->b_addr); in xchk_dir_rec()
219 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); in xchk_dir_rec()
223 struct xfs_dir2_data_entry *dep = bp->b_addr + iter_off; in xchk_dir_rec()
224 struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off; in xchk_dir_rec()
227 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); in xchk_dir_rec()
231 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { in xchk_dir_rec()
232 iter_off += be16_to_cpu(dup->length); in xchk_dir_rec()
237 iter_off += xfs_dir2_data_entsize(mp, dep->namelen); in xchk_dir_rec()
241 ino = be64_to_cpu(dent->inumber); in xchk_dir_rec()
242 hash = be32_to_cpu(ent->hashval); in xchk_dir_rec()
245 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); in xchk_dir_rec()
246 if (dent->namelen == 0) { in xchk_dir_rec()
247 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); in xchk_dir_rec()
252 dname.name = dent->name; in xchk_dir_rec()
253 dname.len = dent->namelen; in xchk_dir_rec()
256 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); in xchk_dir_rec()
259 xfs_trans_brelse(ds->dargs.trans, bp); in xchk_dir_rec()
279 dup_length = be16_to_cpu(dup->length); in xchk_directory_check_free_entry()
282 if (dup_length < be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length)) in xchk_directory_check_free_entry()
285 for (dfp = &bf[XFS_DIR2_DATA_FD_COUNT - 1]; dfp >= bf; dfp--) in xchk_directory_check_free_entry()
286 if (dup_length == be16_to_cpu(dfp->length)) in xchk_directory_check_free_entry()
304 struct xfs_mount *mp = sc->mp; in xchk_directory_data_bestfree()
318 error = xfs_dir3_block_read(sc->tp, sc->ip, &bp); in xchk_directory_data_bestfree()
321 error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, 0, &bp); in xchk_directory_data_bestfree()
329 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory_data_bestfree()
333 bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr); in xchk_directory_data_bestfree()
336 offset = be16_to_cpu(dfp->offset); in xchk_directory_data_bestfree()
339 if (offset >= mp->m_dir_geo->blksize) { in xchk_directory_data_bestfree()
343 dup = bp->b_addr + offset; in xchk_directory_data_bestfree()
347 if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) || in xchk_directory_data_bestfree()
348 be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) || in xchk_directory_data_bestfree()
355 if (smallest_bestfree < be16_to_cpu(dfp->length)) { in xchk_directory_data_bestfree()
360 smallest_bestfree = be16_to_cpu(dfp->length); in xchk_directory_data_bestfree()
365 offset = mp->m_dir_geo->data_entry_offset; in xchk_directory_data_bestfree()
366 end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr); in xchk_directory_data_bestfree()
370 dup = bp->b_addr + offset; in xchk_directory_data_bestfree()
373 if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) { in xchk_directory_data_bestfree()
374 struct xfs_dir2_data_entry *dep = bp->b_addr + offset; in xchk_directory_data_bestfree()
376 newlen = xfs_dir2_data_entsize(mp, dep->namelen); in xchk_directory_data_bestfree()
398 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory_data_bestfree()
402 newlen = be16_to_cpu(dup->length); in xchk_directory_data_bestfree()
420 xfs_trans_brelse(sc->tp, bp); in xchk_directory_data_bestfree()
440 dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr); in xchk_directory_check_freesp()
442 if (len != be16_to_cpu(dfp->length)) in xchk_directory_check_freesp()
445 if (len > 0 && be16_to_cpu(dfp->offset) == 0) in xchk_directory_check_freesp()
462 struct xfs_da_geometry *geo = sc->mp->m_dir_geo; in xchk_directory_leaf1_bestfree()
473 error = xfs_dir3_leaf_read(sc->tp, sc->ip, lblk, &bp); in xchk_directory_leaf1_bestfree()
478 leaf = bp->b_addr; in xchk_directory_leaf1_bestfree()
479 xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf); in xchk_directory_leaf1_bestfree()
481 bestcount = be32_to_cpu(ltp->bestcount); in xchk_directory_leaf1_bestfree()
484 if (xfs_has_crc(sc->mp)) { in xchk_directory_leaf1_bestfree()
485 struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr; in xchk_directory_leaf1_bestfree()
487 if (hdr3->pad != cpu_to_be32(0)) in xchk_directory_leaf1_bestfree()
505 if (leafhdr.count > geo->leaf_max_ents) { in xchk_directory_leaf1_bestfree()
528 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory_leaf1_bestfree()
534 error = xfs_dir3_data_read(sc->tp, sc->ip, in xchk_directory_leaf1_bestfree()
535 xfs_dir2_db_to_da(args->geo, i), in xchk_directory_leaf1_bestfree()
555 xfs_trans_brelse(sc->tp, dbp); in xchk_directory_leaf1_bestfree()
556 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory_leaf1_bestfree()
560 xfs_trans_brelse(sc->tp, bp); in xchk_directory_leaf1_bestfree()
580 error = xfs_dir2_free_read(sc->tp, sc->ip, lblk, &bp); in xchk_directory_free_bestfree()
585 if (xfs_has_crc(sc->mp)) { in xchk_directory_free_bestfree()
586 struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; in xchk_directory_free_bestfree()
588 if (hdr3->pad != cpu_to_be32(0)) in xchk_directory_free_bestfree()
593 xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr); in xchk_directory_free_bestfree()
600 error = xfs_dir3_data_read(sc->tp, sc->ip, in xchk_directory_free_bestfree()
601 (freehdr.firstdb + i) * args->geo->fsbcount, in xchk_directory_free_bestfree()
607 xfs_trans_brelse(sc->tp, dbp); in xchk_directory_free_bestfree()
613 xfs_trans_brelse(sc->tp, bp); in xchk_directory_free_bestfree()
624 .dp = sc ->ip, in xchk_directory_blocks()
626 .geo = sc->mp->m_dir_geo, in xchk_directory_blocks()
627 .trans = sc->tp, in xchk_directory_blocks()
629 struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, XFS_DATA_FORK); in xchk_directory_blocks()
630 struct xfs_mount *mp = sc->mp; in xchk_directory_blocks()
642 if (ifp->if_format != XFS_DINODE_FMT_EXTENTS && in xchk_directory_blocks()
643 ifp->if_format != XFS_DINODE_FMT_BTREE) in xchk_directory_blocks()
656 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); in xchk_directory_blocks()
657 while (found && !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) { in xchk_directory_blocks()
665 * Iterate all the fsbcount-aligned block offsets in in xchk_directory_blocks()
668 * discontiguous directory blocks. When we're done in xchk_directory_blocks()
669 * with the extent record, re-query the bmap at the in xchk_directory_blocks()
670 * next fsbcount-aligned offset to avoid redundant in xchk_directory_blocks()
674 args.geo->fsbcount); in xchk_directory_blocks()
676 lblk += args.geo->fsbcount) { in xchk_directory_blocks()
684 lblk = roundup(dabno, args.geo->fsbcount); in xchk_directory_blocks()
685 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); in xchk_directory_blocks()
688 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory_blocks()
692 if (xfs_iext_lookup_extent(sc->ip, ifp, leaf_lblk, &icur, &got) && in xchk_directory_blocks()
694 got.br_blockcount == args.geo->fsbcount && in xchk_directory_blocks()
706 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory_blocks()
711 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); in xchk_directory_blocks()
712 while (found && !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) { in xchk_directory_blocks()
715 * Single-block dirs shouldn't even be here. in xchk_directory_blocks()
730 * Iterate all the fsbcount-aligned block offsets in in xchk_directory_blocks()
733 * discontiguous directory blocks. When we're done in xchk_directory_blocks()
734 * with the extent record, re-query the bmap at the in xchk_directory_blocks()
735 * next fsbcount-aligned offset to avoid redundant in xchk_directory_blocks()
739 args.geo->fsbcount); in xchk_directory_blocks()
741 lblk += args.geo->fsbcount) { in xchk_directory_blocks()
748 lblk = roundup(dabno, args.geo->fsbcount); in xchk_directory_blocks()
749 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); in xchk_directory_blocks()
762 if (!S_ISDIR(VFS_I(sc->ip)->i_mode)) in xchk_directory()
763 return -ENOENT; in xchk_directory()
771 if (sc->ip->i_disk_size < xfs_dir2_sf_hdr_size(0)) { in xchk_directory()
772 xchk_ino_set_corrupt(sc, sc->ip->i_ino); in xchk_directory()
781 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory()
789 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xchk_directory()
793 error = xchk_dir_walk(sc, sc->ip, xchk_dir_actor, NULL); in xchk_directory()
794 if (error && error != -ECANCELED) in xchk_directory()
818 * scrubber to reconstruct the block mappings. Directories always in xchk_dir_looks_zapped()
824 return dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS && in xchk_dir_looks_zapped()
825 dp->i_df.if_nextents == 0; in xchk_dir_looks_zapped()