Skip to contentSkip to conversation

generic: fixes for different allocation behaviours

PATCH In review Dave Chinner 2 participants 5 messages May 14, 2015 – May 19, 2015

lore
Share & tools
lore
#0 lore raw

cover generic: fixes for different allocation behaviours

Hi folks,

These 3 patches address failures I found when testing the XFS DAX functionality. DAX disables delayed allocation on XFS, so the size of the buffer in the write() call determines the size of the allocation that is done. Hence tests that expect a specific extent layout need to do IO in buffers as large as the extent size they expect to be created.

The other side of this is that some tests also expect partial writes to occur, which happened as a side effect of buffered writes being broken down into PAGE_SIZE chunks. With DAX, that does not happen - the writes tend to either succeed or fail completely, especially if it is an ENOSPC condition that is ocurring.

HEnce these patches address these test assumptions, and now they work correctly and pass on both DAX and non-DAX filesystems.

Cheers,

Dave.

#1 lore raw

PATCH 1/3 generic/018: use xfs_io and larger buffers for writes

From: Dave Chinner <[email protected]>

The test currently uses 'dd' directly for writing to files; instead we should be using the xfs_io pwrite command.

Also, when we have a configuration that does not do delayed allocation (e.g. dax), there is no guarantee that the files will be allocated in the pattern expected, so do all the writes from a single buffer so the kernel can allocate extents in the manner the test expects as much as possible.

---
 tests/generic/018 | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
tests/generic/018 +12 -7
index 2b804b5..fbefbe2 100755
@@ -57,6 +57,7 @@ fragfile=$SCRATCH_MNT/fragfile.$$
 rm -f $fragfile
 
 # Craft some fragmented files, defrag them, check the result.
+bsize=4096
 
 echo "zero-length file:" | tee -a $seqres.full
 touch $fragfile
@@ -67,24 +68,28 @@ $XFS_IO_PROG -f -c "truncate 1m" $fragfile
 _defrag --before 0 --after 0 $fragfile
 
 echo "Contiguous file:" | tee -a $seqres.full
-dd if=/dev/zero of=$fragfile bs=4k count=4 &>/dev/null
+$XFS_IO_PROG -f -c "pwrite -b $((4 * bsize)) 0 $((4 * bsize))" $fragfile \
+					> /dev/null
 _defrag --before 1 --after 1 $fragfile
 
 echo "Write backwards sync, but contiguous - should defrag to 1 extent" | tee -a $seqres.full
-for I in `seq 9 -1 0`; do
-	dd if=/dev/zero of=$fragfile bs=4k count=1 conv=notrunc seek=$I oflag=sync &>/dev/null
+for i in `seq 9 -1 0`; do
+	$XFS_IO_PROG -fs -c "pwrite $((i * bsize)) $bsize" $fragfile \
+					> /dev/null
 done
 _defrag --before 10 --after 1 $fragfile
 
 echo "Write backwards sync leaving holes - defrag should do nothing" | tee -a $seqres.full
-for I in `seq 31 -2 0`; do
-	dd if=/dev/zero of=$fragfile bs=4k count=1 conv=notrunc seek=$I oflag=sync &>/dev/null
+for i in `seq 31 -2 0`; do
+	$XFS_IO_PROG -fs -c "pwrite $((i * bsize)) $bsize" $fragfile \
+					> /dev/null
 done
 _defrag --before 16 --after 16 $fragfile
 
 echo "Write forwards sync leaving holes - defrag should do nothing" | tee -a $seqres.full
-for I in `seq 0 2 31`; do
-	dd if=/dev/zero of=$fragfile bs=4k count=1 conv=notrunc seek=$I oflag=sync &>/dev/null
+for i in `seq 0 2 31`; do
+	$XFS_IO_PROG -fs -c "pwrite $((i * bsize)) $bsize" $fragfile \
+					> /dev/null
 done
 _defrag --before 16 --after 16 $fragfile
 
Signature · 1 line
2.0.0
#2 lore raw

PATCH 2/3 generic/223, xfs/203: IO is not well aligned

In reply to Dave Chinner

From: Dave Chinner <[email protected]>

On certain configurations (e.g. MOUNT_OPTIONS="-o dax") we get different allocation patterns due to the writes being done in multiple pwrite() calls. e.g. the write is 8k, but the buffer size is 4k, and so the filesystem sees 4k writes. If the filesytem is not using delayed allocation, then the allocation context is a 4k write rather than an 8k write and so they don't get appropriately aligned.

Fix this by making the write buffer the same size and the writes being done.

---
 tests/generic/223 | 2 +-
 tests/xfs/203     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
