diff options
author | Jan Kara <jack@suse.cz> | 2014-06-06 02:06:37 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-06-06 02:06:37 -0400 |
commit | 30265117ee1e23fa91920f337a3ea91207f700dc (patch) | |
tree | 92bc5cec785f90d64f8e5f42baa0ce185b0c3cfb /fs/xfs | |
parent | 448011e2ab1c44f7990a62649580bde0da5242b5 (diff) |
xfs: Fix rounding in xfs_alloc_fix_len()
Rounding in xfs_alloc_fix_len() is wrong. As the comment states, the
result should be a number of a form (k*prod+mod) however due to sign
mistake the result is different. As a result allocations on raid arrays
could be misaligned in some cases.
This also seems to fix occasional assertion failure:
XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0)
in xfs_alloc_ag_vextent_size().
Also add an assertion that the result of xfs_alloc_fix_len() is of
expected form.
Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_alloc.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 077c3417a54e..d43813267a80 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -257,16 +257,14 @@ xfs_alloc_fix_len( | |||
257 | k = rlen % args->prod; | 257 | k = rlen % args->prod; |
258 | if (k == args->mod) | 258 | if (k == args->mod) |
259 | return; | 259 | return; |
260 | if (k > args->mod) { | 260 | if (k > args->mod) |
261 | if ((int)(rlen = rlen - k - args->mod) < (int)args->minlen) | 261 | rlen = rlen - (k - args->mod); |
262 | return; | 262 | else |
263 | } else { | 263 | rlen = rlen - args->prod + (args->mod - k); |
264 | if ((int)(rlen = rlen - args->prod - (args->mod - k)) < | 264 | if ((int)rlen < (int)args->minlen) |
265 | (int)args->minlen) | 265 | return; |
266 | return; | 266 | ASSERT(rlen >= args->minlen && rlen <= args->maxlen); |
267 | } | 267 | ASSERT(rlen % args->prod == args->mod); |
268 | ASSERT(rlen >= args->minlen); | ||
269 | ASSERT(rlen <= args->maxlen); | ||
270 | args->len = rlen; | 268 | args->len = rlen; |
271 | } | 269 | } |
272 | 270 | ||