btrfs: add new filter for file cloning error translation
authorFilipe Manana <fdmanana@suse.com>
Mon, 5 Nov 2018 11:15:24 +0000 (11:15 +0000)
committerEryu Guan <guaneryu@gmail.com>
Sun, 11 Nov 2018 14:00:37 +0000 (22:00 +0800)
A bug in file cloning/reflinking was recently found that afftected both
Btrfs and XFS, which was caused by allowing the cloning of an eof block
into the middle of a file when the eof is not aligned to the filesystem's
block size.

The fix consists of returning the errno -EINVAL to user space when the
arguments passed to the system call lead to the scenario of data
corruption. However this overlaps with some cases where the system call,
in Btrfs, returned -EOPNOTSUPP, which means we are trying to reflink
inline extents. That is unsupported in Btrfs due to the huge complexity
of supporting it (due to copying and trimming inline extents, deal with
eventual compression, etc).

We have a few btrfs test cases that verify that attempts to clone inline
extents result in a failure, and are currently expecting an -EINVAL error
message from the output of the cloner program. So create a filter that
converts error messages related to the -EOPNOTSUPP error to messages
related to the -EINVAL error, so that the test can run both on patched
and non-patched linux kernels.

The corresponding btrfs patch for the linux kernel is titled:

 "Btrfs: fix data corruption due to cloning of eof block"

And the VFS change that introduces the -EINVAL error return was introduced
by the following linux kernel commit (landed in 4.20-rc1):

 07d19dc9fbe9 ("vfs: avoid problematic remapping requests into partial EOF block")

The btrfs patch is not yet in Linus' tree (it was submitted around the
same time as this change) and the VFS change was introduced in 4.10-rc1.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
common/filter.btrfs
tests/btrfs/035
tests/btrfs/035.out
tests/btrfs/096
tests/btrfs/096.out
tests/btrfs/112
tests/btrfs/112.out
tests/btrfs/113
tests/btrfs/113.out

index dda8577628b9dafd89ae2f3341ff0e76cffb2aba..d4169cc69112588d74a0fd3a8362c6cc35c8060a 100644 (file)
@@ -97,5 +97,22 @@ _filter_btrfs_qgroup_assign_warnings()
            -e "/quotas may be inconsistent, rescan needed/d"
 }
 
+# Long ago we found that attempting to clone inline extents resulted in hitting
+# a BUG_ON() and then decided to not support such use cases by returning errno
+# -EOPNOTSUPP to user space. Later on, clone/reflink became a VFS API too, since
+# other filesystems (such as XFS) implemented this feature. After that we found
+# one scenario of data corruption due to allowing cloning an EOF block into the
+# middle of a file, and started to reject such scenario by returning the errno
+# -EINVAL to user space (this affected both Btrfs and XFS). Such scenario often
+# overlaps the detection of attempts to clone inline extents, since it is done
+# early on based only on the arguments passed to the clone system call (and
+# btrfs' specific ioctl) before processing the source file extents.
+# So replace error messages related to errno -EOPNOTSUPP to be the same as the
+# one we get from a -EINVAL errno.
+_filter_btrfs_cloner_error()
+{
+       sed -e "s/\(clone failed:\) Operation not supported/\1 Invalid argument/g"
+}
+
 # make sure this script returns success
 /bin/true
index c9c09e1664329d8d548347a1da40241c4d2948c6..a6f67d4fdd2d238597c098c7d7029552e9ef26ea 100755 (executable)
@@ -24,6 +24,7 @@ trap "_cleanup ; exit \$status" 0 1 2 3 15
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/filter.btrfs
 
 # real QA test starts here
 _supported_fs btrfs
@@ -49,7 +50,7 @@ $CLONER_PROG $SCRATCH_MNT/src $SCRATCH_MNT/src.clone2
 snap_src_sz=`ls -lah $SCRATCH_MNT/src.clone1 | awk '{print $5}'`
 echo "attempting ioctl (src.clone1 src)"
 $CLONER_PROG -s 0 -d 0 -l ${snap_src_sz} \
-       $SCRATCH_MNT/src.clone1 $SCRATCH_MNT/src
+       $SCRATCH_MNT/src.clone1 $SCRATCH_MNT/src | _filter_btrfs_cloner_error
 
 # The clone operation should have failed. If it did not it meant we had data
 # loss, because file "src.clone1" has an inline extent which is 10 bytes long
index 3ea7d779078f23117c038f21307f22e1ce817974..d810bb2beb978d881bb93d03e78a26a9946fd723 100644 (file)
@@ -1,6 +1,6 @@
 QA output created by 035
 attempting ioctl (src.clone1 src)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File src data after attempt to clone from src.clone1 into src:
 0000000 62 62 62 62 62 62 62 62 62 62 63 63 63 63 63 63
 0000020 63 63 63 63
index e855294765794d4b2e5a11ad7a5f98abb126b655..b9188e6e592c8bea6250f1953decfdfe898174d3 100755 (executable)
@@ -21,6 +21,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/filter.btrfs
 
 # real QA test starts here
 _supported_fs btrfs
