File Index
Files and directories
Sign in
FILE

dirtree.h

File preview with syntax highlighting.

linux-6.19.14/fs/xfs/scrub/dirtree.h 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 going
 11 * 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 being
 38 * scanned.  These exist in-core, and hopefully there aren't more than a
 39 * 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 can
 85	 * continue to be called after xchk_teardown drops sc->ip but before
 86	 * 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 is
 92	 * the inode number of the surviving parent and the dotdot entry will
 93	 * be set to this value.  If the value is NULLFSINO, then use @root_ino
 94	 * 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 updates
111	 * 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 path
127	 * steps for a particular pathwalk are recorded in sequential
128	 * order in the xfarray.  A pathwalk ends either with a step
129	 * pointing to the root directory (success) or pointing to NULLFSINO
130	 * (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
159bool xchk_dirtree_parentless(const struct xchk_dirtree *dl);
160
161int xchk_dirtree_find_paths_to_root(struct xchk_dirtree *dl);
162int xchk_dirpath_append(struct xchk_dirtree *dl, struct xfs_inode *ip,
163		struct xchk_dirpath *path, const struct xfs_name *name,
164		const struct xfs_parent_rec *pptr);
165void xchk_dirtree_evaluate(struct xchk_dirtree *dl,
166		struct xchk_dirtree_outcomes *oc);
167
168#endif /* __XFS_SCRUB_DIRTREE_H__ */
~/ Read-only file preview.