Commit b8fc82630ae289bb4e661567808afc59e3298dce

Authored by Dave Chinner
Committed by Alex Elder
1 parent e34a314c5e

xfs: speculative delayed allocation uses rounddown_power_of_2 badly

rounddown_power_of_2() returns an undefined result when passed a
value of zero. The specualtive delayed allocation code is doing this
when the inode is zero length. Hence occasionally the preallocation
is much, much larger than is necessary (e.g. 8GB for a 270 _byte_
file). Ensure we don't even pass a zero value to this function so
the result of preallocation is always the desired size.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>

Showing 1 changed file with 6 additions and 1 deletions Side-by-side Diff

... ... @@ -337,7 +337,12 @@
337 337 int shift = 0;
338 338 int64_t freesp;
339 339  
340   - alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size);
  340 + /*
  341 + * rounddown_pow_of_two() returns an undefined result
  342 + * if we pass in alloc_blocks = 0. Hence the "+ 1" to
  343 + * ensure we always pass in a non-zero value.
  344 + */
  345 + alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size) + 1;
341 346 alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN,
342 347 rounddown_pow_of_two(alloc_blocks));
343 348