[PATCH 1/1] generic/275: fix premature enospc errors when fs block size is large

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Darrick J. Wong <djwong@xxxxxxxxxx>

When running this test on an XFS filesystem with a 64k block size, I
see this error:

generic/275       - output mismatch (see /var/tmp/fstests/generic/275.out.bad)
    --- tests/generic/275.out   2021-05-13 11:47:55.694860280 -0700
    +++ /var/tmp/fstests/generic/275.out.bad    2022-07-19 10:38:41.840000000 -0700
    @@ -2,4 +2,7 @@
     ------------------------------
     write until ENOSPC test
     ------------------------------
    +du: cannot access '/opt/tmp1': No such file or directory
    +stat: cannot statx '/opt/tmp1': No such file or directory
    +/tmp/fstests/tests/generic/275: line 74: [: -lt: unary operator expected
     done
    ...
    (Run 'diff -u /tmp/fstests/tests/generic/275.out /var/tmp/fstests/generic/275.out.bad'  to see the entire diff)

The 275.full file indicates that the test was unable to recreate the
$SCRATCH_MNT/tmp1 file after we freed all but the last 256K of free
space in the filesystem.  I mounted the scratch fs, and df reported
exactly 256K of free space available, which means there are 4 blocks
left in the filesystem for user programs to use.

Unfortunately for this test, xfs_create requires sufficient free blocks
in the filesystem to handle full inode btree splits and the maximal
directory expansion for a new dirent.  In other words, there must be
enough free space to handle the worst case space consumption.  That
quantity is 26 blocks, hence the last dd in the test fails with ENOSPC,
which makes the test fail.

Fix all this by creating the file that we use to test the low-space file
write *before* we drain the free space down to 256K.

Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
---
 tests/generic/275 |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)


diff --git a/tests/generic/275 b/tests/generic/275
index 6189edca..f3b05409 100755
--- a/tests/generic/275
+++ b/tests/generic/275
@@ -37,6 +37,15 @@ _scratch_unmount 2>/dev/null
 _scratch_mkfs_sized $((2 * 1024 * 1024 * 1024)) >>$seqres.full 2>&1
 _scratch_mount
 
+# Certain filesystems such as XFS require sufficient free blocks to handle the
+# worst-case directory expansion as a result of a creat() call.  If the fs
+# block size is very large (e.g. 64k) then the number of blocks required for
+# the creat() call can represent far more free space than the 256K left at the
+# end of this test.  Therefore, create the file that the last dd will write to
+# now when we know there's enough free blocks.
+later_file=$SCRATCH_MNT/later
+touch $later_file
+
 # this file will get removed to create 256k of free space after ENOSPC
 # conditions are created.
 dd if=/dev/zero of=$SCRATCH_MNT/tmp1 bs=256K count=1 >>$seqres.full 2>&1
@@ -63,12 +72,12 @@ _freespace=`$DF_PROG -k $SCRATCH_MNT | tail -n 1 | awk '{print $5}'`
 
 # Try to write more than available space in chunks that will allow at least one
 # full write to succeed.
-dd if=/dev/zero of=$SCRATCH_MNT/tmp1 bs=128k count=8 >>$seqres.full 2>&1
+dd if=/dev/zero of=$later_file bs=128k count=8 >>$seqres.full 2>&1
 echo "Bytes written until ENOSPC:" >>$seqres.full
-du $SCRATCH_MNT/tmp1 >>$seqres.full
+du $later_file >>$seqres.full
 
 # And at least some of it should succeed.
-_filesize=`_get_filesize $SCRATCH_MNT/tmp1`
+_filesize=`_get_filesize $later_file`
 [ $_filesize -lt $((128 * 1024)) ] && \
 	_fail "Partial write until enospc failed; wrote $_filesize bytes."
 




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux