Linux Audio

Check our new training course

Loading...
v5.4
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (C) 2017 Oracle.  All Rights Reserved.
  4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
  5 */
  6#ifndef __XFS_SCRUB_COMMON_H__
  7#define __XFS_SCRUB_COMMON_H__
  8
  9/*
 10 * We /could/ terminate a scrub/repair operation early.  If we're not
 11 * in a good place to continue (fatal signal, etc.) then bail out.
 12 * Note that we're careful not to make any judgements about *error.
 13 */
 14static inline bool
 15xchk_should_terminate(
 16	struct xfs_scrub	*sc,
 17	int				*error)
 18{
 19	if (fatal_signal_pending(current)) {
 20		if (*error == 0)
 21			*error = -EAGAIN;
 22		return true;
 23	}
 24	return false;
 25}
 26
 27int xchk_trans_alloc(struct xfs_scrub *sc, uint resblks);
 
 
 
 28bool xchk_process_error(struct xfs_scrub *sc, xfs_agnumber_t agno,
 29		xfs_agblock_t bno, int *error);
 
 
 30bool xchk_fblock_process_error(struct xfs_scrub *sc, int whichfork,
 31		xfs_fileoff_t offset, int *error);
 32
 33bool xchk_xref_process_error(struct xfs_scrub *sc,
 34		xfs_agnumber_t agno, xfs_agblock_t bno, int *error);
 35bool xchk_fblock_xref_process_error(struct xfs_scrub *sc,
 36		int whichfork, xfs_fileoff_t offset, int *error);
 37
 38void xchk_block_set_preen(struct xfs_scrub *sc,
 39		struct xfs_buf *bp);
 40void xchk_ino_set_preen(struct xfs_scrub *sc, xfs_ino_t ino);
 41
 42void xchk_set_corrupt(struct xfs_scrub *sc);
 43void xchk_block_set_corrupt(struct xfs_scrub *sc,
 44		struct xfs_buf *bp);
 45void xchk_ino_set_corrupt(struct xfs_scrub *sc, xfs_ino_t ino);
 46void xchk_fblock_set_corrupt(struct xfs_scrub *sc, int whichfork,
 47		xfs_fileoff_t offset);
 
 
 
 
 48
 49void xchk_block_xref_set_corrupt(struct xfs_scrub *sc,
 50		struct xfs_buf *bp);
 51void xchk_ino_xref_set_corrupt(struct xfs_scrub *sc,
 52		xfs_ino_t ino);
 53void xchk_fblock_xref_set_corrupt(struct xfs_scrub *sc,
 54		int whichfork, xfs_fileoff_t offset);
 55
 56void xchk_ino_set_warning(struct xfs_scrub *sc, xfs_ino_t ino);
 57void xchk_fblock_set_warning(struct xfs_scrub *sc, int whichfork,
 58		xfs_fileoff_t offset);
 59
 60void xchk_set_incomplete(struct xfs_scrub *sc);
 61int xchk_checkpoint_log(struct xfs_mount *mp);
 62
 63/* Are we set up for a cross-referencing check? */
 64bool xchk_should_check_xref(struct xfs_scrub *sc, int *error,
 65			   struct xfs_btree_cur **curpp);
 66
 67/* Setup functions */
 68int xchk_setup_fs(struct xfs_scrub *sc, struct xfs_inode *ip);
 69int xchk_setup_ag_allocbt(struct xfs_scrub *sc,
 70			       struct xfs_inode *ip);
 71int xchk_setup_ag_iallocbt(struct xfs_scrub *sc,
 72				struct xfs_inode *ip);
 73int xchk_setup_ag_rmapbt(struct xfs_scrub *sc,
 74			      struct xfs_inode *ip);
 75int xchk_setup_ag_refcountbt(struct xfs_scrub *sc,
 76				  struct xfs_inode *ip);
 77int xchk_setup_inode(struct xfs_scrub *sc,
 78			  struct xfs_inode *ip);
 79int xchk_setup_inode_bmap(struct xfs_scrub *sc,
 80			       struct xfs_inode *ip);
 81int xchk_setup_inode_bmap_data(struct xfs_scrub *sc,
 82				    struct xfs_inode *ip);
 83int xchk_setup_directory(struct xfs_scrub *sc,
 84			      struct xfs_inode *ip);
 85int xchk_setup_xattr(struct xfs_scrub *sc,
 86			  struct xfs_inode *ip);
 87int xchk_setup_symlink(struct xfs_scrub *sc,
 88			    struct xfs_inode *ip);
 89int xchk_setup_parent(struct xfs_scrub *sc,
 90			   struct xfs_inode *ip);
 91#ifdef CONFIG_XFS_RT
 92int xchk_setup_rt(struct xfs_scrub *sc, struct xfs_inode *ip);
 93#else
 94static inline int
 95xchk_setup_rt(struct xfs_scrub *sc, struct xfs_inode *ip)
 96{
 97	return -ENOENT;
 98}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 99#endif
