diff mbox series

[v2,3/5] generic/xxx: Add MMAP CoW test for 'hole' case

Message ID 20211105045222.157826-4-ruansy.fnst@fujitsu.com (mailing list archive)
State New, archived
Headers show
Series generic: add a couple of MMAP CoW tests | expand

Commit Message

Shiyang Ruan Nov. 5, 2021, 4:52 a.m. UTC
Check what happens if we MMAP CoW blocks 2-4 of a page's worth of blocks when
the second block is a hole.  (MMAP version of generic/218,220)

Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com>
---
 tests/generic/902     | 70 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/902.out |  6 ++++
 2 files changed, 76 insertions(+)
 create mode 100755 tests/generic/902
 create mode 100644 tests/generic/902.out

Comments

Darrick J. Wong Nov. 5, 2021, 4:40 p.m. UTC | #1
On Fri, Nov 05, 2021 at 12:52:20PM +0800, Shiyang Ruan wrote:
> Check what happens if we MMAP CoW blocks 2-4 of a page's worth of blocks when
> the second block is a hole.  (MMAP version of generic/218,220)
> 
> Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com>
> ---
>  tests/generic/902     | 70 +++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/902.out |  6 ++++
>  2 files changed, 76 insertions(+)
>  create mode 100755 tests/generic/902
>  create mode 100644 tests/generic/902.out
> 
> diff --git a/tests/generic/902 b/tests/generic/902
> new file mode 100755
> index 00000000..a0992fc8
> --- /dev/null
> +++ b/tests/generic/902
> @@ -0,0 +1,70 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# FS QA Test No. xxx
> +#
> +# See what happens if we MMAP CoW blocks 2-4 of a page's worth of blocks when
> +# the second block is a hole.  (MMAP version of generic/218,220)
> +#
> +# This test is dependent on the system page size, so we cannot use md5 in
> +# the golden output; we can only compare to a check file.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick clone
> +
> +# Override the default cleanup function.
> +_cleanup()
> +{
> +    cd /
> +    rm -rf $tmp.* $testdir
> +}
> +
> +# Import common functions.
> +. ./common/filter
> +. ./common/reflink
> +
> +# real QA test starts here
> +_require_scratch_reflink
> +_require_xfs_io_command "falloc"
> +
> +pagesz=$(getconf PAGE_SIZE)
> +blksz=$((pagesz / 4))
> +
> +echo "Format and mount"
> +_scratch_mkfs_blocksized $blksz > $seqres.full 2>&1
> +_scratch_mount >> $seqres.full 2>&1
> +
> +testdir=$SCRATCH_MNT/test-$seq
> +mkdir $testdir
> +
> +real_blksz=$(_get_file_block_size $testdir)
> +test $real_blksz != $blksz && _notrun "Failed to format with small blocksize."
> +
> +echo "Create the original files"
> +_pwrite_byte 0x61 0 $pagesz $testdir/file1 >> $seqres.full
> +
> +$XFS_IO_PROG -f -c "truncate $pagesz" $testdir/file2 >> $seqres.full
> +$XFS_IO_PROG -f -c "truncate $pagesz" $testdir/file2.chk >> $seqres.full
> +
> +_reflink_range $testdir/file1 $blksz $testdir/file2 $((blksz * 2)) $blksz >> $seqres.full
> +_pwrite_byte 0x61 $((blksz * 2)) $blksz $testdir/file2.chk >> $seqres.full
> +_scratch_cycle_mount
> +
> +echo "Compare files"
> +cmp -s $testdir/file1 $testdir/file2 && echo "file1 and file2 should not match."
> +cmp -s $testdir/file2 $testdir/file2.chk || echo "file2 and file2.chk don't match."
> +
> +echo "CoW and unmount"
> +$XFS_IO_PROG -f -c "mmap 0 $pagesz" \
> +    -c "mwrite -S 0x63 $((blksz + 17)) $((blksz * 3 - 34))" $testdir/file2 >> $seqres.full
> +$XFS_IO_PROG -f -c "mmap 0 $pagesz" \
> +    -c "mwrite -S 0x63 $((blksz + 17)) $((blksz * 3 - 34))" $testdir/file2.chk >> $seqres.full
> +_scratch_cycle_mount

One thing I noticed about the last two tests is that since you only
write to the two shared blocks in the middle of the page, the fs could
very well ignore the holes in the first and last block when it's
handling the page fault.  XFS/iomap will (iirc) allocate those two holes
at writeback time and flush the whole thing to disk, but that isn't a
guaranteed behavior.

So I think the point of this test is to make sure that COW does the
right thing on a bs<ps filesystem such that the adjoining blocks don't
end up with garbage in them, right?  And we don't care what allocation
decisions the fs makes, so long as the read()able contents are what we
expect, right?

