diff mbox series

[7/8] generic/371: disable speculative preallocation regressions on XFS

Message ID 162561730547.543423.5029188797370208051.stgit@locust (mailing list archive)
State New, archived
Headers show
Series fstests: random fixes | expand

Commit Message

Darrick J. Wong July 7, 2021, 12:21 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Once in a very long while, the fallocate calls in this test will fail
due to ENOSPC conditions.  While in theory this test is careful only to
allocate at most 160M of space from a 256M filesystem, there's a twist
on XFS: speculative preallocation.

The first loop in this test is an 80M appending write done in units of
4k.  Once the file size hits 64k, XFS will begin speculatively
preallocating blocks past the end of the file; as the file grows larger,
so will the speculative preallocation.

Since the pwrite/rm loop races with the fallocate/rm loop, it's possible
that the fallocate loop will free that file just before the buffered
write extends the speculative preallocation out to 160MB.  With fs and
log overhead, that doesn't leave enough free space to start the 80MB
fallocate request, which tries to avoid disappointing the caller by
freeing all speculative preallocations.  That fails if the pwriter
thread owns the IOLOCK on $testfile1, so fallocate returns ENOSPC and
the test fails.

The simple solution here is to disable speculative preallocation by
setting an extent size hint if the fs is XFS.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 tests/generic/371 |    8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Allison Henderson July 9, 2021, 11:50 p.m. UTC | #1
On 7/6/21 5:21 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Once in a very long while, the fallocate calls in this test will fail
> due to ENOSPC conditions.  While in theory this test is careful only to
> allocate at most 160M of space from a 256M filesystem, there's a twist
> on XFS: speculative preallocation.
> 
> The first loop in this test is an 80M appending write done in units of
> 4k.  Once the file size hits 64k, XFS will begin speculatively
> preallocating blocks past the end of the file; as the file grows larger,
> so will the speculative preallocation.
> 
> Since the pwrite/rm loop races with the fallocate/rm loop, it's possible
> that the fallocate loop will free that file just before the buffered
> write extends the speculative preallocation out to 160MB.  With fs and
> log overhead, that doesn't leave enough free space to start the 80MB
> fallocate request, which tries to avoid disappointing the caller by
> freeing all speculative preallocations.  That fails if the pwriter
> thread owns the IOLOCK on $testfile1, so fallocate returns ENOSPC and
> the test fails.
> 
> The simple solution here is to disable speculative preallocation by
> setting an extent size hint if the fs is XFS.
> 
Ok, makes sense
Reviewed-by: Allison Henderson <allison.henderson@oracle.com>

> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>   tests/generic/371 |    8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> 
> diff --git a/tests/generic/371 b/tests/generic/371
> index c94fa85e..a2fdaf7b 100755
> --- a/tests/generic/371
> +++ b/tests/generic/371
> @@ -18,10 +18,18 @@ _begin_fstest auto quick enospc prealloc
>   _supported_fs generic
>   _require_scratch
>   _require_xfs_io_command "falloc"
> +test "$FSTYP" = "xfs" && _require_xfs_io_command "extsize"
>   
>   _scratch_mkfs_sized $((256 * 1024 * 1024)) >> $seqres.full 2>&1
>   _scratch_mount
>   
> +# Disable speculative post-EOF preallocation on XFS, which can grow fast enough
> +# that a racing fallocate then fails.
> +if [ "$FSTYP" = "xfs" ]; then
> +	alloc_sz="$(_get_file_block_size $SCRATCH_MNT)"
> +	$XFS_IO_PROG -c "extsize $alloc_sz" $SCRATCH_MNT >> $seqres.full
> +fi
> +
>   testfile1=$SCRATCH_MNT/testfile1
>   testfile2=$SCRATCH_MNT/testfile2
>   
>
diff mbox series

Patch

diff --git a/tests/generic/371 b/tests/generic/371
index c94fa85e..a2fdaf7b 100755
--- a/tests/generic/371
+++ b/tests/generic/371
@@ -18,10 +18,18 @@  _begin_fstest auto quick enospc prealloc
 _supported_fs generic
 _require_scratch
 _require_xfs_io_command "falloc"
+test "$FSTYP" = "xfs" && _require_xfs_io_command "extsize"
 
 _scratch_mkfs_sized $((256 * 1024 * 1024)) >> $seqres.full 2>&1
 _scratch_mount
 
+# Disable speculative post-EOF preallocation on XFS, which can grow fast enough
+# that a racing fallocate then fails.
+if [ "$FSTYP" = "xfs" ]; then
+	alloc_sz="$(_get_file_block_size $SCRATCH_MNT)"
+	$XFS_IO_PROG -c "extsize $alloc_sz" $SCRATCH_MNT >> $seqres.full
+fi
+
 testfile1=$SCRATCH_MNT/testfile1
 testfile2=$SCRATCH_MNT/testfile2