Commit 5b572570 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: hoist AGI repair context to a heap object

Save ~460 bytes of stack space by moving all the repair context to a
heap object.  We're going to add even more context data in the next
patch, which is why we really need to do this now.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 10d587ec
...@@ -796,15 +796,29 @@ enum { ...@@ -796,15 +796,29 @@ enum {
XREP_AGI_MAX XREP_AGI_MAX
}; };
struct xrep_agi {
struct xfs_scrub *sc;
/* AGI buffer, tracked separately */
struct xfs_buf *agi_bp;
/* context for finding btree roots */
struct xrep_find_ag_btree fab[XREP_AGI_MAX];
/* old AGI contents in case we have to revert */
struct xfs_agi old_agi;
};
/* /*
* Given the inode btree roots described by *fab, find the roots, check them * Given the inode btree roots described by *fab, find the roots, check them
* for sanity, and pass the root data back out via *fab. * for sanity, and pass the root data back out via *fab.
*/ */
STATIC int STATIC int
xrep_agi_find_btrees( xrep_agi_find_btrees(
struct xfs_scrub *sc, struct xrep_agi *ragi)
struct xrep_find_ag_btree *fab)
{ {
struct xfs_scrub *sc = ragi->sc;
struct xrep_find_ag_btree *fab = ragi->fab;
struct xfs_buf *agf_bp; struct xfs_buf *agf_bp;
struct xfs_mount *mp = sc->mp; struct xfs_mount *mp = sc->mp;
int error; int error;
...@@ -837,10 +851,11 @@ xrep_agi_find_btrees( ...@@ -837,10 +851,11 @@ xrep_agi_find_btrees(
*/ */
STATIC void STATIC void
xrep_agi_init_header( xrep_agi_init_header(
struct xfs_scrub *sc, struct xrep_agi *ragi)
struct xfs_buf *agi_bp,
struct xfs_agi *old_agi)
{ {
struct xfs_scrub *sc = ragi->sc;
struct xfs_buf *agi_bp = ragi->agi_bp;
struct xfs_agi *old_agi = &ragi->old_agi;
struct xfs_agi *agi = agi_bp->b_addr; struct xfs_agi *agi = agi_bp->b_addr;
struct xfs_perag *pag = sc->sa.pag; struct xfs_perag *pag = sc->sa.pag;
struct xfs_mount *mp = sc->mp; struct xfs_mount *mp = sc->mp;
...@@ -868,10 +883,12 @@ xrep_agi_init_header( ...@@ -868,10 +883,12 @@ xrep_agi_init_header(
/* Set btree root information in an AGI. */ /* Set btree root information in an AGI. */
STATIC void STATIC void
xrep_agi_set_roots( xrep_agi_set_roots(
struct xfs_scrub *sc, struct xrep_agi *ragi)
struct xfs_agi *agi,
struct xrep_find_ag_btree *fab)
{ {
struct xfs_scrub *sc = ragi->sc;
struct xfs_agi *agi = ragi->agi_bp->b_addr;
struct xrep_find_ag_btree *fab = ragi->fab;
agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root); agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root);
agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height); agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height);
...@@ -884,9 +901,10 @@ xrep_agi_set_roots( ...@@ -884,9 +901,10 @@ xrep_agi_set_roots(
/* Update the AGI counters. */ /* Update the AGI counters. */
STATIC int STATIC int
xrep_agi_calc_from_btrees( xrep_agi_calc_from_btrees(
struct xfs_scrub *sc, struct xrep_agi *ragi)
struct xfs_buf *agi_bp)
{ {
struct xfs_scrub *sc = ragi->sc;
struct xfs_buf *agi_bp = ragi->agi_bp;
struct xfs_btree_cur *cur; struct xfs_btree_cur *cur;
struct xfs_agi *agi = agi_bp->b_addr; struct xfs_agi *agi = agi_bp->b_addr;
struct xfs_mount *mp = sc->mp; struct xfs_mount *mp = sc->mp;
...@@ -931,9 +949,10 @@ xrep_agi_calc_from_btrees( ...@@ -931,9 +949,10 @@ xrep_agi_calc_from_btrees(
/* Trigger reinitialization of the in-core data. */ /* Trigger reinitialization of the in-core data. */
STATIC int STATIC int
xrep_agi_commit_new( xrep_agi_commit_new(
struct xfs_scrub *sc, struct xrep_agi *ragi)
struct xfs_buf *agi_bp)
{ {
struct xfs_scrub *sc = ragi->sc;
struct xfs_buf *agi_bp = ragi->agi_bp;
struct xfs_perag *pag; struct xfs_perag *pag;
struct xfs_agi *agi = agi_bp->b_addr; struct xfs_agi *agi = agi_bp->b_addr;
...@@ -958,30 +977,33 @@ int ...@@ -958,30 +977,33 @@ int
xrep_agi( xrep_agi(
struct xfs_scrub *sc) struct xfs_scrub *sc)
{ {
struct xrep_find_ag_btree fab[XREP_AGI_MAX] = { struct xrep_agi *ragi;
[XREP_AGI_INOBT] = { struct xfs_mount *mp = sc->mp;
int error;
/* We require the rmapbt to rebuild anything. */
if (!xfs_has_rmapbt(mp))
return -EOPNOTSUPP;
sc->buf = kzalloc(sizeof(struct xrep_agi), XCHK_GFP_FLAGS);
if (!sc->buf)
return -ENOMEM;
ragi = sc->buf;
ragi->sc = sc;
ragi->fab[XREP_AGI_INOBT] = (struct xrep_find_ag_btree){
.rmap_owner = XFS_RMAP_OWN_INOBT, .rmap_owner = XFS_RMAP_OWN_INOBT,
.buf_ops = &xfs_inobt_buf_ops, .buf_ops = &xfs_inobt_buf_ops,
.maxlevels = M_IGEO(sc->mp)->inobt_maxlevels, .maxlevels = M_IGEO(sc->mp)->inobt_maxlevels,
}, };
[XREP_AGI_FINOBT] = { ragi->fab[XREP_AGI_FINOBT] = (struct xrep_find_ag_btree){
.rmap_owner = XFS_RMAP_OWN_INOBT, .rmap_owner = XFS_RMAP_OWN_INOBT,
.buf_ops = &xfs_finobt_buf_ops, .buf_ops = &xfs_finobt_buf_ops,
.maxlevels = M_IGEO(sc->mp)->inobt_maxlevels, .maxlevels = M_IGEO(sc->mp)->inobt_maxlevels,
},
[XREP_AGI_END] = {
.buf_ops = NULL
},
}; };
struct xfs_agi old_agi; ragi->fab[XREP_AGI_END] = (struct xrep_find_ag_btree){
struct xfs_mount *mp = sc->mp; .buf_ops = NULL,
struct xfs_buf *agi_bp; };
struct xfs_agi *agi;
int error;
/* We require the rmapbt to rebuild anything. */
if (!xfs_has_rmapbt(mp))
return -EOPNOTSUPP;
/* /*
* Make sure we have the AGI buffer, as scrub might have decided it * Make sure we have the AGI buffer, as scrub might have decided it
...@@ -990,14 +1012,13 @@ xrep_agi( ...@@ -990,14 +1012,13 @@ xrep_agi(
error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp, error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, sc->sa.pag->pag_agno, XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
XFS_AGI_DADDR(mp)), XFS_AGI_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), 0, &agi_bp, NULL); XFS_FSS_TO_BB(mp, 1), 0, &ragi->agi_bp, NULL);
if (error) if (error)
return error; return error;
agi_bp->b_ops = &xfs_agi_buf_ops; ragi->agi_bp->b_ops = &xfs_agi_buf_ops;
agi = agi_bp->b_addr;
/* Find the AGI btree roots. */ /* Find the AGI btree roots. */
error = xrep_agi_find_btrees(sc, fab); error = xrep_agi_find_btrees(ragi);
if (error) if (error)
return error; return error;
...@@ -1006,18 +1027,18 @@ xrep_agi( ...@@ -1006,18 +1027,18 @@ xrep_agi(
return error; return error;
/* Start rewriting the header and implant the btrees we found. */ /* Start rewriting the header and implant the btrees we found. */
xrep_agi_init_header(sc, agi_bp, &old_agi); xrep_agi_init_header(ragi);
xrep_agi_set_roots(sc, agi, fab); xrep_agi_set_roots(ragi);
error = xrep_agi_calc_from_btrees(sc, agi_bp); error = xrep_agi_calc_from_btrees(ragi);
if (error) if (error)
goto out_revert; goto out_revert;
/* Reinitialize in-core state. */ /* Reinitialize in-core state. */
return xrep_agi_commit_new(sc, agi_bp); return xrep_agi_commit_new(ragi);
out_revert: out_revert:
/* Mark the incore AGI state stale and revert the AGI. */ /* Mark the incore AGI state stale and revert the AGI. */
clear_bit(XFS_AGSTATE_AGI_INIT, &sc->sa.pag->pag_opstate); clear_bit(XFS_AGSTATE_AGI_INIT, &sc->sa.pag->pag_opstate);
memcpy(agi, &old_agi, sizeof(old_agi)); memcpy(ragi->agi_bp->b_addr, &ragi->old_agi, sizeof(struct xfs_agi));
return error; return error;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment