110 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved.4 * Author: Darrick J. Wong <djwong@kernel.org>5 */6#ifndef __XFS_SCRUB_NLINKS_H__7#define __XFS_SCRUB_NLINKS_H__8 9/* Live link count control structure. */10struct xchk_nlink_ctrs {11 struct xfs_scrub *sc;12 13 /* Shadow link count data and its mutex. */14 struct xfarray *nlinks;15 struct mutex lock;16 17 /*18 * The collection step uses a separate iscan context from the compare19 * step because the collection iscan coordinates live updates to the20 * observation data while this scanner is running. The compare iscan21 * is secondary and can be reinitialized as needed.22 */23 struct xchk_iscan collect_iscan;24 struct xchk_iscan compare_iscan;25 26 /*27 * Hook into directory updates so that we can receive live updates28 * from other writer threads.29 */30 struct xfs_dir_hook dhook;31 32 /* Orphanage reparenting request. */33 struct xrep_adoption adoption;34 35 /* Directory entry name, plus the trailing null. */36 struct xfs_name xname;37 char namebuf[MAXNAMELEN];38};39 40/*41 * In-core link counts for a given inode in the filesystem.42 *43 * For an empty rootdir, the directory entries and the field to which they are44 * accounted are as follows:45 *46 * Root directory:47 *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)52 *53 * Subdirectory d1:54 *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)59 *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)64 */65struct xchk_nlink {66 /* Count of forward links from parent directories to this file. */67 xfs_nlink_t parents;68 69 /*70 * Count of back links to this parent directory from child71 * subdirectories.72 */73 xfs_nlink_t backrefs;74 75 /*76 * Count of forward links from this directory to all child files and77 * the number of dot entries. Should be zero for non-directories.78 */79 xfs_nlink_t children;80 81 /* Record state flags */82 unsigned int flags;83};84 85/*86 * This incore link count has been written at least once. We never want to87 * store an xchk_nlink that looks uninitialized.88 */89#define XCHK_NLINK_WRITTEN (1U << 0)90 91/* Already checked this link count record. */92#define XCHK_NLINK_COMPARE_SCANNED (1U << 1)93 94/* Already made a repair with this link count record. */95#define XREP_NLINK_DIRTY (1U << 2)96 97/* Compute total link count, using large enough variables to detect overflow. */98static inline uint64_t99xchk_nlink_total(struct xfs_inode *ip, const struct xchk_nlink *live)100{101 uint64_t ret = live->parents;102 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)105 ret++;106 return ret + live->children;107}108 109#endif /* __XFS_SCRUB_NLINKS_H__ */110