If that's correct,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> +
> +echo "Compare files"
> +cmp -s $testdir/file1 $testdir/file2 && echo "file1 and file2 should not match."
> +cmp -s $testdir/file2 $testdir/file2.chk || echo "file2 and file2.chk don't match."
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/902.out b/tests/generic/902.out
> new file mode 100644
> index 00000000..4fb8b6cb
> --- /dev/null
> +++ b/tests/generic/902.out
> @@ -0,0 +1,6 @@
> +QA output created by 902
> +Format and mount
> +Create the original files
> +Compare files
> +CoW and unmount
> +Compare files
> -- 
> 2.33.0
> 
> 
>
Shiyang Ruan Nov. 8, 2021, 6:33 a.m. UTC | #2
在 2021/11/6 0:40, Darrick J. Wong 写道:
> On Fri, Nov 05, 2021 at 12:52:20PM +0800, Shiyang Ruan wrote:
>> Check what happens if we MMAP CoW blocks 2-4 of a page's worth of blocks when
>> the second block is a hole.  (MMAP version of generic/218,220)
>>
>> Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com>
>> ---
>>   tests/generic/902     | 70 +++++++++++++++++++++++++++++++++++++++++++
>>   tests/generic/902.out |  6 ++++
>>   2 files changed, 76 insertions(+)
>>   create mode 100755 tests/generic/902
>>   create mode 100644 tests/generic/902.out
>>
>> diff --git a/tests/generic/902 b/tests/generic/902
>> new file mode 100755
>> index 00000000..a0992fc8
>> --- /dev/null
>> +++ b/tests/generic/902
>> @@ -0,0 +1,70 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +#
>> +# FS QA Test No. xxx
>> +#
>> +# See what happens if we MMAP CoW blocks 2-4 of a page's worth of blocks when
>> +# the second block is a hole.  (MMAP version of generic/218,220)
>> +#
>> +# This test is dependent on the system page size, so we cannot use md5 in
>> +# the golden output; we can only compare to a check file.
>> +#
>> +. ./common/preamble
>> +_begin_fstest auto quick clone
>> +
>> +# Override the default cleanup function.
>> +_cleanup()
>> +{
>> +    cd /
>> +    rm -rf $tmp.* $testdir
>> +}
>> +
>> +# Import common functions.
>> +. ./common/filter
>> +. ./common/reflink
>> +
>> +# real QA test starts here
>> +_require_scratch_reflink
>> +_require_xfs_io_command "falloc"
>> +
>> +pagesz=$(getconf PAGE_SIZE)
>> +blksz=$((pagesz / 4))
>> +
>> +echo "Format and mount"
>> +_scratch_mkfs_blocksized $blksz > $seqres.full 2>&1
>> +_scratch_mount >> $seqres.full 2>&1
>> +
>> +testdir=$SCRATCH_MNT/test-$seq
>> +mkdir $testdir
>> +
>> +real_blksz=$(_get_file_block_size $testdir)
>> +test $real_blksz != $blksz && _notrun "Failed to format with small blocksize."
>> +
>> +echo "Create the original files"
>> +_pwrite_byte 0x61 0 $pagesz $testdir/file1 >> $seqres.full
>> +
>> +$XFS_IO_PROG -f -c "truncate $pagesz" $testdir/file2 >> $seqres.full
>> +$XFS_IO_PROG -f -c "truncate $pagesz" $testdir/file2.chk >> $seqres.full
>> +
>> +_reflink_range $testdir/file1 $blksz $testdir/file2 $((blksz * 2)) $blksz >> $seqres.full
>> +_pwrite_byte 0x61 $((blksz * 2)) $blksz $testdir/file2.chk >> $seqres.full
>> +_scratch_cycle_mount
>> +
>> +echo "Compare files"
>> +cmp -s $testdir/file1 $testdir/file2 && echo "file1 and file2 should not match."
>> +cmp -s $testdir/file2 $testdir/file2.chk || echo "file2 and file2.chk don't match."
>> +
>> +echo "CoW and unmount"
>> +$XFS_IO_PROG -f -c "mmap 0 $pagesz" \
>> +    -c "mwrite -S 0x63 $((blksz + 17)) $((blksz * 3 - 34))" $testdir/file2 >> $seqres.full
>> +$XFS_IO_PROG -f -c "mmap 0 $pagesz" \
>> +    -c "mwrite -S 0x63 $((blksz + 17)) $((blksz * 3 - 34))" $testdir/file2.chk >> $seqres.full
>> +_scratch_cycle_mount
> 
> One thing I noticed about the last two tests is that since you only
> write to the two shared blocks in the middle of the page, the fs could
> very well ignore the holes in the first and last block when it's
> handling the page fault.  XFS/iomap will (iirc) allocate those two holes
> at writeback time and flush the whole thing to disk, but that isn't a
> guaranteed behavior.