@@ -52,11 +53,11 @@ $XFS_IO_PROG -f -s -c "pwrite -S 0xbb 0 2k" \
 # deal with in future IO operations because all inline extents are
 # supposed to start at an offset of 0, resulting in all sorts of
 # chaos.
-# So here we validate that the clone ioctl returns an EOPNOTSUPP,
-# which is what it returns for other cases dealing with inlined
+# So here we validate that the clone ioctl returns an EOPNOTSUPP or
+# EINVAL which is what it returns for other cases dealing with inlined
 # extents.
 $CLONER_PROG -s 0 -d $BLOCK_SIZE -l 2048 \
-       $SCRATCH_MNT/bar $SCRATCH_MNT/foo
+       $SCRATCH_MNT/bar $SCRATCH_MNT/foo | _filter_btrfs_cloner_error
 
 # Because of the inline extent at offset $BLOCK_SIZE, the following
 # write made the kernel crash with a BUG_ON().
index 2a4251eb4ee01bee22fa25d93fde6df6c53d26dd..2710f33eb4ab9557ea3f3f13fb394038ebe370a3 100644 (file)
@@ -3,5 +3,5 @@ Blocks modified: [0 - 0]
 Blocks modified: [1 - 1]
 Blocks modified: [2 - 2]
 Blocks modified: [0 - 0]
-clone failed: Operation not supported
+clone failed: Invalid argument
 Blocks modified: [1 - 1]
index 6ecb1c796943c9c629fe4bbd02d1a11e256e01fd..e4e9d322e5621d1b9aaf96f85645e19431bed86e 100755 (executable)
@@ -23,6 +23,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/filter.btrfs
 
 # real QA test starts here
 _supported_fs btrfs
@@ -53,7 +54,8 @@ test_cloning_inline_extents()
        # clone the inline extent from file bar into this file.
        $XFS_IO_PROG -f -c "pwrite -S 0xaa 0K 16K" $SCRATCH_MNT/foo \
                | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo \
+               | _filter_btrfs_cloner_error
 
        # Doing IO against any range in the first 4K of the file should work.
        # Due to a past clone ioctl bug which allowed cloning the inline extent,
@@ -69,7 +71,8 @@ test_cloning_inline_extents()
        # as well to clone the inline extent from file bar into this file.
        $XFS_IO_PROG -f -c "pwrite -S 0xdd 4K 12K" $SCRATCH_MNT/foo2 \
                | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo2
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo2 \
+               | _filter_btrfs_cloner_error
 
        # Doing IO against any range in the first 4K of the file should work.
        # Due to a past clone ioctl bug which allowed cloning the inline extent,
@@ -84,7 +87,8 @@ test_cloning_inline_extents()
        # but has a prealloc extent. It should not be possible as well to clone
        # the inline extent from file bar into this file.
        $XFS_IO_PROG -f -c "falloc -k 0 1M" $SCRATCH_MNT/foo3 | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo3
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo3 \
+               | _filter_btrfs_cloner_error
 
        # Doing IO against any range in the first 4K of the file should work.
        # Due to a past clone ioctl bug which allowed cloning the inline extent,
@@ -101,7 +105,8 @@ test_cloning_inline_extents()
        # It should be possible to do the extent cloning from bar to this file.
        $XFS_IO_PROG -f -c "pwrite -S 0x01 0 40" $SCRATCH_MNT/foo4 \
                | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo4
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo4 \
+               | _filter_btrfs_cloner_error
 
        # Doing IO against any range in the first 4K of the file should work.
        echo "File foo4 data after clone operation:"
@@ -116,7 +121,8 @@ test_cloning_inline_extents()
        # into this file.
        $XFS_IO_PROG -f -c "pwrite -S 0x03 0 60" $SCRATCH_MNT/foo5 \
                | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo5
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo5 \
+               | _filter_btrfs_cloner_error
 
        # Reading the file should not fail.
        echo "File foo5 data after clone operation:"
@@ -129,7 +135,8 @@ test_cloning_inline_extents()
        # It should not be possible to clone the inline extent from file bar
        # into this file.
        $XFS_IO_PROG -f -c "truncate 16K" $SCRATCH_MNT/foo6 | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo6
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo6 \
+               | _filter_btrfs_cloner_error
 
        # Reading the file should not fail.
        echo "File foo6 data after clone operation:"
@@ -142,7 +149,8 @@ test_cloning_inline_extents()
        # It should be possible to clone the inline extent from file bar into
        # this file.
        $XFS_IO_PROG -f -c "truncate 30" $SCRATCH_MNT/foo7 | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo7
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo7 \
+               | _filter_btrfs_cloner_error
 
        # Reading the file should not fail.
        echo "File foo7 data after clone operation:"
@@ -156,7 +164,8 @@ test_cloning_inline_extents()
        $XFS_IO_PROG -f -c "falloc -k 0 1M" \
                        -c "pwrite -S 0x88 0 20" \
                        $SCRATCH_MNT/foo8 | _filter_xfs_io
