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>
6 #ifndef __XFS_SCRUB_NLINKS_H__
7 #define __XFS_SCRUB_NLINKS_H__
9 /* Live link count control structure. */
10 struct xchk_nlink_ctrs
{
13 /* Shadow link count data and its mutex. */
14 struct xfarray
*nlinks
;
18 * The collection step uses a separate iscan context from the compare
19 * step because the collection iscan coordinates live updates to the
20 * observation data while this scanner is running. The compare iscan
21 * is secondary and can be reinitialized as needed.
23 struct xchk_iscan collect_iscan
;
24 struct xchk_iscan compare_iscan
;
27 * Hook into directory updates so that we can receive live updates
28 * from other writer threads.
30 struct xfs_dir_hook dhook
;
32 /* Orphanage reparenting request. */
33 struct xrep_adoption adoption
;
35 /* Directory entry name, plus the trailing null. */
36 struct xfs_name xname
;
37 char namebuf
[MAXNAMELEN
];
41 * In-core link counts for a given inode in the filesystem.
43 * For an empty rootdir, the directory entries and the field to which they are
44 * accounted are as follows:
48 * . points to self (root.child)
49 * .. points to self (root.parent)
50 * f1 points to a child file (f1.parent)
51 * d1 points to a child dir (d1.parent, root.child)
55 * . points to self (d1.child)
56 * .. points to root dir (root.backref)
57 * f2 points to child file (f2.parent)
58 * f3 points to root.f1 (f1.parent)
60 * root.nlink == 3 (root.dot, root.dotdot, root.d1)
61 * d1.nlink == 2 (root.d1, d1.dot)
62 * f1.nlink == 2 (root.f1, d1.f3)
63 * f2.nlink == 1 (d1.f2)
66 /* Count of forward links from parent directories to this file. */
70 * Count of back links to this parent directory from child
76 * Count of forward links from this directory to all child files and
77 * the number of dot entries. Should be zero for non-directories.
81 /* Record state flags */
86 * This incore link count has been written at least once. We never want to
87 * store an xchk_nlink that looks uninitialized.
89 #define XCHK_NLINK_WRITTEN (1U << 0)
91 /* Already checked this link count record. */
92 #define XCHK_NLINK_COMPARE_SCANNED (1U << 1)
94 /* Already made a repair with this link count record. */
95 #define XREP_NLINK_DIRTY (1U << 2)
97 /* Compute total link count, using large enough variables to detect overflow. */
98 static inline uint64_t
99 xchk_nlink_total(struct xfs_inode
*ip
, const struct xchk_nlink
*live
)
101 uint64_t ret
= live
->parents
;
103 /* Add one link count for the dot entry of any linked directory. */
104 if (ip
&& S_ISDIR(VFS_I(ip
)->i_mode
) && VFS_I(ip
)->i_nlink
)
106 return ret
+ live
->children
;
109 #endif /* __XFS_SCRUB_NLINKS_H__ */