I noticed this too.

> 
> So I think the point of this test is to make sure that COW does the
> right thing on a bs<ps filesystem such that the adjoining blocks don't
> end up with garbage in them, right?  And we don't care what allocation
> decisions the fs makes, so long as the read()able contents are what we
> expect, right?

Yes, this is the purpose of this set of tests, including BufferedIO, 
DIO, MMAP operations.

> 
> If that's correct,
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>

Thanks.


--
Ruan.

> 
> --D
> 
>> +
>> +echo "Compare files"
>> +cmp -s $testdir/file1 $testdir/file2 && echo "file1 and file2 should not match."
>> +cmp -s $testdir/file2 $testdir/file2.chk || echo "file2 and file2.chk don't match."
>> +
>> +# success, all done
>> +status=0
>> +exit
>> diff --git a/tests/generic/902.out b/tests/generic/902.out
>> new file mode 100644
>> index 00000000..4fb8b6cb
>> --- /dev/null
>> +++ b/tests/generic/902.out
>> @@ -0,0 +1,6 @@
>> +QA output created by 902
>> +Format and mount
>> +Create the original files
>> +Compare files
>> +CoW and unmount
>> +Compare files
>> -- 
>> 2.33.0
>>
>>
>>
diff mbox series

Patch

diff --git a/tests/generic/902 b/tests/generic/902
new file mode 100755
index 00000000..a0992fc8
--- /dev/null
+++ b/tests/generic/902
@@ -0,0 +1,70 @@ 
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. xxx
+#
+# See what happens if we MMAP CoW blocks 2-4 of a page's worth of blocks when
+# the second block is a hole.  (MMAP version of generic/218,220)
+#
+# This test is dependent on the system page size, so we cannot use md5 in
+# the golden output; we can only compare to a check file.
+#
+. ./common/preamble
+_begin_fstest auto quick clone
+
+# Override the default cleanup function.
+_cleanup()
+{
+    cd /
+    rm -rf $tmp.* $testdir
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_require_scratch_reflink
+_require_xfs_io_command "falloc"
+
+pagesz=$(getconf PAGE_SIZE)
+blksz=$((pagesz / 4))
+
+echo "Format and mount"
+_scratch_mkfs_blocksized $blksz > $seqres.full 2>&1
+_scratch_mount >> $seqres.full 2>&1
+
+testdir=$SCRATCH_MNT/test-$seq
+mkdir $testdir
+
+real_blksz=$(_get_file_block_size $testdir)
+test $real_blksz != $blksz && _notrun "Failed to format with small blocksize."
+
+echo "Create the original files"
+_pwrite_byte 0x61 0 $pagesz $testdir/file1 >> $seqres.full
+
+$XFS_IO_PROG -f -c "truncate $pagesz" $testdir/file2 >> $seqres.full
+$XFS_IO_PROG -f -c "truncate $pagesz" $testdir/file2.chk >> $seqres.full
+
+_reflink_range $testdir/file1 $blksz $testdir/file2 $((blksz * 2)) $blksz >> $seqres.full
+_pwrite_byte 0x61 $((blksz * 2)) $blksz $testdir/file2.chk >> $seqres.full
+_scratch_cycle_mount
+
+echo "Compare files"
+cmp -s $testdir/file1 $testdir/file2 && echo "file1 and file2 should not match."
+cmp -s $testdir/file2 $testdir/file2.chk || echo "file2 and file2.chk don't match."
+
+echo "CoW and unmount"
+$XFS_IO_PROG -f -c "mmap 0 $pagesz" \
+    -c "mwrite -S 0x63 $((blksz + 17)) $((blksz * 3 - 34))" $testdir/file2 >> $seqres.full
+$XFS_IO_PROG -f -c "mmap 0 $pagesz" \
+    -c "mwrite -S 0x63 $((blksz + 17)) $((blksz * 3 - 34))" $testdir/file2.chk >> $seqres.full
+_scratch_cycle_mount
+
+echo "Compare files"
+cmp -s $testdir/file1 $testdir/file2 && echo "file1 and file2 should not match."
+cmp -s $testdir/file2 $testdir/file2.chk || echo "file2 and file2.chk don't match."
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/902.out b/tests/generic/902.out
new file mode 100644
index 00000000..4fb8b6cb
--- /dev/null
+++ b/tests/generic/902.out
@@ -0,0 +1,6 @@ 
+QA output created by 902
+Format and mount
+Create the original files
+Compare files
+CoW and unmount
+Compare files