Skip to content

Commit b6bb345

Browse files
Christoph HellwigChandan Babu R
authored andcommitted
xfs: simplify and optimize the RT allocation fallback cascade
There are currently multiple levels of fall back if an RT allocation can not be satisfied: 1) xfs_rtallocate_extent extends the minlen and reduces the maxlen due to the extent size hint. If that can't be done, it return -ENOSPC and let's xfs_bmap_rtalloc retry, which then not only drops the extent size hint based alignment, but also the minlen adjustment 2) if xfs_rtallocate_extent gets -ENOSPC from the underlying functions, it only drops the extent size hint based alignment and retries 3) if that still does not succeed, xfs_rtallocate_extent drops the extent size hint (which is a complex no-op at this point) and the minlen using the same code as (1) above 4) if that still doesn't success and the caller wanted an allocation near a blkno, drop that blkno hint. The handling in 1 is rather inefficient as we could just drop the alignment and continue, and 2/3 interact in really weird ways due to the duplicate policy. Move aligning the min and maxlen out of xfs_rtallocate_extent and into a helper called directly by xfs_bmap_rtalloc. This allows just continuing with the allocation if we have to drop the alignment instead of going through the retry loop and also dropping the perfectly usable minlen adjustment that didn't cause the problem, and then just use a single retry that drops both the minlen and alignment requirement when we really are out of space, thus consolidating cases (2) and (3) above. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
1 parent 26e5eed commit b6bb345

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

fs/xfs/xfs_rtalloc.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,21 +1094,6 @@ xfs_rtallocate_extent(
10941094
ASSERT(xfs_isilocked(args.mp->m_rbmip, XFS_ILOCK_EXCL));
10951095
ASSERT(minlen > 0 && minlen <= maxlen);
10961096

1097-
/*
1098-
* If prod is set then figure out what to do to minlen and maxlen.
1099-
*/
1100-
if (prod > 1) {
1101-
xfs_rtxlen_t i;
1102-
1103-
if ((i = maxlen % prod))
1104-
maxlen -= i;
1105-
if ((i = minlen % prod))
1106-
minlen += prod - i;
1107-
if (maxlen < minlen)
1108-
return -ENOSPC;
1109-
}
1110-
1111-
retry:
11121097
if (start == 0) {
11131098
error = xfs_rtallocate_extent_size(&args, minlen,
11141099
maxlen, len, prod, rtx);
@@ -1117,13 +1102,8 @@ xfs_rtallocate_extent(
11171102
maxlen, len, prod, rtx);
11181103
}
11191104
xfs_rtbuf_cache_relse(&args);
1120-
if (error) {
1121-
if (error == -ENOSPC && prod > 1) {
1122-
prod = 1;
1123-
goto retry;
1124-
}
1105+
if (error)
11251106
return error;
1126-
}
11271107

11281108
/*
11291109
* If it worked, update the superblock.
@@ -1354,6 +1334,35 @@ xfs_rtpick_extent(
13541334
return 0;
13551335
}
13561336

1337+
static void
1338+
xfs_rtalloc_align_minmax(
1339+
xfs_rtxlen_t *raminlen,
1340+
xfs_rtxlen_t *ramaxlen,
1341+
xfs_rtxlen_t *prod)
1342+
{
1343+
xfs_rtxlen_t newmaxlen = *ramaxlen;
1344+
xfs_rtxlen_t newminlen = *raminlen;
1345+
xfs_rtxlen_t slack;
1346+
1347+
slack = newmaxlen % *prod;
1348+
if (slack)
1349+
newmaxlen -= slack;
1350+
slack = newminlen % *prod;
1351+
if (slack)
1352+
newminlen += *prod - slack;
1353+
1354+
/*
1355+
* If adjusting for extent size hint alignment produces an invalid
1356+
* min/max len combination, go ahead without it.
1357+
*/
1358+
if (newmaxlen < newminlen) {
1359+
*prod = 1;
1360+
return;
1361+
}
1362+
*ramaxlen = newmaxlen;
1363+
*raminlen = newminlen;
1364+
}
1365+
13571366
int
13581367
xfs_bmap_rtalloc(
13591368
struct xfs_bmalloca *ap)
@@ -1436,10 +1445,13 @@ xfs_bmap_rtalloc(
14361445
* perfectly aligned, otherwise it will just get us in trouble.
14371446
*/
14381447
div_u64_rem(ap->offset, align, &mod);
1439-
if (mod || ap->length % align)
1448+
if (mod || ap->length % align) {
14401449
prod = 1;
1441-
else
1450+
} else {
14421451
prod = xfs_extlen_to_rtxlen(mp, align);
1452+
if (prod > 1)
1453+
xfs_rtalloc_align_minmax(&raminlen, &ralen, &prod);
1454+
}
14431455

14441456
error = xfs_rtallocate_extent(ap->tp, start, raminlen, ralen, &ralen,
14451457
ap->wasdel, prod, &rtx);

0 commit comments

Comments
 (0)