2018-06-06 05:42:14 +03:00
// SPDX-License-Identifier: GPL-2.0+
2017-10-18 07:37:34 +03: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 22:29:12 +03:00
struct xfs_scrub ;
2017-10-18 07:37:35 +03:00
2018-01-08 21:41:34 +03:00
/* Type info and names for the scrub types. */
2018-07-19 22:29:11 +03:00
enum xchk_type {
2018-01-08 21:41:34 +03:00
ST_NONE = 1 , /* disabled */
ST_PERAG , /* per-AG metadata */
ST_FS , /* per-FS metadata */
ST_INODE , /* per-inode metadata */
} ;
2018-07-19 22:29:11 +03:00
struct xchk_meta_ops {
2017-10-18 07:37:35 +03:00
/* Acquire whatever resources are needed for the operation. */
2018-07-19 22:29:12 +03:00
int ( * setup ) ( struct xfs_scrub * ,
2017-10-18 07:37:35 +03:00
struct xfs_inode * ) ;
/* Examine metadata for errors. */
2018-07-19 22:29:12 +03:00
int ( * scrub ) ( struct xfs_scrub * ) ;
2017-10-18 07:37:35 +03:00
2018-05-14 16:34:36 +03:00
/* Repair or optimize the metadata. */
2018-07-19 22:29:12 +03:00
int ( * repair ) ( struct xfs_scrub * ) ;
2018-05-14 16:34:36 +03:00
2017-10-18 07:37:35 +03:00
/* Decide if we even have this piece of metadata. */
bool ( * has ) ( struct xfs_sb * ) ;
2018-01-08 21:41:34 +03:00
/* type describing required/allowed inputs */
2018-07-19 22:29:11 +03:00
enum xchk_type type ;
2017-10-18 07:37:35 +03:00
} ;
2017-10-18 07:37:38 +03:00
/* Buffer pointers and btree cursors for an entire AG. */
2018-07-19 22:29:11 +03:00
struct xchk_ag {
2018-07-19 22:29:12 +03:00
xfs_agnumber_t agno ;
struct xfs_perag * pag ;
2017-10-18 07:37:38 +03:00
/* AG btree roots */
2018-07-19 22:29:12 +03:00
struct xfs_buf * agf_bp ;
struct xfs_buf * agfl_bp ;
struct xfs_buf * agi_bp ;
2017-10-18 07:37:38 +03:00
/* AG btrees */
2018-07-19 22:29:12 +03: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-18 07:37:38 +03:00
} ;
2018-07-19 22:29:12 +03:00
struct xfs_scrub {
2017-10-18 07:37:35 +03:00
/* General scrub state. */
struct xfs_mount * mp ;
struct xfs_scrub_metadata * sm ;
2018-07-19 22:29:11 +03:00
const struct xchk_meta_ops * ops ;
2017-10-18 07:37:35 +03:00
struct xfs_trans * tp ;
struct xfs_inode * ip ;
2017-10-18 07:37:45 +03:00
void * buf ;
2017-10-18 07:37:42 +03:00
uint ilock_flags ;
2017-10-18 07:37:35 +03:00
bool try_harder ;
2018-05-09 20:02:00 +03:00
bool has_quotaofflock ;
2017-10-18 07:37:38 +03:00
/* State tracking for single-AG operations. */
2018-07-19 22:29:12 +03:00
struct xchk_ag sa ;
2017-10-18 07:37:35 +03:00
} ;
2017-10-18 07:37:34 +03:00
/* Metadata scrubbers */
2018-07-19 22:29:12 +03: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-18 07:37:46 +03:00
# ifdef CONFIG_XFS_RT
2018-07-19 22:29:12 +03:00
int xchk_rtbitmap ( struct xfs_scrub * sc ) ;
int xchk_rtsummary ( struct xfs_scrub * sc ) ;
2017-10-18 07:37:46 +03:00
# else
static inline int
2018-07-19 22:29:12 +03:00
xchk_rtbitmap ( struct xfs_scrub * sc )
2017-10-18 07:37:46 +03:00
{
return - ENOENT ;
}
static inline int
2018-07-19 22:29:12 +03:00
xchk_rtsummary ( struct xfs_scrub * sc )
2017-10-18 07:37:46 +03:00
{
return - ENOENT ;
}
# endif
2017-10-18 07:37:47 +03:00
# ifdef CONFIG_XFS_QUOTA
2018-07-19 22:29:12 +03:00
int xchk_quota ( struct xfs_scrub * sc ) ;
2017-10-18 07:37:47 +03:00
# else
static inline int
2018-07-19 22:29:12 +03:00
xchk_quota ( struct xfs_scrub * sc )
2017-10-18 07:37:47 +03:00
{
return - ENOENT ;
}
# endif
2017-10-18 07:37:34 +03:00
2018-01-17 05:53:06 +03:00
/* cross-referencing helpers */
2018-07-19 22:29:12 +03: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 19:46:23 +03:00
xfs_extlen_t len , const struct xfs_owner_info * oinfo ) ;
2018-07-19 22:29:12 +03:00
void xchk_xref_is_not_owned_by ( struct xfs_scrub * sc , xfs_agblock_t agbno ,
2018-12-12 19:46:23 +03:00
xfs_extlen_t len , const struct xfs_owner_info * oinfo ) ;
2018-07-19 22:29:12 +03: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-17 05:53:10 +03:00
# ifdef CONFIG_XFS_RT
2018-07-19 22:29:12 +03:00
void xchk_xref_is_used_rt_space ( struct xfs_scrub * sc , xfs_rtblock_t rtbno ,
xfs_extlen_t len ) ;
2018-01-17 05:53:10 +03:00
# else
2018-07-19 22:29:11 +03:00
# define xchk_xref_is_used_rt_space(sc, rtbno, len) do { } while (0)
2018-01-17 05:53:10 +03:00
# endif
2018-01-17 05:53:06 +03:00
2017-10-18 07:37:34 +03:00
# endif /* __XFS_SCRUB_SCRUB_H__ */