100#ifdef CONFIG_XFS_QUOTA
101int xchk_setup_quota(struct xfs_scrub *sc, struct xfs_inode *ip);
 
 
102#else
103static inline int
104xchk_setup_quota(struct xfs_scrub *sc, struct xfs_inode *ip)
105{
106	return -ENOENT;
107}
 
 
108#endif
109int xchk_setup_fscounters(struct xfs_scrub *sc, struct xfs_inode *ip);
 
110
111void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa);
112int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno,
113		struct xchk_ag *sa);
114void xchk_perag_get(struct xfs_mount *mp, struct xchk_ag *sa);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno,
116		struct xfs_buf **agi, struct xfs_buf **agf,
117		struct xfs_buf **agfl);
118void xchk_ag_btcur_free(struct xchk_ag *sa);
119int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa);
120int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
121		const struct xfs_owner_info *oinfo, xfs_filblks_t *blocks);
122
123int xchk_setup_ag_btree(struct xfs_scrub *sc, struct xfs_inode *ip,
124		bool force_log);
125int xchk_get_inode(struct xfs_scrub *sc, struct xfs_inode *ip_in);
126int xchk_setup_inode_contents(struct xfs_scrub *sc, struct xfs_inode *ip,
127		unsigned int resblks);
 
 
 
 
128void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp);
129
130/*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131 * Don't bother cross-referencing if we already found corruption or cross
132 * referencing discrepancies.
133 */
134static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm)
135{
136	return sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
137			       XFS_SCRUB_OFLAG_XCORRUPT);
138}
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140int xchk_metadata_inode_forks(struct xfs_scrub *sc);
141int xchk_ilock_inverted(struct xfs_inode *ip, uint lock_mode);
142void xchk_stop_reaping(struct xfs_scrub *sc);
143void xchk_start_reaping(struct xfs_scrub *sc);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
145#endif	/* __XFS_SCRUB_COMMON_H__ */
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
  4 * Author: Darrick J. Wong <djwong@kernel.org>
  5 */
  6#ifndef __XFS_SCRUB_COMMON_H__
  7#define __XFS_SCRUB_COMMON_H__
  8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  9int xchk_trans_alloc(struct xfs_scrub *sc, uint resblks);
 10int xchk_trans_alloc_empty(struct xfs_scrub *sc);
 11void xchk_trans_cancel(struct xfs_scrub *sc);
 12
 13bool xchk_process_error(struct xfs_scrub *sc, xfs_agnumber_t agno,
 14		xfs_agblock_t bno, int *error);
 15bool xchk_process_rt_error(struct xfs_scrub *sc, xfs_rgnumber_t rgno,
 16		xfs_rgblock_t rgbno, int *error);
 17bool xchk_fblock_process_error(struct xfs_scrub *sc, int whichfork,
 18		xfs_fileoff_t offset, int *error);
 19
 20bool xchk_xref_process_error(struct xfs_scrub *sc,
 21		xfs_agnumber_t agno, xfs_agblock_t bno, int *error);
 22bool xchk_fblock_xref_process_error(struct xfs_scrub *sc,
 23		int whichfork, xfs_fileoff_t offset, int *error);
 24
 25void xchk_block_set_preen(struct xfs_scrub *sc,
 26		struct xfs_buf *bp);
 27void xchk_ino_set_preen(struct xfs_scrub *sc, xfs_ino_t ino);
 28
 29void xchk_set_corrupt(struct xfs_scrub *sc);
 30void xchk_block_set_corrupt(struct xfs_scrub *sc,
 31		struct xfs_buf *bp);
 32void xchk_ino_set_corrupt(struct xfs_scrub *sc, xfs_ino_t ino);
 33void xchk_fblock_set_corrupt(struct xfs_scrub *sc, int whichfork,
 34		xfs_fileoff_t offset);
 35#ifdef CONFIG_XFS_QUOTA
 36void xchk_qcheck_set_corrupt(struct xfs_scrub *sc, unsigned int dqtype,
 37		xfs_dqid_t id);
 38#endif
 39
 40void xchk_block_xref_set_corrupt(struct xfs_scrub *sc,
 41		struct xfs_buf *bp);
 42void xchk_ino_xref_set_corrupt(struct xfs_scrub *sc,
 43		xfs_ino_t ino);
 44void xchk_fblock_xref_set_corrupt(struct xfs_scrub *sc,
 45		int whichfork, xfs_fileoff_t offset);
 46
 47void xchk_ino_set_warning(struct xfs_scrub *sc, xfs_ino_t ino);
 48void xchk_fblock_set_warning(struct xfs_scrub *sc, int whichfork,
 49		xfs_fileoff_t offset);
 50
 51void xchk_set_incomplete(struct xfs_scrub *sc);
 52int xchk_checkpoint_log(struct xfs_mount *mp);
 53
 54/* Are we set up for a cross-referencing check? */
 55bool xchk_should_check_xref(struct xfs_scrub *sc, int *error,
 56			   struct xfs_btree_cur **curpp);
 57
 58static inline int xchk_setup_nothing(struct xfs_scrub *sc)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 59{
 60	return -ENOENT;
 61}
 62
 63/* Setup functions */
 64int xchk_setup_agheader(struct xfs_scrub *sc);
 65int xchk_setup_fs(struct xfs_scrub *sc);
 66int xchk_setup_ag_allocbt(struct xfs_scrub *sc);
 67int xchk_setup_ag_iallocbt(struct xfs_scrub *sc);
 68int xchk_setup_ag_rmapbt(struct xfs_scrub *sc);
 69int xchk_setup_ag_refcountbt(struct xfs_scrub *sc);
 70int xchk_setup_inode(struct xfs_scrub *sc);
 71int xchk_setup_inode_bmap(struct xfs_scrub *sc);
 72int xchk_setup_inode_bmap_data(struct xfs_scrub *sc);
 73int xchk_setup_directory(struct xfs_scrub *sc);
 74int xchk_setup_xattr(struct xfs_scrub *sc);
 75int xchk_setup_symlink(struct xfs_scrub *sc);
 76int xchk_setup_parent(struct xfs_scrub *sc);
 77int xchk_setup_dirtree(struct xfs_scrub *sc);
 78int xchk_setup_metapath(struct xfs_scrub *sc);
 79#ifdef CONFIG_XFS_RT
 80int xchk_setup_rtbitmap(struct xfs_scrub *sc);
 81int xchk_setup_rtsummary(struct xfs_scrub *sc);
 82int xchk_setup_rgsuperblock(struct xfs_scrub *sc);
 83#else
 84# define xchk_setup_rtbitmap		xchk_setup_nothing
 85# define xchk_setup_rtsummary		xchk_setup_nothing
 86# define xchk_setup_rgsuperblock	xchk_setup_nothing
 87#endif
 88#ifdef CONFIG_XFS_QUOTA
 89int xchk_ino_dqattach(struct xfs_scrub *sc);
 90int xchk_setup_quota(struct xfs_scrub *sc);
 91int xchk_setup_quotacheck(struct xfs_scrub *sc);
 92#else
 93static inline int
 94xchk_ino_dqattach(struct xfs_scrub *sc)
 95{
 96	return 0;
 97}
 98# define xchk_setup_quota		xchk_setup_nothing
 99# define xchk_setup_quotacheck		xchk_setup_nothing
