mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-08 14:13:53 +00:00
xfs: use xfs_alloc_vextent_this_ag() where appropriate
Change obvious callers of single AG allocation to use xfs_alloc_vextent_this_ag(). Drive the per-ag grabbing out to the callers, too, so that callers with active references don't need to do new lookups just for an allocation in a context that already has a perag reference. The only remaining caller that does single AG allocation through xfs_alloc_vextent() is xfs_bmap_btalloc() with XFS_ALLOCTYPE_NEAR_BNO. That is going to need more untangling before it can be converted cleanly. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
4811c933ea
commit
74c36a8689
@ -887,6 +887,7 @@ xfs_ag_shrink_space(
|
||||
struct xfs_alloc_arg args = {
|
||||
.tp = *tpp,
|
||||
.mp = mp,
|
||||
.pag = pag,
|
||||
.type = XFS_ALLOCTYPE_THIS_BNO,
|
||||
.minlen = delta,
|
||||
.maxlen = delta,
|
||||
@ -938,7 +939,7 @@ xfs_ag_shrink_space(
|
||||
return error;
|
||||
|
||||
/* internal log shouldn't also show up in the free space btrees */
|
||||
error = xfs_alloc_vextent(&args);
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (!error && args.agbno == NULLAGBLOCK)
|
||||
error = -ENOSPC;
|
||||
|
||||
|
@ -2723,7 +2723,6 @@ xfs_alloc_fix_freelist(
|
||||
targs.agbp = agbp;
|
||||
targs.agno = args->agno;
|
||||
targs.alignment = targs.minlen = targs.prod = 1;
|
||||
targs.type = XFS_ALLOCTYPE_THIS_AG;
|
||||
targs.pag = pag;
|
||||
error = xfs_alloc_read_agfl(pag, tp, &agflbp);
|
||||
if (error)
|
||||
@ -3271,14 +3270,17 @@ xfs_alloc_vextent_set_fsbno(
|
||||
/*
|
||||
* Allocate within a single AG only.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
xfs_alloc_vextent_this_ag(
|
||||
struct xfs_alloc_arg *args,
|
||||
xfs_agnumber_t minimum_agno)
|
||||
struct xfs_alloc_arg *args)
|
||||
{
|
||||
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);
|
||||
if (error) {
|
||||
if (error == -ENOSPC)
|
||||
@ -3293,11 +3295,8 @@ xfs_alloc_vextent_this_ag(
|
||||
return 0;
|
||||
}
|
||||
|
||||
args->pag = xfs_perag_get(mp, args->agno);
|
||||
error = xfs_alloc_ag_vextent(args);
|
||||
|
||||
xfs_alloc_vextent_set_fsbno(args, minimum_agno);
|
||||
xfs_perag_put(args->pag);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -3480,6 +3479,7 @@ xfs_alloc_vextent(
|
||||
struct xfs_alloc_arg *args)
|
||||
{
|
||||
xfs_agnumber_t minimum_agno = 0;
|
||||
int error;
|
||||
|
||||
if (args->tp->t_highest_agno != NULLAGNUMBER)
|
||||
minimum_agno = args->tp->t_highest_agno;
|
||||
@ -3488,17 +3488,21 @@ xfs_alloc_vextent(
|
||||
case XFS_ALLOCTYPE_THIS_AG:
|
||||
case XFS_ALLOCTYPE_NEAR_BNO:
|
||||
case XFS_ALLOCTYPE_THIS_BNO:
|
||||
return xfs_alloc_vextent_this_ag(args, minimum_agno);
|
||||
args->pag = xfs_perag_get(args->mp,
|
||||
XFS_FSB_TO_AGNO(args->mp, args->fsbno));
|
||||
error = xfs_alloc_vextent_this_ag(args);
|
||||
xfs_perag_put(args->pag);
|
||||
break;
|
||||
case XFS_ALLOCTYPE_START_BNO:
|
||||
return xfs_alloc_vextent_start_ag(args, minimum_agno);
|
||||
case XFS_ALLOCTYPE_FIRST_AG:
|
||||
return xfs_alloc_vextent_first_ag(args, minimum_agno);
|
||||
default:
|
||||
error = -EFSCORRUPTED;
|
||||
ASSERT(0);
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
/* Should never get here */
|
||||
return -EFSCORRUPTED;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Ensure that the freelist is at full capacity. */
|
||||
|
@ -124,6 +124,12 @@ int /* error */
|
||||
xfs_alloc_vextent(
|
||||
xfs_alloc_arg_t *args); /* allocation argument structure */
|
||||
|
||||
/*
|
||||
* Allocate an extent in the specific AG defined by args->fsbno. If there is no
|
||||
* space in that AG, then the allocation will fail.
|
||||
*/
|
||||
int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args);
|
||||
|
||||
/*
|
||||
* Free an extent.
|
||||
*/
|
||||
|
@ -789,6 +789,8 @@ xfs_bmap_local_to_extents(
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.tp = tp;
|
||||
args.mp = ip->i_mount;
|
||||
args.total = total;
|
||||
args.minlen = args.maxlen = args.prod = 1;
|
||||
xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0);
|
||||
/*
|
||||
* Allocate a block. We know we need only one, since the
|
||||
@ -3506,8 +3508,7 @@ xfs_bmap_btalloc(
|
||||
xfs_extlen_t orig_length;
|
||||
xfs_extlen_t blen;
|
||||
xfs_extlen_t nextminlen = 0;
|
||||
int isaligned;
|
||||
int tryagain;
|
||||
int isaligned = 0;
|
||||
int error;
|
||||
int stripe_align;
|
||||
|
||||
@ -3528,7 +3529,6 @@ xfs_bmap_btalloc(
|
||||
|
||||
xfs_bmap_adjacent(ap);
|
||||
|
||||
tryagain = isaligned = 0;
|
||||
args.fsbno = ap->blkno;
|
||||
args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
|
||||
|
||||
@ -3576,9 +3576,9 @@ xfs_bmap_btalloc(
|
||||
* allocation with alignment turned on.
|
||||
*/
|
||||
atype = args.type;
|
||||
tryagain = 1;
|
||||
args.type = XFS_ALLOCTYPE_THIS_BNO;
|
||||
args.alignment = 1;
|
||||
|
||||
/*
|
||||
* Compute the minlen+alignment for the
|
||||
* next case. Set slop so that the value
|
||||
@ -3595,34 +3595,37 @@ xfs_bmap_btalloc(
|
||||
args.minlen - 1;
|
||||
else
|
||||
args.minalignslop = 0;
|
||||
|
||||
args.pag = xfs_perag_get(mp,
|
||||
XFS_FSB_TO_AGNO(mp, args.fsbno));
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
xfs_perag_put(args.pag);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (args.fsbno != NULLFSBLOCK)
|
||||
goto out_success;
|
||||
/*
|
||||
* Exact allocation failed. Now try with alignment
|
||||
* turned on.
|
||||
*/
|
||||
args.pag = NULL;
|
||||
args.type = atype;
|
||||
args.fsbno = ap->blkno;
|
||||
args.alignment = stripe_align;
|
||||
args.minlen = nextminlen;
|
||||
args.minalignslop = 0;
|
||||
isaligned = 1;
|
||||
}
|
||||
} else {
|
||||
args.alignment = 1;
|
||||
args.minalignslop = 0;
|
||||
}
|
||||
args.minleft = ap->minleft;
|
||||
args.wasdel = ap->wasdel;
|
||||
args.resv = XFS_AG_RESV_NONE;
|
||||
args.datatype = ap->datatype;
|
||||
|
||||
error = xfs_alloc_vextent(&args);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (tryagain && args.fsbno == NULLFSBLOCK) {
|
||||
/*
|
||||
* Exact allocation failed. Now try with alignment
|
||||
* turned on.
|
||||
*/
|
||||
args.type = atype;
|
||||
args.fsbno = ap->blkno;
|
||||
args.alignment = stripe_align;
|
||||
args.minlen = nextminlen;
|
||||
args.minalignslop = 0;
|
||||
isaligned = 1;
|
||||
if ((error = xfs_alloc_vextent(&args)))
|
||||
return error;
|
||||
}
|
||||
if (isaligned && args.fsbno == NULLFSBLOCK) {
|
||||
/*
|
||||
* allocation failed, so turn off alignment and
|
||||
@ -3650,8 +3653,13 @@ xfs_bmap_btalloc(
|
||||
return error;
|
||||
ap->tp->t_flags |= XFS_TRANS_LOWMODE;
|
||||
}
|
||||
args.minleft = ap->minleft;
|
||||
args.wasdel = ap->wasdel;
|
||||
args.resv = XFS_AG_RESV_NONE;
|
||||
args.datatype = ap->datatype;
|
||||
|
||||
if (args.fsbno != NULLFSBLOCK) {
|
||||
out_success:
|
||||
xfs_bmap_process_allocated_extent(ap, &args, orig_offset,
|
||||
orig_length);
|
||||
} else {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "xfs_quota.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_rmap.h"
|
||||
#include "xfs_ag.h"
|
||||
|
||||
static struct kmem_cache *xfs_bmbt_cur_cache;
|
||||
|
||||
@ -200,14 +201,18 @@ xfs_bmbt_alloc_block(
|
||||
union xfs_btree_ptr *new,
|
||||
int *stat)
|
||||
{
|
||||
xfs_alloc_arg_t args; /* block allocation args */
|
||||
int error; /* error return value */
|
||||
struct xfs_alloc_arg args;
|
||||
int error;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.tp = cur->bc_tp;
|
||||
args.mp = cur->bc_mp;
|
||||
xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_ino.ip->i_ino,
|
||||
cur->bc_ino.whichfork);
|
||||
args.minlen = args.maxlen = args.prod = 1;
|
||||
args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL;
|
||||
if (!args.wasdel && args.tp->t_blk_res == 0)
|
||||
return -ENOSPC;
|
||||
|
||||
args.fsbno = be64_to_cpu(start->l);
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
@ -222,15 +227,9 @@ xfs_bmbt_alloc_block(
|
||||
args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip,
|
||||
cur->bc_ino.whichfork);
|
||||
|
||||
args.minlen = args.maxlen = args.prod = 1;
|
||||
args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL;
|
||||
if (!args.wasdel && args.tp->t_blk_res == 0) {
|
||||
error = -ENOSPC;
|
||||
goto error0;
|
||||
}
|
||||
error = xfs_alloc_vextent(&args);
|
||||
if (error)
|
||||
goto error0;
|
||||
return error;
|
||||
|
||||
if (args.fsbno == NULLFSBLOCK && args.minleft) {
|
||||
/*
|
||||
@ -243,7 +242,7 @@ xfs_bmbt_alloc_block(
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
error = xfs_alloc_vextent(&args);
|
||||
if (error)
|
||||
goto error0;
|
||||
return error;
|
||||
cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE;
|
||||
}
|
||||
if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) {
|
||||
@ -262,9 +261,6 @@ xfs_bmbt_alloc_block(
|
||||
|
||||
*stat = 1;
|
||||
return 0;
|
||||
|
||||
error0:
|
||||
return error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -630,6 +630,7 @@ xfs_ialloc_ag_alloc(
|
||||
args.mp = tp->t_mountp;
|
||||
args.fsbno = NULLFSBLOCK;
|
||||
args.oinfo = XFS_RMAP_OINFO_INODES;
|
||||
args.pag = pag;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* randomly do sparse inode allocations */
|
||||
@ -683,7 +684,8 @@ xfs_ialloc_ag_alloc(
|
||||
|
||||
/* Allow space for the inode btree to split. */
|
||||
args.minleft = igeo->inobt_maxlevels;
|
||||
if ((error = xfs_alloc_vextent(&args)))
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
@ -731,7 +733,8 @@ xfs_ialloc_ag_alloc(
|
||||
* Allow space for the inode btree to split.
|
||||
*/
|
||||
args.minleft = igeo->inobt_maxlevels;
|
||||
if ((error = xfs_alloc_vextent(&args)))
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -780,7 +783,7 @@ xfs_ialloc_ag_alloc(
|
||||
args.mp->m_sb.sb_inoalignmt) -
|
||||
igeo->ialloc_blks;
|
||||
|
||||
error = xfs_alloc_vextent(&args);
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -103,6 +103,7 @@ __xfs_inobt_alloc_block(
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.tp = cur->bc_tp;
|
||||
args.mp = cur->bc_mp;
|
||||
args.pag = cur->bc_ag.pag;
|
||||
args.oinfo = XFS_RMAP_OINFO_INOBT;
|
||||
args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno);
|
||||
args.minlen = 1;
|
||||
@ -111,7 +112,7 @@ __xfs_inobt_alloc_block(
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
args.resv = resv;
|
||||
|
||||
error = xfs_alloc_vextent(&args);
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -67,6 +67,7 @@ xfs_refcountbt_alloc_block(
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.tp = cur->bc_tp;
|
||||
args.mp = cur->bc_mp;
|
||||
args.pag = cur->bc_ag.pag;
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno,
|
||||
xfs_refc_block(args.mp));
|
||||
@ -74,7 +75,7 @@ xfs_refcountbt_alloc_block(
|
||||
args.minlen = args.maxlen = args.prod = 1;
|
||||
args.resv = XFS_AG_RESV_METADATA;
|
||||
|
||||
error = xfs_alloc_vextent(&args);
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (error)
|
||||
goto out_error;
|
||||
trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno,
|
||||
|
@ -326,6 +326,7 @@ xrep_alloc_ag_block(
|
||||
|
||||
args.tp = sc->tp;
|
||||
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;
|
||||
@ -334,7 +335,7 @@ xrep_alloc_ag_block(
|
||||
args.type = XFS_ALLOCTYPE_THIS_AG;
|
||||
args.resv = resv;
|
||||
|
||||
error = xfs_alloc_vextent(&args);
|
||||
error = xfs_alloc_vextent_this_ag(&args);
|
||||
if (error)
|
||||
return error;
|
||||
if (args.fsbno == NULLFSBLOCK)
|
||||
|
Loading…
Reference in New Issue
Block a user