Message ID | 20181203064256.26768-4-david@fromorbit.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fstests: copy_file_range() bounds testing | expand |
On Mon, Dec 3, 2018 at 8:43 AM Dave Chinner <david@fromorbit.com> wrote: > > From: Dave Chinner <dchinner@redhat.com> > > Test that copy_file_range will return the correct errors for various > error conditions and boundary constraints. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > --- > tests/generic/530 | 165 ++++++++++++++++++++++++++++++++++++++++++ > tests/generic/530.out | 62 ++++++++++++++++ > tests/generic/group | 1 + > 3 files changed, 228 insertions(+) > create mode 100755 tests/generic/530 > create mode 100644 tests/generic/530.out > > diff --git a/tests/generic/530 b/tests/generic/530 > new file mode 100755 > index 000000000000..42243cc70914 > --- /dev/null > +++ b/tests/generic/530 > @@ -0,0 +1,165 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. > +# > +# FS QA Test No. 530 > +# > +# 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_scratch > +_require_xfs_io_command "copy_range" > +_require_user > +_require_test_swapfile > + > +_scratch_mkfs 2>&1 >> $seqres.full > +_scratch_mount > + > + > +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 > +chmod 777 $testdir/file > + > +echo swap files return ETXTBUSY > +_format_swapfile $testdir/swapfile 16m > +swapon $testdir/swapfile > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/file" $testdir/swapfile > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/swapfile" $testdir/copy > +swapoff $testdir/swapfile > + > +# we have to open the file to be immutable rw and hold it open over the > +# chattr command to set it immutable, otherwise we won't be able to open it for > +# writing after it's been made immutable. (i.e. would exercise file mode checks, > +# not immutable inode flag checks). > +echo > +echo immutable file returns EPERM > +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 64k" -c fsync $testdir/immutable | _filter_xfs_io > +$XFS_IO_PROG -f -c "chattr +i" -c "copy_range -l 32k $testdir/file" $testdir/immutable > +$XFS_IO_PROG -f -r -c "chattr -i" $testdir/immutable > +rm -f $testdir/immutable > + > +# can't test this as root, because root is allowed to write to files do not > +# have write permission bits set. > +echo > +echo no write perms on destination returns EACCES > +chown $qa_user:12345 $testdir/copy > +su $qa_user -c "$XFS_IO_PROG -f -c 'chmod -r' -c 'copy_range -l 32k $testdir/file' $testdir/copy" > +rm -f $testdir/copy > + > +echo > +echo source range overlaps EOF returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 112k -l 32k $testdir/file" $testdir/copy > + > +echo > +echo source range beyond EOF returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 128k -l 32k $testdir/file" $testdir/copy > + > +echo > +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 8EiB returns EINVAL > +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/file > +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/copy > +$XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy > +$XFS_IO_PROG -c "copy_range -s $min_off -l $max_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 > + > +echo > +echo copy across devices > +$XFS_IO_PROG -f -c "copy_range -l 128k $testdir/file" $SCRATCH_MNT/copy > +cmp $testdir/file $SCRATCH_MNT/copy > +echo "md5sums after xdev copy:" > +md5sum $testdir/file $SCRATCH_MNT/copy | _filter_test_dir | _filter_scratch > + All the test cases above check for bugs, which I presume your kernel patch series is aimed at fixing(?) This one last test case tests for new functionality that is not currently available for any filesystem in upstream kernel. Does your kernel patch set also add this functionality to xfs? to generic? IMO, it would be better to split this test case for new functionality to a new test, so that this one can pass on stable kernels once all the bug fixes have been applied. Thanks, Amir.
On Mon, Dec 03, 2018 at 09:25:19AM +0200, Amir Goldstein wrote: > On Mon, Dec 3, 2018 at 8:43 AM Dave Chinner <david@fromorbit.com> wrote: > > > > From: Dave Chinner <dchinner@redhat.com> > > > > Test that copy_file_range will return the correct errors for various > > error conditions and boundary constraints. .... > > All the test cases above check for bugs, which I presume your kernel patch > series is aimed at fixing(?) Yes. Document the API (I have a man page patch) write the tests to exercise correct API behaviour (these patches), fix the API implementation until the tests start passing (still to be posted as I wait for these to hit mailing list archives so I can point at them). > This one last test case tests for new functionality that is not > currently available > for any filesystem in upstream kernel. Yup. > Does your kernel patch set also add this functionality to xfs? to generic? Yes and yes. overlay works, too, but I gave up caring about it because it doesn't support the ioctls xfs_io uses in this test to change open file state.... > IMO, it would be better to split this test case for new functionality to a new > test, so that this one can pass on stable kernels once all the bug > fixes have been > applied. Whatever. I'm tired, I've already put in 13 hours on this today and I'm on the back of four 100+ hour weeks working on nothing but this broken heap of crap. Take it or leave it, because I'm just about burnt out on this right now... Cheers, Dave.
On Mon, Dec 3, 2018 at 10:17 AM Dave Chinner <david@fromorbit.com> wrote: > > On Mon, Dec 03, 2018 at 09:25:19AM +0200, Amir Goldstein wrote: > > On Mon, Dec 3, 2018 at 8:43 AM Dave Chinner <david@fromorbit.com> wrote: > > > > > > From: Dave Chinner <dchinner@redhat.com> > > > > > > Test that copy_file_range will return the correct errors for various > > > error conditions and boundary constraints. > .... > > > > All the test cases above check for bugs, which I presume your kernel patch > > series is aimed at fixing(?) > > Yes. Document the API (I have a man page patch) write the tests to > exercise correct API behaviour (these patches), fix the API > implementation until the tests start passing (still to be posted as > I wait for these to hit mailing list archives so I can point at > them). > > > This one last test case tests for new functionality that is not > > currently available > > for any filesystem in upstream kernel. > > Yup. > > > Does your kernel patch set also add this functionality to xfs? to generic? > > Yes and yes. overlay works, too, but I gave up caring about it > because it doesn't support the ioctls xfs_io uses in this test to > change open file state.... Oh, not a problem. I can add FS_IOC_FS[SG]ETXATTR to the overlayfs white list of ioctls. That raises the issue that the test is missing: _require_xfs_io_command "chattr" "-i" and the chattr -i in cleanup(). > > > IMO, it would be better to split this test case for new functionality to a new > > test, so that this one can pass on stable kernels once all the bug > > fixes have been > > applied. > > Whatever. I'm tired, I've already put in 13 hours on this today and > I'm on the back of four 100+ hour weeks working on nothing but this > broken heap of crap. > > Take it or leave it, because I'm just about burnt out on this > right now... > I hear you. I personally have no problem with declaring the cross fs copy_range an interface bug fix that can also go to stable. It's probably going to be harder to get your interface fixes without it. I will leave the call about insisting on separate test to Eryu. If you want me to submit that separate test, I can do that. Thanks, Amir.
On Mon, Dec 3, 2018 at 11:22 AM Amir Goldstein <amir73il@gmail.com> wrote: > > On Mon, Dec 3, 2018 at 10:17 AM Dave Chinner <david@fromorbit.com> wrote: > > > > On Mon, Dec 03, 2018 at 09:25:19AM +0200, Amir Goldstein wrote: > > > On Mon, Dec 3, 2018 at 8:43 AM Dave Chinner <david@fromorbit.com> wrote: > > > > > > > > From: Dave Chinner <dchinner@redhat.com> > > > > > > > > Test that copy_file_range will return the correct errors for various > > > > error conditions and boundary constraints. > > .... > > > > > > All the test cases above check for bugs, which I presume your kernel patch > > > series is aimed at fixing(?) > > > > Yes. Document the API (I have a man page patch) write the tests to > > exercise correct API behaviour (these patches), fix the API > > implementation until the tests start passing (still to be posted as > > I wait for these to hit mailing list archives so I can point at > > them). > > > > > This one last test case tests for new functionality that is not > > > currently available > > > for any filesystem in upstream kernel. > > > > Yup. > > > > > Does your kernel patch set also add this functionality to xfs? to generic? > > > > Yes and yes. overlay works, too, but I gave up caring about it > > because it doesn't support the ioctls xfs_io uses in this test to > > change open file state.... > > Oh, not a problem. I can add FS_IOC_FS[SG]ETXATTR > to the overlayfs white list of ioctls. > > That raises the issue that the test is missing: > > _require_xfs_io_command "chattr" "-i" > Hmm. _require_xfs_io_command "chattr" "+/-x" is documented in doc/requirement-checking.txt, but that seems like fake news. Nevermind. I'll add support for it after implementing FS_IOC_FS[SG]ETXATTR for overlayfs. > and the chattr -i in cleanup(). > That's still important of course. Thanks, Amir.
On Mon, Dec 03, 2018 at 05:42:56PM +1100, Dave Chinner wrote: > From: Dave Chinner <dchinner@redhat.com> > > Test that copy_file_range will return the correct errors for various > error conditions and boundary constraints. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > --- > tests/generic/530 | 165 ++++++++++++++++++++++++++++++++++++++++++ > tests/generic/530.out | 62 ++++++++++++++++ > tests/generic/group | 1 + > 3 files changed, 228 insertions(+) > create mode 100755 tests/generic/530 > create mode 100644 tests/generic/530.out > > diff --git a/tests/generic/530 b/tests/generic/530 > new file mode 100755 > index 000000000000..42243cc70914 > --- /dev/null > +++ b/tests/generic/530 > @@ -0,0 +1,165 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. > +# > +# FS QA Test No. 530 > +# > +# 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_scratch > +_require_xfs_io_command "copy_range" > +_require_user > +_require_test_swapfile > + > +_scratch_mkfs 2>&1 >> $seqres.full > +_scratch_mount > + > + > +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 > +chmod 777 $testdir/file > + > +echo swap files return ETXTBUSY > +_format_swapfile $testdir/swapfile 16m > +swapon $testdir/swapfile > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/file" $testdir/swapfile > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/swapfile" $testdir/copy > +swapoff $testdir/swapfile > + > +# we have to open the file to be immutable rw and hold it open over the > +# chattr command to set it immutable, otherwise we won't be able to open it for > +# writing after it's been made immutable. (i.e. would exercise file mode checks, > +# not immutable inode flag checks). > +echo > +echo immutable file returns EPERM > +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 64k" -c fsync $testdir/immutable | _filter_xfs_io > +$XFS_IO_PROG -f -c "chattr +i" -c "copy_range -l 32k $testdir/file" $testdir/immutable > +$XFS_IO_PROG -f -r -c "chattr -i" $testdir/immutable > +rm -f $testdir/immutable > + > +# can't test this as root, because root is allowed to write to files do not > +# have write permission bits set. > +echo > +echo no write perms on destination returns EACCES > +chown $qa_user:12345 $testdir/copy > +su $qa_user -c "$XFS_IO_PROG -f -c 'chmod -r' -c 'copy_range -l 32k $testdir/file' $testdir/copy" > +rm -f $testdir/copy > + > +echo > +echo source range overlaps EOF returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 112k -l 32k $testdir/file" $testdir/copy > + > +echo > +echo source range beyond EOF returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 128k -l 32k $testdir/file" $testdir/copy > + > +echo > +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 8EiB returns EINVAL > +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/file > +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/copy > +$XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy > +$XFS_IO_PROG -c "copy_range -s $min_off -l $max_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 > + > +echo > +echo copy across devices > +$XFS_IO_PROG -f -c "copy_range -l 128k $testdir/file" $SCRATCH_MNT/copy > +cmp $testdir/file $SCRATCH_MNT/copy > +echo "md5sums after xdev copy:" > +md5sum $testdir/file $SCRATCH_MNT/copy | _filter_test_dir | _filter_scratch Echoing Amir, this should be a separate test because it tests new functionality. Really wishing we'd put a WARN_ONCE(1, "Using EXPERIMENTAL copy_file_range syscall"); in when this got merged. :( :( --D > +# success, all done > +status=0 > +exit > diff --git a/tests/generic/530.out b/tests/generic/530.out > new file mode 100644 > index 000000000000..c433fb989637 > --- /dev/null > +++ b/tests/generic/530.out > @@ -0,0 +1,62 @@ > +QA output created by 530 > +swap files return ETXTBUSY > +copy_range: Text file busy > +copy_range: Text file busy > + > +immutable file returns EPERM > +wrote 65536/65536 bytes at offset 0 > +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) > +copy_range: Operation not permitted > + > +no write perms on destination returns EACCES > +copy_range: Permission denied > + > +source range overlaps EOF returns EINVAL > +copy_range: Invalid argument > + > +source range beyond EOF returns EINVAL > +copy_range: Invalid argument > + > +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 8EiB returns EINVAL > +copy_range: Invalid argument > +copy_range: Invalid argument > + > +destination range beyond 8TiB returns EFBIG > +copy_range: File too large > + > +destination larger than rlimit returns EFBIG > +File size limit exceeded > + > +copy across devices > +md5sums after xdev copy: > +81615449a98aaaad8dc179b3bec87f38 TEST_DIR/test-530/file > +81615449a98aaaad8dc179b3bec87f38 SCRATCH_MNT/copy > diff --git a/tests/generic/group b/tests/generic/group > index cc05792ba3b6..5ba1280aa3e6 100644 > --- a/tests/generic/group > +++ b/tests/generic/group > @@ -523,3 +523,4 @@ > 517 auto quick dedupe clone > 518 auto quick clone > 519 auto quick > +530 auto quick copy_range > -- > 2.19.1 >
On Mon, Dec 3, 2018 at 11:22 AM Amir Goldstein <amir73il@gmail.com> wrote: > > On Mon, Dec 3, 2018 at 10:17 AM Dave Chinner <david@fromorbit.com> wrote: > > > > On Mon, Dec 03, 2018 at 09:25:19AM +0200, Amir Goldstein wrote: > > > On Mon, Dec 3, 2018 at 8:43 AM Dave Chinner <david@fromorbit.com> wrote: > > > > > > > > From: Dave Chinner <dchinner@redhat.com> > > > > > > > > Test that copy_file_range will return the correct errors for various > > > > error conditions and boundary constraints. > > .... > > > > > > All the test cases above check for bugs, which I presume your kernel patch > > > series is aimed at fixing(?) > > > > Yes. Document the API (I have a man page patch) write the tests to > > exercise correct API behaviour (these patches), fix the API > > implementation until the tests start passing (still to be posted as > > I wait for these to hit mailing list archives so I can point at > > them). > > > > > This one last test case tests for new functionality that is not > > > currently available > > > for any filesystem in upstream kernel. > > > > Yup. > > > > > Does your kernel patch set also add this functionality to xfs? to generic? > > > > Yes and yes. overlay works, too, but I gave up caring about it > > because it doesn't support the ioctls xfs_io uses in this test to > > change open file state.... > > Oh, not a problem. I can add FS_IOC_FS[SG]ETXATTR > to the overlayfs white list of ioctls. > > That raises the issue that the test is missing: > > _require_xfs_io_command "chattr" "-i" > > and the chattr -i in cleanup(). > > > > > > IMO, it would be better to split this test case for new functionality to a new > > > test, so that this one can pass on stable kernels once all the bug > > > fixes have been > > > applied. > > > > Whatever. I'm tired, I've already put in 13 hours on this today and > > I'm on the back of four 100+ hour weeks working on nothing but this > > broken heap of crap. > > > > Take it or leave it, because I'm just about burnt out on this > > right now... > > > > I hear you. > > I personally have no problem with declaring the cross fs copy_range an > interface bug fix that can also go to stable. It's probably going to be harder > to get your interface fixes without it. > > I will leave the call about insisting on separate test to Eryu. > If you want me to submit that separate test, I can do that. > Getting back to this (how time flies...) Dave, if you don't mind I am going to re-post your tests splitting the cross device copy test, since Darrick also echoed this request. Cheers, Amir.
On Mon, Dec 3, 2018 at 8:43 AM Dave Chinner <david@fromorbit.com> wrote: > > From: Dave Chinner <dchinner@redhat.com> > > Test that copy_file_range will return the correct errors for various > error conditions and boundary constraints. Below are the changes I have made to V2 on this test in accordance to agreed change of behavior (i.e. short copy up to EOF). This is a heads up before posting to verify my interpretation is correct. I still have more testing to do before posting. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > --- > tests/generic/530 | 165 ++++++++++++++++++++++++++++++++++++++++++ > tests/generic/530.out | 62 ++++++++++++++++ > tests/generic/group | 1 + > 3 files changed, 228 insertions(+) > create mode 100755 tests/generic/530 > create mode 100644 tests/generic/530.out > > diff --git a/tests/generic/530 b/tests/generic/530 > new file mode 100755 > index 000000000000..42243cc70914 > --- /dev/null > +++ b/tests/generic/530 > @@ -0,0 +1,165 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. > +# > +# FS QA Test No. 530 > +# > +# 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_scratch > +_require_xfs_io_command "copy_range" > +_require_user > +_require_test_swapfile Testing on scratch dev, as cross-dev test was split to a new test. > + > +_scratch_mkfs 2>&1 >> $seqres.full > +_scratch_mount > + > + > +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 > +chmod 777 $testdir/file > + > +echo swap files return ETXTBUSY > +_format_swapfile $testdir/swapfile 16m > +swapon $testdir/swapfile > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/file" $testdir/swapfile > +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/swapfile" $testdir/copy > +swapoff $testdir/swapfile > + > +# we have to open the file to be immutable rw and hold it open over the > +# chattr command to set it immutable, otherwise we won't be able to open it for > +# writing after it's been made immutable. (i.e. would exercise file mode checks, > +# not immutable inode flag checks). > +echo > +echo immutable file returns EPERM > +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 64k" -c fsync $testdir/immutable | _filter_xfs_io > +$XFS_IO_PROG -f -c "chattr +i" -c "copy_range -l 32k $testdir/file" $testdir/immutable > +$XFS_IO_PROG -f -r -c "chattr -i" $testdir/immutable > +rm -f $testdir/immutable > + > +# can't test this as root, because root is allowed to write to files do not > +# have write permission bits set. > +echo > +echo no write perms on destination returns EACCES This test case was removed, because it does not comply with current behavior of write(2). > +chown $qa_user:12345 $testdir/copy > +su $qa_user -c "$XFS_IO_PROG -f -c 'chmod -r' -c 'copy_range -l 32k $testdir/file' $testdir/copy" > +rm -f $testdir/copy > + > +echo > +echo source range overlaps EOF returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 112k -l 32k $testdir/file" $testdir/copy > + > +echo > +echo source range beyond EOF returns EINVAL > +$XFS_IO_PROG -f -c "copy_range -s 128k -l 32k $testdir/file" $testdir/copy > + > +echo > +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 8EiB returns EINVAL With accordance to implemented behavior and short copy to EOF, this was changed to: echo source range beyond 8TiB returns EFBIG $XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy > +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/file > +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/copy These ftruncates would fail with EFBIG anyway... > +$XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy > +$XFS_IO_PROG -c "copy_range -s $min_off -l $max_off -d 0 $testdir/file" $testdir/copy This second test does not fail because of short 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 > + > +echo > +echo copy across devices > +$XFS_IO_PROG -f -c "copy_range -l 128k $testdir/file" $SCRATCH_MNT/copy > +cmp $testdir/file $SCRATCH_MNT/copy > +echo "md5sums after xdev copy:" > +md5sum $testdir/file $SCRATCH_MNT/copy | _filter_test_dir | _filter_scratch > + Cross-device copy test was split out to a new test, see WIP: https://github.com/amir73il/xfstests/commits/copy_file_range Thanks, Amir.
diff --git a/tests/generic/530 b/tests/generic/530 new file mode 100755 index 000000000000..42243cc70914 --- /dev/null +++ b/tests/generic/530 @@ -0,0 +1,165 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. +# +# FS QA Test No. 530 +# +# 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_scratch +_require_xfs_io_command "copy_range" +_require_user +_require_test_swapfile + +_scratch_mkfs 2>&1 >> $seqres.full +_scratch_mount + + +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 +chmod 777 $testdir/file + +echo swap files return ETXTBUSY +_format_swapfile $testdir/swapfile 16m +swapon $testdir/swapfile +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/file" $testdir/swapfile +$XFS_IO_PROG -f -c "copy_range -l 32k $testdir/swapfile" $testdir/copy +swapoff $testdir/swapfile + +# we have to open the file to be immutable rw and hold it open over the +# chattr command to set it immutable, otherwise we won't be able to open it for +# writing after it's been made immutable. (i.e. would exercise file mode checks, +# not immutable inode flag checks). +echo +echo immutable file returns EPERM +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 64k" -c fsync $testdir/immutable | _filter_xfs_io +$XFS_IO_PROG -f -c "chattr +i" -c "copy_range -l 32k $testdir/file" $testdir/immutable +$XFS_IO_PROG -f -r -c "chattr -i" $testdir/immutable +rm -f $testdir/immutable + +# can't test this as root, because root is allowed to write to files do not +# have write permission bits set. +echo +echo no write perms on destination returns EACCES +chown $qa_user:12345 $testdir/copy +su $qa_user -c "$XFS_IO_PROG -f -c 'chmod -r' -c 'copy_range -l 32k $testdir/file' $testdir/copy" +rm -f $testdir/copy + +echo +echo source range overlaps EOF returns EINVAL +$XFS_IO_PROG -f -c "copy_range -s 112k -l 32k $testdir/file" $testdir/copy + +echo +echo source range beyond EOF returns EINVAL +$XFS_IO_PROG -f -c "copy_range -s 128k -l 32k $testdir/file" $testdir/copy + +echo +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 8EiB returns EINVAL +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/file +$XFS_IO_PROG -c "truncate $((max_off + 65536))" $testdir/copy +$XFS_IO_PROG -c "copy_range -s $max_off -l $min_off -d 0 $testdir/file" $testdir/copy +$XFS_IO_PROG -c "copy_range -s $min_off -l $max_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 + +echo +echo copy across devices +$XFS_IO_PROG -f -c "copy_range -l 128k $testdir/file" $SCRATCH_MNT/copy +cmp $testdir/file $SCRATCH_MNT/copy +echo "md5sums after xdev copy:" +md5sum $testdir/file $SCRATCH_MNT/copy | _filter_test_dir | _filter_scratch + +# success, all done +status=0 +exit diff --git a/tests/generic/530.out b/tests/generic/530.out new file mode 100644 index 000000000000..c433fb989637 --- /dev/null +++ b/tests/generic/530.out @@ -0,0 +1,62 @@ +QA output created by 530 +swap files return ETXTBUSY +copy_range: Text file busy +copy_range: Text file busy + +immutable file returns EPERM +wrote 65536/65536 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +copy_range: Operation not permitted + +no write perms on destination returns EACCES +copy_range: Permission denied + +source range overlaps EOF returns EINVAL +copy_range: Invalid argument + +source range beyond EOF returns EINVAL +copy_range: Invalid argument + +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 8EiB returns EINVAL +copy_range: Invalid argument +copy_range: Invalid argument + +destination range beyond 8TiB returns EFBIG +copy_range: File too large + +destination larger than rlimit returns EFBIG +File size limit exceeded + +copy across devices +md5sums after xdev copy: +81615449a98aaaad8dc179b3bec87f38 TEST_DIR/test-530/file +81615449a98aaaad8dc179b3bec87f38 SCRATCH_MNT/copy diff --git a/tests/generic/group b/tests/generic/group index cc05792ba3b6..5ba1280aa3e6 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -523,3 +523,4 @@ 517 auto quick dedupe clone 518 auto quick clone 519 auto quick +530 auto quick copy_range