Commit c467c049 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Alex Elder

xfs: split xfs_bmap_btalloc

Split out the nullfb case into a separate function to reduce the stack
footprint and make the code more readable.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <david@fromorbit.com>
Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
parent f7008d0a
...@@ -2550,106 +2550,56 @@ xfs_bmap_rtalloc( ...@@ -2550,106 +2550,56 @@ xfs_bmap_rtalloc(
} }
STATIC int STATIC int
xfs_bmap_btalloc( xfs_bmap_btalloc_nullfb(
xfs_bmalloca_t *ap) /* bmap alloc argument struct */ struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args,
xfs_extlen_t *blen)
{ {
xfs_mount_t *mp; /* mount point structure */ struct xfs_mount *mp = ap->ip->i_mount;
xfs_alloctype_t atype = 0; /* type for allocation routines */ struct xfs_perag *pag;
xfs_extlen_t align; /* minimum allocation alignment */ xfs_agnumber_t ag, startag;
xfs_agnumber_t ag; int notinit = 0;
xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
xfs_agnumber_t startag;
xfs_alloc_arg_t args;
xfs_extlen_t blen;
xfs_extlen_t nextminlen = 0;
xfs_perag_t *pag;
int nullfb; /* true if ap->firstblock isn't set */
int isaligned;
int notinit;
int tryagain;
int error; int error;
mp = ap->ip->i_mount;
align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
if (unlikely(align)) {
error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
align, 0, ap->eof, 0, ap->conv,
&ap->off, &ap->alen);
ASSERT(!error);
ASSERT(ap->alen);
}
nullfb = ap->firstblock == NULLFSBLOCK;
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
if (nullfb) {
if (ap->userdata && xfs_inode_is_filestream(ap->ip)) {
ag = xfs_filestream_lookup_ag(ap->ip);
ag = (ag != NULLAGNUMBER) ? ag : 0;
ap->rval = XFS_AGB_TO_FSB(mp, ag, 0);
} else {
ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
}
} else
ap->rval = ap->firstblock;
xfs_bmap_adjacent(ap);
/*
* If allowed, use ap->rval; otherwise must use firstblock since
* it's in the right allocation group.
*/
if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
;
else
ap->rval = ap->firstblock;
/*
* Normal allocation, done through xfs_alloc_vextent.
*/
tryagain = isaligned = 0;
args.tp = ap->tp;
args.mp = mp;
args.fsbno = ap->rval;
args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
args.firstblock = ap->firstblock;
blen = 0;
if (nullfb) {
if (ap->userdata && xfs_inode_is_filestream(ap->ip)) if (ap->userdata && xfs_inode_is_filestream(ap->ip))
args.type = XFS_ALLOCTYPE_NEAR_BNO; args->type = XFS_ALLOCTYPE_NEAR_BNO;
else else
args.type = XFS_ALLOCTYPE_START_BNO; args->type = XFS_ALLOCTYPE_START_BNO;
args.total = ap->total; args->total = ap->total;
/* /*
* Search for an allocation group with a single extent * Search for an allocation group with a single extent large enough
* large enough for the request. * for the request. If one isn't found, then adjust the minimum
* * allocation size to the largest space found.
* If one isn't found, then adjust the minimum allocation
* size to the largest space found.
*/ */
startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno); startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
if (startag == NULLAGNUMBER) if (startag == NULLAGNUMBER)
startag = ag = 0; startag = ag = 0;
notinit = 0;
pag = xfs_perag_get(mp, ag); pag = xfs_perag_get(mp, ag);
while (blen < ap->alen) { while (*blen < ap->alen) {
if (!pag->pagf_init && if (!pag->pagf_init) {
(error = xfs_alloc_pagf_init(mp, args.tp, error = xfs_alloc_pagf_init(mp, args->tp, ag,
ag, XFS_ALLOC_FLAG_TRYLOCK))) { XFS_ALLOC_FLAG_TRYLOCK);
if (error) {
xfs_perag_put(pag); xfs_perag_put(pag);
return error; return error;
} }
}
/* /*
* See xfs_alloc_fix_freelist... * See xfs_alloc_fix_freelist...
*/ */
if (pag->pagf_init) { if (pag->pagf_init) {
xfs_extlen_t longest; xfs_extlen_t longest;
longest = xfs_alloc_longest_free_extent(mp, pag); longest = xfs_alloc_longest_free_extent(mp, pag);
if (blen < longest) if (*blen < longest)
blen = longest; *blen = longest;
} else } else
notinit = 1; notinit = 1;
if (xfs_inode_is_filestream(ap->ip)) { if (xfs_inode_is_filestream(ap->ip)) {
if (blen >= ap->alen) if (*blen >= ap->alen)
break; break;
if (ap->userdata) { if (ap->userdata) {
...@@ -2684,31 +2634,99 @@ xfs_bmap_btalloc( ...@@ -2684,31 +2634,99 @@ xfs_bmap_btalloc(
pag = xfs_perag_get(mp, ag); pag = xfs_perag_get(mp, ag);
} }
xfs_perag_put(pag); xfs_perag_put(pag);
/* /*
* Since the above loop did a BUF_TRYLOCK, it is * Since the above loop did a BUF_TRYLOCK, it is
* possible that there is space for this request. * possible that there is space for this request.
*/ */
if (notinit || blen < ap->minlen) if (notinit || *blen < ap->minlen)
args.minlen = ap->minlen; args->minlen = ap->minlen;
/* /*
* If the best seen length is less than the request * If the best seen length is less than the request
* length, use the best as the minimum. * length, use the best as the minimum.
*/ */
else if (blen < ap->alen) else if (*blen < ap->alen)
args.minlen = blen; args->minlen = *blen;
/* /*
* Otherwise we've seen an extent as big as alen, * Otherwise we've seen an extent as big as alen,
* use that as the minimum. * use that as the minimum.
*/ */
else else
args.minlen = ap->alen; args->minlen = ap->alen;
/* /*
* set the failure fallback case to look in the selected * set the failure fallback case to look in the selected
* AG as the stream may have moved. * AG as the stream may have moved.
*/ */
if (xfs_inode_is_filestream(ap->ip)) if (xfs_inode_is_filestream(ap->ip))
ap->rval = args.fsbno = XFS_AGB_TO_FSB(mp, ag, 0); ap->rval = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
return 0;
}
STATIC int
xfs_bmap_btalloc(
xfs_bmalloca_t *ap) /* bmap alloc argument struct */
{
xfs_mount_t *mp; /* mount point structure */
xfs_alloctype_t atype = 0; /* type for allocation routines */
xfs_extlen_t align; /* minimum allocation alignment */
xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
xfs_agnumber_t ag;
xfs_alloc_arg_t args;
xfs_extlen_t blen;
xfs_extlen_t nextminlen = 0;
int nullfb; /* true if ap->firstblock isn't set */
int isaligned;
int tryagain;
int error;
mp = ap->ip->i_mount;
align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
if (unlikely(align)) {
error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
align, 0, ap->eof, 0, ap->conv,
&ap->off, &ap->alen);
ASSERT(!error);
ASSERT(ap->alen);
}
nullfb = ap->firstblock == NULLFSBLOCK;
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
if (nullfb) {
if (ap->userdata && xfs_inode_is_filestream(ap->ip)) {
ag = xfs_filestream_lookup_ag(ap->ip);
ag = (ag != NULLAGNUMBER) ? ag : 0;
ap->rval = XFS_AGB_TO_FSB(mp, ag, 0);
} else {
ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
}
} else
ap->rval = ap->firstblock;
xfs_bmap_adjacent(ap);
/*
* If allowed, use ap->rval; otherwise must use firstblock since
* it's in the right allocation group.
*/
if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
;
else
ap->rval = ap->firstblock;
/*
* Normal allocation, done through xfs_alloc_vextent.
*/
tryagain = isaligned = 0;
args.tp = ap->tp;
args.mp = mp;
args.fsbno = ap->rval;
args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
args.firstblock = ap->firstblock;
blen = 0;
if (nullfb) {
error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
if (error)
return error;
} else if (ap->low) { } else if (ap->low) {
if (xfs_inode_is_filestream(ap->ip)) if (xfs_inode_is_filestream(ap->ip))
args.type = XFS_ALLOCTYPE_FIRST_AG; args.type = XFS_ALLOCTYPE_FIRST_AG;
......
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