xfs
[Top] [All Lists]

[PATCH] xfstests: test for file clone functionality of btrfs ("reflinks"

To: xfs@xxxxxxxxxxx
Subject: [PATCH] xfstests: test for file clone functionality of btrfs ("reflinks")
From: Koen De Wit <koen.de.wit@xxxxxxxxxx>
Date: Tue, 11 Dec 2012 17:44:10 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.16) Gecko/20111110 Icedove/3.0.11
Tests included:
  - Creating a reflink and overwriting the original contents
  - Reflinking a directory tree
  - Moving/deleting reflinks
  - Diskspace consumption checks
  - Cross-filesystem copies (should fail)
  - Cross-subvolume copies

Signed-off-by: Koen De Wit <koen.de.wit@xxxxxxxxxx>
---
294 | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 294.out |   89 +++++++++++++++++++++++
 group   |    1 +
 3 files changed, 334 insertions(+)
 create mode 100755 294
 create mode 100644 294.out

diff --git a/294 b/294
new file mode 100755
index 0000000..7c422c8
--- /dev/null
+++ b/294
@@ -0,0 +1,244 @@
+#! /bin/bash
+# FS QA Test No. 294
+#
+# Tests file clone functionality of btrfs ("reflinks"),
+# including cross-subvolume copies.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2012 Oracle.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#-----------------------------------------------------------------------
+#
+# creator
+owner=koen.de.wit@xxxxxxxxxx
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1    # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+    cd /
+    rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+_supported_fs btrfs
+_supported_os Linux
+
+_require_scratch
+
+testdir1=$TEST_DIR/test-$seq
+rm -rf $testdir1
+mkdir $testdir1
+testdir2=$SCRATCH_MNT/test-$seq
+rm -rf $testdir2
+mkdir $testdir2
+
+# ----------------------------------
+
+# Simple test:
+#   - Reflink a file
+#   - Reflink the reflinked file
+#   - Modify the original file
+#   - Modify the reflinked file
+
+_catfiles() {
+    cat original copy1 copy2
+}
+
+cd $testdir1
+echo "aaa" > original
+cp --reflink original copy1
+cp --reflink copy1 copy2
+echo "--- Created file and 2 reflinked copies"
+_catfiles
+echo "bbb" > original
+echo "--- Changed original file"
+_catfiles
+echo "ccc" > copy1
+echo "--- Changed first copy"
+_catfiles
+rm -rf original copy1 copy2
+
+# ----------------------------------
+
+# Reflinking directory tree:
+#   - Create directory and subdirectory, each having one file
+#   - Create 2 reflinked copies of the tree
+#   - Modify the original files
+#   - Modify one of the copies
+
+_catfiles() {
+    cat original/file1 original/subdir/file2 copy1/file1 \
+            copy1/subdir/file2 copy2/file1 copy2/subdir/file2
+}
+
+cd $testdir1
+mkdir original
+mkdir original/subdir
+echo "aaa-1" > original/file1
+echo "aaa-2" > original/subdir/file2
+cp --recursive --reflink original copy1
+cp --recursive --reflink copy1 copy2
+echo "--- Created directory tree and 2 reflinked copies"
+_catfiles
+echo "bbb-1" > original/file1
+echo "bbb-2" > original/subdir/file2
+echo "--- Changed original files"
+_catfiles
+echo "ccc-1" > copy1/file1
+echo "ccc-2" > copy1/subdir/file2
+echo "--- Changed first copy"
+_catfiles
+rm -rf original copy1 copy2
+
+# ----------------------------------
+
+# Moving and deleting reflinks
+#   - Create a file and a reflink
+#   - Move both to a directory
+#   - Delete the original (moved) file, check that the copy still exists.
+
+echo "aaa" > original
+cp --reflink original copy
+mkdir subdir
+mv original subdir/original_moved
+mv copy subdir/copy_moved
+echo "--- Created a file and reflink, moved both to a directory"
+cat subdir/original_moved
+cat subdir/copy_moved
+rm subdir/original_moved
+echo "--- Removed the original file"
+cat subdir/copy_moved
+rm -rf subdir
+
+# ----------------------------------
+
+# Diskspace consumption
+#    - Check that a reflink does not consume space
+#    - Check that a reflinks starts to consume space when the original file
+#      is modified
+#    - Check that diskspace is freed up after deleting all files
+
+_free() {
+    df -P $TEST_DIR | awk 'END {print $4}'
+}
+
+avail0=`_free`
+dd if=/dev/zero of=original bs=1MB count=10
+cp --reflink=always original copy1
+cp --reflink=auto copy1 copy2
+sleep 30
+avail1=`_free`
+echo "--- Created a 10MB file and two reflinks"
+expr $avail0 - $avail1
+dd if=/dev/zero of=original bs=1MB count=10
+avail2=`_free`
+echo "--- Overwritten the original file"
+expr $avail0 - $avail2
+rm original copy1 copy2
+avail3=`_free`
+echo "--- Removed all files"
+expr $avail0 - $avail3
+
+# ----------------------------------
+
+# Cross-filesystem copy
+#    - Copy a file with the reflink=auto option.
+#      A normal copy should be created.
+#    - Copy a file with the reflink=always option. Should result in error,
+#      no file should be created.
+
+_scratch_mkfs
+_scratch_mount
+mkdir $testdir2
+
+echo "aaa" > original
+cp --reflink=auto original $testdir2/copy
+echo "--- Normal copy to second filesystem"
+cat $testdir2/copy
+rm -rf $testdir2
+mkdir $testdir2
+echo "--- Sparse copy to second filesystem (should fail)"
+cp --reflink=always original $testdir2/copyfail 2>&1 | _filter_scratch
+echo "--- Zero files should be created:"
+ls $testdir2/copyfail | wc -l
+
+# ----------------------------------
+
+# Cross-subvolume copy
+#    - Create two subvolumes, mount one of them
+#    - Create a file on each (sub/root)volume,
+#      reflink them on the other volumes
+#    - Change the original files
+#    - Move and delete files
+
+_catfiles() {
+    for D in "test-$seq/" "$SCRATCH_MNT/" "subvol-$seq-2/"
+    do
+        cat $D/file1 $D/file2 $D/file3
+    done
+}
+
+cd $TEST_DIR
+_scratch_unmount
+btrfs subvolume create subvol-$seq-1
+btrfs subvolume create subvol-$seq-2
+mount -t btrfs -o subvol=subvol-$seq-1 $TEST_DEV $SCRATCH_MNT
+
+echo "aaa" > test-$seq/file1
+echo "bbb" > $SCRATCH_MNT/file2
+echo "ccc" > subvol-$seq-2/file3
+cp --reflink test-$seq/file1 subvol-$seq-1
+cp --reflink test-$seq/file1 subvol-$seq-2
+cp --reflink subvol-$seq-1/file2 test-$seq/
+cp --reflink subvol-$seq-1/file2 subvol-$seq-2
+cp --reflink subvol-$seq-2/file3 test-$seq/
+cp --reflink subvol-$seq-2/file3 subvol-$seq-1
+echo "--- Created 3 files, each with 2 reflinks"
+_catfiles
+
+echo "xxx" > test-$seq/file1
+echo "yyy" > $SCRATCH_MNT/file2
+echo "zzz" > subvol-$seq-2/file3
+echo "--- Modified the original files"
+_catfiles
+
+mkdir tmp-$seq
+mv test-$seq/file* tmp-$seq
+mv $SCRATCH_MNT/file* test-$seq/
+mv subvol-$seq-2/file* $SCRATCH_MNT/
+mv tmp-$seq/file* subvol-$seq-2/
+echo "--- Moved files around"
+_catfiles
+
+rm -rf test-$seq
+rm -rf tmp-$seq
+umount $SCRATCH_MNT
+btrfs subvolume delete subvol-$seq-1 | _filter_test_dir
+btrfs subvolume delete subvol-$seq-2 | _filter_test_dir
+
+# success, all done
+status=0
+exit
diff --git a/294.out b/294.out
new file mode 100644
index 0000000..1b9b626
--- /dev/null
+++ b/294.out
@@ -0,0 +1,89 @@
+QA output created by 294
+--- Created file and 2 reflinked copies
+aaa
+aaa
+aaa
+--- Changed original file
+bbb
+aaa
+aaa
+--- Changed first copy
+bbb
+ccc
+aaa
+--- Created directory tree and 2 reflinked copies
+aaa-1
+aaa-2
+aaa-1
+aaa-2
+aaa-1
+aaa-2
+--- Changed original files
+bbb-1
+bbb-2
+aaa-1
+aaa-2
+aaa-1
+aaa-2
+--- Changed first copy
+bbb-1
+bbb-2
+ccc-1
+ccc-2
+aaa-1
+aaa-2
+--- Created a file and reflink, moved both to a directory
+aaa
+aaa
+--- Removed the original file
+aaa
+10+0 records in
+10+0 records out
+--- Created a 10MB file and two reflinks
+9784
+10+0 records in
+10+0 records out
+--- Overwritten the original file
+19560
+--- Removed all files
+0
+--- Normal copy to second filesystem
+aaa
+--- Sparse copy to second filesystem (should fail)
+cp: failed to clone `SCRATCH_MNT/test-294/copyfail' from `original': Invalid cross-device link
+--- Zero files shouls be created:
+0
+Create subvolume './subvol-294-1'
+Create subvolume './subvol-294-2'
+--- Created 3 files, each with 2 reflinks
+aaa
+bbb
+ccc
+aaa
+bbb
+ccc
+aaa
+bbb
+ccc
+--- Modified the original files
+xxx
+bbb
+ccc
+aaa
+yyy
+ccc
+aaa
+bbb
+zzz
+--- Moved files around
+aaa
+yyy
+ccc
+aaa
+bbb
+zzz
+xxx
+bbb
+ccc
+Delete subvolume 'TEST_DIR/subvol-294-1'
+Delete subvolume 'TEST_DIR/subvol-294-2'
diff --git a/group b/group
index dc8db65..b03001e 100644
--- a/group
+++ b/group
@@ -410,3 +410,4 @@ deprecated
 289 auto quick
 290 auto rw prealloc quick ioctl
 291 repair
+294 auto
--
1.7.10.4

<Prev in Thread] Current Thread [Next in Thread>