提交 c977eb10 编写于 作者: C Christoph Hellwig 提交者: Dave Chinner

xfs: split xfs_bmap_btalloc_nullfb

Split xfs_bmap_btalloc_nullfb into one function for filestream allocations
and one for everything else that share a few helpers.  This dramatically
simplifies the control flow.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
上级 8b90a33f
...@@ -3517,6 +3517,67 @@ xfs_bmap_adjacent( ...@@ -3517,6 +3517,67 @@ xfs_bmap_adjacent(
#undef ISVALID #undef ISVALID
} }
static int
xfs_bmap_longest_free_extent(
struct xfs_trans *tp,
xfs_agnumber_t ag,
xfs_extlen_t *blen,
int *notinit)
{
struct xfs_mount *mp = tp->t_mountp;
struct xfs_perag *pag;
xfs_extlen_t longest;
int error = 0;
pag = xfs_perag_get(mp, ag);
if (!pag->pagf_init) {
error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
if (error)
goto out;
if (!pag->pagf_init) {
*notinit = 1;
goto out;
}
}
longest = xfs_alloc_longest_free_extent(mp, pag);
if (*blen < longest)
*blen = longest;
out:
xfs_perag_put(pag);
return error;
}
static void
xfs_bmap_select_minlen(
struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args,
xfs_extlen_t *blen,
int notinit)
{
if (notinit || *blen < ap->minlen) {
/*
* Since we did a BUF_TRYLOCK above, it is possible that
* there is space for this request.
*/
args->minlen = ap->minlen;
} else if (*blen < args->maxlen) {
/*
* If the best seen length is less than the request length,
* use the best as the minimum.
*/
args->minlen = *blen;
} else {
/*
* Otherwise we've seen an extent as big as maxlen, use that
* as the minimum.
*/
args->minlen = args->maxlen;
}
}
STATIC int STATIC int
xfs_bmap_btalloc_nullfb( xfs_bmap_btalloc_nullfb(
struct xfs_bmalloca *ap, struct xfs_bmalloca *ap,
...@@ -3524,109 +3585,74 @@ xfs_bmap_btalloc_nullfb( ...@@ -3524,109 +3585,74 @@ xfs_bmap_btalloc_nullfb(
xfs_extlen_t *blen) xfs_extlen_t *blen)
{ {
struct xfs_mount *mp = ap->ip->i_mount; struct xfs_mount *mp = ap->ip->i_mount;
struct xfs_perag *pag;
xfs_agnumber_t ag, startag; xfs_agnumber_t ag, startag;
int notinit = 0; int notinit = 0;
int error; int error;
if (ap->userdata && xfs_inode_is_filestream(ap->ip)) args->type = XFS_ALLOCTYPE_START_BNO;
args->type = XFS_ALLOCTYPE_NEAR_BNO;
else
args->type = XFS_ALLOCTYPE_START_BNO;
args->total = ap->total; args->total = ap->total;
/*
* Search for an allocation group with a single extent large enough
* for the request. 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;
pag = xfs_perag_get(mp, ag);
while (*blen < args->maxlen) { while (*blen < args->maxlen) {
if (!pag->pagf_init) { error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
error = xfs_alloc_pagf_init(mp, args->tp, ag, &notinit);
XFS_ALLOC_FLAG_TRYLOCK); if (error)
if (error) { return error;
xfs_perag_put(pag);
return error;
}
}
/*
* See xfs_alloc_fix_freelist...
*/
if (pag->pagf_init) {
xfs_extlen_t longest;
longest = xfs_alloc_longest_free_extent(mp, pag);
if (*blen < longest)
*blen = longest;
} else
notinit = 1;
if (xfs_inode_is_filestream(ap->ip) && ap->userdata) {
if (*blen >= args->maxlen)
break;
/*
* If startag is an invalid AG, we've
* come here once before and
* xfs_filestream_new_ag picked the
* best currently available.
*
* Don't continue looping, since we
* could loop forever.
*/
if (startag == NULLAGNUMBER)
break;
error = xfs_filestream_new_ag(ap, &ag);
xfs_perag_put(pag);
if (error)
return error;
/* loop again to set 'blen'*/
startag = NULLAGNUMBER;
pag = xfs_perag_get(mp, ag);
continue;
}
if (++ag == mp->m_sb.sb_agcount) if (++ag == mp->m_sb.sb_agcount)
ag = 0; ag = 0;
if (ag == startag) if (ag == startag)
break; break;
xfs_perag_put(pag);
pag = xfs_perag_get(mp, ag);
} }
xfs_perag_put(pag);
/* xfs_bmap_select_minlen(ap, args, blen, notinit);
* Since the above loop did a BUF_TRYLOCK, it is return 0;
* possible that there is space for this request. }
*/
if (notinit || *blen < ap->minlen) STATIC int
args->minlen = ap->minlen; xfs_bmap_btalloc_filestreams(
/* struct xfs_bmalloca *ap,
* If the best seen length is less than the request struct xfs_alloc_arg *args,
* length, use the best as the minimum. xfs_extlen_t *blen)
*/ {
else if (*blen < args->maxlen) struct xfs_mount *mp = ap->ip->i_mount;
args->minlen = *blen; xfs_agnumber_t ag;
/* int notinit = 0;
* Otherwise we've seen an extent as big as maxlen, int error;
* use that as the minimum.
*/ args->type = XFS_ALLOCTYPE_NEAR_BNO;
else args->total = ap->total;
args->minlen = args->maxlen;
ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
if (ag == NULLAGNUMBER)
ag = 0;
error = xfs_bmap_longest_free_extent(args->tp, ag, blen, &notinit);
if (error)
return error;
if (*blen < args->maxlen) {
error = xfs_filestream_new_ag(ap, &ag);
if (error)
return error;
error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
&notinit);
if (error)
return error;
}
xfs_bmap_select_minlen(ap, args, blen, notinit);
/* /*
* set the failure fallback case to look in the selected * Set the failure fallback case to look in the selected AG as stream
* AG as the stream may have moved. * may have moved.
*/ */
if (xfs_inode_is_filestream(ap->ip)) ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
return 0; return 0;
} }
...@@ -3706,7 +3732,15 @@ xfs_bmap_btalloc( ...@@ -3706,7 +3732,15 @@ xfs_bmap_btalloc(
args.firstblock = *ap->firstblock; args.firstblock = *ap->firstblock;
blen = 0; blen = 0;
if (nullfb) { if (nullfb) {
error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); /*
* Search for an allocation group with a single extent large
* enough for the request. If one isn't found, then adjust
* the minimum allocation size to the largest space found.
*/
if (ap->userdata && xfs_inode_is_filestream(ap->ip))
error = xfs_bmap_btalloc_filestreams(ap, &args, &blen);
else
error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
if (error) if (error)
return error; return error;
} else if (ap->flist->xbf_low) { } else if (ap->flist->xbf_low) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册