Commit 2a4f35f9 authored by Brian Foster's avatar Brian Foster Committed by Darrick J. Wong

xfs: clean up small allocation helper

xfs_alloc_ag_vextent_small() is kind of a mess. Clean it up in
preparation for future changes. No functional changes.
Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent caeaea98
...@@ -1583,92 +1583,80 @@ xfs_alloc_ag_vextent_size( ...@@ -1583,92 +1583,80 @@ xfs_alloc_ag_vextent_size(
} }
/* /*
* Deal with the case where only small freespaces remain. * Deal with the case where only small freespaces remain. Either return the
* Either return the contents of the last freespace record, * contents of the last freespace record, or allocate space from the freelist if
* or allocate space from the freelist if there is nothing in the tree. * there is nothing in the tree.
*/ */
STATIC int /* error */ STATIC int /* error */
xfs_alloc_ag_vextent_small( xfs_alloc_ag_vextent_small(
xfs_alloc_arg_t *args, /* allocation argument structure */ struct xfs_alloc_arg *args, /* allocation argument structure */
xfs_btree_cur_t *ccur, /* by-size cursor */ struct xfs_btree_cur *ccur, /* optional by-size cursor */
xfs_agblock_t *fbnop, /* result block number */ xfs_agblock_t *fbnop, /* result block number */
xfs_extlen_t *flenp, /* result length */ xfs_extlen_t *flenp, /* result length */
int *stat) /* status: 0-freelist, 1-normal/none */ int *stat) /* status: 0-freelist, 1-normal/none */
{ {
int error; int error = 0;
xfs_agblock_t fbno; xfs_agblock_t fbno = NULLAGBLOCK;
xfs_extlen_t flen; xfs_extlen_t flen = 0;
int i; int i;
if ((error = xfs_btree_decrement(ccur, 0, &i))) error = xfs_btree_decrement(ccur, 0, &i);
goto error0; if (error)
goto error;
if (i) { if (i) {
if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i);
goto error0;
XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
}
/*
* Nothing in the btree, try the freelist. Make sure
* to respect minleft even when pulling from the
* freelist.
*/
else if (args->minlen == 1 && args->alignment == 1 &&
args->resv != XFS_AG_RESV_AGFL &&
(be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
> args->minleft)) {
error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
if (error) if (error)
goto error0; goto error;
if (fbno != NULLAGBLOCK) { XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error);
xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1, goto out;
xfs_alloc_allow_busy_reuse(args->datatype)); }
if (xfs_alloc_is_userdata(args->datatype)) { if (args->minlen != 1 || args->alignment != 1 ||
xfs_buf_t *bp; args->resv == XFS_AG_RESV_AGFL ||
(be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) <=
args->minleft))
goto out;
bp = xfs_btree_get_bufs(args->mp, args->tp, error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
args->agno, fbno); if (error)
if (!bp) { goto error;
error = -EFSCORRUPTED; if (fbno == NULLAGBLOCK)
goto error0; goto out;
}
xfs_trans_binval(args->tp, bp);
}
args->len = 1;
args->agbno = fbno;
XFS_WANT_CORRUPTED_GOTO(args->mp,
args->agbno + args->len <=
be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
error0);
args->wasfromfl = 1;
trace_xfs_alloc_small_freelist(args);
/* xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
* If we're feeding an AGFL block to something that xfs_alloc_allow_busy_reuse(args->datatype));
* doesn't live in the free space, we need to clear
* out the OWN_AG rmap.
*/
error = xfs_rmap_free(args->tp, args->agbp, args->agno,
fbno, 1, &XFS_RMAP_OINFO_AG);
if (error)
goto error0;
*stat = 0; if (xfs_alloc_is_userdata(args->datatype)) {
return 0; struct xfs_buf *bp;
bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno);
if (!bp) {
error = -EFSCORRUPTED;
goto error;
} }
/* xfs_trans_binval(args->tp, bp);
* Nothing in the freelist.
*/
else
flen = 0;
} }
args->len = 1;
args->agbno = fbno;
XFS_WANT_CORRUPTED_GOTO(args->mp,
fbno < be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
error);
args->wasfromfl = 1;
trace_xfs_alloc_small_freelist(args);
/* /*
* Can't allocate from the freelist for some reason. * If we're feeding an AGFL block to something that doesn't live in the
* free space, we need to clear out the OWN_AG rmap.
*/ */
else { error = xfs_rmap_free(args->tp, args->agbp, args->agno, fbno, 1,
fbno = NULLAGBLOCK; &XFS_RMAP_OINFO_AG);
flen = 0; if (error)
} goto error;
*stat = 0;
return 0;
out:
/* /*
* Can't do the allocation, give up. * Can't do the allocation, give up.
*/ */
...@@ -1683,7 +1671,7 @@ xfs_alloc_ag_vextent_small( ...@@ -1683,7 +1671,7 @@ xfs_alloc_ag_vextent_small(
trace_xfs_alloc_small_done(args); trace_xfs_alloc_small_done(args);
return 0; return 0;
error0: error:
trace_xfs_alloc_small_error(args); trace_xfs_alloc_small_error(args);
return error; return error;
} }
......
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