1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
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"
16 #include "xfs_iwalk.h"
17 #include "xfs_ialloc.h"
19 #include "xfs_dir2_priv.h"
21 #include "xfs_parent.h"
22 #include "scrub/scrub.h"
23 #include "scrub/common.h"
24 #include "scrub/repair.h"
25 #include "scrub/xfile.h"
26 #include "scrub/xfarray.h"
27 #include "scrub/iscan.h"
28 #include "scrub/orphanage.h"
29 #include "scrub/nlinks.h"
30 #include "scrub/trace.h"
31 #include "scrub/readdir.h"
32 #include "scrub/tempfile.h"
33 #include "scrub/listxattr.h"
36 * Live Inode Link Count Checking
37 * ==============================
39 * Inode link counts are "summary" metadata, in the sense that they are
40 * computed as the number of directory entries referencing each file on the
41 * filesystem. Therefore, we compute the correct link counts by creating a
42 * shadow link count structure and walking every inode.
45 /* Set us up to scrub inode link counts. */
50 struct xchk_nlink_ctrs
*xnc
;
53 xchk_fsgates_enable(sc
, XCHK_FSGATES_DIRENTS
);
55 if (xchk_could_repair(sc
)) {
56 error
= xrep_setup_nlinks(sc
);
61 xnc
= kvzalloc(sizeof(struct xchk_nlink_ctrs
), XCHK_GFP_FLAGS
);
64 xnc
->xname
.name
= xnc
->namebuf
;
68 return xchk_setup_fs(sc
);
72 * Part 1: Collecting file link counts. For each file, we create a shadow link
73 * counting structure, then walk the entire directory tree, incrementing parent
74 * and child link counts for each directory entry seen.
76 * To avoid false corruption reports in part 2, any failure in this part must
77 * set the INCOMPLETE flag even when a negative errno is returned. This care
78 * must be taken with certain errno values (i.e. EFSBADCRC, EFSCORRUPTED,
79 * ECANCELED) that are absorbed into a scrub state flag update by
80 * xchk_*_process_error. Scrub and repair share the same incore data
81 * structures, so the INCOMPLETE flag is critical to prevent a repair based on
82 * insufficient information.
84 * Because we are scanning a live filesystem, it's possible that another thread
85 * will try to update the link counts for an inode that we've already scanned.
86 * This will cause our counts to be incorrect. Therefore, we hook all
87 * directory entry updates because that is when link count updates occur. By
88 * shadowing transaction updates in this manner, live nlink check can ensure by
89 * locking the inode and the shadow structure that its own copies are not out
90 * of date. Because the hook code runs in a different process context from the
91 * scrub code and the scrub state flags are not accessed atomically, failures
92 * in the hook code must abort the iscan and the scrubber must notice the
93 * aborted scan and set the incomplete flag.
95 * Note that we use jump labels and srcu notifier hooks to minimize the
96 * overhead when live nlinks is /not/ running. Locking order for nlink
97 * observations is inode ILOCK -> iscan_lock/xchk_nlink_ctrs lock.
101 * Add a delta to an nlink counter, clamping the value to U32_MAX. Because
102 * XFS_MAXLINK < U32_MAX, the checking code will produce the correct results
103 * even if we lose some precision.
110 uint64_t new_value
= (uint64_t)(*nlinkp
) + delta
;
112 BUILD_BUG_ON(XFS_MAXLINK
> U32_MAX
);
113 *nlinkp
= min_t(uint64_t, new_value
, U32_MAX
);
116 /* Update incore link count information. Caller must hold the nlinks lock. */
118 xchk_nlinks_update_incore(
119 struct xchk_nlink_ctrs
*xnc
,
125 struct xchk_nlink nl
;
131 error
= xfarray_load_sparse(xnc
->nlinks
, ino
, &nl
);
135 trace_xchk_nlinks_update_incore(xnc
->sc
->mp
, ino
, &nl
, parents_delta
,
136 backrefs_delta
, children_delta
);
138 careful_add(&nl
.parents
, parents_delta
);
139 careful_add(&nl
.backrefs
, backrefs_delta
);
140 careful_add(&nl
.children
, children_delta
);
142 nl
.flags
|= XCHK_NLINK_WRITTEN
;
143 error
= xfarray_store(xnc
->nlinks
, ino
, &nl
);
144 if (error
== -EFBIG
) {
146 * EFBIG means we tried to store data at too high a byte offset
147 * in the sparse array. IOWs, we cannot complete the check and
148 * must notify userspace that the check was incomplete.
156 * Apply a link count change from the regular filesystem into our shadow link
157 * count structure based on a directory update in progress.
160 xchk_nlinks_live_update(
161 struct notifier_block
*nb
,
162 unsigned long action
,
165 struct xfs_dir_update_params
*p
= data
;
166 struct xchk_nlink_ctrs
*xnc
;
169 xnc
= container_of(nb
, struct xchk_nlink_ctrs
, dhook
.dirent_hook
.nb
);
172 * Ignore temporary directories being used to stage dir repairs, since
173 * we don't bump the link counts of the children.
175 if (xrep_is_tempfile(p
->dp
))
178 trace_xchk_nlinks_live_update(xnc
->sc
->mp
, p
->dp
, action
, p
->ip
->i_ino
,
179 p
->delta
, p
->name
->name
, p
->name
->len
);
182 * If we've already scanned @dp, update the number of parents that link
183 * to @ip. If @ip is a subdirectory, update the number of child links
186 if (xchk_iscan_want_live_update(&xnc
->collect_iscan
, p
->dp
->i_ino
)) {
187 mutex_lock(&xnc
->lock
);
188 error
= xchk_nlinks_update_incore(xnc
, p
->ip
->i_ino
, p
->delta
,
190 if (!error
&& S_ISDIR(VFS_IC(p
->ip
)->i_mode
))
191 error
= xchk_nlinks_update_incore(xnc
, p
->dp
->i_ino
, 0,
193 mutex_unlock(&xnc
->lock
);
199 * If @ip is a subdirectory and we've already scanned it, update the
200 * number of backrefs pointing to @dp.
202 if (S_ISDIR(VFS_IC(p
->ip
)->i_mode
) &&
203 xchk_iscan_want_live_update(&xnc
->collect_iscan
, p
->ip
->i_ino
)) {
204 mutex_lock(&xnc
->lock
);
205 error
= xchk_nlinks_update_incore(xnc
, p
->dp
->i_ino
, 0,
207 mutex_unlock(&xnc
->lock
);
215 xchk_iscan_abort(&xnc
->collect_iscan
);
219 /* Bump the observed link count for the inode referenced by this entry. */
221 xchk_nlinks_collect_dirent(
222 struct xfs_scrub
*sc
,
223 struct xfs_inode
*dp
,
224 xfs_dir2_dataptr_t dapos
,
225 const struct xfs_name
*name
,
229 struct xchk_nlink_ctrs
*xnc
= priv
;
230 bool dot
= false, dotdot
= false;
233 /* Does this name make sense? */
234 if (name
->len
== 0 || !xfs_dir2_namecheck(name
->name
, name
->len
)) {
239 if (name
->len
== 1 && name
->name
[0] == '.')
241 else if (name
->len
== 2 && name
->name
[0] == '.' &&
242 name
->name
[1] == '.')
245 /* Don't accept a '.' entry that points somewhere else. */
246 if (dot
&& ino
!= dp
->i_ino
) {
251 /* Don't accept an invalid inode number. */
252 if (!xfs_verify_dir_ino(sc
->mp
, ino
)) {
257 /* Update the shadow link counts if we haven't already failed. */
259 if (xchk_iscan_aborted(&xnc
->collect_iscan
)) {
264 trace_xchk_nlinks_collect_dirent(sc
->mp
, dp
, ino
, name
);
266 mutex_lock(&xnc
->lock
);
269 * If this is a dotdot entry, it is a back link from dp to ino. How
270 * we handle this depends on whether or not dp is the root directory.
272 * The root directory is its own parent, so we pretend the dotdot entry
273 * establishes the "parent" of the root directory. Increment the
274 * number of parents of the root directory.
276 * Otherwise, increment the number of backrefs pointing back to ino.
278 * If the filesystem has parent pointers, we walk the pptrs to
279 * determine the backref count.
282 if (xchk_inode_is_dirtree_root(dp
))
283 error
= xchk_nlinks_update_incore(xnc
, ino
, 1, 0, 0);
284 else if (!xfs_has_parent(sc
->mp
))
285 error
= xchk_nlinks_update_incore(xnc
, ino
, 0, 1, 0);
293 * If this dirent is a forward link from dp to ino, increment the
294 * number of parents linking into ino.
296 if (!dot
&& !dotdot
) {
297 error
= xchk_nlinks_update_incore(xnc
, ino
, 1, 0, 0);
303 * If this dirent is a forward link to a subdirectory, increment the
304 * number of child links of dp.
306 if (!dot
&& !dotdot
&& name
->type
== XFS_DIR3_FT_DIR
) {
307 error
= xchk_nlinks_update_incore(xnc
, dp
->i_ino
, 0, 0, 1);
312 mutex_unlock(&xnc
->lock
);
316 mutex_unlock(&xnc
->lock
);
318 xchk_iscan_abort(&xnc
->collect_iscan
);
320 xchk_set_incomplete(sc
);
324 /* Bump the backref count for the inode referenced by this parent pointer. */
326 xchk_nlinks_collect_pptr(
327 struct xfs_scrub
*sc
,
328 struct xfs_inode
*ip
,
329 unsigned int attr_flags
,
330 const unsigned char *name
,
331 unsigned int namelen
,
333 unsigned int valuelen
,
336 struct xfs_name xname
= {
340 struct xchk_nlink_ctrs
*xnc
= priv
;
341 const struct xfs_parent_rec
*pptr_rec
= value
;
342 xfs_ino_t parent_ino
;
345 /* Update the shadow link counts if we haven't already failed. */
347 if (xchk_iscan_aborted(&xnc
->collect_iscan
)) {
352 if (!(attr_flags
& XFS_ATTR_PARENT
))
355 error
= xfs_parent_from_attr(sc
->mp
, attr_flags
, name
, namelen
, value
,
356 valuelen
, &parent_ino
, NULL
);
360 trace_xchk_nlinks_collect_pptr(sc
->mp
, ip
, &xname
, pptr_rec
);
362 mutex_lock(&xnc
->lock
);
364 error
= xchk_nlinks_update_incore(xnc
, parent_ino
, 0, 1, 0);
368 mutex_unlock(&xnc
->lock
);
372 mutex_unlock(&xnc
->lock
);
373 xchk_iscan_abort(&xnc
->collect_iscan
);
375 xchk_set_incomplete(sc
);
379 /* Walk a directory to bump the observed link counts of the children. */
381 xchk_nlinks_collect_dir(
382 struct xchk_nlink_ctrs
*xnc
,
383 struct xfs_inode
*dp
)
385 struct xfs_scrub
*sc
= xnc
->sc
;
386 unsigned int lock_mode
;
390 * Ignore temporary directories being used to stage dir repairs, since
391 * we don't bump the link counts of the children.
393 if (xrep_is_tempfile(dp
))
396 /* Prevent anyone from changing this directory while we walk it. */
397 xfs_ilock(dp
, XFS_IOLOCK_SHARED
);
398 lock_mode
= xfs_ilock_data_map_shared(dp
);
401 * The dotdot entry of an unlinked directory still points to the last
402 * parent, but the parent no longer links to this directory. Skip the
403 * directory to avoid overcounting.
405 if (VFS_I(dp
)->i_nlink
== 0)
409 * We cannot count file links if the directory looks as though it has
410 * been zapped by the inode record repair code.
412 if (xchk_dir_looks_zapped(dp
)) {
417 error
= xchk_dir_walk(sc
, dp
, xchk_nlinks_collect_dirent
, xnc
);
418 if (error
== -ECANCELED
) {
425 /* Walk the parent pointers to get real backref counts. */
426 if (xfs_has_parent(sc
->mp
)) {
428 * If the extended attributes look as though they has been
429 * zapped by the inode record repair code, we cannot scan for
432 if (xchk_pptr_looks_zapped(dp
)) {
437 error
= xchk_xattr_walk(sc
, dp
, xchk_nlinks_collect_pptr
, NULL
,
439 if (error
== -ECANCELED
) {
447 xchk_iscan_mark_visited(&xnc
->collect_iscan
, dp
);
451 xchk_set_incomplete(sc
);
452 xchk_iscan_abort(&xnc
->collect_iscan
);
454 xfs_iunlock(dp
, lock_mode
);
455 xfs_iunlock(dp
, XFS_IOLOCK_SHARED
);
459 /* If this looks like a valid pointer, count it. */
461 xchk_nlinks_collect_metafile(
462 struct xchk_nlink_ctrs
*xnc
,
465 if (!xfs_verify_ino(xnc
->sc
->mp
, ino
))
468 trace_xchk_nlinks_collect_metafile(xnc
->sc
->mp
, ino
);
469 return xchk_nlinks_update_incore(xnc
, ino
, 1, 0, 0);
472 /* Bump the link counts of metadata files rooted in the superblock. */
474 xchk_nlinks_collect_metafiles(
475 struct xchk_nlink_ctrs
*xnc
)
477 struct xfs_mount
*mp
= xnc
->sc
->mp
;
478 int error
= -ECANCELED
;
481 if (xchk_iscan_aborted(&xnc
->collect_iscan
))
484 mutex_lock(&xnc
->lock
);
485 error
= xchk_nlinks_collect_metafile(xnc
, mp
->m_sb
.sb_rbmino
);
489 error
= xchk_nlinks_collect_metafile(xnc
, mp
->m_sb
.sb_rsumino
);
493 error
= xchk_nlinks_collect_metafile(xnc
, mp
->m_sb
.sb_uquotino
);
497 error
= xchk_nlinks_collect_metafile(xnc
, mp
->m_sb
.sb_gquotino
);
501 error
= xchk_nlinks_collect_metafile(xnc
, mp
->m_sb
.sb_pquotino
);
504 mutex_unlock(&xnc
->lock
);
509 mutex_unlock(&xnc
->lock
);
510 xchk_iscan_abort(&xnc
->collect_iscan
);
512 xchk_set_incomplete(xnc
->sc
);
516 /* Advance the collection scan cursor for this non-directory file. */
518 xchk_nlinks_collect_file(
519 struct xchk_nlink_ctrs
*xnc
,
520 struct xfs_inode
*ip
)
522 xfs_ilock(ip
, XFS_IOLOCK_SHARED
);
523 xchk_iscan_mark_visited(&xnc
->collect_iscan
, ip
);
524 xfs_iunlock(ip
, XFS_IOLOCK_SHARED
);
528 /* Walk all directories and count inode links. */
531 struct xchk_nlink_ctrs
*xnc
)
533 struct xfs_scrub
*sc
= xnc
->sc
;
534 struct xfs_inode
*ip
;
537 /* Count the rt and quota files that are rooted in the superblock. */
538 error
= xchk_nlinks_collect_metafiles(xnc
);
543 * Set up for a potentially lengthy filesystem scan by reducing our
544 * transaction resource usage for the duration. Specifically:
546 * Cancel the transaction to release the log grant space while we scan
549 * Create a new empty transaction to eliminate the possibility of the
550 * inode scan deadlocking on cyclical metadata.
552 * We pass the empty transaction to the file scanning function to avoid
553 * repeatedly cycling empty transactions. This can be done even though
554 * we take the IOLOCK to quiesce the file because empty transactions
555 * do not take sb_internal.
557 xchk_trans_cancel(sc
);
558 error
= xchk_trans_alloc_empty(sc
);
562 while ((error
= xchk_iscan_iter(&xnc
->collect_iscan
, &ip
)) == 1) {
563 if (S_ISDIR(VFS_I(ip
)->i_mode
))
564 error
= xchk_nlinks_collect_dir(xnc
, ip
);
566 error
= xchk_nlinks_collect_file(xnc
, ip
);
571 if (xchk_should_terminate(sc
, &error
))
574 xchk_iscan_iter_finish(&xnc
->collect_iscan
);
576 xchk_set_incomplete(sc
);
578 * If we couldn't grab an inode that was busy with a state
579 * change, change the error code so that we exit to userspace
580 * as quickly as possible.
588 * Switch out for a real transaction in preparation for building a new
591 xchk_trans_cancel(sc
);
592 return xchk_setup_fs(sc
);
596 * Part 2: Comparing file link counters. Walk each inode and compare the link
597 * counts against our shadow information; and then walk each shadow link count
598 * structure (that wasn't covered in the first part), comparing it against the
602 /* Read the observed link count for comparison with the actual inode. */
604 xchk_nlinks_comparison_read(
605 struct xchk_nlink_ctrs
*xnc
,
607 struct xchk_nlink
*obs
)
609 struct xchk_nlink nl
;
612 error
= xfarray_load_sparse(xnc
->nlinks
, ino
, &nl
);
616 nl
.flags
|= (XCHK_NLINK_COMPARE_SCANNED
| XCHK_NLINK_WRITTEN
);
618 error
= xfarray_store(xnc
->nlinks
, ino
, &nl
);
619 if (error
== -EFBIG
) {
621 * EFBIG means we tried to store data at too high a byte offset
622 * in the sparse array. IOWs, we cannot complete the check and
623 * must notify userspace that the check was incomplete. This
624 * shouldn't really happen outside of the collection phase.
626 xchk_set_incomplete(xnc
->sc
);
632 /* Copy the counters, but do not expose the internal state. */
633 obs
->parents
= nl
.parents
;
634 obs
->backrefs
= nl
.backrefs
;
635 obs
->children
= nl
.children
;
640 /* Check our link count against an inode. */
642 xchk_nlinks_compare_inode(
643 struct xchk_nlink_ctrs
*xnc
,
644 struct xfs_inode
*ip
)
646 struct xchk_nlink obs
;
647 struct xfs_scrub
*sc
= xnc
->sc
;
648 uint64_t total_links
;
649 unsigned int actual_nlink
;
653 * Ignore temporary files being used to stage repairs, since we assume
654 * they're correct for non-directories, and the directory repair code
655 * doesn't bump the link counts for the children.
657 if (xrep_is_tempfile(ip
))
660 xfs_ilock(ip
, XFS_ILOCK_SHARED
);
661 mutex_lock(&xnc
->lock
);
663 if (xchk_iscan_aborted(&xnc
->collect_iscan
)) {
664 xchk_set_incomplete(xnc
->sc
);
669 error
= xchk_nlinks_comparison_read(xnc
, ip
->i_ino
, &obs
);
674 * If we don't have ftype to get an accurate count of the subdirectory
675 * entries in this directory, take advantage of the fact that on a
676 * consistent ftype=0 filesystem, the number of subdirectory
677 * backreferences (dotdot entries) pointing towards this directory
678 * should be equal to the number of subdirectory entries in the
681 if (!xfs_has_ftype(sc
->mp
) && S_ISDIR(VFS_I(ip
)->i_mode
))
682 obs
.children
= obs
.backrefs
;
684 total_links
= xchk_nlink_total(ip
, &obs
);
685 actual_nlink
= VFS_I(ip
)->i_nlink
;
687 trace_xchk_nlinks_compare_inode(sc
->mp
, ip
, &obs
);
690 * If we found so many parents that we'd overflow i_nlink, we must flag
691 * this as a corruption. The VFS won't let users increase the link
692 * count, but it will let them decrease it.
694 if (total_links
> XFS_NLINK_PINNED
) {
695 xchk_ino_set_corrupt(sc
, ip
->i_ino
);
697 } else if (total_links
> XFS_MAXLINK
) {
698 xchk_ino_set_warning(sc
, ip
->i_ino
);
701 /* Link counts should match. */
702 if (total_links
!= actual_nlink
) {
703 xchk_ino_set_corrupt(sc
, ip
->i_ino
);
707 if (S_ISDIR(VFS_I(ip
)->i_mode
) && actual_nlink
> 0) {
709 * The collection phase ignores directories with zero link
710 * count, so we ignore them here too.
712 * The number of subdirectory backreferences (dotdot entries)
713 * pointing towards this directory should be equal to the
714 * number of subdirectory entries in the directory.
716 if (obs
.children
!= obs
.backrefs
)
717 xchk_ino_xref_set_corrupt(sc
, ip
->i_ino
);
720 * Non-directories and unlinked directories should not have
723 if (obs
.backrefs
!= 0) {
724 xchk_ino_set_corrupt(sc
, ip
->i_ino
);
729 * Non-directories and unlinked directories should not have
732 if (obs
.children
!= 0) {
733 xchk_ino_set_corrupt(sc
, ip
->i_ino
);
738 if (xchk_inode_is_dirtree_root(ip
)) {
740 * For the root of a directory tree, both the '.' and '..'
741 * entries should point to the root directory. The dotdot
742 * entry is counted as a parent of the root /and/ a backref of
743 * the root directory.
745 if (obs
.parents
!= 1) {
746 xchk_ino_set_corrupt(sc
, ip
->i_ino
);
749 } else if (actual_nlink
> 0) {
751 * Linked files that are not the root directory should have at
754 if (obs
.parents
== 0) {
755 xchk_ino_set_corrupt(sc
, ip
->i_ino
);
761 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
764 mutex_unlock(&xnc
->lock
);
765 xfs_iunlock(ip
, XFS_ILOCK_SHARED
);
770 * Check our link count against an inode that wasn't checked previously. This
771 * is intended to catch directories with dangling links, though we could be
772 * racing with inode allocation in other threads.
775 xchk_nlinks_compare_inum(
776 struct xchk_nlink_ctrs
*xnc
,
779 struct xchk_nlink obs
;
780 struct xfs_mount
*mp
= xnc
->sc
->mp
;
781 struct xfs_trans
*tp
= xnc
->sc
->tp
;
782 struct xfs_buf
*agi_bp
;
783 struct xfs_inode
*ip
;
787 * The first iget failed, so try again with the variant that returns
788 * either an incore inode or the AGI buffer. If the function returns
789 * EINVAL/ENOENT, it should have passed us the AGI buffer so that we
790 * can guarantee that the inode won't be allocated while we check for
791 * a zero link count in the observed link count data.
793 error
= xchk_iget_agi(xnc
->sc
, ino
, &agi_bp
, &ip
);
795 /* Actually got an inode, so use the inode compare. */
796 error
= xchk_nlinks_compare_inode(xnc
, ip
);
797 xchk_irele(xnc
->sc
, ip
);
800 if (error
== -ENOENT
|| error
== -EINVAL
) {
801 /* No inode was found. Check for zero link count below. */
807 /* Ensure that we have protected against inode allocation/freeing. */
808 if (agi_bp
== NULL
) {
809 ASSERT(agi_bp
!= NULL
);
810 xchk_set_incomplete(xnc
->sc
);
814 if (xchk_iscan_aborted(&xnc
->collect_iscan
)) {
815 xchk_set_incomplete(xnc
->sc
);
820 mutex_lock(&xnc
->lock
);
821 error
= xchk_nlinks_comparison_read(xnc
, ino
, &obs
);
825 trace_xchk_nlinks_check_zero(mp
, ino
, &obs
);
828 * If we can't grab the inode, the link count had better be zero. We
829 * still hold the AGI to prevent inode allocation/freeing.
831 if (xchk_nlink_total(NULL
, &obs
) != 0) {
832 xchk_ino_set_corrupt(xnc
->sc
, ino
);
837 mutex_unlock(&xnc
->lock
);
840 xfs_trans_brelse(tp
, agi_bp
);
845 * Try to visit every inode in the filesystem to compare the link count. Move
846 * on if we can't grab an inode, since we'll revisit unchecked nlink records in
850 xchk_nlinks_compare_iter(
851 struct xchk_nlink_ctrs
*xnc
,
852 struct xfs_inode
**ipp
)
857 error
= xchk_iscan_iter(&xnc
->compare_iscan
, ipp
);
858 } while (error
== -EBUSY
);
863 /* Compare the link counts we observed against the live information. */
866 struct xchk_nlink_ctrs
*xnc
)
868 struct xchk_nlink nl
;
869 struct xfs_scrub
*sc
= xnc
->sc
;
870 struct xfs_inode
*ip
;
871 xfarray_idx_t cur
= XFARRAY_CURSOR_INIT
;
874 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
878 * Create a new empty transaction so that we can advance the iscan
879 * cursor without deadlocking if the inobt has a cycle and push on the
880 * inactivation workqueue.
882 xchk_trans_cancel(sc
);
883 error
= xchk_trans_alloc_empty(sc
);
888 * Use the inobt to walk all allocated inodes to compare the link
889 * counts. Inodes skipped by _compare_iter will be tried again in the
890 * next phase of the scan.
892 xchk_iscan_start(sc
, 0, 0, &xnc
->compare_iscan
);
893 while ((error
= xchk_nlinks_compare_iter(xnc
, &ip
)) == 1) {
894 error
= xchk_nlinks_compare_inode(xnc
, ip
);
895 xchk_iscan_mark_visited(&xnc
->compare_iscan
, ip
);
900 if (xchk_should_terminate(sc
, &error
))
903 xchk_iscan_iter_finish(&xnc
->compare_iscan
);
904 xchk_iscan_teardown(&xnc
->compare_iscan
);
908 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
912 * Walk all the non-null nlink observations that weren't checked in the
915 mutex_lock(&xnc
->lock
);
916 while ((error
= xfarray_iter(xnc
->nlinks
, &cur
, &nl
)) == 1) {
917 xfs_ino_t ino
= cur
- 1;
919 if (nl
.flags
& XCHK_NLINK_COMPARE_SCANNED
)
922 mutex_unlock(&xnc
->lock
);
924 error
= xchk_nlinks_compare_inum(xnc
, ino
);
928 if (xchk_should_terminate(xnc
->sc
, &error
))
931 mutex_lock(&xnc
->lock
);
933 mutex_unlock(&xnc
->lock
);
938 /* Tear down everything associated with a nlinks check. */
940 xchk_nlinks_teardown_scan(
943 struct xchk_nlink_ctrs
*xnc
= priv
;
945 /* Discourage any hook functions that might be running. */
946 xchk_iscan_abort(&xnc
->collect_iscan
);
948 xfs_dir_hook_del(xnc
->sc
->mp
, &xnc
->dhook
);
950 xfarray_destroy(xnc
->nlinks
);
953 xchk_iscan_teardown(&xnc
->collect_iscan
);
954 mutex_destroy(&xnc
->lock
);
959 * Scan all inodes in the entire filesystem to generate link count data. If
960 * the scan is successful, the counts will be left alive for a repair. If any
961 * error occurs, we'll tear everything down.
964 xchk_nlinks_setup_scan(
965 struct xfs_scrub
*sc
,
966 struct xchk_nlink_ctrs
*xnc
)
968 struct xfs_mount
*mp
= sc
->mp
;
970 unsigned long long max_inos
;
971 xfs_agnumber_t last_agno
= mp
->m_sb
.sb_agcount
- 1;
972 xfs_agino_t first_agino
, last_agino
;
975 mutex_init(&xnc
->lock
);
977 /* Retry iget every tenth of a second for up to 30 seconds. */
978 xchk_iscan_start(sc
, 30000, 100, &xnc
->collect_iscan
);
981 * Set up enough space to store an nlink record for the highest
982 * possible inode number in this system.
984 xfs_agino_range(mp
, last_agno
, &first_agino
, &last_agino
);
985 max_inos
= XFS_AGINO_TO_INO(mp
, last_agno
, last_agino
) + 1;
986 descr
= xchk_xfile_descr(sc
, "file link counts");
987 error
= xfarray_create(descr
, min(XFS_MAXINUMBER
+ 1, max_inos
),
988 sizeof(struct xchk_nlink
), &xnc
->nlinks
);
994 * Hook into the directory entry code so that we can capture updates to
995 * file link counts. The hook only triggers for inodes that were
996 * already scanned, and the scanner thread takes each inode's ILOCK,
997 * which means that any in-progress inode updates will finish before we
998 * can scan the inode.
1000 ASSERT(sc
->flags
& XCHK_FSGATES_DIRENTS
);
1001 xfs_dir_hook_setup(&xnc
->dhook
, xchk_nlinks_live_update
);
1002 error
= xfs_dir_hook_add(mp
, &xnc
->dhook
);
1006 /* Use deferred cleanup to pass the inode link count data to repair. */
1007 sc
->buf_cleanup
= xchk_nlinks_teardown_scan
;
1011 xchk_nlinks_teardown_scan(xnc
);
1015 /* Scrub the link count of all inodes on the filesystem. */
1018 struct xfs_scrub
*sc
)
1020 struct xchk_nlink_ctrs
*xnc
= sc
->buf
;
1023 /* Set ourselves up to check link counts on the live filesystem. */
1024 error
= xchk_nlinks_setup_scan(sc
, xnc
);
1028 /* Walk all inodes, picking up link count information. */
1029 error
= xchk_nlinks_collect(xnc
);
1030 if (!xchk_xref_process_error(sc
, 0, 0, &error
))
1033 /* Fail fast if we're not playing with a full dataset. */
1034 if (xchk_iscan_aborted(&xnc
->collect_iscan
))
1035 xchk_set_incomplete(sc
);
1036 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_INCOMPLETE
)
1039 /* Compare link counts. */
1040 error
= xchk_nlinks_compare(xnc
);
1041 if (!xchk_xref_process_error(sc
, 0, 0, &error
))
1044 /* Check one last time for an incomplete dataset. */
1045 if (xchk_iscan_aborted(&xnc
->collect_iscan
))
1046 xchk_set_incomplete(sc
);