summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_rtalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_rtalloc.c')
-rw-r--r--fs/xfs/xfs_rtalloc.c211
1 files changed, 71 insertions, 140 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 35380d0cfe9b..a810482339ad 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -156,17 +156,17 @@ xfs_rtallocate_range(
* properly update the summary.
*/
error = xfs_rtfind_back(args, start, 0, &preblock);
- if (error) {
+ if (error)
return error;
- }
+
/*
* Find the next allocated block (end of free extent).
*/
error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1,
&postblock);
- if (error) {
+ if (error)
return error;
- }
+
/*
* Decrement the summary information corresponding to the entire
* (old) free extent.
@@ -174,9 +174,9 @@ xfs_rtallocate_range(
error = xfs_rtmodify_summary(args,
XFS_RTBLOCKLOG(postblock + 1 - preblock),
xfs_rtx_to_rbmblock(mp, preblock), -1);
- if (error) {
+ if (error)
return error;
- }
+
/*
* If there are blocks not being allocated at the front of the
* old extent, add summary data for them to be free.
@@ -185,10 +185,10 @@ xfs_rtallocate_range(
error = xfs_rtmodify_summary(args,
XFS_RTBLOCKLOG(start - preblock),
xfs_rtx_to_rbmblock(mp, preblock), 1);
- if (error) {
+ if (error)
return error;
- }
}
+
/*
* If there are blocks not being allocated at the end of the
* old extent, add summary data for them to be free.
@@ -197,15 +197,14 @@ xfs_rtallocate_range(
error = xfs_rtmodify_summary(args,
XFS_RTBLOCKLOG(postblock - end),
xfs_rtx_to_rbmblock(mp, end + 1), 1);
- if (error) {
+ if (error)
return error;
- }
}
+
/*
* Modify the bitmap to mark this extent allocated.
*/
- error = xfs_rtmodify_range(args, start, len, 0);
- return error;
+ return xfs_rtmodify_range(args, start, len, 0);
}
/*
@@ -267,17 +266,17 @@ xfs_rtallocate_extent_block(
* If it's not so then next will contain the first non-free.
*/
error = xfs_rtcheck_range(args, i, maxlen, 1, &next, &stat);
- if (error) {
+ if (error)
return error;
- }
+
if (stat) {
/*
* i for maxlen is all free, allocate and return that.
*/
error = xfs_rtallocate_range(args, i, maxlen);
- if (error) {
+ if (error)
return error;
- }
+
*len = maxlen;
*rtx = i;
return 0;
@@ -302,9 +301,8 @@ xfs_rtallocate_extent_block(
*/
if (next < end) {
error = xfs_rtfind_forw(args, next, end, &i);
- if (error) {
+ if (error)
return error;
- }
} else
break;
}
@@ -327,9 +325,8 @@ xfs_rtallocate_extent_block(
* Allocate besti for bestlen & return that.
*/
error = xfs_rtallocate_range(args, besti, bestlen);
- if (error) {
+ if (error)
return error;
- }
*len = bestlen;
*rtx = besti;
return 0;
@@ -338,8 +335,7 @@ xfs_rtallocate_extent_block(
* Allocation failed. Set *nextp to the next block to try.
*/
*nextp = next;
- *rtx = NULLRTEXTNO;
- return 0;
+ return -ENOSPC;
}
/*
@@ -369,17 +365,16 @@ xfs_rtallocate_extent_exact(
* Check if the range in question (for maxlen) is free.
*/
error = xfs_rtcheck_range(args, start, maxlen, 1, &next, &isfree);
- if (error) {
+ if (error)
return error;
- }
+
if (isfree) {
/*
* If it is, allocate it and return success.
*/
error = xfs_rtallocate_range(args, start, maxlen);
- if (error) {
+ if (error)
return error;
- }
*len = maxlen;
*rtx = start;
return 0;
@@ -388,33 +383,23 @@ xfs_rtallocate_extent_exact(
* If not, allocate what there is, if it's at least minlen.
*/
maxlen = next - start;
- if (maxlen < minlen) {
- /*
- * Failed, return failure status.
- */
- *rtx = NULLRTEXTNO;
- return 0;
- }
+ if (maxlen < minlen)
+ return -ENOSPC;
+
/*
* Trim off tail of extent, if prod is specified.
*/
if (prod > 1 && (i = maxlen % prod)) {
maxlen -= i;
- if (maxlen < minlen) {
- /*
- * Now we can't do it, return failure status.
- */
- *rtx = NULLRTEXTNO;
- return 0;
- }
+ if (maxlen < minlen)
+ return -ENOSPC;
}
/*
* Allocate what we can and return it.
*/
error = xfs_rtallocate_range(args, start, maxlen);
- if (error) {
+ if (error)
return error;
- }
*len = maxlen;
*rtx = start;
return 0;
@@ -443,7 +428,6 @@ xfs_rtallocate_extent_near(
int j; /* secondary loop control */
int log2len; /* log2 of minlen */
xfs_rtxnum_t n; /* next rtext to try */
- xfs_rtxnum_t r; /* result rtext */
ASSERT(minlen % prod == 0);
ASSERT(maxlen % prod == 0);
@@ -457,26 +441,18 @@ xfs_rtallocate_extent_near(
/* Make sure we don't run off the end of the rt volume. */
maxlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod);
- if (maxlen < minlen) {
- *rtx = NULLRTEXTNO;
- return 0;
- }
+ if (maxlen < minlen)
+ return -ENOSPC;
/*
* Try the exact allocation first.
*/
error = xfs_rtallocate_extent_exact(args, start, minlen, maxlen, len,
- prod, &r);
- if (error) {
+ prod, rtx);
+ if (error != -ENOSPC)
return error;
- }
- /*
- * If the exact allocation worked, return that.
- */
- if (r != NULLRTEXTNO) {
- *rtx = r;
- return 0;
- }
+
+
bbno = xfs_rtx_to_rbmblock(mp, start);
i = 0;
j = -1;
@@ -492,9 +468,9 @@ xfs_rtallocate_extent_near(
*/
error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1,
bbno + i, &maxlog);
- if (error) {
+ if (error)
return error;
- }
+
/*
* If there are any useful extents starting here, try
* allocating one.
@@ -513,17 +489,9 @@ xfs_rtallocate_extent_near(
*/
error = xfs_rtallocate_extent_block(args,
bbno + i, minlen, maxavail, len,
- &n, prod, &r);
- if (error) {
+ &n, prod, rtx);
+ if (error != -ENOSPC)
return error;
- }
- /*
- * If it worked, return it.
- */
- if (r != NULLRTEXTNO) {
- *rtx = r;
- return 0;
- }
}
/*
* On the negative side of the starting location.
@@ -557,17 +525,9 @@ xfs_rtallocate_extent_near(
error = xfs_rtallocate_extent_block(args,
bbno + j, minlen,
maxavail, len, &n, prod,
- &r);
- if (error) {
+ rtx);
+ if (error != -ENOSPC)
return error;
- }
- /*
- * If it works, return the extent.
- */
- if (r != NULLRTEXTNO) {
- *rtx = r;
- return 0;
- }
}
}
}
@@ -601,8 +561,7 @@ xfs_rtallocate_extent_near(
else
break;
}
- *rtx = NULLRTEXTNO;
- return 0;
+ return -ENOSPC;
}
/*
@@ -624,7 +583,6 @@ xfs_rtallocate_extent_size(
xfs_fileoff_t i; /* bitmap block number */
int l; /* level number (loop control) */
xfs_rtxnum_t n; /* next rtext to be tried */
- xfs_rtxnum_t r; /* result rtext number */
xfs_suminfo_t sum; /* summary information for extents */
ASSERT(minlen % prod == 0);
@@ -647,9 +605,8 @@ xfs_rtallocate_extent_size(
* Get the summary for this level/block.
*/
error = xfs_rtget_summary(args, l, i, &sum);
- if (error) {
+ if (error)
return error;
- }
/*
* Nothing there, on to the next block.
*/
@@ -659,17 +616,9 @@ xfs_rtallocate_extent_size(
* Try allocating the extent.
*/
error = xfs_rtallocate_extent_block(args, i, maxlen,
- maxlen, len, &n, prod, &r);
- if (error) {
+ maxlen, len, &n, prod, rtx);
+ if (error != -ENOSPC)
return error;
- }
- /*
- * If it worked, return that.
- */
- if (r != NULLRTEXTNO) {
- *rtx = r;
- return 0;
- }
/*
* If the "next block to try" returned from the
* allocator is beyond the next bitmap block,
@@ -683,10 +632,8 @@ xfs_rtallocate_extent_size(
* Didn't find any maxlen blocks. Try smaller ones, unless
* we're asking for a fixed size extent.
*/
- if (minlen > --maxlen) {
- *rtx = NULLRTEXTNO;
- return 0;
- }
+ if (minlen > --maxlen)
+ return -ENOSPC;
ASSERT(minlen != 0);
ASSERT(maxlen != 0);
@@ -705,9 +652,9 @@ xfs_rtallocate_extent_size(
* Get the summary information for this level/block.
*/
error = xfs_rtget_summary(args, l, i, &sum);
- if (error) {
+ if (error)
return error;
- }
+
/*
* If nothing there, go on to next.
*/
@@ -721,17 +668,10 @@ xfs_rtallocate_extent_size(
error = xfs_rtallocate_extent_block(args, i,
XFS_RTMAX(minlen, 1 << l),
XFS_RTMIN(maxlen, (1 << (l + 1)) - 1),
- len, &n, prod, &r);
- if (error) {
+ len, &n, prod, rtx);
+ if (error != -ENOSPC)
return error;
- }
- /*
- * If it worked, return that extent.
- */
- if (r != NULLRTEXTNO) {
- *rtx = r;
- return 0;
- }
+
/*
* If the "next block to try" returned from the
* allocator is beyond the next bitmap block,
@@ -744,8 +684,7 @@ xfs_rtallocate_extent_size(
/*
* Got nothing, return failure.
*/
- *rtx = NULLRTEXTNO;
- return 0;
+ return -ENOSPC;
}
/*
@@ -1182,14 +1121,13 @@ xfs_rtallocate_extent(
xfs_rtxlen_t *len, /* out: actual length allocated */
int wasdel, /* was a delayed allocation extent */
xfs_rtxlen_t prod, /* extent product factor */
- xfs_rtxnum_t *rtblock) /* out: start rtext allocated */
+ xfs_rtxnum_t *rtx) /* out: start rtext allocated */
{
struct xfs_rtalloc_args args = {
.mp = tp->t_mountp,
.tp = tp,
};
int error; /* error value */
- xfs_rtxnum_t r; /* result allocated rtext */
ASSERT(xfs_isilocked(args.mp->m_rbmip, XFS_ILOCK_EXCL));
ASSERT(minlen > 0 && minlen <= maxlen);
@@ -1204,42 +1142,35 @@ xfs_rtallocate_extent(
maxlen -= i;
if ((i = minlen % prod))
minlen += prod - i;
- if (maxlen < minlen) {
- *rtblock = NULLRTEXTNO;
- return 0;
- }
+ if (maxlen < minlen)
+ return -ENOSPC;
}
retry:
if (start == 0) {
error = xfs_rtallocate_extent_size(&args, minlen,
- maxlen, len, prod, &r);
+ maxlen, len, prod, rtx);
} else {
error = xfs_rtallocate_extent_near(&args, start, minlen,
- maxlen, len, prod, &r);
+ maxlen, len, prod, rtx);
}
-
xfs_rtbuf_cache_relse(&args);
- if (error)
+ if (error) {
+ if (error == -ENOSPC && prod > 1) {
+ prod = 1;
+ goto retry;
+ }
return error;
+ }
/*
* If it worked, update the superblock.
*/
- if (r != NULLRTEXTNO) {
- long slen = (long)*len;
-
- ASSERT(*len >= minlen && *len <= maxlen);
- if (wasdel)
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FREXTENTS, -slen);
- else
- xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, -slen);
- } else if (prod > 1) {
- prod = 1;
- goto retry;
- }
-
- *rtblock = r;
+ ASSERT(*len >= minlen && *len <= maxlen);
+ if (wasdel)
+ xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FREXTENTS, -(long)*len);
+ else
+ xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, -(long)*len);
return 0;
}
@@ -1553,16 +1484,16 @@ retry:
raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen));
error = xfs_rtallocate_extent(ap->tp, rtx, raminlen, ralen, &ralen,
ap->wasdel, prod, &rtx);
- if (error)
- return error;
-
- if (rtx != NULLRTEXTNO) {
+ if (!error) {
ap->blkno = xfs_rtx_to_rtb(mp, rtx);
ap->length = xfs_rtxlen_to_extlen(mp, ralen);
xfs_bmap_alloc_account(ap);
return 0;
}
+ if (error != -ENOSPC)
+ return error;
+
if (align > mp->m_sb.sb_rextsize) {
/*
* We previously enlarged the request length to try to satisfy