Skip to content

Commit 590b165

Browse files
committed
xfs: refactor xfs_iomap_prealloc_size
Refactor xfs_iomap_prealloc_size to be the function that dynamically computes the per-file preallocation size by moving the allocsize= case to the caller. Break up the huge comment preceding the function to annotate the relevant parts of the code, and remove the impossible check_writeio case. Suggested-by: Christoph Hellwig <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Brian Foster <[email protected]>
1 parent f0322c7 commit 590b165

File tree

1 file changed

+35
-48
lines changed

1 file changed

+35
-48
lines changed

fs/xfs/xfs_iomap.c

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -352,22 +352,10 @@ xfs_quota_calc_throttle(
352352
}
353353

354354
/*
355-
* If we are doing a write at the end of the file and there are no allocations
356-
* past this one, then extend the allocation out to the file system's write
357-
* iosize.
358-
*
359355
* If we don't have a user specified preallocation size, dynamically increase
360356
* the preallocation size as the size of the file grows. Cap the maximum size
361357
* at a single extent or less if the filesystem is near full. The closer the
362-
* filesystem is to full, the smaller the maximum prealocation.
363-
*
364-
* As an exception we don't do any preallocation at all if the file is smaller
365-
* than the minimum preallocation and we are using the default dynamic
366-
* preallocation scheme, as it is likely this is the only write to the file that
367-
* is going to be done.
368-
*
369-
* We clean up any extra space left over when the file is closed in
370-
* xfs_inactive().
358+
* filesystem is to being full, the smaller the maximum preallocation.
371359
*/
372360
STATIC xfs_fsblock_t
373361
xfs_iomap_prealloc_size(
@@ -389,41 +377,28 @@ xfs_iomap_prealloc_size(
389377
int shift = 0;
390378
int qshift = 0;
391379

392-
if (offset + count <= XFS_ISIZE(ip))
393-
return 0;
394-
395-
if (!(mp->m_flags & XFS_MOUNT_ALLOCSIZE) &&
396-
(XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_allocsize_blocks)))
380+
/*
381+
* As an exception we don't do any preallocation at all if the file is
382+
* smaller than the minimum preallocation and we are using the default
383+
* dynamic preallocation scheme, as it is likely this is the only write
384+
* to the file that is going to be done.
385+
*/
386+
if (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_allocsize_blocks))
397387
return 0;
398388

399389
/*
400-
* If an explicit allocsize is set, the file is small, or we
401-
* are writing behind a hole, then use the minimum prealloc:
390+
* Use the minimum preallocation size for small files or if we are
391+
* writing right after a hole.
402392
*/
403-
if ((mp->m_flags & XFS_MOUNT_ALLOCSIZE) ||
404-
XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) ||
393+
if (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) ||
405394
!xfs_iext_prev_extent(ifp, &ncur, &prev) ||
406395
prev.br_startoff + prev.br_blockcount < offset_fsb)
407396
return mp->m_allocsize_blocks;
408397

409398
/*
410-
* Determine the initial size of the preallocation. We are beyond the
411-
* current EOF here, but we need to take into account whether this is
412-
* a sparse write or an extending write when determining the
413-
* preallocation size. Hence we need to look up the extent that ends
414-
* at the current write offset and use the result to determine the
415-
* preallocation size.
416-
*
417-
* If the extent is a hole, then preallocation is essentially disabled.
418-
* Otherwise we take the size of the preceding data extents as the basis
419-
* for the preallocation size. Note that we don't care if the previous
420-
* extents are written or not.
421-
*
422-
* If the size of the extents is greater than half the maximum extent
423-
* length, then use the current offset as the basis. This ensures that
424-
* for large files the preallocation size always extends to MAXEXTLEN
425-
* rather than falling short due to things like stripe unit/width
426-
* alignment of real extents.
399+
* Take the size of the preceding data extents as the basis for the
400+
* preallocation size. Note that we don't care if the previous extents
401+
* are written or not.
427402
*/
428403
plen = prev.br_blockcount;
429404
while (xfs_iext_prev_extent(ifp, &ncur, &got)) {
@@ -435,19 +410,25 @@ xfs_iomap_prealloc_size(
435410
plen += got.br_blockcount;
436411
prev = got;
437412
}
413+
414+
/*
415+
* If the size of the extents is greater than half the maximum extent
416+
* length, then use the current offset as the basis. This ensures that
417+
* for large files the preallocation size always extends to MAXEXTLEN
418+
* rather than falling short due to things like stripe unit/width
419+
* alignment of real extents.
420+
*/
438421
alloc_blocks = plen * 2;
439422
if (alloc_blocks > MAXEXTLEN)
440423
alloc_blocks = XFS_B_TO_FSB(mp, offset);
441-
if (!alloc_blocks)
442-
goto check_writeio;
443424
qblocks = alloc_blocks;
444425

445426
/*
446427
* MAXEXTLEN is not a power of two value but we round the prealloc down
447428
* to the nearest power of two value after throttling. To prevent the
448-
* round down from unconditionally reducing the maximum supported prealloc
449-
* size, we round up first, apply appropriate throttling, round down and
450-
* cap the value to MAXEXTLEN.
429+
* round down from unconditionally reducing the maximum supported
430+
* prealloc size, we round up first, apply appropriate throttling,
431+
* round down and cap the value to MAXEXTLEN.
451432
*/
452433
alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(MAXEXTLEN),
453434
alloc_blocks);
@@ -508,7 +489,6 @@ xfs_iomap_prealloc_size(
508489
*/
509490
while (alloc_blocks && alloc_blocks >= freesp)
510491
alloc_blocks >>= 4;
511-
check_writeio:
512492
if (alloc_blocks < mp->m_allocsize_blocks)
513493
alloc_blocks = mp->m_allocsize_blocks;
514494
trace_xfs_iomap_prealloc_size(ip, alloc_blocks, shift,
@@ -975,9 +955,16 @@ xfs_buffered_write_iomap_begin(
975955
if (error)
976956
goto out_unlock;
977957

978-
if (eof) {
979-
prealloc_blocks = xfs_iomap_prealloc_size(ip, allocfork, offset,
980-
count, &icur);
958+
if (eof && offset + count > XFS_ISIZE(ip)) {
959+
/*
960+
* Determine the initial size of the preallocation.
961+
* We clean up any extra preallocation when the file is closed.
962+
*/
963+
if (mp->m_flags & XFS_MOUNT_ALLOCSIZE)
964+
prealloc_blocks = mp->m_allocsize_blocks;
965+
else
966+
prealloc_blocks = xfs_iomap_prealloc_size(ip, allocfork,
967+
offset, count, &icur);
981968
if (prealloc_blocks) {
982969
xfs_extlen_t align;
983970
xfs_off_t end_offset;

0 commit comments

Comments
 (0)