1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2017 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
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_icache.h"
17 #include "xfs_dir2_priv.h"
18 #include "scrub/scrub.h"
19 #include "scrub/common.h"
20 #include "scrub/dabtree.h"
22 /* Set us up to scrub directories. */
28 return xchk_setup_inode_contents(sc
, ip
, 0);
33 /* Scrub a directory entry. */
36 /* VFS fill-directory iterator */
37 struct dir_context dir_iter
;
42 /* Check that an inode's mode matches a given DT_ type. */
45 struct xchk_dir_ctx
*sdc
,
50 struct xfs_mount
*mp
= sdc
->sc
->mp
;
55 if (!xfs_sb_version_hasftype(&mp
->m_sb
)) {
56 if (dtype
!= DT_UNKNOWN
&& dtype
!= DT_DIR
)
57 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
,
63 * Grab the inode pointed to by the dirent. We release the
64 * inode before we cancel the scrub transaction. Since we're
65 * don't know a priori that releasing the inode won't trigger
66 * eofblocks cleanup (which allocates what would be a nested
67 * transaction), we can't use DONTCACHE here because DONTCACHE
68 * inodes can trigger immediate inactive cleanup of the inode.
70 error
= xfs_iget(mp
, sdc
->sc
->tp
, inum
, 0, 0, &ip
);
71 if (!xchk_fblock_xref_process_error(sdc
->sc
, XFS_DATA_FORK
, offset
,
75 /* Convert mode to the DT_* values that dir_emit uses. */
76 ino_dtype
= xfs_dir3_get_dtype(mp
,
77 xfs_mode_to_ftype(VFS_I(ip
)->i_mode
));
78 if (ino_dtype
!= dtype
)
79 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
, offset
);
86 * Scrub a single directory entry.
88 * We use the VFS directory iterator (i.e. readdir) to call this
89 * function for every directory entry in a directory. Once we're here,
90 * we check the inode number to make sure it's sane, then we check that
91 * we can look up this filename. Finally, we check the ftype.
95 struct dir_context
*dir_iter
,
102 struct xfs_mount
*mp
;
103 struct xfs_inode
*ip
;
104 struct xchk_dir_ctx
*sdc
;
105 struct xfs_name xname
;
106 xfs_ino_t lookup_ino
;
110 sdc
= container_of(dir_iter
, struct xchk_dir_ctx
, dir_iter
);
113 offset
= xfs_dir2_db_to_da(mp
->m_dir_geo
,
114 xfs_dir2_dataptr_to_db(mp
->m_dir_geo
, pos
));
116 if (xchk_should_terminate(sdc
->sc
, &error
))
119 /* Does this inode number make sense? */
120 if (!xfs_verify_dir_ino(mp
, ino
)) {
121 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
, offset
);
125 /* Does this name make sense? */
126 if (!xfs_dir2_namecheck(name
, namelen
)) {
127 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
, offset
);
131 if (!strncmp(".", name
, namelen
)) {
132 /* If this is "." then check that the inum matches the dir. */
133 if (xfs_sb_version_hasftype(&mp
->m_sb
) && type
!= DT_DIR
)
134 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
,
136 if (ino
!= ip
->i_ino
)
137 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
,
139 } else if (!strncmp("..", name
, namelen
)) {
141 * If this is ".." in the root inode, check that the inum
144 if (xfs_sb_version_hasftype(&mp
->m_sb
) && type
!= DT_DIR
)
145 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
,
147 if (ip
->i_ino
== mp
->m_sb
.sb_rootino
&& ino
!= ip
->i_ino
)
148 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
,
152 /* Verify that we can look up this name by hash. */
155 xname
.type
= XFS_DIR3_FT_UNKNOWN
;
157 error
= xfs_dir_lookup(sdc
->sc
->tp
, ip
, &xname
, &lookup_ino
, NULL
);
158 if (!xchk_fblock_process_error(sdc
->sc
, XFS_DATA_FORK
, offset
,
161 if (lookup_ino
!= ino
) {
162 xchk_fblock_set_corrupt(sdc
->sc
, XFS_DATA_FORK
, offset
);
166 /* Verify the file type. This function absorbs error codes. */
167 error
= xchk_dir_check_ftype(sdc
, offset
, lookup_ino
, type
);
172 * A negative error code returned here is supposed to cause the
173 * dir_emit caller (xfs_readdir) to abort the directory iteration
174 * and return zero to xchk_directory.
176 if (error
== 0 && sdc
->sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
177 return -EFSCORRUPTED
;
181 /* Scrub a directory btree record. */
184 struct xchk_da_btree
*ds
,
187 struct xfs_da_state_blk
*blk
= &ds
->state
->path
.blk
[level
];
188 struct xfs_mount
*mp
= ds
->state
->mp
;
189 struct xfs_inode
*dp
= ds
->dargs
.dp
;
190 struct xfs_da_geometry
*geo
= mp
->m_dir_geo
;
191 struct xfs_dir2_data_entry
*dent
;
193 struct xfs_dir2_leaf_entry
*ent
;
195 unsigned int iter_off
;
199 xfs_dir2_data_aoff_t off
;
200 xfs_dir2_dataptr_t ptr
;
201 xfs_dahash_t calc_hash
;
203 struct xfs_dir3_icleaf_hdr hdr
;
207 ASSERT(blk
->magic
== XFS_DIR2_LEAF1_MAGIC
||
208 blk
->magic
== XFS_DIR2_LEAFN_MAGIC
);
210 xfs_dir2_leaf_hdr_from_disk(mp
, &hdr
, blk
->bp
->b_addr
);
211 ent
= hdr
.ents
+ blk
->index
;
213 /* Check the hash of the entry. */
214 error
= xchk_da_btree_hash(ds
, level
, &ent
->hashval
);
218 /* Valid hash pointer? */
219 ptr
= be32_to_cpu(ent
->address
);
223 /* Find the directory entry's location. */
224 db
= xfs_dir2_dataptr_to_db(geo
, ptr
);
225 off
= xfs_dir2_dataptr_to_off(geo
, ptr
);
226 rec_bno
= xfs_dir2_db_to_da(geo
, db
);
228 if (rec_bno
>= geo
->leafblk
) {
229 xchk_da_set_corrupt(ds
, level
);
232 error
= xfs_dir3_data_read(ds
->dargs
.trans
, dp
, rec_bno
,
233 XFS_DABUF_MAP_HOLE_OK
, &bp
);
234 if (!xchk_fblock_process_error(ds
->sc
, XFS_DATA_FORK
, rec_bno
,
238 xchk_fblock_set_corrupt(ds
->sc
, XFS_DATA_FORK
, rec_bno
);
241 xchk_buffer_recheck(ds
->sc
, bp
);
243 if (ds
->sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
246 dent
= bp
->b_addr
+ off
;
248 /* Make sure we got a real directory entry. */
249 iter_off
= geo
->data_entry_offset
;
250 end
= xfs_dir3_data_end_offset(geo
, bp
->b_addr
);
252 xchk_fblock_set_corrupt(ds
->sc
, XFS_DATA_FORK
, rec_bno
);
256 struct xfs_dir2_data_entry
*dep
= bp
->b_addr
+ iter_off
;
257 struct xfs_dir2_data_unused
*dup
= bp
->b_addr
+ iter_off
;
259 if (iter_off
>= end
) {
260 xchk_fblock_set_corrupt(ds
->sc
, XFS_DATA_FORK
, rec_bno
);
264 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
265 iter_off
+= be16_to_cpu(dup
->length
);
270 iter_off
+= xfs_dir2_data_entsize(mp
, dep
->namelen
);
273 /* Retrieve the entry, sanity check it, and compare hashes. */
274 ino
= be64_to_cpu(dent
->inumber
);
275 hash
= be32_to_cpu(ent
->hashval
);
276 tag
= be16_to_cpup(xfs_dir2_data_entry_tag_p(mp
, dent
));
277 if (!xfs_verify_dir_ino(mp
, ino
) || tag
!= off
)
278 xchk_fblock_set_corrupt(ds
->sc
, XFS_DATA_FORK
, rec_bno
);
279 if (dent
->namelen
== 0) {
280 xchk_fblock_set_corrupt(ds
->sc
, XFS_DATA_FORK
, rec_bno
);
283 calc_hash
= xfs_da_hashname(dent
->name
, dent
->namelen
);
284 if (calc_hash
!= hash
)
285 xchk_fblock_set_corrupt(ds
->sc
, XFS_DATA_FORK
, rec_bno
);
288 xfs_trans_brelse(ds
->dargs
.trans
, bp
);
294 * Is this unused entry either in the bestfree or smaller than all of
295 * them? We've already checked that the bestfrees are sorted longest to
296 * shortest, and that there aren't any bogus entries.
299 xchk_directory_check_free_entry(
300 struct xfs_scrub
*sc
,
302 struct xfs_dir2_data_free
*bf
,
303 struct xfs_dir2_data_unused
*dup
)
305 struct xfs_dir2_data_free
*dfp
;
306 unsigned int dup_length
;
308 dup_length
= be16_to_cpu(dup
->length
);
310 /* Unused entry is shorter than any of the bestfrees */
311 if (dup_length
< be16_to_cpu(bf
[XFS_DIR2_DATA_FD_COUNT
- 1].length
))
314 for (dfp
= &bf
[XFS_DIR2_DATA_FD_COUNT
- 1]; dfp
>= bf
; dfp
--)
315 if (dup_length
== be16_to_cpu(dfp
->length
))
318 /* Unused entry should be in the bestfrees but wasn't found. */
319 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
322 /* Check free space info in a directory data block. */
324 xchk_directory_data_bestfree(
325 struct xfs_scrub
*sc
,
329 struct xfs_dir2_data_unused
*dup
;
330 struct xfs_dir2_data_free
*dfp
;
332 struct xfs_dir2_data_free
*bf
;
333 struct xfs_mount
*mp
= sc
->mp
;
335 unsigned int nr_bestfrees
= 0;
336 unsigned int nr_frees
= 0;
337 unsigned int smallest_bestfree
;
344 /* dir block format */
345 if (lblk
!= XFS_B_TO_FSBT(mp
, XFS_DIR2_DATA_OFFSET
))
346 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
347 error
= xfs_dir3_block_read(sc
->tp
, sc
->ip
, &bp
);
349 /* dir data format */
350 error
= xfs_dir3_data_read(sc
->tp
, sc
->ip
, lblk
, 0, &bp
);
352 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, lblk
, &error
))
354 xchk_buffer_recheck(sc
, bp
);
356 /* XXX: Check xfs_dir3_data_hdr.pad is zero once we start setting it. */
358 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
361 /* Do the bestfrees correspond to actual free space? */
362 bf
= xfs_dir2_data_bestfree_p(mp
, bp
->b_addr
);
363 smallest_bestfree
= UINT_MAX
;
364 for (dfp
= &bf
[0]; dfp
< &bf
[XFS_DIR2_DATA_FD_COUNT
]; dfp
++) {
365 offset
= be16_to_cpu(dfp
->offset
);
368 if (offset
>= mp
->m_dir_geo
->blksize
) {
369 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
372 dup
= bp
->b_addr
+ offset
;
373 tag
= be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup
));
375 /* bestfree doesn't match the entry it points at? */
376 if (dup
->freetag
!= cpu_to_be16(XFS_DIR2_DATA_FREE_TAG
) ||
377 be16_to_cpu(dup
->length
) != be16_to_cpu(dfp
->length
) ||
379 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
383 /* bestfree records should be ordered largest to smallest */
384 if (smallest_bestfree
< be16_to_cpu(dfp
->length
)) {
385 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
389 smallest_bestfree
= be16_to_cpu(dfp
->length
);
393 /* Make sure the bestfrees are actually the best free spaces. */
394 offset
= mp
->m_dir_geo
->data_entry_offset
;
395 end
= xfs_dir3_data_end_offset(mp
->m_dir_geo
, bp
->b_addr
);
397 /* Iterate the entries, stopping when we hit or go past the end. */
398 while (offset
< end
) {
399 dup
= bp
->b_addr
+ offset
;
401 /* Skip real entries */
402 if (dup
->freetag
!= cpu_to_be16(XFS_DIR2_DATA_FREE_TAG
)) {
403 struct xfs_dir2_data_entry
*dep
= bp
->b_addr
+ offset
;
405 newlen
= xfs_dir2_data_entsize(mp
, dep
->namelen
);
407 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
,
415 /* Spot check this free entry */
416 tag
= be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup
));
418 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
423 * Either this entry is a bestfree or it's smaller than
424 * any of the bestfrees.
426 xchk_directory_check_free_entry(sc
, lblk
, bf
, dup
);
427 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
431 newlen
= be16_to_cpu(dup
->length
);
433 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
441 /* We're required to fill all the space. */
443 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
445 /* Did we see at least as many free slots as there are bestfrees? */
446 if (nr_frees
< nr_bestfrees
)
447 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
449 xfs_trans_brelse(sc
->tp
, bp
);
455 * Does the free space length in the free space index block ($len) match
456 * the longest length in the directory data block's bestfree array?
457 * Assume that we've already checked that the data block's bestfree
461 xchk_directory_check_freesp(
462 struct xfs_scrub
*sc
,
467 struct xfs_dir2_data_free
*dfp
;
469 dfp
= xfs_dir2_data_bestfree_p(sc
->mp
, dbp
->b_addr
);
471 if (len
!= be16_to_cpu(dfp
->length
))
472 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
474 if (len
> 0 && be16_to_cpu(dfp
->offset
) == 0)
475 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
478 /* Check free space info in a directory leaf1 block. */
480 xchk_directory_leaf1_bestfree(
481 struct xfs_scrub
*sc
,
482 struct xfs_da_args
*args
,
485 struct xfs_dir3_icleaf_hdr leafhdr
;
486 struct xfs_dir2_leaf_tail
*ltp
;
487 struct xfs_dir2_leaf
*leaf
;
490 struct xfs_da_geometry
*geo
= sc
->mp
->m_dir_geo
;
496 unsigned int stale
= 0;
500 /* Read the free space block. */
501 error
= xfs_dir3_leaf_read(sc
->tp
, sc
->ip
, lblk
, &bp
);
502 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, lblk
, &error
))
504 xchk_buffer_recheck(sc
, bp
);
507 xfs_dir2_leaf_hdr_from_disk(sc
->ip
->i_mount
, &leafhdr
, leaf
);
508 ltp
= xfs_dir2_leaf_tail_p(geo
, leaf
);
509 bestcount
= be32_to_cpu(ltp
->bestcount
);
510 bestp
= xfs_dir2_leaf_bests_p(ltp
);
512 if (xfs_sb_version_hascrc(&sc
->mp
->m_sb
)) {
513 struct xfs_dir3_leaf_hdr
*hdr3
= bp
->b_addr
;
515 if (hdr3
->pad
!= cpu_to_be32(0))
516 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
520 * There should be as many bestfree slots as there are dir data
521 * blocks that can fit under i_size.
523 if (bestcount
!= xfs_dir2_byte_to_db(geo
, sc
->ip
->i_d
.di_size
)) {
524 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
528 /* Is the leaf count even remotely sane? */
529 if (leafhdr
.count
> geo
->leaf_max_ents
) {
530 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
534 /* Leaves and bests don't overlap in leaf format. */
535 if ((char *)&leafhdr
.ents
[leafhdr
.count
] > (char *)bestp
) {
536 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
540 /* Check hash value order, count stale entries. */
541 for (i
= 0; i
< leafhdr
.count
; i
++) {
542 hash
= be32_to_cpu(leafhdr
.ents
[i
].hashval
);
543 if (i
> 0 && lasthash
> hash
)
544 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
546 if (leafhdr
.ents
[i
].address
==
547 cpu_to_be32(XFS_DIR2_NULL_DATAPTR
))
550 if (leafhdr
.stale
!= stale
)
551 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
552 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
555 /* Check all the bestfree entries. */
556 for (i
= 0; i
< bestcount
; i
++, bestp
++) {
557 best
= be16_to_cpu(*bestp
);
558 if (best
== NULLDATAOFF
)
560 error
= xfs_dir3_data_read(sc
->tp
, sc
->ip
,
561 i
* args
->geo
->fsbcount
, 0, &dbp
);
562 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, lblk
,
565 xchk_directory_check_freesp(sc
, lblk
, dbp
, best
);
566 xfs_trans_brelse(sc
->tp
, dbp
);
567 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
574 /* Check free space info in a directory freespace block. */
576 xchk_directory_free_bestfree(
577 struct xfs_scrub
*sc
,
578 struct xfs_da_args
*args
,
581 struct xfs_dir3_icfree_hdr freehdr
;
585 unsigned int stale
= 0;
589 /* Read the free space block */
590 error
= xfs_dir2_free_read(sc
->tp
, sc
->ip
, lblk
, &bp
);
591 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, lblk
, &error
))
593 xchk_buffer_recheck(sc
, bp
);
595 if (xfs_sb_version_hascrc(&sc
->mp
->m_sb
)) {
596 struct xfs_dir3_free_hdr
*hdr3
= bp
->b_addr
;
598 if (hdr3
->pad
!= cpu_to_be32(0))
599 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
602 /* Check all the entries. */
603 xfs_dir2_free_hdr_from_disk(sc
->ip
->i_mount
, &freehdr
, bp
->b_addr
);
604 for (i
= 0; i
< freehdr
.nvalid
; i
++) {
605 best
= be16_to_cpu(freehdr
.bests
[i
]);
606 if (best
== NULLDATAOFF
) {
610 error
= xfs_dir3_data_read(sc
->tp
, sc
->ip
,
611 (freehdr
.firstdb
+ i
) * args
->geo
->fsbcount
,
613 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, lblk
,
616 xchk_directory_check_freesp(sc
, lblk
, dbp
, best
);
617 xfs_trans_brelse(sc
->tp
, dbp
);
620 if (freehdr
.nused
+ stale
!= freehdr
.nvalid
)
621 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
626 /* Check free space information in directories. */
628 xchk_directory_blocks(
629 struct xfs_scrub
*sc
)
631 struct xfs_bmbt_irec got
;
632 struct xfs_da_args args
;
633 struct xfs_ifork
*ifp
;
634 struct xfs_mount
*mp
= sc
->mp
;
635 xfs_fileoff_t leaf_lblk
;
636 xfs_fileoff_t free_lblk
;
638 struct xfs_iext_cursor icur
;
644 /* Ignore local format directories. */
645 if (sc
->ip
->i_d
.di_format
!= XFS_DINODE_FMT_EXTENTS
&&
646 sc
->ip
->i_d
.di_format
!= XFS_DINODE_FMT_BTREE
)
649 ifp
= XFS_IFORK_PTR(sc
->ip
, XFS_DATA_FORK
);
650 lblk
= XFS_B_TO_FSB(mp
, XFS_DIR2_DATA_OFFSET
);
651 leaf_lblk
= XFS_B_TO_FSB(mp
, XFS_DIR2_LEAF_OFFSET
);
652 free_lblk
= XFS_B_TO_FSB(mp
, XFS_DIR2_FREE_OFFSET
);
654 /* Is this a block dir? */
656 args
.geo
= mp
->m_dir_geo
;
658 error
= xfs_dir2_isblock(&args
, &is_block
);
659 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, lblk
, &error
))
662 /* Iterate all the data extents in the directory... */
663 found
= xfs_iext_lookup_extent(sc
->ip
, ifp
, lblk
, &icur
, &got
);
664 while (found
&& !(sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)) {
665 /* Block directories only have a single block at offset 0. */
667 (got
.br_startoff
> 0 ||
668 got
.br_blockcount
!= args
.geo
->fsbcount
)) {
669 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
,
674 /* No more data blocks... */
675 if (got
.br_startoff
>= leaf_lblk
)
679 * Check each data block's bestfree data.
681 * Iterate all the fsbcount-aligned block offsets in
682 * this directory. The directory block reading code is
683 * smart enough to do its own bmap lookups to handle
684 * discontiguous directory blocks. When we're done
685 * with the extent record, re-query the bmap at the
686 * next fsbcount-aligned offset to avoid redundant
689 for (lblk
= roundup((xfs_dablk_t
)got
.br_startoff
,
691 lblk
< got
.br_startoff
+ got
.br_blockcount
;
692 lblk
+= args
.geo
->fsbcount
) {
693 error
= xchk_directory_data_bestfree(sc
, lblk
,
698 dabno
= got
.br_startoff
+ got
.br_blockcount
;
699 lblk
= roundup(dabno
, args
.geo
->fsbcount
);
700 found
= xfs_iext_lookup_extent(sc
->ip
, ifp
, lblk
, &icur
, &got
);
703 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
706 /* Look for a leaf1 block, which has free info. */
707 if (xfs_iext_lookup_extent(sc
->ip
, ifp
, leaf_lblk
, &icur
, &got
) &&
708 got
.br_startoff
== leaf_lblk
&&
709 got
.br_blockcount
== args
.geo
->fsbcount
&&
710 !xfs_iext_next_extent(ifp
, &icur
, &got
)) {
712 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
715 error
= xchk_directory_leaf1_bestfree(sc
, &args
,
721 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
724 /* Scan for free blocks */
726 found
= xfs_iext_lookup_extent(sc
->ip
, ifp
, lblk
, &icur
, &got
);
727 while (found
&& !(sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)) {
729 * Dirs can't have blocks mapped above 2^32.
730 * Single-block dirs shouldn't even be here.
732 lblk
= got
.br_startoff
;
733 if (lblk
& ~0xFFFFFFFFULL
) {
734 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
738 xchk_fblock_set_corrupt(sc
, XFS_DATA_FORK
, lblk
);
743 * Check each dir free block's bestfree data.
745 * Iterate all the fsbcount-aligned block offsets in
746 * this directory. The directory block reading code is
747 * smart enough to do its own bmap lookups to handle
748 * discontiguous directory blocks. When we're done
749 * with the extent record, re-query the bmap at the
750 * next fsbcount-aligned offset to avoid redundant
753 for (lblk
= roundup((xfs_dablk_t
)got
.br_startoff
,
755 lblk
< got
.br_startoff
+ got
.br_blockcount
;
756 lblk
+= args
.geo
->fsbcount
) {
757 error
= xchk_directory_free_bestfree(sc
, &args
,
762 dabno
= got
.br_startoff
+ got
.br_blockcount
;
763 lblk
= roundup(dabno
, args
.geo
->fsbcount
);
764 found
= xfs_iext_lookup_extent(sc
->ip
, ifp
, lblk
, &icur
, &got
);
770 /* Scrub a whole directory. */
773 struct xfs_scrub
*sc
)
775 struct xchk_dir_ctx sdc
= {
776 .dir_iter
.actor
= xchk_dir_actor
,
784 if (!S_ISDIR(VFS_I(sc
->ip
)->i_mode
))
787 /* Plausible size? */
788 if (sc
->ip
->i_d
.di_size
< xfs_dir2_sf_hdr_size(0)) {
789 xchk_ino_set_corrupt(sc
, sc
->ip
->i_ino
);
793 /* Check directory tree structure */
794 error
= xchk_da_btree(sc
, XFS_DATA_FORK
, xchk_dir_rec
, NULL
);
798 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
801 /* Check the freespace. */
802 error
= xchk_directory_blocks(sc
);
806 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
810 * Check that every dirent we see can also be looked up by hash.
811 * Userspace usually asks for a 32k buffer, so we will too.
813 bufsize
= (size_t)min_t(loff_t
, XFS_READDIR_BUFSIZE
,
814 sc
->ip
->i_d
.di_size
);
817 * Look up every name in this directory by hash.
819 * Use the xfs_readdir function to call xchk_dir_actor on
820 * every directory entry in this directory. In _actor, we check
821 * the name, inode number, and ftype (if applicable) of the
822 * entry. xfs_readdir uses the VFS filldir functions to provide
825 * The VFS grabs a read or write lock via i_rwsem before it reads
826 * or writes to a directory. If we've gotten this far we've
827 * already obtained IOLOCK_EXCL, which (since 4.10) is the same as
828 * getting a write lock on i_rwsem. Therefore, it is safe for us
829 * to drop the ILOCK here in order to reuse the _readdir and
830 * _dir_lookup routines, which do their own ILOCK locking.
833 sc
->ilock_flags
&= ~XFS_ILOCK_EXCL
;
834 xfs_iunlock(sc
->ip
, XFS_ILOCK_EXCL
);
836 error
= xfs_readdir(sc
->tp
, sc
->ip
, &sdc
.dir_iter
, bufsize
);
837 if (!xchk_fblock_process_error(sc
, XFS_DATA_FORK
, 0,
840 if (oldpos
== sdc
.dir_iter
.pos
)
842 oldpos
= sdc
.dir_iter
.pos
;