提交 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,40 +3576,57 @@ xfs_bmap_btalloc_at_eof( ...@@ -3576,40 +3576,57 @@ 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))
is_filestream = true;
/*
* Determine the initial block number we will target for allocation.
*/
if (is_filestream) {
xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip);
if (agno == NULLAGNUMBER) if (agno == NULLAGNUMBER)
agno = 0; agno = 0;
ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0); ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0);
} else {
ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
}
xfs_bmap_adjacent(ap); 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.
*/
if (is_filestream) {
/* /*
* If there is very little free space before we start a * If there is very little free space before we start a
* filestreams allocation, we're almost guaranteed to fail to * filestreams allocation, we're almost guaranteed to fail to
...@@ -3618,67 +3635,71 @@ xfs_bmap_btalloc_best_length( ...@@ -3618,67 +3635,71 @@ xfs_bmap_btalloc_best_length(
*/ */
if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
args->minlen = ap->minlen; args->minlen = ap->minlen;
goto critically_low_space; return xfs_bmap_btalloc_low_space(ap, args);
}
error = xfs_bmap_btalloc_filestreams(ap, args, &blen);
} else {
error = xfs_bmap_btalloc_select_lengths(ap, args, &blen);
} }
if (error)
return error;
/* /*
* Don't attempt optimal EOF allocation if previous allocations barely * Search for an allocation group with a single extent large enough for
* succeeded due to being near ENOSPC. It is highly unlikely we'll get * the request. If one isn't found, then adjust the minimum allocation
* optimal or even aligned allocations in this case, so don't waste time * size to the largest space found.
* trying.
*/ */
if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { error = xfs_bmap_btalloc_filestreams_select_lengths(ap, args, &blen);
error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
is_filestream);
if (error) if (error)
return error; return error;
if (args->fsbno != NULLFSBLOCK)
return 0; if (ap->aeof) {
error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
true);
if (error || args->fsbno != NULLFSBLOCK)
return error;
} }
if (is_filestream)
error = xfs_alloc_vextent_near_bno(args, ap->blkno); error = xfs_alloc_vextent_near_bno(args, ap->blkno);
else if (error || args->fsbno != NULLFSBLOCK)
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error)
return error; return error;
if (args->fsbno != NULLFSBLOCK)
return 0; 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);
/* /*
* Try a locality first full filesystem minimum length allocation whilst * Search for an allocation group with a single extent large enough for
* still maintaining necessary total block reservation requirements. * the request. If one isn't found, then adjust the minimum allocation
* size to the largest space found.
*/ */
if (args->minlen > ap->minlen) { error = xfs_bmap_btalloc_select_lengths(ap, args, &blen);
args->minlen = ap->minlen;
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error) if (error)
return error; return error;
}
if (args->fsbno != NULLFSBLOCK)
return 0;
/* /*
* We are now critically low on space, so this is a last resort * Don't attempt optimal EOF allocation if previous allocations barely
* allocation attempt: no reserve, no locality, blocking, minimum * succeeded due to being near ENOSPC. It is highly unlikely we'll get
* length, full filesystem free space scan. We also indicate to future * optimal or even aligned allocations in this case, so don't waste time
* allocations in this transaction that we are critically low on space * trying.
* so they don't waste time on allocation modes that are unlikely to
* succeed.
*/ */
critically_low_space: if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) {
args->total = ap->minlen; error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
error = xfs_alloc_vextent_first_ag(args, 0); false);
if (error) if (error || args->fsbno != NULLFSBLOCK)
return error; return error;
ap->tp->t_flags |= XFS_TRANS_LOWMODE; }
return 0;
error = xfs_alloc_vextent_start_ag(args, ap->blkno);
if (error || args->fsbno != NULLFSBLOCK)
return error;
return xfs_bmap_btalloc_low_space(ap, args);
} }
static int static int
...@@ -3712,6 +3733,10 @@ xfs_bmap_btalloc( ...@@ -3712,6 +3733,10 @@ 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);
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); 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.
先完成此消息的编辑!
想要评论请 注册