brintos

brintos / linux-shallow public Read only

0
0
Text · 4.9 KiB · 1e16863 Raw
179 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * Copyright (c) 2023-2024 Oracle.  All Rights Reserved.4 * Author: Darrick J. Wong <djwong@kernel.org>5 */6#ifndef __XFS_SCRUB_DIRTREE_H__7#define __XFS_SCRUB_DIRTREE_H__8 9/*10 * Each of these represents one parent pointer path step in a chain going11 * up towards the directory tree root.  These are stored inside an xfarray.12 */13struct xchk_dirpath_step {14	/* Directory entry name associated with this parent link. */15	xfblob_cookie		name_cookie;16	unsigned int		name_len;17 18	/* Handle of the parent directory. */19	struct xfs_parent_rec	pptr_rec;20};21 22enum xchk_dirpath_outcome {23	XCHK_DIRPATH_SCANNING = 0,	/* still being put together */24	XCHK_DIRPATH_DELETE,		/* delete this path */25	XCHK_DIRPATH_CORRUPT,		/* corruption detected in path */26	XCHK_DIRPATH_LOOP,		/* cycle detected further up */27	XCHK_DIRPATH_STALE,		/* path is stale */28	XCHK_DIRPATH_OK,		/* path reaches the root */29 30	XREP_DIRPATH_DELETING,		/* path is being deleted */31	XREP_DIRPATH_DELETED,		/* path has been deleted */32	XREP_DIRPATH_ADOPTING,		/* path is being adopted */33	XREP_DIRPATH_ADOPTED,		/* path has been adopted */34};35 36/*37 * Each of these represents one parent pointer path out of the directory being38 * scanned.  These exist in-core, and hopefully there aren't more than a39 * handful of them.40 */41struct xchk_dirpath {42	struct list_head	list;43 44	/* Index of the first step in this path. */45	xfarray_idx_t		first_step;46 47	/* Index of the second step in this path. */48	xfarray_idx_t		second_step;49 50	/* Inodes seen while walking this path. */51	struct xino_bitmap	seen_inodes;52 53	/* Number of steps in this path. */54	unsigned int		nr_steps;55 56	/* Which path is this? */57	unsigned int		path_nr;58 59	/* What did we conclude from following this path? */60	enum xchk_dirpath_outcome outcome;61};62 63struct xchk_dirtree_outcomes {64	/* Number of XCHK_DIRPATH_DELETE */65	unsigned int		bad;66 67	/* Number of XCHK_DIRPATH_CORRUPT or XCHK_DIRPATH_LOOP */68	unsigned int		suspect;69 70	/* Number of XCHK_DIRPATH_OK */71	unsigned int		good;72 73	/* Directory needs to be added to lost+found */74	bool			needs_adoption;75};76 77struct xchk_dirtree {78	struct xfs_scrub	*sc;79 80	/* Root inode that we're looking for. */81	xfs_ino_t		root_ino;82 83	/*84	 * This is the inode that we're scanning.  The live update hook can85	 * continue to be called after xchk_teardown drops sc->ip but before86	 * it calls buf_cleanup, so we keep a copy.87	 */88	xfs_ino_t		scan_ino;89 90	/*91	 * If we start deleting redundant paths to this subdirectory, this is92	 * the inode number of the surviving parent and the dotdot entry will93	 * be set to this value.  If the value is NULLFSINO, then use @root_ino94	 * as a stand-in until the orphanage can adopt the subdirectory.95	 */96	xfs_ino_t		parent_ino;97 98	/* Scratch buffer for scanning pptr xattrs */99	struct xfs_parent_rec	pptr_rec;100	struct xfs_da_args	pptr_args;101 102	/* Name buffer */103	struct xfs_name		xname;104	char			namebuf[MAXNAMELEN];105 106	/* Information for reparenting this directory. */107	struct xrep_adoption	adoption;108 109	/*110	 * Hook into directory updates so that we can receive live updates111	 * from other writer threads.112	 */113	struct xfs_dir_hook	dhook;114 115	/* Parent pointer update arguments. */116	struct xfs_parent_args	ppargs;117 118	/* lock for everything below here */119	struct mutex		lock;120 121	/* buffer for the live update functions to use for dirent names */122	struct xfs_name		hook_xname;123	unsigned char		hook_namebuf[MAXNAMELEN];124 125	/*126	 * All path steps observed during this scan.  Each of the path127	 * steps for a particular pathwalk are recorded in sequential128	 * order in the xfarray.  A pathwalk ends either with a step129	 * pointing to the root directory (success) or pointing to NULLFSINO130	 * (loop detected, empty dir detected, etc).131	 */132	struct xfarray		*path_steps;133 134	/* All names observed during this scan. */135	struct xfblob		*path_names;136 137	/* All paths being tracked by this scanner. */138	struct list_head	path_list;139 140	/* Number of paths in path_list. */141	unsigned int		nr_paths;142 143	/* Number of parents found by a pptr scan. */144	unsigned int		parents_found;145 146	/* Have the path data been invalidated by a concurrent update? */147	bool			stale:1;148 149	/* Has the scan been aborted? */150	bool			aborted:1;151};152 153#define xchk_dirtree_for_each_path_safe(dl, path, n) \154	list_for_each_entry_safe((path), (n), &(dl)->path_list, list)155 156#define xchk_dirtree_for_each_path(dl, path) \157	list_for_each_entry((path), &(dl)->path_list, list)158 159static inline bool160xchk_dirtree_parentless(const struct xchk_dirtree *dl)161{162	struct xfs_scrub	*sc = dl->sc;163 164	if (sc->ip == sc->mp->m_rootip)165		return true;166	if (VFS_I(sc->ip)->i_nlink == 0)167		return true;168	return false;169}170 171int xchk_dirtree_find_paths_to_root(struct xchk_dirtree *dl);172int xchk_dirpath_append(struct xchk_dirtree *dl, struct xfs_inode *ip,173		struct xchk_dirpath *path, const struct xfs_name *name,174		const struct xfs_parent_rec *pptr);175void xchk_dirtree_evaluate(struct xchk_dirtree *dl,176		struct xchk_dirtree_outcomes *oc);177 178#endif /* __XFS_SCRUB_DIRTREE_H__ */179