-       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo8
+       $CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/bar $SCRATCH_MNT/foo8 \
+               | _filter_btrfs_cloner_error
 
        echo "File foo8 data after clone operation:"
        # Must have a size of 20 bytes, with all bytes having a value of 0x88
index 23b0d0972acf69a211de71e3a2cdbedd57aa3656..3a95e14d1592079ff30b2b0bab98daea8a4f687d 100644 (file)
@@ -6,7 +6,7 @@ wrote 50/50 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 16384/16384 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo data after clone operation:
 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
 *
@@ -15,7 +15,7 @@ wrote 100/100 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 12288/12288 bytes at offset 4096
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo2 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -24,7 +24,7 @@ File foo2 data after clone operation:
 0040000
 wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 First 50 bytes of foo3 after clone operation:
 0000000
 wrote 90/90 bytes at offset 0
@@ -40,13 +40,13 @@ wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 60/60 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo5 data after clone operation:
 0000000 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03
 *
 0000060 03 03 03 03 03 03 03 03 03 03 03 03
 0000074
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo6 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -58,7 +58,7 @@ File foo7 data after clone operation:
 0000062
 wrote 20/20 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo8 data after clone operation:
 0000000 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88
 0000020 88 88 88 88
@@ -70,7 +70,7 @@ wrote 50/50 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 16384/16384 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo data after clone operation:
 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
 *
@@ -79,7 +79,7 @@ wrote 100/100 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 12288/12288 bytes at offset 4096
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo2 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -88,7 +88,7 @@ File foo2 data after clone operation:
 0040000
 wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 First 50 bytes of foo3 after clone operation:
 0000000
 wrote 90/90 bytes at offset 0
@@ -104,13 +104,13 @@ wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 60/60 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo5 data after clone operation:
 0000000 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03
 *
 0000060 03 03 03 03 03 03 03 03 03 03 03 03
 0000074
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo6 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -122,7 +122,7 @@ File foo7 data after clone operation:
 0000062
 wrote 20/20 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo8 data after clone operation:
 0000000 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88
 0000020 88 88 88 88
@@ -134,7 +134,7 @@ wrote 50/50 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 16384/16384 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo data after clone operation:
 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
 *
@@ -143,7 +143,7 @@ wrote 100/100 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 12288/12288 bytes at offset 4096
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo2 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -152,7 +152,7 @@ File foo2 data after clone operation:
 0040000
 wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 First 50 bytes of foo3 after clone operation:
 0000000
 wrote 90/90 bytes at offset 0
@@ -168,13 +168,13 @@ wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 60/60 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo5 data after clone operation:
 0000000 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03
 *
 0000060 03 03 03 03 03 03 03 03 03 03 03 03
 0000074
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo6 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -186,7 +186,7 @@ File foo7 data after clone operation:
 0000062
 wrote 20/20 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo8 data after clone operation:
 0000000 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88
 0000020 88 88 88 88
@@ -198,7 +198,7 @@ wrote 50/50 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 16384/16384 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo data after clone operation:
 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
 *
@@ -207,7 +207,7 @@ wrote 100/100 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 12288/12288 bytes at offset 4096
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo2 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -216,7 +216,7 @@ File foo2 data after clone operation:
 0040000
 wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 First 50 bytes of foo3 after clone operation:
 0000000
 wrote 90/90 bytes at offset 0
@@ -232,13 +232,13 @@ wrote 90/90 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 60/60 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo5 data after clone operation:
 0000000 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03
 *
 0000060 03 03 03 03 03 03 03 03 03 03 03 03
 0000074
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo6 data after clone operation:
 0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 *
@@ -250,7 +250,7 @@ File foo7 data after clone operation:
 0000062
 wrote 20/20 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File foo8 data after clone operation:
 0000000 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88
 0000020 88 88 88 88
index 416406df1ac211cbef12fc14184b13f2037d13ac..6400a7c99c17692c02ddab6acdf56a70caca16d9 100755 (executable)
@@ -25,6 +25,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/filter.btrfs
 
 # real QA test starts here
 _supported_fs btrfs
@@ -78,7 +79,8 @@ $XFS_IO_PROG -c "truncate 128" $SCRATCH_MNT/foo
 # it's normally not a very common case to clone very small files (only case
 # where we get inline extents) and copying inline extents does not save any
 # space (unlike for normal, non-inlined extents).
-$CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
+$CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar \
+       | _filter_btrfs_cloner_error
 
 # Now because the above clone operation used to succeed, and due to foo's inline
 # extent not being shinked by the truncate operation, our file bar got the whole
index 3847b35f2f26f3b87855ae0b81f61dbae9afdc87..ed2688db4dbe11949a6178f99b9c97a6dc27bb57 100644 (file)
@@ -5,7 +5,7 @@ wrote 384/384 bytes at offset 128
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 256/256 bytes at offset 0
 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-clone failed: Operation not supported
+clone failed: Invalid argument
 File bar's content after the clone operation:
 0000000 bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb
 *