18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Oracle. All Rights Reserved. 48c2ecf20Sopenharmony_ci * Author: Darrick J. Wong <darrick.wong@oracle.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#ifndef __XFS_SCRUB_SCRUB_H__ 78c2ecf20Sopenharmony_ci#define __XFS_SCRUB_SCRUB_H__ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct xfs_scrub; 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* Type info and names for the scrub types. */ 128c2ecf20Sopenharmony_cienum xchk_type { 138c2ecf20Sopenharmony_ci ST_NONE = 1, /* disabled */ 148c2ecf20Sopenharmony_ci ST_PERAG, /* per-AG metadata */ 158c2ecf20Sopenharmony_ci ST_FS, /* per-FS metadata */ 168c2ecf20Sopenharmony_ci ST_INODE, /* per-inode metadata */ 178c2ecf20Sopenharmony_ci}; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistruct xchk_meta_ops { 208c2ecf20Sopenharmony_ci /* Acquire whatever resources are needed for the operation. */ 218c2ecf20Sopenharmony_ci int (*setup)(struct xfs_scrub *, 228c2ecf20Sopenharmony_ci struct xfs_inode *); 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci /* Examine metadata for errors. */ 258c2ecf20Sopenharmony_ci int (*scrub)(struct xfs_scrub *); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci /* Repair or optimize the metadata. */ 288c2ecf20Sopenharmony_ci int (*repair)(struct xfs_scrub *); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci /* Decide if we even have this piece of metadata. */ 318c2ecf20Sopenharmony_ci bool (*has)(struct xfs_sb *); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci /* type describing required/allowed inputs */ 348c2ecf20Sopenharmony_ci enum xchk_type type; 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* Buffer pointers and btree cursors for an entire AG. */ 388c2ecf20Sopenharmony_cistruct xchk_ag { 398c2ecf20Sopenharmony_ci xfs_agnumber_t agno; 408c2ecf20Sopenharmony_ci struct xfs_perag *pag; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci /* AG btree roots */ 438c2ecf20Sopenharmony_ci struct xfs_buf *agf_bp; 448c2ecf20Sopenharmony_ci struct xfs_buf *agfl_bp; 458c2ecf20Sopenharmony_ci struct xfs_buf *agi_bp; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci /* AG btrees */ 488c2ecf20Sopenharmony_ci struct xfs_btree_cur *bno_cur; 498c2ecf20Sopenharmony_ci struct xfs_btree_cur *cnt_cur; 508c2ecf20Sopenharmony_ci struct xfs_btree_cur *ino_cur; 518c2ecf20Sopenharmony_ci struct xfs_btree_cur *fino_cur; 528c2ecf20Sopenharmony_ci struct xfs_btree_cur *rmap_cur; 538c2ecf20Sopenharmony_ci struct xfs_btree_cur *refc_cur; 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistruct xfs_scrub { 578c2ecf20Sopenharmony_ci /* General scrub state. */ 588c2ecf20Sopenharmony_ci struct xfs_mount *mp; 598c2ecf20Sopenharmony_ci struct xfs_scrub_metadata *sm; 608c2ecf20Sopenharmony_ci const struct xchk_meta_ops *ops; 618c2ecf20Sopenharmony_ci struct xfs_trans *tp; 628c2ecf20Sopenharmony_ci struct xfs_inode *ip; 638c2ecf20Sopenharmony_ci void *buf; 648c2ecf20Sopenharmony_ci uint ilock_flags; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* See the XCHK/XREP state flags below. */ 678c2ecf20Sopenharmony_ci unsigned int flags; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci /* 708c2ecf20Sopenharmony_ci * The XFS_SICK_* flags that correspond to the metadata being scrubbed 718c2ecf20Sopenharmony_ci * or repaired. We will use this mask to update the in-core fs health 728c2ecf20Sopenharmony_ci * status with whatever we find. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci unsigned int sick_mask; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci /* State tracking for single-AG operations. */ 778c2ecf20Sopenharmony_ci struct xchk_ag sa; 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci/* XCHK state flags grow up from zero, XREP state flags grown down from 2^31 */ 818c2ecf20Sopenharmony_ci#define XCHK_TRY_HARDER (1 << 0) /* can't get resources, try again */ 828c2ecf20Sopenharmony_ci#define XCHK_HAS_QUOTAOFFLOCK (1 << 1) /* we hold the quotaoff lock */ 838c2ecf20Sopenharmony_ci#define XCHK_REAPING_DISABLED (1 << 2) /* background block reaping paused */ 848c2ecf20Sopenharmony_ci#define XREP_ALREADY_FIXED (1 << 31) /* checking our repair work */ 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* Metadata scrubbers */ 878c2ecf20Sopenharmony_ciint xchk_tester(struct xfs_scrub *sc); 888c2ecf20Sopenharmony_ciint xchk_superblock(struct xfs_scrub *sc); 898c2ecf20Sopenharmony_ciint xchk_agf(struct xfs_scrub *sc); 908c2ecf20Sopenharmony_ciint xchk_agfl(struct xfs_scrub *sc); 918c2ecf20Sopenharmony_ciint xchk_agi(struct xfs_scrub *sc); 928c2ecf20Sopenharmony_ciint xchk_bnobt(struct xfs_scrub *sc); 938c2ecf20Sopenharmony_ciint xchk_cntbt(struct xfs_scrub *sc); 948c2ecf20Sopenharmony_ciint xchk_inobt(struct xfs_scrub *sc); 958c2ecf20Sopenharmony_ciint xchk_finobt(struct xfs_scrub *sc); 968c2ecf20Sopenharmony_ciint xchk_rmapbt(struct xfs_scrub *sc); 978c2ecf20Sopenharmony_ciint xchk_refcountbt(struct xfs_scrub *sc); 988c2ecf20Sopenharmony_ciint xchk_inode(struct xfs_scrub *sc); 998c2ecf20Sopenharmony_ciint xchk_bmap_data(struct xfs_scrub *sc); 1008c2ecf20Sopenharmony_ciint xchk_bmap_attr(struct xfs_scrub *sc); 1018c2ecf20Sopenharmony_ciint xchk_bmap_cow(struct xfs_scrub *sc); 1028c2ecf20Sopenharmony_ciint xchk_directory(struct xfs_scrub *sc); 1038c2ecf20Sopenharmony_ciint xchk_xattr(struct xfs_scrub *sc); 1048c2ecf20Sopenharmony_ciint xchk_symlink(struct xfs_scrub *sc); 1058c2ecf20Sopenharmony_ciint xchk_parent(struct xfs_scrub *sc); 1068c2ecf20Sopenharmony_ci#ifdef CONFIG_XFS_RT 1078c2ecf20Sopenharmony_ciint xchk_rtbitmap(struct xfs_scrub *sc); 1088c2ecf20Sopenharmony_ciint xchk_rtsummary(struct xfs_scrub *sc); 1098c2ecf20Sopenharmony_ci#else 1108c2ecf20Sopenharmony_cistatic inline int 1118c2ecf20Sopenharmony_cixchk_rtbitmap(struct xfs_scrub *sc) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci return -ENOENT; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_cistatic inline int 1168c2ecf20Sopenharmony_cixchk_rtsummary(struct xfs_scrub *sc) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci return -ENOENT; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci#endif 1218c2ecf20Sopenharmony_ci#ifdef CONFIG_XFS_QUOTA 1228c2ecf20Sopenharmony_ciint xchk_quota(struct xfs_scrub *sc); 1238c2ecf20Sopenharmony_ci#else 1248c2ecf20Sopenharmony_cistatic inline int 1258c2ecf20Sopenharmony_cixchk_quota(struct xfs_scrub *sc) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci return -ENOENT; 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci#endif 1308c2ecf20Sopenharmony_ciint xchk_fscounters(struct xfs_scrub *sc); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci/* cross-referencing helpers */ 1338c2ecf20Sopenharmony_civoid xchk_xref_is_used_space(struct xfs_scrub *sc, xfs_agblock_t agbno, 1348c2ecf20Sopenharmony_ci xfs_extlen_t len); 1358c2ecf20Sopenharmony_civoid xchk_xref_is_not_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, 1368c2ecf20Sopenharmony_ci xfs_extlen_t len); 1378c2ecf20Sopenharmony_civoid xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, 1388c2ecf20Sopenharmony_ci xfs_extlen_t len); 1398c2ecf20Sopenharmony_civoid xchk_xref_is_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, 1408c2ecf20Sopenharmony_ci xfs_extlen_t len, const struct xfs_owner_info *oinfo); 1418c2ecf20Sopenharmony_civoid xchk_xref_is_not_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, 1428c2ecf20Sopenharmony_ci xfs_extlen_t len, const struct xfs_owner_info *oinfo); 1438c2ecf20Sopenharmony_civoid xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno, 1448c2ecf20Sopenharmony_ci xfs_extlen_t len); 1458c2ecf20Sopenharmony_civoid xchk_xref_is_cow_staging(struct xfs_scrub *sc, xfs_agblock_t bno, 1468c2ecf20Sopenharmony_ci xfs_extlen_t len); 1478c2ecf20Sopenharmony_civoid xchk_xref_is_not_shared(struct xfs_scrub *sc, xfs_agblock_t bno, 1488c2ecf20Sopenharmony_ci xfs_extlen_t len); 1498c2ecf20Sopenharmony_ci#ifdef CONFIG_XFS_RT 1508c2ecf20Sopenharmony_civoid xchk_xref_is_used_rt_space(struct xfs_scrub *sc, xfs_rtblock_t rtbno, 1518c2ecf20Sopenharmony_ci xfs_extlen_t len); 1528c2ecf20Sopenharmony_ci#else 1538c2ecf20Sopenharmony_ci# define xchk_xref_is_used_rt_space(sc, rtbno, len) do { } while (0) 1548c2ecf20Sopenharmony_ci#endif 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistruct xchk_fscounters { 1578c2ecf20Sopenharmony_ci uint64_t icount; 1588c2ecf20Sopenharmony_ci uint64_t ifree; 1598c2ecf20Sopenharmony_ci uint64_t fdblocks; 1608c2ecf20Sopenharmony_ci unsigned long long icount_min; 1618c2ecf20Sopenharmony_ci unsigned long long icount_max; 1628c2ecf20Sopenharmony_ci}; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci#endif /* __XFS_SCRUB_SCRUB_H__ */ 165