提交 89563e7d 编写于 作者: D Dave Chinner

xfs: factor out filestreams from xfs_bmap_btalloc_nullfb

There's many if (filestreams) {} else {} branches in this function.
Split it out into a filestreams specific function so that we can
then work directly on cleaning up the filestreams code without
impacting the rest of the allocation algorithms.
Signed-off-by: NDave Chinner <dchinner@redhat.com>
Reviewed-by: NDarrick J. Wong <djwong@kernel.org>
上级 35bf2b1a
...@@ -3234,8 +3234,8 @@ xfs_bmap_btalloc_select_lengths( ...@@ -3234,8 +3234,8 @@ xfs_bmap_btalloc_select_lengths(
return error; return error;
} }
STATIC int static int
xfs_bmap_btalloc_filestreams( xfs_bmap_btalloc_filestreams_select_lengths(
struct xfs_bmalloca *ap, struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args, struct xfs_alloc_arg *args,
xfs_extlen_t *blen) xfs_extlen_t *blen)
...@@ -3576,54 +3576,109 @@ xfs_bmap_btalloc_at_eof( ...@@ -3576,54 +3576,109 @@ xfs_bmap_btalloc_at_eof(
return 0; return 0;
} }
/*
* We have failed multiple allocation attempts so now are in a low space
* allocation situation. Try a locality first full filesystem minimum length
* allocation whilst still maintaining necessary total block reservation
* requirements.
*
* If that fails, we are now critically low on space, so perform a last resort
* allocation attempt: no reserve, no locality, blocking, minimum length, full
* filesystem free space scan. We also indicate to future allocations in this
* transaction that we are critically low on space so they don't waste time on
* allocation modes that are unlikely to succeed.
*/
static int static int
xfs_bmap_btalloc_best_length( xfs_bmap_btalloc_low_space(
struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args)
{
int error;
if (args->minlen > ap->minlen) {
args->minlen = ap->minlen;
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error || args->fsbno != NULLFSBLOCK)
return error;
}
/* Last ditch attempt before failure is declared. */
args->total = ap->minlen;
error = xfs_alloc_vextent_first_ag(args, 0);
if (error)
return error;
ap->tp->t_flags |= XFS_TRANS_LOWMODE;
return 0;
}
static int
xfs_bmap_btalloc_filestreams(
struct xfs_bmalloca *ap, struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args, struct xfs_alloc_arg *args,
int stripe_align) int stripe_align)
{ {
struct xfs_mount *mp = args->mp; xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip);
xfs_extlen_t blen = 0; xfs_extlen_t blen = 0;
bool is_filestream = false;
int error; int error;
if ((ap->datatype & XFS_ALLOC_USERDATA) && /* Determine the initial block number we will target for allocation. */
xfs_inode_is_filestream(ap->ip)) if (agno == NULLAGNUMBER)
is_filestream = true; agno = 0;
ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0);
xfs_bmap_adjacent(ap);
/* /*
* Determine the initial block number we will target for allocation. * If there is very little free space before we start a
* filestreams allocation, we're almost guaranteed to fail to
* find an AG with enough contiguous free space to succeed, so
* just go straight to the low space algorithm.
*/ */
if (is_filestream) { if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip); args->minlen = ap->minlen;
if (agno == NULLAGNUMBER) return xfs_bmap_btalloc_low_space(ap, args);
agno = 0;
ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0);
} else {
ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
} }
xfs_bmap_adjacent(ap);
/* /*
* Search for an allocation group with a single extent large enough for * Search for an allocation group with a single extent large enough for
* the request. If one isn't found, then adjust the minimum allocation * the request. If one isn't found, then adjust the minimum allocation
* size to the largest space found. * size to the largest space found.
*/ */
if (is_filestream) { error = xfs_bmap_btalloc_filestreams_select_lengths(ap, args, &blen);
/* if (error)
* If there is very little free space before we start a return error;
* filestreams allocation, we're almost guaranteed to fail to
* find an AG with enough contiguous free space to succeed, so if (ap->aeof) {
* just go straight to the low space algorithm. error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
*/ true);
if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { if (error || args->fsbno != NULLFSBLOCK)
args->minlen = ap->minlen; return error;
goto critically_low_space;
}
error = xfs_bmap_btalloc_filestreams(ap, args, &blen);
} else {
error = xfs_bmap_btalloc_select_lengths(ap, args, &blen);
} }
error = xfs_alloc_vextent_near_bno(args, ap->blkno);
if (error || args->fsbno != NULLFSBLOCK)
return error;
return xfs_bmap_btalloc_low_space(ap, args);
}
static int
xfs_bmap_btalloc_best_length(
struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args,
int stripe_align)
{
xfs_extlen_t blen = 0;
int error;
ap->blkno = XFS_INO_TO_FSB(args->mp, ap->ip->i_ino);
xfs_bmap_adjacent(ap);
/*
* 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.
*/
error = xfs_bmap_btalloc_select_lengths(ap, args, &blen);
if (error) if (error)
return error; return error;
...@@ -3635,50 +3690,16 @@ xfs_bmap_btalloc_best_length( ...@@ -3635,50 +3690,16 @@ xfs_bmap_btalloc_best_length(
*/ */
if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) {
error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align, error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
is_filestream); false);
if (error) if (error || args->fsbno != NULLFSBLOCK)
return error; return error;
if (args->fsbno != NULLFSBLOCK)
return 0;
} }
if (is_filestream) error = xfs_alloc_vextent_start_ag(args, ap->blkno);
error = xfs_alloc_vextent_near_bno(args, ap->blkno); if (error || args->fsbno != NULLFSBLOCK)
else
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error)
return error; return error;
if (args->fsbno != NULLFSBLOCK)
return 0;
/*
* Try a locality first full filesystem minimum length allocation whilst
* still maintaining necessary total block reservation requirements.
*/
if (args->minlen > ap->minlen) {
args->minlen = ap->minlen;
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error)
return error;
}
if (args->fsbno != NULLFSBLOCK)
return 0;
/* return xfs_bmap_btalloc_low_space(ap, args);
* We are now critically low on space, so this is a last resort
* allocation attempt: no reserve, no locality, blocking, minimum
* length, full filesystem free space scan. We also indicate to future
* allocations in this transaction that we are critically low on space
* so they don't waste time on allocation modes that are unlikely to
* succeed.
*/
critically_low_space:
args->total = ap->minlen;
error = xfs_alloc_vextent_first_ag(args, 0);
if (error)
return error;
ap->tp->t_flags |= XFS_TRANS_LOWMODE;
return 0;
} }
static int static int
...@@ -3712,7 +3733,11 @@ xfs_bmap_btalloc( ...@@ -3712,7 +3733,11 @@ xfs_bmap_btalloc(
/* Trim the allocation back to the maximum an AG can fit. */ /* Trim the allocation back to the maximum an AG can fit. */
args.maxlen = min(ap->length, mp->m_ag_max_usable); args.maxlen = min(ap->length, mp->m_ag_max_usable);
error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align); if ((ap->datatype & XFS_ALLOC_USERDATA) &&
xfs_inode_is_filestream(ap->ip))
error = xfs_bmap_btalloc_filestreams(ap, &args, stripe_align);
else
error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align);
if (error) if (error)
return error; return error;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册