mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
xfs: refactor the btree cursor allocation logic in xchk_ag_btcur_init
Change xchk_ag_btcur_init to allocate all cursors first and only then check if we should delete them again because the btree is to damaged. This allows reusing the sick_mask in struct xfs_btree_ops and simplifies the code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
7f47734ad6
commit
4803992619
@ -588,46 +588,50 @@ xchk_ag_btcur_init(
|
||||
{
|
||||
struct xfs_mount *mp = sc->mp;
|
||||
|
||||
if (sa->agf_bp &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_BNO)) {
|
||||
if (sa->agf_bp) {
|
||||
/* Set up a bnobt cursor for cross-referencing. */
|
||||
sa->bno_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
|
||||
sa->pag, XFS_BTNUM_BNO);
|
||||
}
|
||||
xchk_ag_btree_del_cursor_if_sick(sc, &sa->bno_cur,
|
||||
XFS_SCRUB_TYPE_BNOBT);
|
||||
|
||||
if (sa->agf_bp &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_CNT)) {
|
||||
/* Set up a cntbt cursor for cross-referencing. */
|
||||
sa->cnt_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
|
||||
sa->pag, XFS_BTNUM_CNT);
|
||||
xchk_ag_btree_del_cursor_if_sick(sc, &sa->cnt_cur,
|
||||
XFS_SCRUB_TYPE_CNTBT);
|
||||
|
||||
/* Set up a rmapbt cursor for cross-referencing. */
|
||||
if (xfs_has_rmapbt(mp)) {
|
||||
sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp,
|
||||
sa->agf_bp, sa->pag);
|
||||
xchk_ag_btree_del_cursor_if_sick(sc, &sa->rmap_cur,
|
||||
XFS_SCRUB_TYPE_RMAPBT);
|
||||
}
|
||||
|
||||
/* Set up a refcountbt cursor for cross-referencing. */
|
||||
if (xfs_has_reflink(mp)) {
|
||||
sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
|
||||
sa->agf_bp, sa->pag);
|
||||
xchk_ag_btree_del_cursor_if_sick(sc, &sa->refc_cur,
|
||||
XFS_SCRUB_TYPE_REFCNTBT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up a inobt cursor for cross-referencing. */
|
||||
if (sa->agi_bp &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) {
|
||||
if (sa->agi_bp) {
|
||||
/* Set up a inobt cursor for cross-referencing. */
|
||||
sa->ino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp,
|
||||
XFS_BTNUM_INO);
|
||||
}
|
||||
xchk_ag_btree_del_cursor_if_sick(sc, &sa->ino_cur,
|
||||
XFS_SCRUB_TYPE_INOBT);
|
||||
|
||||
/* Set up a finobt cursor for cross-referencing. */
|
||||
if (sa->agi_bp && xfs_has_finobt(mp) &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) {
|
||||
sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp,
|
||||
XFS_BTNUM_FINO);
|
||||
}
|
||||
|
||||
/* Set up a rmapbt cursor for cross-referencing. */
|
||||
if (sa->agf_bp && xfs_has_rmapbt(mp) &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_RMAP)) {
|
||||
sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp,
|
||||
sa->pag);
|
||||
}
|
||||
|
||||
/* Set up a refcountbt cursor for cross-referencing. */
|
||||
if (sa->agf_bp && xfs_has_reflink(mp) &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) {
|
||||
sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
|
||||
sa->agf_bp, sa->pag);
|
||||
/* Set up a finobt cursor for cross-referencing. */
|
||||
if (xfs_has_finobt(mp)) {
|
||||
sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp,
|
||||
sa->agi_bp, XFS_BTNUM_FINO);
|
||||
xchk_ag_btree_del_cursor_if_sick(sc, &sa->fino_cur,
|
||||
XFS_SCRUB_TYPE_FINOBT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,13 +248,13 @@ xchk_update_health(
|
||||
}
|
||||
|
||||
/* Is the given per-AG btree healthy enough for scanning? */
|
||||
bool
|
||||
xchk_ag_btree_healthy_enough(
|
||||
void
|
||||
xchk_ag_btree_del_cursor_if_sick(
|
||||
struct xfs_scrub *sc,
|
||||
struct xfs_perag *pag,
|
||||
xfs_btnum_t btnum)
|
||||
struct xfs_btree_cur **curp,
|
||||
unsigned int sm_type)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
unsigned int mask = (*curp)->bc_ops->sick_mask;
|
||||
|
||||
/*
|
||||
* We always want the cursor if it's the same type as whatever we're
|
||||
@ -263,41 +263,8 @@ xchk_ag_btree_healthy_enough(
|
||||
* Otherwise, we're only interested in the btree for cross-referencing.
|
||||
* If we know the btree is bad then don't bother, just set XFAIL.
|
||||
*/
|
||||
switch (btnum) {
|
||||
case XFS_BTNUM_BNO:
|
||||
if (sc->sm->sm_type == XFS_SCRUB_TYPE_BNOBT)
|
||||
return true;
|
||||
mask = XFS_SICK_AG_BNOBT;
|
||||
break;
|
||||
case XFS_BTNUM_CNT:
|
||||
if (sc->sm->sm_type == XFS_SCRUB_TYPE_CNTBT)
|
||||
return true;
|
||||
mask = XFS_SICK_AG_CNTBT;
|
||||
break;
|
||||
case XFS_BTNUM_INO:
|
||||
if (sc->sm->sm_type == XFS_SCRUB_TYPE_INOBT)
|
||||
return true;
|
||||
mask = XFS_SICK_AG_INOBT;
|
||||
break;
|
||||
case XFS_BTNUM_FINO:
|
||||
if (sc->sm->sm_type == XFS_SCRUB_TYPE_FINOBT)
|
||||
return true;
|
||||
mask = XFS_SICK_AG_FINOBT;
|
||||
break;
|
||||
case XFS_BTNUM_RMAP:
|
||||
if (sc->sm->sm_type == XFS_SCRUB_TYPE_RMAPBT)
|
||||
return true;
|
||||
mask = XFS_SICK_AG_RMAPBT;
|
||||
break;
|
||||
case XFS_BTNUM_REFC:
|
||||
if (sc->sm->sm_type == XFS_SCRUB_TYPE_REFCNTBT)
|
||||
return true;
|
||||
mask = XFS_SICK_AG_REFCNTBT;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return true;
|
||||
}
|
||||
if (sc->sm->sm_type == sm_type)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we just repaired some AG metadata, sc->sick_mask will reflect all
|
||||
@ -309,12 +276,11 @@ xchk_ag_btree_healthy_enough(
|
||||
type_to_health_flag[sc->sm->sm_type].group == XHG_AG)
|
||||
mask &= ~sc->sick_mask;
|
||||
|
||||
if (xfs_ag_has_sickness(pag, mask)) {
|
||||
if (xfs_ag_has_sickness((*curp)->bc_ag.pag, mask)) {
|
||||
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XFAIL;
|
||||
return false;
|
||||
xfs_btree_del_cursor(*curp, XFS_BTREE_NOERROR);
|
||||
*curp = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
unsigned int xchk_health_mask_for_scrub_type(__u32 scrub_type);
|
||||
void xchk_update_health(struct xfs_scrub *sc);
|
||||
bool xchk_ag_btree_healthy_enough(struct xfs_scrub *sc, struct xfs_perag *pag,
|
||||
xfs_btnum_t btnum);
|
||||
void xchk_ag_btree_del_cursor_if_sick(struct xfs_scrub *sc,
|
||||
struct xfs_btree_cur **curp, unsigned int sm_type);
|
||||
void xchk_mark_healthy_if_clean(struct xfs_scrub *sc, unsigned int mask);
|
||||
bool xchk_file_looks_zapped(struct xfs_scrub *sc, unsigned int mask);
|
||||
int xchk_health_record(struct xfs_scrub *sc);
|
||||
|
Loading…
Reference in New Issue
Block a user