tests/generic/223 +1 -1
index a67b8d5..f150dc9 100755
@@ -69,7 +69,7 @@ for SUNIT_K in 8 16 32 64 128; do
 			$XFS_IO_PROG -f -c "falloc 0 $SIZE" \
 				$SCRATCH_MNT/file-$FILE-$SIZE-falloc \
 					>> $seqres.full 2>&1
-			$XFS_IO_PROG -f -c "pwrite 0 $SIZE" \
+			$XFS_IO_PROG -f -c "pwrite -b $SIZE 0 $SIZE" \
 				$SCRATCH_MNT/file-$FILE-$SIZE-write \
 					>> $seqres.full 2>&1
 			src/t_stripealign $SCRATCH_MNT/file-$FILE-$SIZE-falloc \
tests/xfs/203 +2 -2
index 7e18ca3..2ac5290 100755
@@ -38,11 +38,11 @@ _write_holes()
 	let fsize=$(($writes * 0x100000))
 
 	# prevent EOF preallocation from affecting results
-	xfs_io -f $file -c "truncate $fsize"
+	$XFS_IO_PROG -f $file -c "truncate $fsize"
 
 	offset=0
 	for i in `seq 0 $writes`; do
-		xfs_io -f $file -c "pwrite -q $offset 64k"
+		$XFS_IO_PROG -f $file -c "pwrite -b 64k -q $offset 64k"
 		let offset=$offset+0x100000
 	done
 }
Signature · 1 line
2.0.0
#3 lore raw

PATCH 3/3 generic/275: writes may not partially succeed

In reply to Dave Chinner

From: Dave Chinner <[email protected]>

When a large IO is done as a single buffer, there is no guarantee that it will partially succeed when close to ENOSPC. The test assumes that the kernel is going to break the write down into smaller chunks (i.e. buffered IO breaking it down into PAGE_SIZE allocations), but certain configurations will not do this. e.g. extent size hints are set or DAX is being used) and hence the large write fails completely as there is not space for the entire allocation to be made.

Hence break the final write in the test up into multiple small writes, thereby acheiving the same effect - ensuring that we can write more data after removing some space....

---
 tests/generic/275 | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
tests/generic/275 +7 -3
index 7382edb..f1963d8 100755
@@ -57,6 +57,8 @@ umount $SCRATCH_DEV 2>/dev/null
 _scratch_mkfs_sized $((2 * 1024 * 1024 * 1024)) >>$seqres.full 2>&1
 _scratch_mount
 
+# 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
 [ $? -ne 0 ] && _fail "Error creating file"
 
@@ -79,14 +81,16 @@ $DF_PROG $SCRATCH_MNT >>$seqres.full 2>&1
 _freespace=`$DF_PROG -k $SCRATCH_MNT | tail -n 1 | awk '{print $5}'`
 [ $_freespace -gt 1024 ] && _fail "could not sufficiently fill filesystem"
 
-# Try a write larger than available space
-dd if=/dev/zero of=$SCRATCH_MNT/tmp1 bs=1M count=1 >>$seqres.full 2>&1
+# 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
 echo "Bytes written until ENOSPC:" >>$seqres.full
 du $SCRATCH_MNT/tmp1 >>$seqres.full
 
 # And at least some of it should succeed.
 _filesize=`ls -l $SCRATCH_MNT/tmp1 | awk '{print $5}'`
-[ $_filesize -eq 0 ] && _fail "write file err: Partial write until enospc failed; wrote 0 bytes."
+[ $_filesize -lt $((128 * 1024)) ] && \
+	_fail "Partial write until enospc failed; wrote $_filesize bytes."
 
 echo "done"
 status=0
Signature · 1 line
2.0.0
Reviewed-by on the v1 series
#4 lore raw
In reply to Dave Chinner
Quoted 9 lines · Dave Chinner

Hi folks,

These 3 patches address failures I found when testing the XFS DAX functionality. DAX disables delayed allocation on XFS, so the size of the buffer in the write() call determines the size of the allocation that is done. Hence tests that expect a specific extent layout need to do IO in buffers as large as the extent size they expect to be created.

Quoted 9 lines

The other side of this is that some tests also expect partial writes to occur, which happened as a side effect of buffered writes being broken down into PAGE_SIZE chunks. With DAX, that does not happen - the writes tend to either succeed or fail completely, especially if it is an ENOSPC condition that is ocurring.

HEnce these patches address these test assumptions, and now they work correctly and pass on both DAX and non-DAX filesystems.

All look fine to me:

Quoted 7 lines

Cheers,

Dave.
--
To unsubscribe from this list: send the line "unsubscribe fstests" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html