Message ID | 20230118224505.1964941-24-david@fromorbit.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | xfs: per-ag centric allocation alogrithms | expand |
On Thu, Jan 19, 2023 at 09:44:46AM +1100, Dave Chinner wrote: > From: Dave Chinner <dchinner@redhat.com> > > Two of the callers to xfs_alloc_vextent_this_ag() actually want > exact block number allocation, not anywhere-in-ag allocation. Split > this out from _this_ag() as a first class citizen so no external > extent allocation code needs to care about args->type anymore. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > --- > fs/xfs/libxfs/xfs_ag.c | 6 ++-- > fs/xfs/libxfs/xfs_alloc.c | 65 ++++++++++++++++++++++++++++++++------ > fs/xfs/libxfs/xfs_alloc.h | 13 ++++++-- > fs/xfs/libxfs/xfs_bmap.c | 6 ++-- > fs/xfs/libxfs/xfs_ialloc.c | 6 ++-- > fs/xfs/scrub/repair.c | 4 +-- > 6 files changed, 73 insertions(+), 27 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c > index 053d77a283f7..86696a1c6891 100644 > --- a/fs/xfs/libxfs/xfs_ag.c > +++ b/fs/xfs/libxfs/xfs_ag.c > @@ -888,7 +888,6 @@ xfs_ag_shrink_space( > .tp = *tpp, > .mp = mp, > .pag = pag, > - .type = XFS_ALLOCTYPE_THIS_BNO, > .minlen = delta, > .maxlen = delta, > .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, > @@ -920,8 +919,6 @@ xfs_ag_shrink_space( > if (delta >= aglen) > return -EINVAL; > > - args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta); > - > /* > * Make sure that the last inode cluster cannot overlap with the new > * end of the AG, even if it's sparse. > @@ -939,7 +936,8 @@ xfs_ag_shrink_space( > return error; > > /* internal log shouldn't also show up in the free space btrees */ > - error = xfs_alloc_vextent_this_ag(&args); > + error = xfs_alloc_vextent_exact_bno(&args, > + XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta)); > if (!error && args.agbno == NULLAGBLOCK) > error = -ENOSPC; > > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c > index 485a73eab9d9..b810a94aad70 100644 > --- a/fs/xfs/libxfs/xfs_alloc.c > +++ b/fs/xfs/libxfs/xfs_alloc.c > @@ -3272,28 +3272,34 @@ xfs_alloc_vextent_set_fsbno( > */ > int > xfs_alloc_vextent_this_ag( > - struct xfs_alloc_arg *args) > + struct xfs_alloc_arg *args, > + xfs_agnumber_t agno) > { > struct xfs_mount *mp = args->mp; > xfs_agnumber_t minimum_agno = 0; > + xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); Same xfs_rfsblock_t vs. xfs_fsblock_t comment here too. These conversions look like a good improvement though -- it's very helpful that we can now look at an xfs_alloc_vextent_* call and know exactly which behavior we're getting. --D > int error; > > if (args->tp->t_highest_agno != NULLAGNUMBER) > minimum_agno = args->tp->t_highest_agno; > > - error = xfs_alloc_vextent_check_args(args, args->fsbno); > + if (minimum_agno > agno) { > + trace_xfs_alloc_vextent_skip_deadlock(args); > + args->fsbno = NULLFSBLOCK; > + return 0; > + } > + > + error = xfs_alloc_vextent_check_args(args, target); > if (error) { > if (error == -ENOSPC) > return 0; > return error; > } > > - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); > - if (minimum_agno > args->agno) { > - trace_xfs_alloc_vextent_skip_deadlock(args); > - args->fsbno = NULLFSBLOCK; > - return 0; > - } > + args->agno = agno; > + args->agbno = 0; > + args->fsbno = target; > + args->type = XFS_ALLOCTYPE_THIS_AG; > > error = xfs_alloc_ag_vextent(args); > xfs_alloc_vextent_set_fsbno(args, minimum_agno); > @@ -3450,7 +3456,7 @@ xfs_alloc_vextent_start_ag( > * pass, so will not recurse into AGs lower than indicated by fsbno. > */ > int > - xfs_alloc_vextent_first_ag( > +xfs_alloc_vextent_first_ag( > struct xfs_alloc_arg *args, > xfs_rfsblock_t target) > { > @@ -3472,12 +3478,51 @@ int > start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); > args->type = XFS_ALLOCTYPE_THIS_AG; > args->fsbno = target; > - error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, > + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, > start_agno, 0); > xfs_alloc_vextent_set_fsbno(args, minimum_agno); > return error; > } > > +/* > + * Allocate within a single AG only. > + */ > +int > +xfs_alloc_vextent_exact_bno( > + struct xfs_alloc_arg *args, > + xfs_rfsblock_t target) > +{ > + struct xfs_mount *mp = args->mp; > + xfs_agnumber_t minimum_agno = 0; > + int error; > + > + if (args->tp->t_highest_agno != NULLAGNUMBER) > + minimum_agno = args->tp->t_highest_agno; > + > + error = xfs_alloc_vextent_check_args(args, target); > + if (error) { > + if (error == -ENOSPC) > + return 0; > + return error; > + } > + > + args->agno = XFS_FSB_TO_AGNO(mp, target); > + if (minimum_agno > args->agno) { > + trace_xfs_alloc_vextent_skip_deadlock(args); > + return 0; > + } > + > + args->agbno = XFS_FSB_TO_AGBNO(mp, target); > + args->fsbno = target; > + args->type = XFS_ALLOCTYPE_THIS_BNO; > + error = xfs_alloc_ag_vextent(args); > + if (error) > + return error; > + > + xfs_alloc_vextent_set_fsbno(args, minimum_agno); > + return 0; > +} > + > /* > * Allocate an extent as close to the target as possible. If there are not > * viable candidates in the AG, then fail the allocation. > diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h > index f38a2f8e20fb..106b4deb1110 100644 > --- a/fs/xfs/libxfs/xfs_alloc.h > +++ b/fs/xfs/libxfs/xfs_alloc.h > @@ -114,10 +114,10 @@ xfs_alloc_log_agf( > uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ > > /* > - * Allocate an extent in the specific AG defined by args->fsbno. If there is no > - * space in that AG, then the allocation will fail. > + * Allocate an extent anywhere in the specific AG given. If there is no > + * space matching the requirements in that AG, then the allocation will fail. > */ > -int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); > +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); > > /* > * Allocate an extent as close to the target as possible. If there are not > @@ -126,6 +126,13 @@ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); > int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, > xfs_rfsblock_t target); > > +/* > + * Allocate an extent exactly at the target given. If this is not possible > + * then the allocation fails. > + */ > +int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args, > + xfs_rfsblock_t target); > + > /* > * Best effort full filesystem allocation scan. > * > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 4446b035eed5..c9902df16e25 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -3514,7 +3514,6 @@ xfs_bmap_btalloc_at_eof( > xfs_extlen_t nextminlen = 0; > > atype = args->type; > - args->type = XFS_ALLOCTYPE_THIS_BNO; > args->alignment = 1; > > /* > @@ -3532,8 +3531,8 @@ xfs_bmap_btalloc_at_eof( > else > args->minalignslop = 0; > > - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); > - error = xfs_alloc_vextent_this_ag(args); > + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); > + error = xfs_alloc_vextent_exact_bno(args, ap->blkno); > xfs_perag_put(args->pag); > if (error) > return error; > @@ -3546,7 +3545,6 @@ xfs_bmap_btalloc_at_eof( > */ > args->pag = NULL; > args->type = atype; > - args->fsbno = ap->blkno; > args->alignment = stripe_align; > args->minlen = nextminlen; > args->minalignslop = 0; > diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c > index daa6f7055bba..d2525f0cc6cd 100644 > --- a/fs/xfs/libxfs/xfs_ialloc.c > +++ b/fs/xfs/libxfs/xfs_ialloc.c > @@ -662,8 +662,6 @@ xfs_ialloc_ag_alloc( > goto sparse_alloc; > if (likely(newino != NULLAGINO && > (args.agbno < be32_to_cpu(agi->agi_length)))) { > - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); > - args.type = XFS_ALLOCTYPE_THIS_BNO; > args.prod = 1; > > /* > @@ -684,7 +682,9 @@ xfs_ialloc_ag_alloc( > > /* Allow space for the inode btree to split. */ > args.minleft = igeo->inobt_maxlevels; > - error = xfs_alloc_vextent_this_ag(&args); > + error = xfs_alloc_vextent_exact_bno(&args, > + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, > + args.agbno)); > if (error) > return error; > > diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c > index 5f4b50aac4bb..1b71174ec0d6 100644 > --- a/fs/xfs/scrub/repair.c > +++ b/fs/xfs/scrub/repair.c > @@ -328,14 +328,12 @@ xrep_alloc_ag_block( > args.mp = sc->mp; > args.pag = sc->sa.pag; > args.oinfo = *oinfo; > - args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); > args.minlen = 1; > args.maxlen = 1; > args.prod = 1; > - args.type = XFS_ALLOCTYPE_THIS_AG; > args.resv = resv; > > - error = xfs_alloc_vextent_this_ag(&args); > + error = xfs_alloc_vextent_this_ag(&args, sc->sa.pag->pag_agno); > if (error) > return error; > if (args.fsbno == NULLFSBLOCK) > -- > 2.39.0 >
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 053d77a283f7..86696a1c6891 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -888,7 +888,6 @@ xfs_ag_shrink_space( .tp = *tpp, .mp = mp, .pag = pag, - .type = XFS_ALLOCTYPE_THIS_BNO, .minlen = delta, .maxlen = delta, .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE, @@ -920,8 +919,6 @@ xfs_ag_shrink_space( if (delta >= aglen) return -EINVAL; - args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta); - /* * Make sure that the last inode cluster cannot overlap with the new * end of the AG, even if it's sparse. @@ -939,7 +936,8 @@ xfs_ag_shrink_space( return error; /* internal log shouldn't also show up in the free space btrees */ - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta)); if (!error && args.agbno == NULLAGBLOCK) error = -ENOSPC; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 485a73eab9d9..b810a94aad70 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -3272,28 +3272,34 @@ xfs_alloc_vextent_set_fsbno( */ int xfs_alloc_vextent_this_ag( - struct xfs_alloc_arg *args) + struct xfs_alloc_arg *args, + xfs_agnumber_t agno) { struct xfs_mount *mp = args->mp; xfs_agnumber_t minimum_agno = 0; + xfs_rfsblock_t target = XFS_AGB_TO_FSB(mp, agno, 0); int error; if (args->tp->t_highest_agno != NULLAGNUMBER) minimum_agno = args->tp->t_highest_agno; - error = xfs_alloc_vextent_check_args(args, args->fsbno); + if (minimum_agno > agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + args->fsbno = NULLFSBLOCK; + return 0; + } + + error = xfs_alloc_vextent_check_args(args, target); if (error) { if (error == -ENOSPC) return 0; return error; } - args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); - if (minimum_agno > args->agno) { - trace_xfs_alloc_vextent_skip_deadlock(args); - args->fsbno = NULLFSBLOCK; - return 0; - } + args->agno = agno; + args->agbno = 0; + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_AG; error = xfs_alloc_ag_vextent(args); xfs_alloc_vextent_set_fsbno(args, minimum_agno); @@ -3450,7 +3456,7 @@ xfs_alloc_vextent_start_ag( * pass, so will not recurse into AGs lower than indicated by fsbno. */ int - xfs_alloc_vextent_first_ag( +xfs_alloc_vextent_first_ag( struct xfs_alloc_arg *args, xfs_rfsblock_t target) { @@ -3472,12 +3478,51 @@ int start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target)); args->type = XFS_ALLOCTYPE_THIS_AG; args->fsbno = target; - error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, + error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, 0); xfs_alloc_vextent_set_fsbno(args, minimum_agno); return error; } +/* + * Allocate within a single AG only. + */ +int +xfs_alloc_vextent_exact_bno( + struct xfs_alloc_arg *args, + xfs_rfsblock_t target) +{ + struct xfs_mount *mp = args->mp; + xfs_agnumber_t minimum_agno = 0; + int error; + + if (args->tp->t_highest_agno != NULLAGNUMBER) + minimum_agno = args->tp->t_highest_agno; + + error = xfs_alloc_vextent_check_args(args, target); + if (error) { + if (error == -ENOSPC) + return 0; + return error; + } + + args->agno = XFS_FSB_TO_AGNO(mp, target); + if (minimum_agno > args->agno) { + trace_xfs_alloc_vextent_skip_deadlock(args); + return 0; + } + + args->agbno = XFS_FSB_TO_AGBNO(mp, target); + args->fsbno = target; + args->type = XFS_ALLOCTYPE_THIS_BNO; + error = xfs_alloc_ag_vextent(args); + if (error) + return error; + + xfs_alloc_vextent_set_fsbno(args, minimum_agno); + return 0; +} + /* * Allocate an extent as close to the target as possible. If there are not * viable candidates in the AG, then fail the allocation. diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index f38a2f8e20fb..106b4deb1110 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -114,10 +114,10 @@ xfs_alloc_log_agf( uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ /* - * Allocate an extent in the specific AG defined by args->fsbno. If there is no - * space in that AG, then the allocation will fail. + * Allocate an extent anywhere in the specific AG given. If there is no + * space matching the requirements in that AG, then the allocation will fail. */ -int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); +int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); /* * Allocate an extent as close to the target as possible. If there are not @@ -126,6 +126,13 @@ int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args); int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, xfs_rfsblock_t target); +/* + * Allocate an extent exactly at the target given. If this is not possible + * then the allocation fails. + */ +int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args, + xfs_rfsblock_t target); + /* * Best effort full filesystem allocation scan. * diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4446b035eed5..c9902df16e25 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3514,7 +3514,6 @@ xfs_bmap_btalloc_at_eof( xfs_extlen_t nextminlen = 0; atype = args->type; - args->type = XFS_ALLOCTYPE_THIS_BNO; args->alignment = 1; /* @@ -3532,8 +3531,8 @@ xfs_bmap_btalloc_at_eof( else args->minalignslop = 0; - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, args->fsbno)); - error = xfs_alloc_vextent_this_ag(args); + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); + error = xfs_alloc_vextent_exact_bno(args, ap->blkno); xfs_perag_put(args->pag); if (error) return error; @@ -3546,7 +3545,6 @@ xfs_bmap_btalloc_at_eof( */ args->pag = NULL; args->type = atype; - args->fsbno = ap->blkno; args->alignment = stripe_align; args->minlen = nextminlen; args->minalignslop = 0; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index daa6f7055bba..d2525f0cc6cd 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -662,8 +662,6 @@ xfs_ialloc_ag_alloc( goto sparse_alloc; if (likely(newino != NULLAGINO && (args.agbno < be32_to_cpu(agi->agi_length)))) { - args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno); - args.type = XFS_ALLOCTYPE_THIS_BNO; args.prod = 1; /* @@ -684,7 +682,9 @@ xfs_ialloc_ag_alloc( /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_exact_bno(&args, + XFS_AGB_TO_FSB(args.mp, pag->pag_agno, + args.agbno)); if (error) return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 5f4b50aac4bb..1b71174ec0d6 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -328,14 +328,12 @@ xrep_alloc_ag_block( args.mp = sc->mp; args.pag = sc->sa.pag; args.oinfo = *oinfo; - args.fsbno = XFS_AGB_TO_FSB(args.mp, sc->sa.pag->pag_agno, 0); args.minlen = 1; args.maxlen = 1; args.prod = 1; - args.type = XFS_ALLOCTYPE_THIS_AG; args.resv = resv; - error = xfs_alloc_vextent_this_ag(&args); + error = xfs_alloc_vextent_this_ag(&args, sc->sa.pag->pag_agno); if (error) return error; if (args.fsbno == NULLFSBLOCK)