100#endif
101int xchk_setup_fscounters(struct xfs_scrub *sc);
102int xchk_setup_nlinks(struct xfs_scrub *sc);
103
104void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa);
105int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno,
106		struct xchk_ag *sa);
107int xchk_perag_drain_and_lock(struct xfs_scrub *sc);
108
109/*
110 * Grab all AG resources, treating the inability to grab the perag structure as
111 * a fs corruption.  This is intended for callers checking an ondisk reference
112 * to a given AG, which means that the AG must still exist.
113 */
114static inline int
115xchk_ag_init_existing(
116	struct xfs_scrub	*sc,
117	xfs_agnumber_t		agno,
118	struct xchk_ag		*sa)
119{
120	int			error = xchk_ag_init(sc, agno, sa);
121
122	return error == -ENOENT ? -EFSCORRUPTED : error;
123}
124
125#ifdef CONFIG_XFS_RT
126
127/* All the locks we need to check an rtgroup. */
128#define XCHK_RTGLOCK_ALL	(XFS_RTGLOCK_BITMAP)
129
130int xchk_rtgroup_init(struct xfs_scrub *sc, xfs_rgnumber_t rgno,
131		struct xchk_rt *sr);
132
133static inline int
134xchk_rtgroup_init_existing(
135	struct xfs_scrub	*sc,
136	xfs_rgnumber_t		rgno,
137	struct xchk_rt		*sr)
138{
139	int			error = xchk_rtgroup_init(sc, rgno, sr);
140
141	return error == -ENOENT ? -EFSCORRUPTED : error;
142}
143
144void xchk_rtgroup_lock(struct xchk_rt *sr, unsigned int rtglock_flags);
145void xchk_rtgroup_free(struct xfs_scrub *sc, struct xchk_rt *sr);
146#else
147# define xchk_rtgroup_init(sc, rgno, sr)		(-EFSCORRUPTED)
148# define xchk_rtgroup_init_existing(sc, rgno, sr)	(-EFSCORRUPTED)
149# define xchk_rtgroup_lock(sc, lockflags)		do { } while (0)
150# define xchk_rtgroup_free(sc, sr)			do { } while (0)
151#endif /* CONFIG_XFS_RT */
152
153int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno,
154		struct xchk_ag *sa);
 
