On Mon, Mar 16, 2020 at 08:29:42AM -0400, Brian Foster wrote: > On Sun, Mar 15, 2020 at 04:51:06PM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > > > Add support for btree staging cursors for the free space btrees. This > > is needed both for online repair and also to convert xfs_repair to use > > btree bulk loading. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > --- > > fs/xfs/libxfs/xfs_alloc_btree.c | 98 +++++++++++++++++++++++++++++++-------- > > fs/xfs/libxfs/xfs_alloc_btree.h | 7 +++ > > 2 files changed, 86 insertions(+), 19 deletions(-) > > > > > > diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c > > index a28041fdf4c0..93792ee7924e 100644 > > --- a/fs/xfs/libxfs/xfs_alloc_btree.c > > +++ b/fs/xfs/libxfs/xfs_alloc_btree.c > ... > > @@ -485,36 +520,61 @@ xfs_allocbt_init_cursor( > ... > > > > +/* > > + * Install a new free space btree root. Caller is responsible for invalidating > > + * and freeing the old btree blocks. > > + */ > > +void > > +xfs_allocbt_commit_staged_btree( > > + struct xfs_btree_cur *cur, > > + struct xfs_trans *tp, > > + struct xfs_buf *agbp) > > +{ > > + struct xfs_agf *agf = agbp->b_addr; > > + struct xbtree_afakeroot *afake = cur->bc_ag.afake; > > + > > + ASSERT(cur->bc_flags & XFS_BTREE_STAGING); > > + > > + agf->agf_roots[cur->bc_btnum] = cpu_to_be32(afake->af_root); > > + agf->agf_levels[cur->bc_btnum] = cpu_to_be32(afake->af_levels); > > + xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); > > + > > + if (cur->bc_btnum == XFS_BTNUM_BNO) { > > + xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_bnobt_ops); > > + } else { > > + cur->bc_flags |= XFS_BTREE_LASTREC_UPDATE; > > Any reason this is set here and not at init time for the staging cursor? Originally it was so that ->update_lastrec couldn't get called, but since you're not supposed to be calling the regular btree operations anyway I suppose it doesn't matter if the flag is set in staging cursors... will fix. --D > Brian > > > + xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_cntbt_ops); > > + } > > +} > > + > > /* > > * Calculate number of records in an alloc btree block. > > */ > > diff --git a/fs/xfs/libxfs/xfs_alloc_btree.h b/fs/xfs/libxfs/xfs_alloc_btree.h > > index c9305ebb69f6..047f09f0be3c 100644 > > --- a/fs/xfs/libxfs/xfs_alloc_btree.h > > +++ b/fs/xfs/libxfs/xfs_alloc_btree.h > > @@ -13,6 +13,7 @@ > > struct xfs_buf; > > struct xfs_btree_cur; > > struct xfs_mount; > > +struct xbtree_afakeroot; > > > > /* > > * Btree block header size depends on a superblock flag. > > @@ -48,8 +49,14 @@ struct xfs_mount; > > extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *, > > struct xfs_trans *, struct xfs_buf *, > > xfs_agnumber_t, xfs_btnum_t); > > +struct xfs_btree_cur *xfs_allocbt_stage_cursor(struct xfs_mount *mp, > > + struct xbtree_afakeroot *afake, xfs_agnumber_t agno, > > + xfs_btnum_t btnum); > > extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int); > > extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp, > > unsigned long long len); > > > > +void xfs_allocbt_commit_staged_btree(struct xfs_btree_cur *cur, > > + struct xfs_trans *tp, struct xfs_buf *agbp); > > + > > #endif /* __XFS_ALLOC_BTREE_H__ */ > > >