Message ID | 20190526084535.999-5-amir73il@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fstests: copy_file_range() tests | expand |
On Sun, May 26, 2019 at 11:45:34AM +0300, Amir Goldstein wrote: > Test that copy_file_range will return the correct errors for various > error conditions and boundary constraints. > > [Amir] Split out cross-device copy_range test and use only scratch dev. > Split out immutable/swapfile test cases to reduce the requirements to > run the bounds check to minimum and get coverage for more filesystems. > Remove the tests for read past EOF and write after chmod -r, > because we decided to stick with read(2)/write(2) semantics. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > Signed-off-by: Amir Goldstein <amir73il@gmail.com> > --- > tests/generic/990 | 123 ++++++++++++++++++++++++++++++++++++++++++ > tests/generic/990.out | 37 +++++++++++++ > tests/generic/group | 1 + > 3 files changed, 161 insertions(+) > create mode 100755 tests/generic/990 > create mode 100644 tests/generic/990.out > > diff --git a/tests/generic/990 b/tests/generic/990 > new file mode 100755 > index 00000000..5e2421b6 > --- /dev/null > +++ b/tests/generic/990 > @@ -0,0 +1,123 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. > +# > +# FS QA Test No. 990 > +# > +# Exercise copy_file_range() syscall error conditions. > +# > +seq=`basename $0` > +seqres=$RESULT_DIR/$seq > +echo "QA output created by $seq" > + > +here=`pwd` > +tmp=/tmp/$$ > +status=1 # failure is the default! > +trap "_cleanup; exit \$status" 0 1 2 3 7 15 > + > +_cleanup() > +{ > + cd / > + rm -rf $tmp.* > +} > + > +# get standard environment, filters and checks > +. ./common/rc > +. ./common/filter > + > +# real QA test starts here > +_supported_os Linux > +_supported_fs generic > + > +rm -f $seqres.full > + > +_require_test > +_require_xfs_io_command "copy_range" > +# > +# This test effectively requires xfs_io v4.20 with the commits > +# 2a42470b xfs_io: copy_file_range length is a size_t > +# 1a05efba io: open pipes in non-blocking mode So, uh, is this going to cause test hangs on xfsprogs < 4.20? --D > +# > +# The same xfs_io release also included the new 'chmod' command. > +# Use this fake requirement to prevent the test case of copy_range with fifo > +# from hanging the test with old xfs_io. > +# > +_require_xfs_io_command "chmod" > + > +testdir="$TEST_DIR/test-$seq" > +rm -rf $testdir > +mkdir $testdir > + > +rm -f $seqres.full > + > +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 128k" $testdir/file >> $seqres.full 2>&1 > + > +echo source range overlaps destination range in same file returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 32k -d 48k -l 32k $testdir/file" $testdir/file > + > +echo > +echo destination file O_RDONLY returns EBADF > +$XFS_IO_PROG -f -r -c "copy_range -l 32k $testdir/file" $testdir/copy > + > +echo > +echo destination file O_APPEND returns EBADF > +$XFS_IO_PROG -f -a -c "copy_range -l 32k $testdir/file" $testdir/copy > + > +echo > +echo source/destination as directory returns EISDIR > +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir" $testdir/copy > + > +echo > +echo source/destination as blkdev returns EINVAL > +mknod $testdir/dev1 b 1 3 > +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir/dev1 > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/dev1" $testdir/copy > + > +echo > +echo source/destination as chardev returns EINVAL > +mknod $testdir/dev2 c 1 3 > +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir/dev2 > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/dev2" $testdir/copy > + > +echo > +echo source/destination as FIFO returns EINVAL > +mkfifo $testdir/fifo > +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir/fifo > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/fifo" $testdir/copy > + > +max_off=$((8 * 2**60 - 65536 - 1)) > +min_off=65537 > + > +echo > +echo length beyond 8EiB wraps around 0 returns EOVERFLOW > +$XFS_IO_PROG -f -c "copy_range -l 10e -s $max_off $testdir/file" $testdir/copy > +$XFS_IO_PROG -f -c "copy_range -l 10e -d $max_off $testdir/file" $testdir/copy > + > +echo > +echo source range beyond 8TiB returns 0 > +$XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy > + > +echo > +echo destination range beyond 8TiB returns EFBIG > +$XFS_IO_PROG -c "copy_range -l $min_off -s 0 -d $max_off $testdir/file" $testdir/copy > + > +echo > +echo destination larger than rlimit returns EFBIG > +rm -f $testdir/copy > +$XFS_IO_PROG -c "truncate 128k" $testdir/file > + > +# need a wrapper so the "File size limit exceeded" error can be filtered > +do_rlimit_copy() > +{ > + $XFS_IO_PROG -f -c "copy_range -l 32k -s 0 -d 16m $testdir/file" $testdir/copy > +} > + > +ulimit -f $((8 * 1024)) > +ulimit -c 0 > +do_rlimit_copy 2>&1 | grep -o "File size limit exceeded" > +ulimit -f unlimited > + > +# success, all done > +status=0 > +exit > diff --git a/tests/generic/990.out b/tests/generic/990.out > new file mode 100644 > index 00000000..05d137de > --- /dev/null > +++ b/tests/generic/990.out > @@ -0,0 +1,37 @@ > +QA output created by 990 > +source range overlaps destination range in same file returns EINVAL > +copy_range: Invalid argument > + > +destination file O_RDONLY returns EBADF > +copy_range: Bad file descriptor > + > +destination file O_APPEND returns EBADF > +copy_range: Bad file descriptor > + > +source/destination as directory returns EISDIR > +copy_range: Is a directory > +copy_range: Is a directory > + > +source/destination as blkdev returns EINVAL > +copy_range: Invalid argument > +copy_range: Invalid argument > + > +source/destination as chardev returns EINVAL > +copy_range: Invalid argument > +copy_range: Invalid argument > + > +source/destination as FIFO returns EINVAL > +copy_range: Invalid argument > +copy_range: Invalid argument > + > +length beyond 8EiB wraps around 0 returns EOVERFLOW > +copy_range: Value too large for defined data type > +copy_range: Value too large for defined data type > + > +source range beyond 8TiB returns 0 > + > +destination range beyond 8TiB returns EFBIG > +copy_range: File too large > + > +destination larger than rlimit returns EFBIG > +File size limit exceeded > diff --git a/tests/generic/group b/tests/generic/group > index 4c100781..86802d54 100644 > --- a/tests/generic/group > +++ b/tests/generic/group > @@ -552,3 +552,4 @@ > 547 auto quick log > 988 auto quick copy_range > 989 auto quick copy_range swap > +990 auto quick copy_range > -- > 2.17.1 >
On Wed, May 29, 2019 at 5:16 AM Darrick J. Wong <darrick.wong@oracle.com> wrote: > > On Sun, May 26, 2019 at 11:45:34AM +0300, Amir Goldstein wrote: > > Test that copy_file_range will return the correct errors for various > > error conditions and boundary constraints. > > > > [Amir] Split out cross-device copy_range test and use only scratch dev. > > Split out immutable/swapfile test cases to reduce the requirements to > > run the bounds check to minimum and get coverage for more filesystems. > > Remove the tests for read past EOF and write after chmod -r, > > because we decided to stick with read(2)/write(2) semantics. > > > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > > Signed-off-by: Amir Goldstein <amir73il@gmail.com> > > --- > > tests/generic/990 | 123 ++++++++++++++++++++++++++++++++++++++++++ > > tests/generic/990.out | 37 +++++++++++++ > > tests/generic/group | 1 + > > 3 files changed, 161 insertions(+) > > create mode 100755 tests/generic/990 > > create mode 100644 tests/generic/990.out > > > > diff --git a/tests/generic/990 b/tests/generic/990 > > new file mode 100755 > > index 00000000..5e2421b6 > > --- /dev/null > > +++ b/tests/generic/990 > > @@ -0,0 +1,123 @@ > > +#! /bin/bash > > +# SPDX-License-Identifier: GPL-2.0 > > +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. > > +# > > +# FS QA Test No. 990 > > +# > > +# Exercise copy_file_range() syscall error conditions. > > +# > > +seq=`basename $0` > > +seqres=$RESULT_DIR/$seq > > +echo "QA output created by $seq" > > + > > +here=`pwd` > > +tmp=/tmp/$$ > > +status=1 # failure is the default! > > +trap "_cleanup; exit \$status" 0 1 2 3 7 15 > > + > > +_cleanup() > > +{ > > + cd / > > + rm -rf $tmp.* > > +} > > + > > +# get standard environment, filters and checks > > +. ./common/rc > > +. ./common/filter > > + > > +# real QA test starts here > > +_supported_os Linux > > +_supported_fs generic > > + > > +rm -f $seqres.full > > + > > +_require_test > > +_require_xfs_io_command "copy_range" > > +# > > +# This test effectively requires xfs_io v4.20 with the commits > > +# 2a42470b xfs_io: copy_file_range length is a size_t > > +# 1a05efba io: open pipes in non-blocking mode > > So, uh, is this going to cause test hangs on xfsprogs < 4.20? Yes, from the pipe test case: $XFS_IO_PROG -f -c "copy_range -l 32k $testdir/fifo" $testdir/copy I could introduce _require_xfs_io_min_ver, but it goes completely against "testing features" methodology. I guess I could implement _require_xfs_io_non_block_fifo, but that also seems quite ugly to me? BTW, per your comment about splitting the fifo test case, I believe that would be wrong. I split the swap/immutable file test cases to provide better bounds test coverage for filesystems that do not support swap/immutable files. If I split the fifo test case, it will provide better bounds test coverage for test setups with old xfs_io and new kernel (in old kernel bounds test will fail anyway), so what do users gain from that? Thanks, Amir.
diff --git a/tests/generic/990 b/tests/generic/990 new file mode 100755 index 00000000..5e2421b6 --- /dev/null +++ b/tests/generic/990 @@ -0,0 +1,123 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. +# +# FS QA Test No. 990 +# +# Exercise copy_file_range() syscall error conditions. +# +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_os Linux +_supported_fs generic + +rm -f $seqres.full + +_require_test +_require_xfs_io_command "copy_range" +# +# This test effectively requires xfs_io v4.20 with the commits +# 2a42470b xfs_io: copy_file_range length is a size_t +# 1a05efba io: open pipes in non-blocking mode +# +# The same xfs_io release also included the new 'chmod' command. +# Use this fake requirement to prevent the test case of copy_range with fifo +# from hanging the test with old xfs_io. +# +_require_xfs_io_command "chmod" + +testdir="$TEST_DIR/test-$seq" +rm -rf $testdir +mkdir $testdir + +rm -f $seqres.full + +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 128k" $testdir/file >> $seqres.full 2>&1 + +echo source range overlaps destination range in same file returns EINVAL +$XFS_IO_PROG -f -c "copy_range -s 32k -d 48k -l 32k $testdir/file" $testdir/file + +echo +echo destination file O_RDONLY returns EBADF +$XFS_IO_PROG -f -r -c "copy_range -l 32k $testdir/file" $testdir/copy + +echo +echo destination file O_APPEND returns EBADF +$XFS_IO_PROG -f -a -c "copy_range -l 32k $testdir/file" $testdir/copy + +echo +echo source/destination as directory returns EISDIR +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir" $testdir/copy + +echo +echo source/destination as blkdev returns EINVAL +mknod $testdir/dev1 b 1 3 +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir/dev1 +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/dev1" $testdir/copy + +echo +echo source/destination as chardev returns EINVAL +mknod $testdir/dev2 c 1 3 +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir/dev2 +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/dev2" $testdir/copy + +echo +echo source/destination as FIFO returns EINVAL +mkfifo $testdir/fifo +$XFS_IO_PROG -c "copy_range -l 32k $testdir/file" $testdir/fifo +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/fifo" $testdir/copy + +max_off=$((8 * 2**60 - 65536 - 1)) +min_off=65537 + +echo +echo length beyond 8EiB wraps around 0 returns EOVERFLOW +$XFS_IO_PROG -f -c "copy_range -l 10e -s $max_off $testdir/file" $testdir/copy +$XFS_IO_PROG -f -c "copy_range -l 10e -d $max_off $testdir/file" $testdir/copy + +echo +echo source range beyond 8TiB returns 0 +$XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy + +echo +echo destination range beyond 8TiB returns EFBIG +$XFS_IO_PROG -c "copy_range -l $min_off -s 0 -d $max_off $testdir/file" $testdir/copy + +echo +echo destination larger than rlimit returns EFBIG +rm -f $testdir/copy +$XFS_IO_PROG -c "truncate 128k" $testdir/file + +# need a wrapper so the "File size limit exceeded" error can be filtered +do_rlimit_copy() +{ + $XFS_IO_PROG -f -c "copy_range -l 32k -s 0 -d 16m $testdir/file" $testdir/copy +} + +ulimit -f $((8 * 1024)) +ulimit -c 0 +do_rlimit_copy 2>&1 | grep -o "File size limit exceeded" +ulimit -f unlimited + +# success, all done +status=0 +exit diff --git a/tests/generic/990.out b/tests/generic/990.out new file mode 100644 index 00000000..05d137de --- /dev/null +++ b/tests/generic/990.out @@ -0,0 +1,37 @@ +QA output created by 990 +source range overlaps destination range in same file returns EINVAL +copy_range: Invalid argument + +destination file O_RDONLY returns EBADF +copy_range: Bad file descriptor + +destination file O_APPEND returns EBADF +copy_range: Bad file descriptor + +source/destination as directory returns EISDIR +copy_range: Is a directory +copy_range: Is a directory + +source/destination as blkdev returns EINVAL +copy_range: Invalid argument +copy_range: Invalid argument + +source/destination as chardev returns EINVAL +copy_range: Invalid argument +copy_range: Invalid argument + +source/destination as FIFO returns EINVAL +copy_range: Invalid argument +copy_range: Invalid argument + +length beyond 8EiB wraps around 0 returns EOVERFLOW +copy_range: Value too large for defined data type +copy_range: Value too large for defined data type + +source range beyond 8TiB returns 0 + +destination range beyond 8TiB returns EFBIG +copy_range: File too large + +destination larger than rlimit returns EFBIG +File size limit exceeded diff --git a/tests/generic/group b/tests/generic/group index 4c100781..86802d54 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -552,3 +552,4 @@ 547 auto quick log 988 auto quick copy_range 989 auto quick copy_range swap +990 auto quick copy_range