2018-06-05 19:42:14 -07:00
// SPDX-License-Identifier: GPL-2.0+
2017-10-17 21:37:34 -07:00
/*
* Copyright ( C ) 2017 Oracle . All Rights Reserved .
* Author : Darrick J . Wong < darrick . wong @ oracle . com >
*/
# ifndef __XFS_SCRUB_SCRUB_H__
# define __XFS_SCRUB_SCRUB_H__
2018-07-19 12:29:12 -07:00
struct xfs_scrub ;
2017-10-17 21:37:35 -07:00
2018-01-08 10:41:34 -08:00
/* Type info and names for the scrub types. */
2018-07-19 12:29:11 -07:00
enum xchk_type {
2018-01-08 10:41:34 -08:00
ST_NONE = 1 , /* disabled */
ST_PERAG , /* per-AG metadata */
ST_FS , /* per-FS metadata */
ST_INODE , /* per-inode metadata */
} ;
2018-07-19 12:29:11 -07:00
struct xchk_meta_ops {
2017-10-17 21:37:35 -07:00
/* Acquire whatever resources are needed for the operation. */
2018-07-19 12:29:12 -07:00
int ( * setup ) ( struct xfs_scrub * ,
2017-10-17 21:37:35 -07:00
struct xfs_inode * ) ;
/* Examine metadata for errors. */
2018-07-19 12:29:12 -07:00
int ( * scrub ) ( struct xfs_scrub * ) ;
2017-10-17 21:37:35 -07:00
2018-05-14 06:34:36 -07:00
/* Repair or optimize the metadata. */
2018-07-19 12:29:12 -07:00
int ( * repair ) ( struct xfs_scrub * ) ;
2018-05-14 06:34:36 -07:00
2017-10-17 21:37:35 -07:00
/* Decide if we even have this piece of metadata. */
bool ( * has ) ( struct xfs_sb * ) ;
2018-01-08 10:41:34 -08:00
/* type describing required/allowed inputs */
2018-07-19 12:29:11 -07:00
enum xchk_type type ;
2017-10-17 21:37:35 -07:00
} ;
2017-10-17 21:37:38 -07:00
/* Buffer pointers and btree cursors for an entire AG. */
2018-07-19 12:29:11 -07:00
struct xchk_ag {
2018-07-19 12:29:12 -07:00
xfs_agnumber_t agno ;
struct xfs_perag * pag ;
2017-10-17 21:37:38 -07:00
/* AG btree roots */
2018-07-19 12:29:12 -07:00
struct xfs_buf * agf_bp ;
struct xfs_buf * agfl_bp ;
struct xfs_buf * agi_bp ;
2017-10-17 21:37:38 -07:00
/* AG btrees */
2018-07-19 12:29:12 -07:00
struct xfs_btree_cur * bno_cur ;
struct xfs_btree_cur * cnt_cur ;
struct xfs_btree_cur * ino_cur ;
struct xfs_btree_cur * fino_cur ;
struct xfs_btree_cur * rmap_cur ;
struct xfs_btree_cur * refc_cur ;
2017-10-17 21:37:38 -07:00
} ;
2018-07-19 12:29:12 -07:00
struct xfs_scrub {
2017-10-17 21:37:35 -07:00
/* General scrub state. */
struct xfs_mount * mp ;
struct xfs_scrub_metadata * sm ;
2018-07-19 12:29:11 -07:00
const struct xchk_meta_ops * ops ;
2017-10-17 21:37:35 -07:00
struct xfs_trans * tp ;
struct xfs_inode * ip ;
2017-10-17 21:37:45 -07:00
void * buf ;
2017-10-17 21:37:42 -07:00
uint ilock_flags ;
2019-04-16 08:21:59 -07:00
2019-04-16 08:22:00 -07:00
/* See the XCHK/XREP state flags below. */
2019-04-16 08:21:59 -07:00
unsigned int flags ;
2017-10-17 21:37:38 -07:00
2019-04-16 08:22:00 -07:00
/*
* The XFS_SICK_ * flags that correspond to the metadata being scrubbed
* or repaired . We will use this mask to update the in - core fs health
* status with whatever we find .
*/
unsigned int sick_mask ;
2017-10-17 21:37:38 -07:00
/* State tracking for single-AG operations. */
2018-07-19 12:29:12 -07:00
struct xchk_ag sa ;
2017-10-17 21:37:35 -07:00
} ;
2019-04-16 08:22:00 -07:00
/* XCHK state flags grow up from zero, XREP state flags grown down from 2^31 */
2019-04-16 08:21:59 -07:00
# define XCHK_TRY_HARDER (1 << 0) /* can't get resources, try again */
# define XCHK_HAS_QUOTAOFFLOCK (1 << 1) /* we hold the quotaoff lock */
2019-04-25 18:26:23 -07:00
# define XCHK_REAPING_DISABLED (1 << 2) /* background block reaping paused */
2019-04-16 08:22:00 -07:00
# define XREP_ALREADY_FIXED (1 << 31) /* checking our repair work */
2019-04-16 08:21:59 -07:00
2017-10-17 21:37:34 -07:00
/* Metadata scrubbers */
2018-07-19 12:29:12 -07:00
int xchk_tester ( struct xfs_scrub * sc ) ;
int xchk_superblock ( struct xfs_scrub * sc ) ;
int xchk_agf ( struct xfs_scrub * sc ) ;
int xchk_agfl ( struct xfs_scrub * sc ) ;
int xchk_agi ( struct xfs_scrub * sc ) ;
int xchk_bnobt ( struct xfs_scrub * sc ) ;
int xchk_cntbt ( struct xfs_scrub * sc ) ;
int xchk_inobt ( struct xfs_scrub * sc ) ;
int xchk_finobt ( struct xfs_scrub * sc ) ;
int xchk_rmapbt ( struct xfs_scrub * sc ) ;
int xchk_refcountbt ( struct xfs_scrub * sc ) ;
int xchk_inode ( struct xfs_scrub * sc ) ;
int xchk_bmap_data ( struct xfs_scrub * sc ) ;
int xchk_bmap_attr ( struct xfs_scrub * sc ) ;
int xchk_bmap_cow ( struct xfs_scrub * sc ) ;
int xchk_directory ( struct xfs_scrub * sc ) ;
int xchk_xattr ( struct xfs_scrub * sc ) ;
int xchk_symlink ( struct xfs_scrub * sc ) ;
int xchk_parent ( struct xfs_scrub * sc ) ;
2017-10-17 21:37:46 -07:00
# ifdef CONFIG_XFS_RT
2018-07-19 12:29:12 -07:00
int xchk_rtbitmap ( struct xfs_scrub * sc ) ;
int xchk_rtsummary ( struct xfs_scrub * sc ) ;
2017-10-17 21:37:46 -07:00
# else
static inline int
2018-07-19 12:29:12 -07:00
xchk_rtbitmap ( struct xfs_scrub * sc )
2017-10-17 21:37:46 -07:00
{
return - ENOENT ;
}
static inline int
2018-07-19 12:29:12 -07:00
xchk_rtsummary ( struct xfs_scrub * sc )
2017-10-17 21:37:46 -07:00
{
return - ENOENT ;
}
# endif
2017-10-17 21:37:47 -07:00
# ifdef CONFIG_XFS_QUOTA
2018-07-19 12:29:12 -07:00
int xchk_quota ( struct xfs_scrub * sc ) ;
2017-10-17 21:37:47 -07:00
# else
static inline int
2018-07-19 12:29:12 -07:00
xchk_quota ( struct xfs_scrub * sc )
2017-10-17 21:37:47 -07:00
{
return - ENOENT ;
}
# endif
2019-04-25 18:26:24 -07:00
int xchk_fscounters ( struct xfs_scrub * sc ) ;
2017-10-17 21:37:34 -07:00
2018-01-16 18:53:06 -08:00
/* cross-referencing helpers */
2018-07-19 12:29:12 -07:00
void xchk_xref_is_used_space ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
xfs_extlen_t len ) ;
void xchk_xref_is_not_inode_chunk ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
xfs_extlen_t len ) ;
void xchk_xref_is_inode_chunk ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
xfs_extlen_t len ) ;
void xchk_xref_is_owned_by ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
2018-12-12 08:46:23 -08:00
xfs_extlen_t len , const struct xfs_owner_info * oinfo ) ;
2018-07-19 12:29:12 -07:00
void xchk_xref_is_not_owned_by ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
2018-12-12 08:46:23 -08:00
xfs_extlen_t len , const struct xfs_owner_info * oinfo ) ;
2018-07-19 12:29:12 -07:00
void xchk_xref_has_no_owner ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
xfs_extlen_t len ) ;
void xchk_xref_is_cow_staging ( struct xfs_scrub * sc , xfs_agblock_t bno ,
xfs_extlen_t len ) ;
void xchk_xref_is_not_shared ( struct xfs_scrub * sc , xfs_agblock_t bno ,
xfs_extlen_t len ) ;
2018-01-16 18:53:10 -08:00
# ifdef CONFIG_XFS_RT
2018-07-19 12:29:12 -07:00
void xchk_xref_is_used_rt_space ( struct xfs_scrub * sc , xfs_rtblock_t rtbno ,
xfs_extlen_t len ) ;
2018-01-16 18:53:10 -08:00
# else
2018-07-19 12:29:11 -07:00
# define xchk_xref_is_used_rt_space(sc, rtbno, len) do { } while (0)
2018-01-16 18:53:10 -08:00
# endif
2018-01-16 18:53:06 -08:00
2019-04-25 18:26:24 -07:00
struct xchk_fscounters {
uint64_t icount ;
uint64_t ifree ;
uint64_t fdblocks ;
unsigned long long icount_min ;
unsigned long long icount_max ;
} ;
2017-10-17 21:37:34 -07:00
# endif /* __XFS_SCRUB_SCRUB_H__ */