155void xchk_ag_btcur_free(struct xchk_ag *sa);
156void xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa);
157int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
158		const struct xfs_owner_info *oinfo, xfs_filblks_t *blocks);
159
160int xchk_setup_ag_btree(struct xfs_scrub *sc, bool force_log);
161int xchk_iget_for_scrubbing(struct xfs_scrub *sc);
162int xchk_setup_inode_contents(struct xfs_scrub *sc, unsigned int resblks);
163int xchk_install_live_inode(struct xfs_scrub *sc, struct xfs_inode *ip);
164
165void xchk_ilock(struct xfs_scrub *sc, unsigned int ilock_flags);
166bool xchk_ilock_nowait(struct xfs_scrub *sc, unsigned int ilock_flags);
167void xchk_iunlock(struct xfs_scrub *sc, unsigned int ilock_flags);
168
169void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp);
170
171/*
172 * Grab the inode at @inum.  The caller must have created a scrub transaction
173 * so that we can confirm the inumber by walking the inobt and not deadlock on
174 * a loop in the inobt.
175 */
176int xchk_iget(struct xfs_scrub *sc, xfs_ino_t inum, struct xfs_inode **ipp);
177int xchk_iget_agi(struct xfs_scrub *sc, xfs_ino_t inum,
178		struct xfs_buf **agi_bpp, struct xfs_inode **ipp);
179void xchk_irele(struct xfs_scrub *sc, struct xfs_inode *ip);
180int xchk_install_handle_inode(struct xfs_scrub *sc, struct xfs_inode *ip);
181
182/*
183 * Safe version of (untrusted) xchk_iget that uses an empty transaction to
184 * avoid deadlocking on loops in the inobt.  This should only be used in a
185 * scrub or repair setup routine, and only prior to grabbing a transaction.
186 */
187static inline int
188xchk_iget_safe(struct xfs_scrub *sc, xfs_ino_t inum, struct xfs_inode **ipp)
189{
190	int	error;
191
192	ASSERT(sc->tp == NULL);
193
194	error = xchk_trans_alloc(sc, 0);
195	if (error)
196		return error;
197	error = xchk_iget(sc, inum, ipp);
198	xchk_trans_cancel(sc);
199	return error;
200}
201
202/*
203 * Don't bother cross-referencing if we already found corruption or cross
204 * referencing discrepancies.
205 */
206static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm)
207{
208	return sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
209			       XFS_SCRUB_OFLAG_XCORRUPT);
210}
211
212bool xchk_dir_looks_zapped(struct xfs_inode *dp);
213bool xchk_pptr_looks_zapped(struct xfs_inode *ip);
214
215/* Decide if a repair is required. */
216static inline bool xchk_needs_repair(const struct xfs_scrub_metadata *sm)
217{
218	return sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
219			       XFS_SCRUB_OFLAG_XCORRUPT |
220			       XFS_SCRUB_OFLAG_PREEN);
221}
222
223/*
224 * "Should we prepare for a repair?"
225 *
226 * Return true if the caller permits us to repair metadata and we're not
227 * setting up for a post-repair evaluation.
228 */
229static inline bool xchk_could_repair(const struct xfs_scrub *sc)
230{
231	return (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR) &&
232		!(sc->flags & XREP_ALREADY_FIXED);
233}
234
235int xchk_metadata_inode_forks(struct xfs_scrub *sc);
236
237/*
238 * Helper macros to allocate and format xfile description strings.
239 * Callers must kfree the pointer returned.
240 */
241#define xchk_xfile_descr(sc, fmt, ...) \
242	kasprintf(XCHK_GFP_FLAGS, "XFS (%s): " fmt, \
243			(sc)->mp->m_super->s_id, ##__VA_ARGS__)
244#define xchk_xfile_ag_descr(sc, fmt, ...) \
245	kasprintf(XCHK_GFP_FLAGS, "XFS (%s): AG 0x%x " fmt, \
246			(sc)->mp->m_super->s_id, \
247			(sc)->sa.pag ? \
248				pag_agno((sc)->sa.pag) : (sc)->sm->sm_agno, \
249			##__VA_ARGS__)
250#define xchk_xfile_ino_descr(sc, fmt, ...) \
251	kasprintf(XCHK_GFP_FLAGS, "XFS (%s): inode 0x%llx " fmt, \
252			(sc)->mp->m_super->s_id, \
253			(sc)->ip ? (sc)->ip->i_ino : (sc)->sm->sm_ino, \
254			##__VA_ARGS__)
255
256/*
257 * Setting up a hook to wait for intents to drain is costly -- we have to take
258 * the CPU hotplug lock and force an i-cache flush on all CPUs once to set it
259 * up, and again to tear it down.  These costs add up quickly, so we only want
260 * to enable the drain waiter if the drain actually detected a conflict with
261 * running intent chains.
262 */
263static inline bool xchk_need_intent_drain(struct xfs_scrub *sc)
264{
265	return sc->flags & XCHK_NEED_DRAIN;
266}
267
268void xchk_fsgates_enable(struct xfs_scrub *sc, unsigned int scrub_fshooks);
269
270int xchk_inode_is_allocated(struct xfs_scrub *sc, xfs_agino_t agino,
271		bool *inuse);
272
273bool xchk_inode_is_dirtree_root(const struct xfs_inode *ip);
274bool xchk_inode_is_sb_rooted(const struct xfs_inode *ip);
275xfs_ino_t xchk_inode_rootdir_inum(const struct xfs_inode *ip);
276
277#endif	/* __XFS_SCRUB_COMMON_H__ */