linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls
@ 2015-11-13 21:36 Darrick J. Wong
  2015-11-13 21:36 ` [PATCH 01/12] test-scripts: test migration scripts Darrick J. Wong
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:36 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Hi all,

This is part of the third revision of an RFC for adding to XFS support
for tracking reverse-mappings of physical blocks to file and metadata;
and support for mapping multiple file logical blocks to the same
physical block, more commonly known as reflinking.

This patchset aims to make xfstests perform more rigorous testing of
the NFS/CIFS/btrfs/XFS file clone, reflink, and dedupe ioctls.
There are now tests of the basic functionality of the three ioctls;
tests to ensure that the filesystem exhibits the expected copy on
write semantics; tests to try to suss out race conditions in the new
write paths; tests to ensure that the ioctls peform basic disk
accounting correctly; tests of the interaction between reflink and the
various fallocate verbs (allocate, punch, collapse, insert zeroes);
and some attempts to test the upper limits of reflinking and ENOSPC
behavior.

Since the last posting, each test tries to reflink (or dedupe) on the
test or scratch FS to decide if they're going to run, instead of
guessing based on FS type.  Per Dave's suggestion, I also converted
the basic functionality tests to use fixed sizes so that I can use
md5sum in the golden output to check that the file contents match
exactly.

Since "RFCv3.1", I've made the following changes:

 * Renumbered the tests to the lowest numbers possible, per Dave's
   request.

 * Fixed the reflink and dedupe _require tests so that they can run
   on things like NFS which support reflink but not dedupe.

 * Added checks for lsattr/chattr support so that we don't produce
   bogus failures on NFS, and put the *attr tests in separate test
   files.

 * Appended a couple of tools I wrote to handle finding minimal test
   numbers and moving tests around.

If you're going to start using this mess, you probably ought to just
pull from my github trees for kernel[1], xfsprogs[2], xfstests[3], and
xfs-docs[4].  They should just work with the btrfs that's in 4.3...
and somewhat buggily with the 4.3 XFS patched with [1].

Comments and questions are, as always, welcome.

--D

[1] https://github.com/djwong/linux/tree/for-dave
[2] https://github.com/djwong/xfsprogs/tree/for-dave
[3] https://github.com/djwong/xfstests/tree/for-dave
[4] https://github.com/djwong/xfs-documentation/tree/for-dave

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/12] test-scripts: test migration scripts
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
@ 2015-11-13 21:36 ` Darrick J. Wong
  2015-11-16 20:58   ` Dave Chinner
  2015-11-13 21:36 ` [PATCH 02/12] btrfs: move btrfs reflink tests to generic Darrick J. Wong
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:36 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Add two scripts: "nextid" finds the next available test ID number in a
group, and "mvtest" relocates a test, fixes the golden output, and
moves the group entry for that test.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 mvtest |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 nextid |   35 +++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)
 create mode 100755 mvtest
 create mode 100755 nextid


diff --git a/mvtest b/mvtest
new file mode 100755
index 0000000..b5406d1
--- /dev/null
+++ b/mvtest
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Renumber a test
+
+if [ -z "$1" ] || [ "$1" = "--help" ]; then
+	echo "Usage: $0 path_to_test new_path_to_test"
+	exit 1
+fi
+
+src="$1"
+dest="$2"
+
+die() {
+	echo "$@"
+	exit 1
+}
+
+nsort() {
+	sort -g < "$1" > "$2"
+}
+
+append() {
+	out="$1"
+	shift
+	echo "$@" >> "${out}"
+}
+
+test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest."
+test -e "tests/${src}" || die "Test \"${src}\" does not exist."
+test ! -e "tests/${dest}" || die "Test \"${src}\" already exists."
+
+sid="$(basename "${src}")"
+did="$(basename "${dest}")"
+
+sgroup="$(basename "$(dirname "tests/${src}")")"
+dgroup="$(basename "$(dirname "tests/${dest}")")"
+
+sgroupfile="tests/${sgroup}/group"
+dgroupfile="tests/${sgroup}/group"
+
+$DBG git mv "tests/${src}" "tests/${dest}"
+$DBG git mv "tests/${src}.out" "tests/${dest}.out"
+$DBG sed -e "s/^# FS QA Test No. ${sid}$/# FS QA Test No. ${did}/g" -i "tests/${dest}"
+$DBG sed -e "s/^QA output created by ${sid}$/QA output created by ${did}/g" -i "tests/${dest}.out"
+$DBG sed -e "s/test-${sid}/test-${did}/g" -i "tests/${dest}.out"
+
+grpline="$(grep "^${sid} " "${sgroupfile}")"
+newgrpline="$(echo "${grpline}" | sed -e "s/^${sid} /${did} /g")"
+
+$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}"
+$DBG cp "${dgroupfile}" "${dgroupfile}.new"
+$DBG append "${dgroupfile}.new" "${newgrpline}"
+$DBG nsort "${dgroupfile}.new" "${dgroupfile}"
+$DBG rm "${dgroupfile}.new"
+
+echo "Moved \"${src}\" to \"${dest}\"."
+
+exit 0
diff --git a/nextid b/nextid
new file mode 100755
index 0000000..285b549
--- /dev/null
+++ b/nextid
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# Given a group name, find the next available test number.
+
+if [ -z "$1" ] || [ "$1" = "--help" ]; then
+	echo "Usage: $0 groupname[/start_looking_at_this_number]"
+	exit 1
+fi
+
+die() {
+	echo "$@"
+	exit 1
+}
+
+if [ "$(basename "$1")" != "$1" ]; then
+	group="$(dirname "$1")"
+	id="$(basename "$1")"
+else
+	group="$1"
+	id=1
+fi
+test -e "tests/${group}/group" || die "Unknown group \"${group}\"."
+
+while test "${id}" -lt 1000; do
+	name="$(printf "%.03d" "${id}")"
+	if [ ! -e "tests/${group}/${name}" ]; then
+		echo "${group}/${name}"
+		exit 0
+	fi
+	id=$((id + 1))
+done
+
+echo "No free IDs less than ${id} in group \"${group}\"."
+
+exit 1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/12] btrfs: move btrfs reflink tests to generic
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
  2015-11-13 21:36 ` [PATCH 01/12] test-scripts: test migration scripts Darrick J. Wong
@ 2015-11-13 21:36 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 03/12] reflink: add test support routines to a separate file Darrick J. Wong
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:36 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Move the cp --reflink tests from btrfs/ to generic/ since xfs now
supports that ioctl.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/btrfs/026       |   92 -----------------------------------------
 tests/btrfs/026.out   |   16 -------
 tests/btrfs/027       |  109 -------------------------------------------------
 tests/btrfs/027.out   |   25 -----------
 tests/btrfs/028       |   83 -------------------------------------
 tests/btrfs/028.out   |    7 ---
 tests/btrfs/group     |    3 -
 tests/generic/110     |   92 +++++++++++++++++++++++++++++++++++++++++
 tests/generic/110.out |   16 +++++++
 tests/generic/111     |  109 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/111.out |   25 +++++++++++
 tests/generic/115     |   83 +++++++++++++++++++++++++++++++++++++
 tests/generic/115.out |    7 +++
 tests/generic/group   |    3 +
 14 files changed, 335 insertions(+), 335 deletions(-)
 delete mode 100755 tests/btrfs/026
 delete mode 100644 tests/btrfs/026.out
 delete mode 100755 tests/btrfs/027
 delete mode 100644 tests/btrfs/027.out
 delete mode 100755 tests/btrfs/028
 delete mode 100644 tests/btrfs/028.out
 create mode 100755 tests/generic/110
 create mode 100644 tests/generic/110.out
 create mode 100755 tests/generic/111
 create mode 100644 tests/generic/111.out
 create mode 100755 tests/generic/115
 create mode 100644 tests/generic/115.out


diff --git a/tests/btrfs/026 b/tests/btrfs/026
deleted file mode 100755
index 7559ca2..0000000
--- a/tests/btrfs/026
+++ /dev/null
@@ -1,92 +0,0 @@
-#! /bin/bash
-# FS QA Test No. 026
-#
-# Tests file clone functionality of btrfs ("reflinks"):
-#   - Reflink a file
-#   - Reflink the reflinked file
-#   - Modify the original file
-#   - Modify the reflinked file
-#
-#-----------------------------------------------------------------------
-# Copyright (c) 2014, Oracle and/or its affiliates.  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
-#-----------------------------------------------------------------------
-#
-
-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 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_xfs_io_command "fiemap"
-_require_cp_reflink
-_require_test
-
-TESTDIR1=$TEST_DIR/test-$seq
-rm -rf $TESTDIR1
-mkdir $TESTDIR1
-
-_checksum_files() {
-    for F in original copy1 copy2
-    do
-        md5sum $TESTDIR1/$F | _filter_test_dir
-    done
-}
-
-rm -f $seqres.full
-
-echo "Create the original file and reflink to copy1, copy2"
-$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \
-    >> $seqres.full 2>&1
-cp --reflink $TESTDIR1/original $TESTDIR1/copy1
-cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2
-_verify_reflink $TESTDIR1/original $TESTDIR1/copy1
-_verify_reflink $TESTDIR1/original $TESTDIR1/copy2
-echo "Original md5sums:"
-_checksum_files
-
-echo "Overwrite original file with new data"
-$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \
-    >> $seqres.full 2>&1
-echo "md5sums after overwriting original:"
-_checksum_files
-
-echo "Overwrite copy1 with different new data"
-$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \
-    >> $seqres.full 2>&1
-echo "md5sums after overwriting copy1:"
-_checksum_files
-
-# success, all done
-status=0
-exit
diff --git a/tests/btrfs/026.out b/tests/btrfs/026.out
deleted file mode 100644
index 3b90ff0..0000000
--- a/tests/btrfs/026.out
+++ /dev/null
@@ -1,16 +0,0 @@
-QA output created by 026
-Create the original file and reflink to copy1, copy2
-Original md5sums:
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-026/original
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-026/copy1
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-026/copy2
-Overwrite original file with new data
-md5sums after overwriting original:
-4a847a25439532bf48b68c9e9536ed5b  TEST_DIR/test-026/original
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-026/copy1
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-026/copy2
-Overwrite copy1 with different new data
-md5sums after overwriting copy1:
-4a847a25439532bf48b68c9e9536ed5b  TEST_DIR/test-026/original
-e271cd47d9f62ebc96cb4e67ae4d16db  TEST_DIR/test-026/copy1
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-026/copy2
diff --git a/tests/btrfs/027 b/tests/btrfs/027
deleted file mode 100755
index d2b812b..0000000
--- a/tests/btrfs/027
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /bin/bash
-# FS QA Test No. 027
-#
-# Tests file clone functionality of btrfs ("reflinks") on directory
-# trees.
-#   - Create directory and subdirectory, each having one file
-#   - Create 2 recursive reflinked copies of the tree
-#   - Modify the original files
-#   - Modify one of the copies
-#
-#-----------------------------------------------------------------------
-# Copyright (c) 2014, Oracle and/or its affiliates.  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
-#-----------------------------------------------------------------------
-
-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 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_xfs_io_command "fiemap"
-_require_cp_reflink
-_require_test
-
-TESTDIR1=$TEST_DIR/test-$seq
-rm -rf $TESTDIR1
-mkdir $TESTDIR1
-
-_checksum_files() {
-    for F in original/file1 original/subdir/file2 \
-                 copy1/file1 copy1/subdir/file2 \
-                 copy2/file1 copy2/subdir/file2
-        do
-            md5sum $TESTDIR1/$F | _filter_test_dir
-        done
-}
-
-rm -f $seqres.full
-
-mkdir $TESTDIR1/original
-mkdir $TESTDIR1/original/subdir
-
-echo "Create the original files and reflink dirs"
-$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \
-    >> $seqres.full 2>&1
-$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \
-    $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1
-cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1
-cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2
-
-_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1
-_verify_reflink $TESTDIR1/original/subdir/file2 \
-    $TESTDIR1/copy1/subdir/file2
-_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1
-_verify_reflink $TESTDIR1/original/subdir/file2 \
-    $TESTDIR1/copy2/subdir/file2
-
-echo "Original md5sums:"
-_checksum_files
-
-echo "Overwrite original/file1 and original/subdir/file2 with new data"
-$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \
-    >> $seqres.full 2>&1
-$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \
-    $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1
-echo "md5sums now:"
-_checksum_files
-
-echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data"
-$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \
-    >> $seqres.full 2>&1
-$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \
-    $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1
-echo "md5sums now:"
-_checksum_files
-
-# success, all done
-status=0
-exit
diff --git a/tests/btrfs/027.out b/tests/btrfs/027.out
deleted file mode 100644
index 7b7e3bb..0000000
--- a/tests/btrfs/027.out
+++ /dev/null
@@ -1,25 +0,0 @@
-QA output created by 027
-Create the original files and reflink dirs
-Original md5sums:
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-027/original/file1
-ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-027/original/subdir/file2
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-027/copy1/file1
-ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-027/copy1/subdir/file2
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-027/copy2/file1
-ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-027/copy2/subdir/file2
-Overwrite original/file1 and original/subdir/file2 with new data
-md5sums now:
-260f6785c0537fd12582dcae28a3c1a9  TEST_DIR/test-027/original/file1
-b8d91fb600f6f2191f2ba66665374860  TEST_DIR/test-027/original/subdir/file2
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-027/copy1/file1
-ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-027/copy1/subdir/file2
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-027/copy2/file1
-ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-027/copy2/subdir/file2
-Overwrite copy1/file1 and copy1/subdir/file2 with new data
-md5sums now:
-260f6785c0537fd12582dcae28a3c1a9  TEST_DIR/test-027/original/file1
-b8d91fb600f6f2191f2ba66665374860  TEST_DIR/test-027/original/subdir/file2
-b20229a003e3985c4b0e6806abcd6642  TEST_DIR/test-027/copy1/file1
-b815b24069db14e0a3a07169fd563e93  TEST_DIR/test-027/copy1/subdir/file2
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-027/copy2/file1
-ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-027/copy2/subdir/file2
diff --git a/tests/btrfs/028 b/tests/btrfs/028
deleted file mode 100755
index 7193337..0000000
--- a/tests/btrfs/028
+++ /dev/null
@@ -1,83 +0,0 @@
-#! /bin/bash
-# FS QA Test No. 028
-#
-# Moving and deleting cloned ("reflinked") files on btrfs:
-#   - Create a file and a reflink
-#   - Move both to a directory
-#   - Delete the original (moved) file, check that the copy still exists.
-#
-#-----------------------------------------------------------------------
-# Copyright (c) 2014, Oracle and/or its affiliates.  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
-#-----------------------------------------------------------------------
-
-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 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_xfs_io_command "fiemap"
-_require_cp_reflink
-_require_test
-
-rm -f $seqres.full
-
-TESTDIR1=$TEST_DIR/test-$seq
-rm -rf $TESTDIR1
-mkdir $TESTDIR1
-
-echo "Create the original files and reflink dirs"
-$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \
-    >> $seqres.full
-cp --reflink $TESTDIR1/original $TESTDIR1/copy
-
-_verify_reflink $TESTDIR1/original $TESTDIR1/copy
-
-echo "Move orig & reflink copy to subdir and md5sum:"
-mkdir $TESTDIR1/subdir
-mv $TESTDIR1/original $TESTDIR1/subdir/original_moved
-mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved
-_verify_reflink $TESTDIR1/subdir/original_moved \
-    $TESTDIR1/subdir/copy_moved
-
-md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir
-md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir
-
-echo "remove orig from subdir and md5sum reflink copy:"
-rm $TESTDIR1/subdir/original_moved
-md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir
-rm -rf $TESTDIR1/subdir
-
-# success, all done
-status=0
-exit
diff --git a/tests/btrfs/028.out b/tests/btrfs/028.out
deleted file mode 100644
index f683fce..0000000
--- a/tests/btrfs/028.out
+++ /dev/null
@@ -1,7 +0,0 @@
-QA output created by 028
-Create the original files and reflink dirs
-Move orig & reflink copy to subdir and md5sum:
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-028/subdir/original_moved
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-028/subdir/copy_moved
-remove orig from subdir and md5sum reflink copy:
-42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-028/subdir/copy_moved
diff --git a/tests/btrfs/group b/tests/btrfs/group
index 7cf7dd7..c5d529f 100644
--- a/tests/btrfs/group
+++ b/tests/btrfs/group
@@ -28,9 +28,6 @@
 023 auto
 024 auto quick compress
 025 auto quick send clone
-026 auto quick clone
-027 auto quick clone
-028 auto quick clone
 029 auto quick clone
 030 auto quick send
 031 auto quick subvol clone
diff --git a/tests/generic/110 b/tests/generic/110
new file mode 100755
index 0000000..ec74357
--- /dev/null
+++ b/tests/generic/110
@@ -0,0 +1,92 @@
+#! /bin/bash
+# FS QA Test No. 110
+#
+# Tests file clone functionality of btrfs ("reflinks"):
+#   - Reflink a file
+#   - Reflink the reflinked file
+#   - Modify the original file
+#   - Modify the reflinked file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2014, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+#
+
+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 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_xfs_io_command "fiemap"
+_require_cp_reflink
+_require_test
+
+TESTDIR1=$TEST_DIR/test-$seq
+rm -rf $TESTDIR1
+mkdir $TESTDIR1
+
+_checksum_files() {
+    for F in original copy1 copy2
+    do
+        md5sum $TESTDIR1/$F | _filter_test_dir
+    done
+}
+
+rm -f $seqres.full
+
+echo "Create the original file and reflink to copy1, copy2"
+$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \
+    >> $seqres.full 2>&1
+cp --reflink $TESTDIR1/original $TESTDIR1/copy1
+cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2
+_verify_reflink $TESTDIR1/original $TESTDIR1/copy1
+_verify_reflink $TESTDIR1/original $TESTDIR1/copy2
+echo "Original md5sums:"
+_checksum_files
+
+echo "Overwrite original file with new data"
+$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \
+    >> $seqres.full 2>&1
+echo "md5sums after overwriting original:"
+_checksum_files
+
+echo "Overwrite copy1 with different new data"
+$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \
+    >> $seqres.full 2>&1
+echo "md5sums after overwriting copy1:"
+_checksum_files
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/110.out b/tests/generic/110.out
new file mode 100644
index 0000000..e58b9d8
--- /dev/null
+++ b/tests/generic/110.out
@@ -0,0 +1,16 @@
+QA output created by 110
+Create the original file and reflink to copy1, copy2
+Original md5sums:
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-110/original
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-110/copy1
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-110/copy2
+Overwrite original file with new data
+md5sums after overwriting original:
+4a847a25439532bf48b68c9e9536ed5b  TEST_DIR/test-110/original
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-110/copy1
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-110/copy2
+Overwrite copy1 with different new data
+md5sums after overwriting copy1:
+4a847a25439532bf48b68c9e9536ed5b  TEST_DIR/test-110/original
+e271cd47d9f62ebc96cb4e67ae4d16db  TEST_DIR/test-110/copy1
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-110/copy2
diff --git a/tests/generic/111 b/tests/generic/111
new file mode 100755
index 0000000..9da3f40
--- /dev/null
+++ b/tests/generic/111
@@ -0,0 +1,109 @@
+#! /bin/bash
+# FS QA Test No. 111
+#
+# Tests file clone functionality of btrfs ("reflinks") on directory
+# trees.
+#   - Create directory and subdirectory, each having one file
+#   - Create 2 recursive reflinked copies of the tree
+#   - Modify the original files
+#   - Modify one of the copies
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2014, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 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_xfs_io_command "fiemap"
+_require_cp_reflink
+_require_test
+
+TESTDIR1=$TEST_DIR/test-$seq
+rm -rf $TESTDIR1
+mkdir $TESTDIR1
+
+_checksum_files() {
+    for F in original/file1 original/subdir/file2 \
+                 copy1/file1 copy1/subdir/file2 \
+                 copy2/file1 copy2/subdir/file2
+        do
+            md5sum $TESTDIR1/$F | _filter_test_dir
+        done
+}
+
+rm -f $seqres.full
+
+mkdir $TESTDIR1/original
+mkdir $TESTDIR1/original/subdir
+
+echo "Create the original files and reflink dirs"
+$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \
+    >> $seqres.full 2>&1
+$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \
+    $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1
+cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1
+cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2
+
+_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1
+_verify_reflink $TESTDIR1/original/subdir/file2 \
+    $TESTDIR1/copy1/subdir/file2
+_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1
+_verify_reflink $TESTDIR1/original/subdir/file2 \
+    $TESTDIR1/copy2/subdir/file2
+
+echo "Original md5sums:"
+_checksum_files
+
+echo "Overwrite original/file1 and original/subdir/file2 with new data"
+$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \
+    >> $seqres.full 2>&1
+$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \
+    $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1
+echo "md5sums now:"
+_checksum_files
+
+echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data"
+$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \
+    >> $seqres.full 2>&1
+$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \
+    $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1
+echo "md5sums now:"
+_checksum_files
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/111.out b/tests/generic/111.out
new file mode 100644
index 0000000..e410802
--- /dev/null
+++ b/tests/generic/111.out
@@ -0,0 +1,25 @@
+QA output created by 111
+Create the original files and reflink dirs
+Original md5sums:
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-111/original/file1
+ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-111/original/subdir/file2
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-111/copy1/file1
+ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-111/copy1/subdir/file2
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-111/copy2/file1
+ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-111/copy2/subdir/file2
+Overwrite original/file1 and original/subdir/file2 with new data
+md5sums now:
+260f6785c0537fd12582dcae28a3c1a9  TEST_DIR/test-111/original/file1
+b8d91fb600f6f2191f2ba66665374860  TEST_DIR/test-111/original/subdir/file2
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-111/copy1/file1
+ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-111/copy1/subdir/file2
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-111/copy2/file1
+ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-111/copy2/subdir/file2
+Overwrite copy1/file1 and copy1/subdir/file2 with new data
+md5sums now:
+260f6785c0537fd12582dcae28a3c1a9  TEST_DIR/test-111/original/file1
+b8d91fb600f6f2191f2ba66665374860  TEST_DIR/test-111/original/subdir/file2
+b20229a003e3985c4b0e6806abcd6642  TEST_DIR/test-111/copy1/file1
+b815b24069db14e0a3a07169fd563e93  TEST_DIR/test-111/copy1/subdir/file2
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-111/copy2/file1
+ca390545f0aedb54b808d6128c56a7dd  TEST_DIR/test-111/copy2/subdir/file2
diff --git a/tests/generic/115 b/tests/generic/115
new file mode 100755
index 0000000..35f0417
--- /dev/null
+++ b/tests/generic/115
@@ -0,0 +1,83 @@
+#! /bin/bash
+# FS QA Test No. 115
+#
+# Moving and deleting cloned ("reflinked") files on btrfs:
+#   - Create a file and a reflink
+#   - Move both to a directory
+#   - Delete the original (moved) file, check that the copy still exists.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2014, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 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_xfs_io_command "fiemap"
+_require_cp_reflink
+_require_test
+
+rm -f $seqres.full
+
+TESTDIR1=$TEST_DIR/test-$seq
+rm -rf $TESTDIR1
+mkdir $TESTDIR1
+
+echo "Create the original files and reflink dirs"
+$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \
+    >> $seqres.full
+cp --reflink $TESTDIR1/original $TESTDIR1/copy
+
+_verify_reflink $TESTDIR1/original $TESTDIR1/copy
+
+echo "Move orig & reflink copy to subdir and md5sum:"
+mkdir $TESTDIR1/subdir
+mv $TESTDIR1/original $TESTDIR1/subdir/original_moved
+mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved
+_verify_reflink $TESTDIR1/subdir/original_moved \
+    $TESTDIR1/subdir/copy_moved
+
+md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir
+md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir
+
+echo "remove orig from subdir and md5sum reflink copy:"
+rm $TESTDIR1/subdir/original_moved
+md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir
+rm -rf $TESTDIR1/subdir
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/115.out b/tests/generic/115.out
new file mode 100644
index 0000000..a532214
--- /dev/null
+++ b/tests/generic/115.out
@@ -0,0 +1,7 @@
+QA output created by 115
+Create the original files and reflink dirs
+Move orig & reflink copy to subdir and md5sum:
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-115/subdir/original_moved
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-115/subdir/copy_moved
+remove orig from subdir and md5sum reflink copy:
+42d69d1a6d333a7ebdf64792a555e392  TEST_DIR/test-115/subdir/copy_moved
diff --git a/tests/generic/group b/tests/generic/group
index 1dd4269..aa31c8b 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -112,9 +112,12 @@
 107 auto quick metadata
 108 auto quick rw
 109 auto metadata dir
+110 auto quick clone
+111 auto quick clone
 112 rw aio auto quick
 113 rw aio auto quick
 114 rw aio auto quick
+115 auto quick clone
 117 attr auto quick
 120 other auto quick
 123 perms auto quick


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/12] reflink: add test support routines to a separate file
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
  2015-11-13 21:36 ` [PATCH 01/12] test-scripts: test migration scripts Darrick J. Wong
  2015-11-13 21:36 ` [PATCH 02/12] btrfs: move btrfs reflink tests to generic Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls Darrick J. Wong
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Put all the reflink/dedupe-related test support routines in a separate
file, then modify the existing reflink tests to use them.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 common/rc         |   51 +++++++++------
 common/reflink    |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/btrfs/029   |    1 
 tests/btrfs/031   |    1 
 tests/btrfs/108   |    1 
 tests/btrfs/109   |    1 
 tests/generic/110 |    3 +
 tests/generic/111 |    3 +
 tests/generic/115 |    3 +
 9 files changed, 225 insertions(+), 24 deletions(-)
 create mode 100644 common/reflink


diff --git a/common/rc b/common/rc
index adf1edf..4c2f42c 100644
--- a/common/rc
+++ b/common/rc
@@ -82,6 +82,27 @@ _md5_checksum()
 	md5sum $1 | cut -d ' ' -f1
 }
 
+# Write a byte into a range of a file
+_pwrite_byte() {
+	pattern="$1"
+	offset="$2"
+	len="$3"
+	file="$4"
+	xfs_io_args="$5"
+
+	"$XFS_IO_PROG" $xfs_io_args -f -c "pwrite -S $pattern $offset $len" "$file"
+}
+
+# mmap-write a byte into a range of a file
+_mwrite_byte() {
+	pattern="$1"
+	offset="$2"
+	len="$3"
+	mmap_len="$4"
+	file="$5"
+
+	"$XFS_IO_PROG" -f -c "mmap -rw 0 $mmap_len" -c "mwrite -S $pattern $offset $len" "$file"
+}
 
 # ls -l w/ selinux sometimes puts a dot at the end:
 # -rwxrw-r--. id1 id2 file1
@@ -2569,12 +2590,6 @@ _require_ugid_map()
 	fi
 }
 
-_require_cp_reflink()
-{
-       cp --help | grep -q reflink || \
-               _notrun "This test requires a cp with --reflink support."
-}
-
 _require_fssum()
 {
 	FSSUM_PROG=$here/src/fssum
@@ -2588,21 +2603,6 @@ _require_cloner()
 		_notrun "cloner binary not present at $CLONER_PROG"
 }
 
-# Given 2 files, verify that they have the same mapping but different
-# inodes - i.e. an undisturbed reflink
-# Silent if so, make noise if not
-_verify_reflink()
-{
-       # not a hard link or symlink?
-       cmp -s  <(stat -c '%i' $1) <(stat -c '%i' $2) \
-               && echo "$1 and $2 are not reflinks: same inode number"
-
-       # same mapping?
-       diff -u <($XFS_IO_PROG -c "fiemap" $1 | grep -v $1) \
-               <($XFS_IO_PROG -c "fiemap" $2 | grep -v $2) \
-               || echo "$1 and $2 are not reflinks: different extents"
-}
-
 _require_atime()
 {
 	if [ "$FSTYP" == "nfs" ]; then
@@ -2764,6 +2764,15 @@ _require_btrfs_dev_del_by_devid()
 			"(must support 'btrfs device delete <devid> /<mnt>')"
 }
 
+_require_test_lsattr()
+{
+	testio=$(lsattr -d $TEST_DIR 2>&1)
+	echo $testio | grep -q "Operation not supported" && \
+		_notrun "lsattr not supported by test filesystem type: $FSTYP"
+	echo $testio | grep -q "Inappropriate ioctl for device" && \
+		_notrun "lsattr not supported by test filesystem type: $FSTYP"
+}
+
 _get_total_inode()
 {
 	if [ -z "$1" ]; then
diff --git a/common/reflink b/common/reflink
new file mode 100644
index 0000000..eab7f66
--- /dev/null
+++ b/common/reflink
@@ -0,0 +1,185 @@
+##/bin/bash
+# Routines for reflinking, deduping, and comparing parts of files.
+#-----------------------------------------------------------------------
+#  Copyright (c) 2015 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; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will 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 to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+#  USA
+#
+#  Contact information: Oracle Corporation, 500 Oracle Parkway,
+#  Redwood Shores, CA 94065, USA, or: http://www.oracle.com/
+#-----------------------------------------------------------------------
+
+# Check that cp has a reflink argument
+_require_cp_reflink()
+{
+       cp --help | grep -q reflink || \
+               _notrun "This test requires a cp with --reflink support."
+}
+
+# Given 2 files, verify that they have the same mapping but different
+# inodes - i.e. an undisturbed reflink
+# Silent if so, make noise if not
+_verify_reflink()
+{
+       # not a hard link or symlink?
+       cmp -s  <(stat -c '%i' $1) <(stat -c '%i' $2) \
+               && echo "$1 and $2 are not reflinks: same inode number"
+
+       # same mapping?
+       diff -u <($XFS_IO_PROG -c "fiemap" $1 | grep -v $1) \
+               <($XFS_IO_PROG -c "fiemap" $2 | grep -v $2) \
+               || echo "$1 and $2 are not reflinks: different extents"
+}
+
+# New reflink/dedupe helpers
+
+# this test requires the test fs support reflink...
+_require_test_reflink()
+{
+	_require_test
+	_require_xfs_io_command "reflink"
+
+	rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2"
+	"$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file1" > /dev/null
+	"$XFS_IO_PROG" -f -c "reflink $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" > /dev/null
+	if [ ! -s "$TEST_DIR/file2" ]; then
+		rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2"
+		_notrun "Reflink not supported by test filesystem type: $FSTYP"
+	fi
+	rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2"
+}
+
+# this test requires the scratch fs support reflink...
+_require_scratch_reflink()
+{
+	_require_scratch
+	_require_xfs_io_command "reflink"
+
+	_scratch_mkfs > /dev/null
+	_scratch_mount
+	"$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file1" > /dev/null
+	"$XFS_IO_PROG" -f -c "reflink $SCRATCH_MNT/file1 0 0 65536" "$SCRATCH_MNT/file2" > /dev/null
+	if [ ! -s "$SCRATCH_MNT/file2" ]; then
+		_scratch_unmount
+		_notrun "Reflink not supported by scratch filesystem type: $FSTYP"
+	fi
+	_scratch_unmount
+}
+
+# this test requires the test fs support dedupe...
+_require_test_dedupe()
+{
+	_require_test
+	_require_xfs_io_command "dedupe"
+
+	rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2"
+	"$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file1" > /dev/null
+	"$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file2" > /dev/null
+	testio="$("$XFS_IO_PROG" -f -c "dedupe $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" 2>&1)"
+	echo $testio | grep -q "Operation not supported" && \
+		_notrun "Dedupe not supported by test filesystem type: $FSTYP"
+	echo $testio | grep -q "Inappropriate ioctl for device" && \
+		_notrun "Dedupe not supported by test filesystem type: $FSTYP"
+	rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2"
+}
+
+# this test requires the scratch fs support dedupe...
+_require_scratch_dedupe()
+{
+	_require_scratch
+	_require_xfs_io_command "dedupe"
+
+	_scratch_mkfs > /dev/null
+	_scratch_mount
+	"$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file1" > /dev/null
+	"$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file2" > /dev/null
+	testio="$("$XFS_IO_PROG" -f -c "dedupe $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" 2>&1)"
+	echo $testio | grep -q "Operation not supported" && \
+		_notrun "Dedupe not supported by test filesystem type: $FSTYP"
+	echo $testio | grep -q "Inappropriate ioctl for device" && \
+		_notrun "Dedupe not supported by test filesystem type: $FSTYP"
+	_scratch_unmount
+}
+
+# Prints a range of a file as a hex dump
+_read_range() {
+	file="$1"
+	offset="$2"
+	len="$3"
+	xfs_io_args="$4"
+
+	$XFS_IO_PROG $xfs_io_args -f -c "pread -q -v $offset $len" "$file" | cut -d ' ' -f '3-18'
+}
+
+# Compare ranges of two files
+_compare_range() {
+	file1="$1"
+	offset1="$2"
+	file2="$3"
+	offset2="$4"
+	len="$5"
+
+	cmp -s <(_read_range "$file1" "$offset1" "$len") \
+	       <(_read_range "$file2" "$offset2" "$len")
+}
+
+# Prints the md5 checksum of a hexdump of a part of a given file
+_md5_range_checksum() {
+	file="$1"
+	offset="$2"
+	len="$3"
+
+	md5sum <(_read_range "$file" "$offset" "$len") | cut -d ' ' -f 1
+}
+
+# Reflink some file1 into file2 via cp
+_cp_reflink() {
+	file1="$1"
+	file2="$2"
+
+	cp --reflink=always "$file1" "$file2"
+}
+
+# Reflink some file1 into file2
+_reflink() {
+	file1="$1"
+	file2="$2"
+
+	"$XFS_IO_PROG" -f -c "reflink $file1" "$file2"
+}
+
+# Reflink some part of file1 into another part of file2
+_reflink_range() {
+	file1="$1"
+	offset1="$2"
+	file2="$3"
+	offset2="$4"
+	len="$5"
+	xfs_io_args="$6"
+
+	"$XFS_IO_PROG" $xfs_io_args -f -c "reflink $file1 $offset1 $offset2 $len" "$file2"
+}
+
+# Dedupe some part of file1 into another part of file2
+_dedupe_range() {
+	file1="$1"
+	offset1="$2"
+	file2="$3"
+	offset2="$4"
+	len="$5"
+	xfs_io_args="$6"
+
+	"$XFS_IO_PROG" $xfs_io_args -f -c "dedupe $file1 $offset1 $offset2 $len" "$file2"
+}
diff --git a/tests/btrfs/029 b/tests/btrfs/029
index 0b77b33..175317a 100755
--- a/tests/btrfs/029
+++ b/tests/btrfs/029
@@ -47,6 +47,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/reflink
 
 # real QA test starts here
 _supported_fs btrfs
diff --git a/tests/btrfs/031 b/tests/btrfs/031
index bcd332c..c5763da 100755
--- a/tests/btrfs/031
+++ b/tests/btrfs/031
@@ -48,6 +48,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/reflink
 
 # real QA test starts here
 _supported_fs btrfs
diff --git a/tests/btrfs/108 b/tests/btrfs/108
index 5e3a403..18e5b99 100755
--- a/tests/btrfs/108
+++ b/tests/btrfs/108
@@ -41,6 +41,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/reflink
 
 # real QA test starts here
 _supported_fs btrfs
diff --git a/tests/btrfs/109 b/tests/btrfs/109
index e2aeb73..b86336c 100755
--- a/tests/btrfs/109
+++ b/tests/btrfs/109
@@ -41,6 +41,7 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/reflink
 
 # real QA test starts here
 _supported_fs btrfs
diff --git a/tests/generic/110 b/tests/generic/110
index ec74357..468d859 100755
--- a/tests/generic/110
+++ b/tests/generic/110
@@ -43,9 +43,10 @@ _cleanup()
 # get standard environment, filters and checks
 . common/rc
 . common/filter
+. common/reflink
 
 # real QA test starts here
-_supported_fs btrfs
+_require_test_reflink
 _supported_os Linux
 
 _require_xfs_io_command "fiemap"
diff --git a/tests/generic/111 b/tests/generic/111
index 9da3f40..1797233 100755
--- a/tests/generic/111
+++ b/tests/generic/111
@@ -43,9 +43,10 @@ _cleanup()
 # get standard environment, filters and checks
 . common/rc
 . common/filter
+. common/reflink
 
 # real QA test starts here
-_supported_fs btrfs
+_require_test_reflink
 _supported_os Linux
 
 _require_xfs_io_command "fiemap"
diff --git a/tests/generic/115 b/tests/generic/115
index 35f0417..b5c64ec 100755
--- a/tests/generic/115
+++ b/tests/generic/115
@@ -41,9 +41,10 @@ _cleanup()
 # get standard environment, filters and checks
 . ./common/rc
 . ./common/filter
+. ./common/reflink
 
 # real QA test starts here
-_supported_fs btrfs
+_require_test_reflink
 _supported_os Linux
 
 _require_xfs_io_command "fiemap"

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (2 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 03/12] reflink: add test support routines to a separate file Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 05/12] reflink: test CoW behaviors of reflinked files Darrick J. Wong
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Test the operation of the btrfs (and now xfs) reflink and dedupe
ioctls at various file offsets and with matching and nonmatching
files.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/116     |   92 +++++++++++++++++++++++++++
 tests/generic/116.out |    8 ++
 tests/generic/118     |   93 +++++++++++++++++++++++++++
 tests/generic/118.out |   11 +++
 tests/generic/119     |  170 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/119.out |   30 +++++++++
 tests/generic/121     |   92 +++++++++++++++++++++++++++
 tests/generic/121.out |    8 ++
 tests/generic/122     |   92 +++++++++++++++++++++++++++
 tests/generic/122.out |   12 +++
 tests/generic/134     |  128 +++++++++++++++++++++++++++++++++++++
 tests/generic/134.out |   16 +++++
 tests/generic/136     |  128 +++++++++++++++++++++++++++++++++++++
 tests/generic/136.out |   17 +++++
 tests/generic/137     |  131 ++++++++++++++++++++++++++++++++++++++
 tests/generic/137.out |    8 ++
 tests/generic/group   |    8 ++
 17 files changed, 1044 insertions(+)
 create mode 100755 tests/generic/116
 create mode 100644 tests/generic/116.out
 create mode 100755 tests/generic/118
 create mode 100644 tests/generic/118.out
 create mode 100755 tests/generic/119
 create mode 100644 tests/generic/119.out
 create mode 100755 tests/generic/121
 create mode 100644 tests/generic/121.out
 create mode 100755 tests/generic/122
 create mode 100644 tests/generic/122.out
 create mode 100755 tests/generic/134
 create mode 100644 tests/generic/134.out
 create mode 100755 tests/generic/136
 create mode 100644 tests/generic/136.out
 create mode 100755 tests/generic/137
 create mode 100644 tests/generic/137.out


diff --git a/tests/generic/116 b/tests/generic/116
new file mode 100755
index 0000000..2b4b505
--- /dev/null
+++ b/tests/generic/116
@@ -0,0 +1,92 @@
+#! /bin/bash
+# FS QA Test No. 116
+#
+# Ensure that we can reflink parts of two identical files:
+#   - Reflink identical parts of two identical files
+#   - Check that we still have identical contents
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \
+       || echo "Files do not match"
+
+echo "Reflink the middle blocks together"
+free_before="$(stat -f -c '%a' "$TESTDIR")"
+_reflink_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full"
+_test_remount
+free_after="$(stat -f -c '%a' "$TESTDIR")"
+echo "freesp changed by $free_before -> $free_after" >> "$seqres.full"
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \
+       || echo "Start sections do not match"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) \
+       || echo "Middle sections do not match"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \
+		$((BLKSZ * 6)) $((BLKSZ * 2)) \
+       || echo "End sections do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/116.out b/tests/generic/116.out
new file mode 100644
index 0000000..5adfc62
--- /dev/null
+++ b/tests/generic/116.out
@@ -0,0 +1,8 @@
+QA output created by 116
+Create the original files
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-116/file1
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-116/file2
+Reflink the middle blocks together
+Compare sections
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-116/file1
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-116/file2
diff --git a/tests/generic/118 b/tests/generic/118
new file mode 100755
index 0000000..651b72c
--- /dev/null
+++ b/tests/generic/118
@@ -0,0 +1,93 @@
+#! /bin/bash
+# FS QA Test No. 118
+#
+# Ensuring that we can reflink non-matching parts of files:
+#   - Reflink identical ranges of two different files
+#   - Check that the non-linked ranges still do not match
+#   - Check that we end up with identical contents in the linked ranges
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \
+       || echo "Files do not match (intentional)"
+
+echo "Reflink the middle blocks together"
+free_before="$(stat -f -c '%a' "$TESTDIR")"
+_reflink_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full"
+_test_remount
+free_after="$(stat -f -c '%a' "$TESTDIR")"
+echo "freesp changed by $free_before -> $free_after" >> "$seqres.full"
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \
+       || echo "Start sections do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) \
+       || echo "Middle sections do not match"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \
+		$((BLKSZ * 6)) $((BLKSZ * 2)) \
+       || echo "End sections do not match (intentional)"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/118.out b/tests/generic/118.out
new file mode 100644
index 0000000..8fdaf59
--- /dev/null
+++ b/tests/generic/118.out
@@ -0,0 +1,11 @@
+QA output created by 118
+Create the original files
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-118/file1
+5e3501f97fd2669babfcbd3e1972e833  TEST_DIR/test-118/file2
+Files do not match (intentional)
+Reflink the middle blocks together
+Compare sections
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-118/file1
+f7f9e44d37909868014e9151f5293ab0  TEST_DIR/test-118/file2
+Start sections do not match (intentional)
+End sections do not match (intentional)
diff --git a/tests/generic/119 b/tests/generic/119
new file mode 100755
index 0000000..9d57379
--- /dev/null
+++ b/tests/generic/119
@@ -0,0 +1,170 @@
+#! /bin/bash
+# FS QA Test No. 119
+#
+# Reflinking two sets of files together:
+#   - Reflink identical parts of two identical files
+#   - Reflink identical parts of two other identical files
+#   - Reflink identical parts of all four files
+#   - Check that we end up with identical contents
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR=$TEST_DIR/test-$seq
+rm -rf $TESTDIR
+mkdir $TESTDIR
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ * 8)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((BLKSZ * 8)) "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x63 0 $((BLKSZ * 8)) "$TESTDIR/file3" >> "$seqres.full"
+_pwrite_byte 0x64 0 $((BLKSZ * 8)) "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \
+       || echo "Files 1-2 do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 8)) \
+       || echo "Files 1-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 8)) \
+       || echo "Files 1-4 do not match (intentional)"
+
+echo "Reflink the first four blocks together, 1-2 3-4"
+free_before="$(stat -f -c '%a' "$TESTDIR")"
+_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) >> "$seqres.full"
+_reflink_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) >> "$seqres.full"
+_test_remount
+free_after="$(stat -f -c '%a' "$TESTDIR")"
+echo "freesp changed by $free_before -> $free_after" >> "$seqres.full"
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \
+       || echo "Sections of file 1-2 do not match"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 4)) \
+       || echo "Sections of file 1-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \
+       || echo "Sections of file 1-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $((BLKSZ * 4)) \
+       || echo "Sections of file 2-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \
+       || echo "Sections of file 2-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \
+       || echo "Sections of file 3-4 do not match"
+
+echo "Reflink the first two blocks together, 1-3 1-4"
+free_before="$(stat -f -c '%a' $TESTDIR)"
+_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) >> "$seqres.full"
+_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) >> "$seqres.full"
+_test_remount
+free_after="$(stat -f -c '%a' $TESTDIR)"
+echo "freesp changed by $free_before -> $free_after" >> "$seqres.full"
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 2)) \
+       || echo "Sections of files 1-2 do not match"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) \
+       || echo "Sections of files 1-3 do not match"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \
+       || echo "Sections of files 1-4 do not match"
+
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) \
+       || echo "Sections of files 2-3 do not match"
+
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \
+       || echo "Sections of files 2-4 do not match"
+
+_compare_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \
+       || echo "Sections of files 3-4 do not match"
+
+echo "Compare previously reflinked sections"
+_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file2" \
+		$((BLKSZ * 2)) $((BLKSZ * 2)) \
+       || echo "Sections of file 1-2 do not match"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file3" \
+		$((BLKSZ * 2)) $((BLKSZ * 2)) \
+       || echo "Sections of file 1-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file4" \
+		$((BLKSZ * 2)) $((BLKSZ * 2)) \
+       || echo "Sections of file 1-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" $((BLKSZ * 2)) "$TESTDIR/file3" \
+		$((BLKSZ * 2)) $((BLKSZ * 2)) \
+       || echo "Sections of file 2-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" $((BLKSZ * 2)) "$TESTDIR/file4" \
+		$((BLKSZ * 2)) $((BLKSZ * 2)) \
+       || echo "Sections of file 2-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file3" $((BLKSZ * 2)) "$TESTDIR/file4" \
+		$((BLKSZ * 2)) $((BLKSZ * 2)) \
+       || echo "Sections of file 3-4 do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/119.out b/tests/generic/119.out
new file mode 100644
index 0000000..85893d5
--- /dev/null
+++ b/tests/generic/119.out
@@ -0,0 +1,30 @@
+QA output created by 119
+Create the original files
+30c2557e8302a5beb290c71520d87f42  TEST_DIR/test-119/file1
+efb787f7990e43c7dc30565d8cc344d4  TEST_DIR/test-119/file2
+c83f38d4622a78b74e3480634194b08f  TEST_DIR/test-119/file3
+1c11fd3151d2229f5cf43903386aa432  TEST_DIR/test-119/file4
+Files 1-2 do not match (intentional)
+Files 1-3 do not match (intentional)
+Files 1-4 do not match (intentional)
+Reflink the first four blocks together, 1-2 3-4
+Compare sections
+30c2557e8302a5beb290c71520d87f42  TEST_DIR/test-119/file1
+63bdb182cdf03a8a19e83234d869d00a  TEST_DIR/test-119/file2
+c83f38d4622a78b74e3480634194b08f  TEST_DIR/test-119/file3
+dc2ae3db14e97fad93faf939170b085c  TEST_DIR/test-119/file4
+Sections of file 1-3 do not match (intentional)
+Sections of file 1-4 do not match (intentional)
+Sections of file 2-3 do not match (intentional)
+Sections of file 2-4 do not match (intentional)
+Reflink the first two blocks together, 1-3 1-4
+Compare sections
+30c2557e8302a5beb290c71520d87f42  TEST_DIR/test-119/file1
+63bdb182cdf03a8a19e83234d869d00a  TEST_DIR/test-119/file2
+89a444ff9d6af60ba487e9a0ca2161e2  TEST_DIR/test-119/file3
+0c263058794a54c5e197ece52386f5be  TEST_DIR/test-119/file4
+Compare previously reflinked sections
+Sections of file 1-3 do not match (intentional)
+Sections of file 1-4 do not match (intentional)
+Sections of file 2-3 do not match (intentional)
+Sections of file 2-4 do not match (intentional)
diff --git a/tests/generic/121 b/tests/generic/121
new file mode 100755
index 0000000..9a5b383
--- /dev/null
+++ b/tests/generic/121
@@ -0,0 +1,92 @@
+#! /bin/bash
+# FS QA Test No. 121
+#
+# Ensure that we can dedupe parts of two files:
+#   - Dedupe identical parts of two identical files
+#   - Check that still have identical contents
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_dedupe
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \
+       || echo "Files 1-2 do not match (intentional)"
+
+echo "Dedupe the middle blocks together"
+free_before="$(stat -f -c '%a' "$TESTDIR")"
+_dedupe_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full"
+_test_remount
+free_after="$(stat -f -c '%a' "$TESTDIR")"
+echo "freesp changed by $free_before -> $free_after" >> "$seqres.full"
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \
+       || echo "Start sections do not match"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) \
+       || echo "Middle sections do not match"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \
+		$((BLKSZ * 6)) $((BLKSZ * 2)) \
+       || echo "End sections do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/121.out b/tests/generic/121.out
new file mode 100644
index 0000000..d865c7e
--- /dev/null
+++ b/tests/generic/121.out
@@ -0,0 +1,8 @@
+QA output created by 121
+Create the original files
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-121/file1
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-121/file2
+Dedupe the middle blocks together
+Compare sections
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-121/file1
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-121/file2
diff --git a/tests/generic/122 b/tests/generic/122
new file mode 100755
index 0000000..0edb48d
--- /dev/null
+++ b/tests/generic/122
@@ -0,0 +1,92 @@
+#! /bin/bash
+# FS QA Test No. 122
+#
+# Ensuring that we cannot dedupe non-matching parts of files:
+#   - Fail to dedupe non-identical parts of two different files
+#   - Check that nothing changes in either file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_dedupe
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 "$((BLKSZ * 8))" \
+       || echo "Files 1-2 do not match (intentional)"
+
+echo "(Fail to) dedupe the middle blocks together"
+free_before="$(stat -f -c '%a' "$TESTDIR")"
+_dedupe_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full"
+_test_remount
+free_after="$(stat -f -c '%a' "$TESTDIR")"
+echo "freesp changed by $free_before -> $free_after" >> "$seqres.full"
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \
+       || echo "Start sections do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \
+		$((BLKSZ * 4)) $((BLKSZ * 2)) \
+       || echo "Middle sections do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \
+		$((BLKSZ * 6)) $((BLKSZ * 2)) \
+       || echo "End sections do not match (intentional)"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/122.out b/tests/generic/122.out
new file mode 100644
index 0000000..c7cfec2
--- /dev/null
+++ b/tests/generic/122.out
@@ -0,0 +1,12 @@
+QA output created by 122
+Create the original files
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-122/file1
+5e3501f97fd2669babfcbd3e1972e833  TEST_DIR/test-122/file2
+Files 1-2 do not match (intentional)
+(Fail to) dedupe the middle blocks together
+Compare sections
+35ac8d7917305c385c30f3d82c30a8f6  TEST_DIR/test-122/file1
+5e3501f97fd2669babfcbd3e1972e833  TEST_DIR/test-122/file2
+Start sections do not match (intentional)
+Middle sections do not match (intentional)
+End sections do not match (intentional)
diff --git a/tests/generic/134 b/tests/generic/134
new file mode 100755
index 0000000..4dc710c
--- /dev/null
+++ b/tests/generic/134
@@ -0,0 +1,128 @@
+#! /bin/bash
+# FS QA Test No. 134
+#
+# Ensure that we can reflink the last block of a file whose size isn't
+# block-aligned.
+#   - Create two 'a' files file whose size isn't block-aligned.
+#   - Create two 'b' files file whose size isn't block-aligned.
+#   - Reflink the last block of file1 to the last block in file2 and file3.
+#   - Check that files 1-2 match, 3-4 don't match, and that nothing matches 3.
+#   - Check that the ends of 1-3 match, and 1-3 do not match the end of file4.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file3" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+C1="$(_md5_checksum $TESTDIR/file1)"
+C2="$(_md5_checksum $TESTDIR/file2)"
+C3="$(_md5_checksum $TESTDIR/file3)"
+C4="$(_md5_checksum $TESTDIR/file4)"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "Reflink the last blocks together, 1-2 1-3"
+_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 >> "$seqres.full"
+_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+C1="$(_md5_checksum $TESTDIR/file1)"
+C2="$(_md5_checksum $TESTDIR/file2)"
+C3="$(_md5_checksum $TESTDIR/file3)"
+C4="$(_md5_checksum $TESTDIR/file4)"
+
+echo "Compare files"
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" != "${C4}" || echo "file3 and file4 should match"
+
+echo "Compare sections"
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 \
+       || echo "End sections of files 1-2 do not match"
+
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \
+       || echo "End sections of files 1-3 do not match"
+
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \
+       || echo "End sections of files 1-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \
+       || echo "End sections of files 2-3 do not match"
+
+_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \
+       || echo "End sections of files 2-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file3" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \
+       || echo "End sections of files 3-4 do not match (intentional)"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/134.out b/tests/generic/134.out
new file mode 100644
index 0000000..b5e0f43
--- /dev/null
+++ b/tests/generic/134.out
@@ -0,0 +1,16 @@
+QA output created by 134
+Create the original files
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-134/file1
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-134/file2
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-134/file3
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-134/file4
+Reflink the last blocks together, 1-2 1-3
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-134/file1
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-134/file2
+e236f2fe789f0aa34b50e981a2f0243a  TEST_DIR/test-134/file3
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-134/file4
+Compare files
+Compare sections
+End sections of files 1-4 do not match (intentional)
+End sections of files 2-4 do not match (intentional)
+End sections of files 3-4 do not match (intentional)
diff --git a/tests/generic/136 b/tests/generic/136
new file mode 100755
index 0000000..89ee751
--- /dev/null
+++ b/tests/generic/136
@@ -0,0 +1,128 @@
+#! /bin/bash
+# FS QA Test No. 136
+#
+# Ensure that we can dedupe the last block of a file whose size isn't
+# block-aligned.
+#   - Create two 'a' files file whose size isn't block-aligned.
+#   - Create two 'b' files file whose size isn't block-aligned.
+#   - Dedupe the last block of file1 to the last block in file2 and file3.
+#   - Check that files 1-2 match, and that 3-4 match.
+#   - Check that the ends of 1-2 and 3-4 match, and that 1-3 don't match.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_dedupe
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file3" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+C1="$(_md5_checksum $TESTDIR/file1)"
+C2="$(_md5_checksum $TESTDIR/file2)"
+C3="$(_md5_checksum $TESTDIR/file3)"
+C4="$(_md5_checksum $TESTDIR/file4)"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "Dedupe the last blocks together"
+_dedupe_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 >> "$seqres.full"
+_dedupe_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+
+C1="$(_md5_checksum $TESTDIR/file1)"
+C2="$(_md5_checksum $TESTDIR/file2)"
+C3="$(_md5_checksum $TESTDIR/file3)"
+C4="$(_md5_checksum $TESTDIR/file4)"
+
+echo "Compare files"
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "Compare sections"
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 \
+       || echo "End sections of files 1-2 do not match"
+
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \
+       || echo "End sections of files 1-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \
+       || echo "End sections of files 1-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \
+       || echo "End sections of files 2-3 do not match (intentional)"
+
+_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \
+       || echo "End sections of files 2-4 do not match (intentional)"
+
+_compare_range "$TESTDIR/file3" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \
+       || echo "End sections of files 3-4 do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/136.out b/tests/generic/136.out
new file mode 100644
index 0000000..99a5465
--- /dev/null
+++ b/tests/generic/136.out
@@ -0,0 +1,17 @@
+QA output created by 136
+Create the original files
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-136/file1
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-136/file2
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-136/file3
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-136/file4
+Dedupe the last blocks together
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-136/file1
+c4fd505be25a0c91bcca9f502b9a8156  TEST_DIR/test-136/file2
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-136/file3
+07ac67bf7f271195442509e79cde4cee  TEST_DIR/test-136/file4
+Compare files
+Compare sections
+End sections of files 1-3 do not match (intentional)
+End sections of files 1-4 do not match (intentional)
+End sections of files 2-3 do not match (intentional)
+End sections of files 2-4 do not match (intentional)
diff --git a/tests/generic/137 b/tests/generic/137
new file mode 100755
index 0000000..a640f4f
--- /dev/null
+++ b/tests/generic/137
@@ -0,0 +1,131 @@
+#! /bin/bash
+# FS QA Test No. 137
+#
+# Ensure that we can reflink and dedupe blocks within the same file...
+#   - Create a file with three distinct blocks ABB
+#   - Reflink block zero to the multiple-of-three blocks
+#   - Reflink block one to the multiple-of-five blocks
+#   - Dedupe block two to the multiple-of-seven blocks
+#   - Check that we successfully avoid deduping with holes, unwritten
+#     extents, and non-matches; but actually dedupe real matches.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_test_dedupe
+_require_xfs_io_command "falloc"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $((BLKSZ * 2)) "$TESTDIR/file1" >> "$seqres.full"
+
+NR_BLKS=1024
+
+echo "fallocate half the file"
+"$XFS_IO_PROG" -f -c "falloc $((NR_BLKS * BLKSZ / 2)) $((NR_BLKS * BLKSZ / 2))" "$TESTDIR/file1" >> "$seqres.full"
+
+echo "Reflink block zero to the threes"
+seq 1 $((NR_BLKS / 3)) | while read nr; do
+	_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file1" $((nr * 3 * BLKSZ)) \
+			$BLKSZ >> "$seqres.full"
+done
+
+echo "Reflink block one to the fives"
+seq 1 $((NR_BLKS / 5)) | while read nr; do
+	_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file1" \
+			$((nr * 5 * BLKSZ)) $BLKSZ >> "$seqres.full"
+done
+
+echo "Dedupe block two to the sevens"
+seq 1 $((NR_BLKS / 7)) | while read nr; do
+	_dedupe_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file1" \
+			$((nr * 7 * BLKSZ)) $BLKSZ >> "$seqres.full"
+done
+
+_test_remount
+
+echo "Check block mappings"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+
+crcZ=$(_md5_range_checksum /dev/zero 0 $BLKSZ)
+crc0=$(_md5_range_checksum "$TESTDIR/file1" 0 $BLKSZ)
+crc1=$(_md5_range_checksum "$TESTDIR/file1" $BLKSZ $BLKSZ)
+crc2=$(_md5_range_checksum "$TESTDIR/file1" $((BLKSZ * 2)) $BLKSZ)
+
+check_block() {
+	lblk="$1"
+	rem7=$((lblk % 7))
+	rem5=$((lblk % 5))
+	rem3=$((lblk % 3))
+
+	crc=$(_md5_range_checksum "$TESTDIR/file1" $((lblk * BLKSZ)) $BLKSZ)
+
+	if [ $rem7 -eq 0 ]; then
+		if [ $rem5 -eq 0 ]; then
+			test $crc2 = $crc || echo "lblk $lblk doesn't match block 2"
+		elif [ $rem3 -eq 0 ]; then
+			test $crc0 = $crc || echo "lblk $lblk doesn't match block 0"
+		elif [ $lblk -lt $((NR_BLKS / 2)) ]; then
+			test $crcZ = $crc || echo "lblk $lblk isn't zeroed"
+		fi
+	elif [ $rem5 -eq 0 ]; then
+		test $crc1 = $crc || echo "lblk $lblk doesn't match block 1"
+	elif [ $rem3 -eq 0 ]; then
+		test $crc0 = $crc || echo "lblk $lblk doesn't match block 0"
+	elif [ $lblk -lt $((NR_BLKS / 2)) ]; then
+		test $crcZ = $crc || echo "lblk $lblk isn't zeroed"
+	fi
+}
+
+seq 3 $((NR_BLKS - 1)) | while read lblk; do
+	err="$(check_block $lblk)"
+	test -n "$err" && echo "$lblk: $err"
+done
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/137.out b/tests/generic/137.out
new file mode 100644
index 0000000..7808988
--- /dev/null
+++ b/tests/generic/137.out
@@ -0,0 +1,8 @@
+QA output created by 137
+Create the original file blocks
+fallocate half the file
+Reflink block zero to the threes
+Reflink block one to the fives
+Dedupe block two to the sevens
+Check block mappings
+2ea37912bdbd71b9ed4734d3141cbe9c  TEST_DIR/test-137/file1
diff --git a/tests/generic/group b/tests/generic/group
index aa31c8b..50cc132 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -118,8 +118,13 @@
 113 rw aio auto quick
 114 rw aio auto quick
 115 auto quick clone
+116 auto quick clone
 117 attr auto quick
+118 auto quick clone
+119 auto quick clone
 120 other auto quick
+121 auto quick clone
+122 auto quick clone
 123 perms auto quick
 124 pattern auto quick
 125 other auto
@@ -131,7 +136,10 @@
 131 perms auto quick
 132 pattern auto
 133 rw auto
+134 auto quick clone
 135 metadata auto quick
+136 auto quick clone
+137 auto quick clone
 141 rw auto quick
 169 rw metadata auto quick
 184 metadata auto quick

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/12] reflink: test CoW behaviors of reflinked files
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (3 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 06/12] reflink: test the various fallocate modes Darrick J. Wong
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Ensure that CoW happens correctly with buffered, directio, and mmap writes.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/138     |  152 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/138.out |   19 ++++++
 tests/generic/139     |  151 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/139.out |   19 ++++++
 tests/generic/140     |  152 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/140.out |   19 ++++++
 tests/generic/142     |   91 +++++++++++++++++++++++++++++
 tests/generic/142.out |    8 +++
 tests/generic/143     |   91 +++++++++++++++++++++++++++++
 tests/generic/143.out |    8 +++
 tests/generic/group   |    5 ++
 11 files changed, 715 insertions(+)
 create mode 100755 tests/generic/138
 create mode 100644 tests/generic/138.out
 create mode 100755 tests/generic/139
 create mode 100644 tests/generic/139.out
 create mode 100755 tests/generic/140
 create mode 100644 tests/generic/140.out
 create mode 100755 tests/generic/142
 create mode 100644 tests/generic/142.out
 create mode 100755 tests/generic/143
 create mode 100644 tests/generic/143.out


diff --git a/tests/generic/138 b/tests/generic/138
new file mode 100755
index 0000000..c084679
--- /dev/null
+++ b/tests/generic/138
@@ -0,0 +1,152 @@
+#! /bin/bash
+# FS QA Test No. 138
+#
+# Ensuring that copy on write through the page cache works:
+#   - Reflink two files together
+#   - Write to the beginning, middle, and end
+#   - Check that the files are now different where we say they're different.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+
+cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match"
+cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match"
+
+echo "pagecache CoW the second file"
+_pwrite_byte 0x62 0 17 "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x62 0 17 "$TESTDIR/file3" >> "$seqres.full"
+
+_pwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 "$TESTDIR/file3" >> "$seqres.full"
+
+_pwrite_byte 0x62 $((BLKSZ * 48 - 8)) 17 "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 48 - 8)) 17 "$TESTDIR/file3" >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+
+cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match (intentional)"
+cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match (intentional)"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match"
+
+echo "Compare the CoW'd section to the before file"
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 17 \
+       || echo "Start sections do not match (intentional)"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16 - 34)) \
+		"$TESTDIR/file2" $((BLKSZ * 16 - 34)) 17 \
+       || echo "Middle sections do not match (intentional)"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 48 - 8)) \
+		"$TESTDIR/file2" $((BLKSZ * 48 - 8)) 17 \
+       || echo "End sections do not match (intentional)"
+
+echo "Compare the CoW'd section to the after file"
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 17 \
+       || echo "Start sections do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16 - 34)) \
+		"$TESTDIR/file3" $((BLKSZ * 16 - 34)) 17 \
+       || echo "Middle sections do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 48 - 8)) \
+		"$TESTDIR/file3" $((BLKSZ * 48 - 8)) 17 \
+       || echo "End sections do not match"
+
+echo "Compare the not CoW'd sections"
+_compare_range "$TESTDIR/file1" 18 "$TESTDIR/file2" 18 17 \
+       || echo "Start sections of 1-2 do not match"
+
+_compare_range "$TESTDIR/file2" 18 "$TESTDIR/file3" 18 17 \
+       || echo "Start sections of 2-3 do not match"
+
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16 - 17)) \
+		"$TESTDIR/file2" $((BLKSZ * 16 - 17)) 82 \
+       || echo "Middle sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16 - 17)) \
+		"$TESTDIR/file3" $((BLKSZ * 16 - 17)) 82 \
+       || echo "Middle sections of 2-3 do not match"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 48 - 108)) \
+		"$TESTDIR/file2" $((BLKSZ * 48 - 108)) 100 \
+       || echo "End sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 48 - 108)) \
+		"$TESTDIR/file3" $((BLKSZ * 48 - 108)) 100 \
+       || echo "End sections of 2-3 do not match"
+
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 14)) \
+		"$TESTDIR/file2" $((BLKSZ * 14)) $BLKSZ \
+       || echo "Untouched sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 14)) \
+		"$TESTDIR/file3" $((BLKSZ * 14)) $BLKSZ \
+       || echo "Untouched sections of 2-3 do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/138.out b/tests/generic/138.out
new file mode 100644
index 0000000..b0cafab
--- /dev/null
+++ b/tests/generic/138.out
@@ -0,0 +1,19 @@
+QA output created by 138
+Create the original files
+Compare files
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-138/file1
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-138/file2
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-138/file3
+pagecache CoW the second file
+Compare files
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-138/file1
+4a879c2f322121f6f4b8ebede1909a7c  TEST_DIR/test-138/file2
+4a879c2f322121f6f4b8ebede1909a7c  TEST_DIR/test-138/file3
+Files 1-2 do not match (intentional)
+Files 1-3 do not match (intentional)
+Compare the CoW'd section to the before file
+Start sections do not match (intentional)
+Middle sections do not match (intentional)
+End sections do not match (intentional)
+Compare the CoW'd section to the after file
+Compare the not CoW'd sections
diff --git a/tests/generic/139 b/tests/generic/139
new file mode 100755
index 0000000..54c68fb
--- /dev/null
+++ b/tests/generic/139
@@ -0,0 +1,151 @@
+#! /bin/bash
+# FS QA Test No. 139
+#
+# Ensuring that copy on write in direct-io mode works:
+#   - Reflink two files together
+#   - Write to the beginning, middle, and end in direct-io mode
+#   - Check that the files are now different where we say they're different.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR=$TEST_DIR/test-$seq
+rm -rf $TESTDIR
+mkdir $TESTDIR
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+
+cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 should match"
+cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 should match"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 should match"
+
+echo "directio CoW the second file"
+_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2" -d >> "$seqres.full"
+_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file3" -d >> "$seqres.full"
+
+_pwrite_byte 0x62 $((BLKSZ * 16 - 512)) 512 "$TESTDIR/file2" -d >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 16 - 512)) 512 "$TESTDIR/file3" -d >> "$seqres.full"
+
+_pwrite_byte 0x62 $((BLKSZ * 48)) $BLKSZ "$TESTDIR/file2" -d >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 48)) $BLKSZ "$TESTDIR/file3" -d >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+
+cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 should not match (intentional)"
+cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 should not match (intentional)"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 should match"
+
+echo "Compare the CoW'd section to the before file"
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $BLKSZ \
+       || echo "Start sections do not match (intentional)"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16 - 512)) \
+		"$TESTDIR/file2" $((BLKSZ * 16 - 512)) 512 \
+       || echo "Middle sections do not match (intentional)"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 48 - 512)) \
+		"$TESTDIR/file2" $((BLKSZ * 48 - 512)) $BLKSZ \
+       || echo "End sections do not match (intentional)"
+
+echo "Compare the CoW'd section to the after file"
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $BLKSZ \
+       || echo "Start sections do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16 - 512)) \
+		"$TESTDIR/file3" $((BLKSZ * 16 - 512)) 512 \
+       || echo "Middle sections do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 48 - 512)) \
+		"$TESTDIR/file3" $((BLKSZ * 48 - 512)) $BLKSZ \
+       || echo "End sections do not match"
+
+echo "Compare the not CoW'd sections"
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 512 \
+       || echo "Start sections of 1-2 do not match"
+_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 512 \
+       || echo "Start sections of 2-3 do not match"
+
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16 - 1024)) \
+		"$TESTDIR/file2" $((BLKSZ * 16 - 1024)) 512 \
+       || echo "Middle sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16 - 1024)) \
+		"$TESTDIR/file3" $((BLKSZ * 16 - 1024)) 512 \
+       || echo "Middle sections of 2-3 do not match"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 48 - 1024)) \
+		"$TESTDIR/file2" $((BLKSZ * 48 - 1024)) 512 \
+       || echo "End sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 48 - 1024)) \
+		"$TESTDIR/file3" $((BLKSZ * 48 - 1024)) 512 \
+       || echo "End sections of 2-3 do not match"
+
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16)) \
+		"$TESTDIR/file2" $((BLKSZ * 16)) 512 \
+       || echo "Untouched sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16)) \
+		"$TESTDIR/file3" $((BLKSZ * 16)) 512 \
+       || echo "Untouched sections of 2-3 do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/139.out b/tests/generic/139.out
new file mode 100644
index 0000000..28d04f5
--- /dev/null
+++ b/tests/generic/139.out
@@ -0,0 +1,19 @@
+QA output created by 139
+Create the original files
+Compare files
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-139/file1
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-139/file2
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-139/file3
+directio CoW the second file
+Compare files
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-139/file1
+ff5626fb6c71b242d6b1a43de25c9a85  TEST_DIR/test-139/file2
+ff5626fb6c71b242d6b1a43de25c9a85  TEST_DIR/test-139/file3
+Files 1-2 should not match (intentional)
+Files 1-3 should not match (intentional)
+Compare the CoW'd section to the before file
+Start sections do not match (intentional)
+Middle sections do not match (intentional)
+End sections do not match (intentional)
+Compare the CoW'd section to the after file
+Compare the not CoW'd sections
diff --git a/tests/generic/140 b/tests/generic/140
new file mode 100755
index 0000000..6299d8e
--- /dev/null
+++ b/tests/generic/140
@@ -0,0 +1,152 @@
+#! /bin/bash
+# FS QA Test No. 140
+#
+# Ensuring that mmap copy on write through the page cache works:
+#   - Reflink two files together
+#   - Write to the beginning, middle, and end
+#   - Check that the files are now different where we say they're different.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+
+cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match"
+cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match"
+
+echo "mmap CoW the second file"
+_mwrite_byte 0x62 0 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full"
+_mwrite_byte 0x62 0 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full"
+
+_mwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full"
+_mwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full"
+
+_mwrite_byte 0x62 $((BLKSZ * 48 - 20)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full"
+_mwrite_byte 0x62 $((BLKSZ * 48 - 20)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+
+cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match (intentional)"
+cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match (intentional)"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match"
+
+echo "Compare the CoW'd section to the before file"
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 17 \
+       || echo "Start sections do not match (intentional)"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16 - 34)) \
+		"$TESTDIR/file2" $((BLKSZ * 16 - 34)) 17 \
+       || echo "Middle sections do not match (intentional)"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 48 - 20)) \
+		"$TESTDIR/file2" $((BLKSZ * 48 - 20)) 17 \
+       || echo "End sections do not match (intentional)"
+
+echo "Compare the CoW'd section to the after file"
+_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 17 \
+       || echo "Start sections do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16 - 34)) \
+		"$TESTDIR/file3" $((BLKSZ * 16 - 34)) 17 \
+       || echo "Middle sections do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 48 - 20)) \
+		"$TESTDIR/file3" $((BLKSZ * 48 - 20)) 17 \
+       || echo "End sections do not match"
+
+echo "Compare the not CoW'd sections"
+_compare_range "$TESTDIR/file1" 18 "$TESTDIR/file2" 18 17 \
+       || echo "Start sections of 1-2 do not match"
+
+_compare_range "$TESTDIR/file2" 18 "$TESTDIR/file3" 18 17 \
+       || echo "Start sections of 2-3 do not match"
+
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 16 - 17)) \
+		"$TESTDIR/file2" $((BLKSZ * 16 - 17)) 82 \
+       || echo "Middle sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 16 - 17)) \
+		"$TESTDIR/file3" $((BLKSZ * 16 - 17)) 82 \
+       || echo "Middle sections of 2-3 do not match"
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 48 - 120)) \
+		"$TESTDIR/file2" $((BLKSZ * 48 - 120)) 100 \
+       || echo "End sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 48 - 120)) \
+		"$TESTDIR/file3" $((BLKSZ * 48 - 120)) 100 \
+       || echo "End sections of 2-3 do not match"
+
+
+_compare_range  "$TESTDIR/file1" $((BLKSZ * 14)) \
+		"$TESTDIR/file2" $((BLKSZ * 14)) $BLKSZ \
+       || echo "Untouched sections of 1-2 do not match"
+
+_compare_range  "$TESTDIR/file2" $((BLKSZ * 14)) \
+		"$TESTDIR/file3" $((BLKSZ * 14)) $BLKSZ \
+       || echo "Untouched sections of 2-3 do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/140.out b/tests/generic/140.out
new file mode 100644
index 0000000..51a5b85
--- /dev/null
+++ b/tests/generic/140.out
@@ -0,0 +1,19 @@
+QA output created by 140
+Create the original files
+Compare files
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-140/file1
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-140/file2
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-140/file3
+mmap CoW the second file
+Compare files
+60ebe700450b6015c17fa15cacb9493b  TEST_DIR/test-140/file1
+795ecfd281dbda4916431376228e4187  TEST_DIR/test-140/file2
+795ecfd281dbda4916431376228e4187  TEST_DIR/test-140/file3
+Files 1-2 do not match (intentional)
+Files 1-3 do not match (intentional)
+Compare the CoW'd section to the before file
+Start sections do not match (intentional)
+Middle sections do not match (intentional)
+End sections do not match (intentional)
+Compare the CoW'd section to the after file
+Compare the not CoW'd sections
diff --git a/tests/generic/142 b/tests/generic/142
new file mode 100755
index 0000000..cf6d634
--- /dev/null
+++ b/tests/generic/142
@@ -0,0 +1,91 @@
+#! /bin/bash
+# FS QA Test No. 142
+#
+# Ensure that reflinking a file N times and CoWing the copies leaves the
+# original intact.
+#   - Create a file and record its hash
+#   - Create some reflink copies
+#   - Rewrite all the reflink copies
+#   - Compare the contents of the original file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ=65536
+NR=9
+_pwrite_byte 0x61 0 $((BLKSZ * 256)) "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+csum="$(_md5_checksum "$TESTDIR/file1")"
+
+echo "Create the reflink copies"
+seq 2 $NR | while read i; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+
+echo "Rewrite the copies"
+seq 2 $NR | while read i; do
+	_pwrite_byte 0x62 0 $((BLKSZ * 256)) "$TESTDIR/file$i" >> "$seqres.full"
+done
+_test_remount
+
+echo "Examine original file"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+mod_csum="$(_md5_checksum "$TESTDIR/file2")"
+new_csum="$(_md5_checksum "$TESTDIR/file1")"
+test "${csum}" != "${mod_csum}" || echo "checksums do not match"
+test "${csum}" = "${new_csum}" || echo "checksums do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/142.out b/tests/generic/142.out
new file mode 100644
index 0000000..b55d0f0
--- /dev/null
+++ b/tests/generic/142.out
@@ -0,0 +1,8 @@
+QA output created by 142
+Create the original file blocks
+f4820540fc0ac02750739896fe028d56  TEST_DIR/test-142/file1
+Create the reflink copies
+Rewrite the copies
+Examine original file
+f4820540fc0ac02750739896fe028d56  TEST_DIR/test-142/file1
+eb34153e9ed1e774db28cbbe4090a449  TEST_DIR/test-142/file2
diff --git a/tests/generic/143 b/tests/generic/143
new file mode 100755
index 0000000..d2ccb94
--- /dev/null
+++ b/tests/generic/143
@@ -0,0 +1,91 @@
+#! /bin/bash
+# FS QA Test No. 143
+#
+# Ensure that reflinking a file N times and DIO CoWing the copies leaves the
+# original intact.
+#   - Create a file and record its hash
+#   - Create some reflink copies
+#   - Rewrite all the reflink copies w/ directio
+#   - Compare the contents of the original file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ=65536
+NR=9
+_pwrite_byte 0x61 0 $((BLKSZ * 256)) "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+csum="$(_md5_checksum "$TESTDIR/file1")"
+
+echo "Create the reflink copies"
+seq 2 $NR | while read i; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+
+echo "Rewrite the copies"
+seq 2 $NR | while read i; do
+	_pwrite_byte 0x62 0 $((BLKSZ * 256)) "$TESTDIR/file$i" -d >> "$seqres.full"
+done
+_test_remount
+
+echo "Examine original file"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+
+mod_csum="$(_md5_checksum "$TESTDIR/file2")"
+new_csum="$(_md5_checksum "$TESTDIR/file1")"
+test "${csum}" != "${mod_csum}" || echo "checksums do not match"
+test "${csum}" = "${new_csum}" || echo "checksums do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/143.out b/tests/generic/143.out
new file mode 100644
index 0000000..70a1e71
--- /dev/null
+++ b/tests/generic/143.out
@@ -0,0 +1,8 @@
+QA output created by 143
+Create the original file blocks
+f4820540fc0ac02750739896fe028d56  TEST_DIR/test-143/file1
+Create the reflink copies
+Rewrite the copies
+Examine original file
+f4820540fc0ac02750739896fe028d56  TEST_DIR/test-143/file1
+eb34153e9ed1e774db28cbbe4090a449  TEST_DIR/test-143/file2
diff --git a/tests/generic/group b/tests/generic/group
index 50cc132..7b55707 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -140,7 +140,12 @@
 135 metadata auto quick
 136 auto quick clone
 137 auto quick clone
+138 auto quick clone
+139 auto quick clone
+140 auto quick clone
 141 rw auto quick
+142 auto quick clone
+143 auto quick clone
 169 rw metadata auto quick
 184 metadata auto quick
 192 atime auto

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/12] reflink: test the various fallocate modes
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (4 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 05/12] reflink: test CoW behaviors of reflinked files Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 07/12] reflink: test accuracy of free block counts Darrick J. Wong
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Check that the variants of fallocate (allocate, punch, zero range,
collapse range, insert range) do the right thing when they're run
against a range of reflinked blocks.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/144     |  142 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/144.out |   16 ++++++
 tests/generic/145     |  142 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/145.out |   19 +++++++
 tests/generic/146     |  136 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/146.out |   19 +++++++
 tests/generic/147     |  139 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/147.out |   19 +++++++
 tests/generic/148     |  116 ++++++++++++++++++++++++++++++++++++++++
 tests/generic/148.out |   15 +++++
 tests/generic/149     |  136 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/149.out |   19 +++++++
 tests/generic/group   |    6 ++
 13 files changed, 924 insertions(+)
 create mode 100755 tests/generic/144
 create mode 100644 tests/generic/144.out
 create mode 100755 tests/generic/145
 create mode 100644 tests/generic/145.out
 create mode 100755 tests/generic/146
 create mode 100644 tests/generic/146.out
 create mode 100755 tests/generic/147
 create mode 100644 tests/generic/147.out
 create mode 100755 tests/generic/148
 create mode 100644 tests/generic/148.out
 create mode 100755 tests/generic/149
 create mode 100644 tests/generic/149.out


diff --git a/tests/generic/144 b/tests/generic/144
new file mode 100755
index 0000000..bee0893
--- /dev/null
+++ b/tests/generic/144
@@ -0,0 +1,142 @@
+#! /bin/bash
+# FS QA Test No. 144
+#
+# Ensure that fallocate steps around reflinked ranges:
+#   - Reflink parts of two files together
+#   - Fallocate all the other sparse space.
+#   - Check that the reflinked areas are still there.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "falloc"
+_require_xfs_io_command "truncate"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $((BLKSZ * 5 + 37)) "$TESTDIR/file1" >> "$seqres.full"
+
+_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ \
+		$((BLKSZ * 4 + 37)) >> "$seqres.full"
+
+"$XFS_IO_PROG" -f -c "truncate $((BLKSZ * 5 + 37))" "$TESTDIR/file3" >> "$seqres.full"
+_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $BLKSZ >> "$seqres.full"
+
+"$XFS_IO_PROG" -f -c "truncate $((BLKSZ * 5 + 37))" "$TESTDIR/file4" >> "$seqres.full"
+_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ $BLKSZ >> "$seqres.full"
+_reflink_range "$TESTDIR/file1" $((BLKSZ * 3)) "$TESTDIR/file4" $((BLKSZ * 3)) \
+		$BLKSZ >> "$seqres.full"
+
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file5"
+_test_remount
+
+echo "Compare sections"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file5" | _filter_test_dir
+
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ \
+		$((BLKSZ * 4 + 37)) \
+	|| echo "shared parts of files 1-2 changed"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $BLKSZ \
+	|| echo "shared parts of files 1-3 changed"
+
+_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ $BLKSZ \
+	|| echo "shared parts of files 1-4 changed"
+
+_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file5" 0 $((BLKSZ * 5 + 37)) \
+	|| echo "shared parts of files 1-5 changed"
+
+echo "Compare files"
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+C5="$(_md5_checksum "$TESTDIR/file5")"
+
+test "${C1}" != "${C2}" || echo "file1 and file2 should not match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C1}"  = "${C5}" || echo "file1 and file5 should match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C2}" != "${C5}" || echo "file2 and file5 should not match"
+test "${C3}" != "${C4}" || echo "file3 and file4 should not match"
+test "${C3}" != "${C5}" || echo "file3 and file5 should not match"
+test "${C4}" != "${C5}" || echo "file4 and file5 should not match"
+
+echo "falloc everything"
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file2" >> "$seqres.full"
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file3" >> "$seqres.full"
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file5" | _filter_test_dir
+
+D1="$(_md5_checksum "$TESTDIR/file1")"
+D2="$(_md5_checksum "$TESTDIR/file2")"
+D3="$(_md5_checksum "$TESTDIR/file3")"
+D4="$(_md5_checksum "$TESTDIR/file4")"
+D5="$(_md5_checksum "$TESTDIR/file5")"
+
+test "${C1}" = "${D1}" || echo "file1 should not change"
+test "${C2}" = "${D2}" || echo "file2 should not change"
+test "${C3}" = "${D3}" || echo "file3 should not change"
+test "${C4}" = "${D4}" || echo "file4 should not change"
+test "${C5}" = "${D5}" || echo "file2 should not change"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/144.out b/tests/generic/144.out
new file mode 100644
index 0000000..0bcf4b9
--- /dev/null
+++ b/tests/generic/144.out
@@ -0,0 +1,16 @@
+QA output created by 144
+Create the original files
+Compare sections
+ee8004e6298fa128477bd4aa1adc69fb  TEST_DIR/test-144/file1
+a7cb8cb9697d59413e0d10495d226398  TEST_DIR/test-144/file2
+7d42a0a2865c94f45435a2ce7627da02  TEST_DIR/test-144/file3
+7f528bc76f4d61ff9cff7bc1906579c6  TEST_DIR/test-144/file4
+ee8004e6298fa128477bd4aa1adc69fb  TEST_DIR/test-144/file5
+Compare files
+falloc everything
+Compare files
+ee8004e6298fa128477bd4aa1adc69fb  TEST_DIR/test-144/file1
+a7cb8cb9697d59413e0d10495d226398  TEST_DIR/test-144/file2
+7d42a0a2865c94f45435a2ce7627da02  TEST_DIR/test-144/file3
+7f528bc76f4d61ff9cff7bc1906579c6  TEST_DIR/test-144/file4
+ee8004e6298fa128477bd4aa1adc69fb  TEST_DIR/test-144/file5
diff --git a/tests/generic/145 b/tests/generic/145
new file mode 100755
index 0000000..8a14f82
--- /dev/null
+++ b/tests/generic/145
@@ -0,0 +1,142 @@
+#! /bin/bash
+# FS QA Test No. 145
+#
+# Ensure that collapse range steps around reflinked ranges:
+#   - Create three reflink clones of a file
+#   - Collapse the start, middle, and end of the reflink range of each
+#     of the three files, respectively
+#   - Check that the reflinked areas are still there.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "falloc"
+_require_xfs_io_command "fcollapse"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4"
+
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file1"
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file3"
+"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file4"
+
+_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" = "${C3}" || echo "file1 and file3 should match"
+test "${C1}" = "${C4}" || echo "file1 and file4 should match"
+test "${C2}" = "${C3}" || echo "file2 and file3 should match"
+test "${C2}" = "${C4}" || echo "file2 and file4 should match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "fcollapse files"
+"$XFS_IO_PROG" -f -c "fcollapse 0 $BLKSZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "fcollapse $BLKSZ $BLKSZ" "$TESTDIR/file3"
+"$XFS_IO_PROG" -f -c "fcollapse $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" != "${C2}" || echo "file1 and file2 should not match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" != "${C4}" || echo "file3 and file4 should not match"
+
+echo "Compare against check files"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match"
+cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match"
+cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/145.out b/tests/generic/145.out
new file mode 100644
index 0000000..e36c61d
--- /dev/null
+++ b/tests/generic/145.out
@@ -0,0 +1,19 @@
+QA output created by 145
+Create the original files
+564b34fb4a562f6d864f371248e48540  TEST_DIR/test-145/file1
+564b34fb4a562f6d864f371248e48540  TEST_DIR/test-145/file2
+564b34fb4a562f6d864f371248e48540  TEST_DIR/test-145/file3
+564b34fb4a562f6d864f371248e48540  TEST_DIR/test-145/file4
+9a239246ce4bee20f2de1b0ba41a41e0  TEST_DIR/test-145/file2.chk
+859c251680d8bbf0f859f5c6d7a6a2a2  TEST_DIR/test-145/file3.chk
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-145/file4.chk
+fcollapse files
+Compare files
+564b34fb4a562f6d864f371248e48540  TEST_DIR/test-145/file1
+9a239246ce4bee20f2de1b0ba41a41e0  TEST_DIR/test-145/file2
+859c251680d8bbf0f859f5c6d7a6a2a2  TEST_DIR/test-145/file3
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-145/file4
+9a239246ce4bee20f2de1b0ba41a41e0  TEST_DIR/test-145/file2.chk
+859c251680d8bbf0f859f5c6d7a6a2a2  TEST_DIR/test-145/file3.chk
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-145/file4.chk
+Compare against check files
diff --git a/tests/generic/146 b/tests/generic/146
new file mode 100755
index 0000000..9e3eff6
--- /dev/null
+++ b/tests/generic/146
@@ -0,0 +1,136 @@
+#! /bin/bash
+# FS QA Test No. 146
+#
+# Ensure that punch-hole steps around reflinked ranges:
+#   - Create three reflink clones of a file
+#   - Punch the start, middle, and end of the reflink range of each
+#     of the three files, respectively
+#   - Check that the reflinked areas are still there.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "fpunch"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4"
+
+_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" = "${C3}" || echo "file1 and file3 should match"
+test "${C1}" = "${C4}" || echo "file1 and file4 should match"
+test "${C2}" = "${C3}" || echo "file2 and file3 should match"
+test "${C2}" = "${C4}" || echo "file2 and file4 should match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "fpunch files"
+"$XFS_IO_PROG" -f -c "fpunch 0 $BLKSZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "fpunch $BLKSZ $BLKSZ" "$TESTDIR/file3"
+"$XFS_IO_PROG" -f -c "fpunch $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" != "${C2}" || echo "file1 and file2 should not match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" != "${C4}" || echo "file3 and file4 should not match"
+
+echo "Compare against check files"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match"
+cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match"
+cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/146.out b/tests/generic/146.out
new file mode 100644
index 0000000..ead7e90
--- /dev/null
+++ b/tests/generic/146.out
@@ -0,0 +1,19 @@
+QA output created by 146
+Create the original files
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-146/file1
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-146/file2
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-146/file3
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-146/file4
+e263fae701bc40c23a3edb20aad5573e  TEST_DIR/test-146/file2.chk
+91722d7c8baf83f300a8dc35f1ffcce2  TEST_DIR/test-146/file3.chk
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-146/file4.chk
+fpunch files
+Compare files
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-146/file1
+e263fae701bc40c23a3edb20aad5573e  TEST_DIR/test-146/file2
+91722d7c8baf83f300a8dc35f1ffcce2  TEST_DIR/test-146/file3
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-146/file4
+e263fae701bc40c23a3edb20aad5573e  TEST_DIR/test-146/file2.chk
+91722d7c8baf83f300a8dc35f1ffcce2  TEST_DIR/test-146/file3.chk
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-146/file4.chk
+Compare against check files
diff --git a/tests/generic/147 b/tests/generic/147
new file mode 100755
index 0000000..c35bdd9
--- /dev/null
+++ b/tests/generic/147
@@ -0,0 +1,139 @@
+#! /bin/bash
+# FS QA Test No. 812
+#
+# Ensure that insert range steps around reflinked ranges:
+#   - Create three reflink clones of a file
+#   - Insert into the start, middle, and end of the reflink range of each
+#     of the three files, respectively
+#   - Check that the reflinked areas are still there.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "finsert"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4"
+
+_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x61 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" = "${C3}" || echo "file1 and file3 should match"
+test "${C1}" = "${C4}" || echo "file1 and file4 should match"
+test "${C2}" = "${C3}" || echo "file2 and file3 should match"
+test "${C2}" = "${C4}" || echo "file2 and file4 should match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "finsert files"
+"$XFS_IO_PROG" -f -c "finsert 0 $BLKSZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "finsert $BLKSZ $BLKSZ" "$TESTDIR/file3"
+"$XFS_IO_PROG" -f -c "finsert $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" != "${C2}" || echo "file1 and file2 should not match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" != "${C4}" || echo "file3 and file4 should not match"
+
+echo "Compare against check files"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match"
+cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match"
+cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/147.out b/tests/generic/147.out
new file mode 100644
index 0000000..bee79c2
--- /dev/null
+++ b/tests/generic/147.out
@@ -0,0 +1,19 @@
+QA output created by 147
+Create the original files
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-147/file1
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-147/file2
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-147/file3
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-147/file4
+2b0921503c9f661b7690ac5b42f01f97  TEST_DIR/test-147/file2.chk
+c424badbaad621c331a8ef213b78ac2a  TEST_DIR/test-147/file3.chk
+33b4940294a1d94bee813907d6105ff7  TEST_DIR/test-147/file4.chk
+finsert files
+Compare files
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-147/file1
+2b0921503c9f661b7690ac5b42f01f97  TEST_DIR/test-147/file2
+c424badbaad621c331a8ef213b78ac2a  TEST_DIR/test-147/file3
+33b4940294a1d94bee813907d6105ff7  TEST_DIR/test-147/file4
+2b0921503c9f661b7690ac5b42f01f97  TEST_DIR/test-147/file2.chk
+c424badbaad621c331a8ef213b78ac2a  TEST_DIR/test-147/file3.chk
+33b4940294a1d94bee813907d6105ff7  TEST_DIR/test-147/file4.chk
+Compare against check files
diff --git a/tests/generic/148 b/tests/generic/148
new file mode 100755
index 0000000..3d7a762
--- /dev/null
+++ b/tests/generic/148
@@ -0,0 +1,116 @@
+#! /bin/bash
+# FS QA Test No. 148
+#
+# Ensure that truncating the last block in a reflinked file CoWs appropriately:
+#   - Create a file that doesn't end on a block boundary
+#   - Create two reflink clones of the file
+#   - Shorten one of the clones with truncate
+#   - Lengthen the other clone with truncate
+#   - Check that the reflinked areas are still there.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "truncate"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ 37 "$TESTDIR/file1" >> "$seqres.full"
+
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ 34 "$TESTDIR/file2.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ 37 "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ + 37)) 3 "$TESTDIR/file3.chk" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" = "${C3}" || echo "file1 and file3 should match"
+test "${C2}" = "${C3}" || echo "file2 and file3 should match"
+
+echo "truncate files"
+"$XFS_IO_PROG" -f -c "truncate $((BLKSZ + 34))" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "truncate $((BLKSZ + 40))" "$TESTDIR/file3"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+
+test "${C1}" != "${C2}" || echo "file1 and file2 should not match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+
+echo "Compare against check files"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match"
+cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/148.out b/tests/generic/148.out
new file mode 100644
index 0000000..1896d95
--- /dev/null
+++ b/tests/generic/148.out
@@ -0,0 +1,15 @@
+QA output created by 148
+Create the original files
+f924bdda449af63913cad4357e39301e  TEST_DIR/test-148/file1
+f924bdda449af63913cad4357e39301e  TEST_DIR/test-148/file2
+f924bdda449af63913cad4357e39301e  TEST_DIR/test-148/file3
+16cb529abe447a9f203a3d5eb3433c8b  TEST_DIR/test-148/file2.chk
+6f042ad39f6c74f4b73936db89baa2e2  TEST_DIR/test-148/file3.chk
+truncate files
+Compare files
+f924bdda449af63913cad4357e39301e  TEST_DIR/test-148/file1
+16cb529abe447a9f203a3d5eb3433c8b  TEST_DIR/test-148/file2
+6f042ad39f6c74f4b73936db89baa2e2  TEST_DIR/test-148/file3
+16cb529abe447a9f203a3d5eb3433c8b  TEST_DIR/test-148/file2.chk
+6f042ad39f6c74f4b73936db89baa2e2  TEST_DIR/test-148/file3.chk
+Compare against check files
diff --git a/tests/generic/149 b/tests/generic/149
new file mode 100755
index 0000000..44b5ae4
--- /dev/null
+++ b/tests/generic/149
@@ -0,0 +1,136 @@
+#! /bin/bash
+# FS QA Test No. 813
+#
+# Ensure that zero-range steps around reflinked ranges:
+#   - Create three reflink clones of a file
+#   - Zero-range the start, middle, and end of the reflink range of each
+#     of the three files, respectively
+#   - Check that the reflinked areas are still there.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "fzero"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original files"
+BLKSZ=65536
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4"
+
+_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full"
+
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full"
+_test_remount
+
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" = "${C2}" || echo "file1 and file2 should match"
+test "${C1}" = "${C3}" || echo "file1 and file3 should match"
+test "${C1}" = "${C4}" || echo "file1 and file4 should match"
+test "${C2}" = "${C3}" || echo "file2 and file3 should match"
+test "${C2}" = "${C4}" || echo "file2 and file4 should match"
+test "${C3}" = "${C4}" || echo "file3 and file4 should match"
+
+echo "fzero files"
+"$XFS_IO_PROG" -f -c "fzero 0 $BLKSZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "fzero $BLKSZ $BLKSZ" "$TESTDIR/file3"
+"$XFS_IO_PROG" -f -c "fzero $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4"
+_test_remount
+
+echo "Compare files"
+md5sum "$TESTDIR/file1" | _filter_test_dir
+md5sum "$TESTDIR/file2" | _filter_test_dir
+md5sum "$TESTDIR/file3" | _filter_test_dir
+md5sum "$TESTDIR/file4" | _filter_test_dir
+md5sum "$TESTDIR/file2.chk" | _filter_test_dir
+md5sum "$TESTDIR/file3.chk" | _filter_test_dir
+md5sum "$TESTDIR/file4.chk" | _filter_test_dir
+
+C1="$(_md5_checksum "$TESTDIR/file1")"
+C2="$(_md5_checksum "$TESTDIR/file2")"
+C3="$(_md5_checksum "$TESTDIR/file3")"
+C4="$(_md5_checksum "$TESTDIR/file4")"
+
+test "${C1}" != "${C2}" || echo "file1 and file2 should not match"
+test "${C1}" != "${C3}" || echo "file1 and file3 should not match"
+test "${C1}" != "${C4}" || echo "file1 and file4 should not match"
+test "${C2}" != "${C3}" || echo "file2 and file3 should not match"
+test "${C2}" != "${C4}" || echo "file2 and file4 should not match"
+test "${C3}" != "${C4}" || echo "file3 and file4 should not match"
+
+echo "Compare against check files"
+cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match"
+cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match"
+cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/149.out b/tests/generic/149.out
new file mode 100644
index 0000000..dc3ceda
--- /dev/null
+++ b/tests/generic/149.out
@@ -0,0 +1,19 @@
+QA output created by 149
+Create the original files
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-149/file1
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-149/file2
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-149/file3
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-149/file4
+e263fae701bc40c23a3edb20aad5573e  TEST_DIR/test-149/file2.chk
+91722d7c8baf83f300a8dc35f1ffcce2  TEST_DIR/test-149/file3.chk
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-149/file4.chk
+fzero files
+Compare files
+856bb58abaf1ac79aa1aa45b7de7218b  TEST_DIR/test-149/file1
+e263fae701bc40c23a3edb20aad5573e  TEST_DIR/test-149/file2
+91722d7c8baf83f300a8dc35f1ffcce2  TEST_DIR/test-149/file3
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-149/file4
+e263fae701bc40c23a3edb20aad5573e  TEST_DIR/test-149/file2.chk
+91722d7c8baf83f300a8dc35f1ffcce2  TEST_DIR/test-149/file3.chk
+c931e8500c1a56a5b7369f7f1b971690  TEST_DIR/test-149/file4.chk
+Compare against check files
diff --git a/tests/generic/group b/tests/generic/group
index 7b55707..477c52b 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -146,6 +146,12 @@
 141 rw auto quick
 142 auto quick clone
 143 auto quick clone
+144 auto quick clone
+145 auto quick clone
+146 auto quick clone
+147 auto quick clone
+148 auto quick clone
+149 auto quick clone
 169 rw metadata auto quick
 184 metadata auto quick
 192 atime auto

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/12] reflink: test accuracy of free block counts
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (5 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 06/12] reflink: test the various fallocate modes Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 08/12] reflink: test error conditions due to bad inputs Darrick J. Wong
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Check that the free block counts seem to be handled correctly in
the reflink operation and subsequent attempts to rewrite reflinked
copies.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/150     |   78 +++++++++++++++++++++++++++++++
 tests/generic/150.out |    4 ++
 tests/generic/151     |   98 +++++++++++++++++++++++++++++++++++++++
 tests/generic/151.out |    8 +++
 tests/generic/152     |  103 +++++++++++++++++++++++++++++++++++++++++
 tests/generic/152.out |    8 +++
 tests/generic/153     |  102 ++++++++++++++++++++++++++++++++++++++++
 tests/generic/153.out |    8 +++
 tests/generic/154     |  110 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/154.out |   11 ++++
 tests/generic/155     |  114 +++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/155.out |   11 ++++
 tests/generic/156     |  124 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/156.out |   12 +++++
 tests/generic/group   |    7 +++
 15 files changed, 798 insertions(+)
 create mode 100755 tests/generic/150
 create mode 100644 tests/generic/150.out
 create mode 100755 tests/generic/151
 create mode 100644 tests/generic/151.out
 create mode 100755 tests/generic/152
 create mode 100644 tests/generic/152.out
 create mode 100755 tests/generic/153
 create mode 100644 tests/generic/153.out
 create mode 100755 tests/generic/154
 create mode 100644 tests/generic/154.out
 create mode 100755 tests/generic/155
 create mode 100644 tests/generic/155.out
 create mode 100755 tests/generic/156
 create mode 100644 tests/generic/156.out


diff --git a/tests/generic/150 b/tests/generic/150
new file mode 100755
index 0000000..3046e92
--- /dev/null
+++ b/tests/generic/150
@@ -0,0 +1,78 @@
+#! /bin/bash
+# FS QA Test No. 150
+#
+# Ensure that reflinking a file N times doesn't eat a lot of blocks
+#   - Create a file and record fs block usage
+#   - Create some reflink copies
+#   - Compare fs block usage to before
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f $TESTDIR -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+NR=7
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+sync
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file.$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $FREE_BLOCKS0 $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/150.out b/tests/generic/150.out
new file mode 100644
index 0000000..94580a6
--- /dev/null
+++ b/tests/generic/150.out
@@ -0,0 +1,4 @@
+QA output created by 150
+Create the original file blocks
+Create the reflink copies
+free blocks after reflink is in range
diff --git a/tests/generic/151 b/tests/generic/151
new file mode 100755
index 0000000..c42ca1d
--- /dev/null
+++ b/tests/generic/151
@@ -0,0 +1,98 @@
+#! /bin/bash
+# FS QA Test No. 151
+#
+# Ensure that deleting all copies of a file reflinked N times releases the blocks
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - Delete some copies of the file
+#   - Record fs block usage (2)
+#   - Delete all copies of the file
+#   - Compare fs block usage to (2), (1), and (0)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=7
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+sync
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file.$i"
+done
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/survivor"
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Delete most of the files"
+rm -rf "$TESTDIR"/file*
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Delete all the files"
+rm -rf "$TESTDIR"/*
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3
+
+_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after deleting some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v
+
+_within_tolerance "free blocks after deleting all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/151.out b/tests/generic/151.out
new file mode 100644
index 0000000..214be54
--- /dev/null
+++ b/tests/generic/151.out
@@ -0,0 +1,8 @@
+QA output created by 151
+Create the original file blocks
+Create the reflink copies
+Delete most of the files
+Delete all the files
+free blocks after reflink is in range
+free blocks after deleting some reflink copies is in range
+free blocks after deleting all copies is in range
diff --git a/tests/generic/152 b/tests/generic/152
new file mode 100755
index 0000000..95ffe40
--- /dev/null
+++ b/tests/generic/152
@@ -0,0 +1,103 @@
+#! /bin/bash
+# FS QA Test No. 152
+#
+# Ensure that punching all copies of a file reflinked N times releases the blocks
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - Punch some blocks of the copies
+#   - Record fs block usage (2)
+#   - Punch all blocks of the copies
+#   - Compare fs block usage to (2), (1), and (0)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "fpunch"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+sync
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Punch most of the blocks"
+"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "fpunch 0 $((SZ / 2))" "$TESTDIR/file3"
+"$XFS_IO_PROG" -f -c "fpunch $((SZ / 2)) $((SZ / 2))" "$TESTDIR/file4"
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Punch all the files"
+for i in `seq 2 $NR`; do
+	"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file$i"
+done
+"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file1"
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3
+
+_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after punching some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v
+
+_within_tolerance "free blocks after punching all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/152.out b/tests/generic/152.out
new file mode 100644
index 0000000..10b2003
--- /dev/null
+++ b/tests/generic/152.out
@@ -0,0 +1,8 @@
+QA output created by 152
+Create the original file blocks
+Create the reflink copies
+Punch most of the blocks
+Punch all the files
+free blocks after reflink is in range
+free blocks after punching some reflink copies is in range
+free blocks after punching all copies is in range
diff --git a/tests/generic/153 b/tests/generic/153
new file mode 100755
index 0000000..2deee20
--- /dev/null
+++ b/tests/generic/153
@@ -0,0 +1,102 @@
+#! /bin/bash
+# FS QA Test No. 153
+#
+# Ensure that collapse-range on all copies of a file reflinked N times releases the blocks
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - Collapse-range some blocks of the copies
+#   - Record fs block usage (2)
+#   - Truncate all blocks of the copies
+#   - Compare fs block usage to (2), (1), and (0)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "fcollapse"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Collapse most of the blocks"
+"$XFS_IO_PROG" -f -c "fcollapse 0 $(((BLKS - 1) * BLKSZ))" $TESTDIR/file2
+"$XFS_IO_PROG" -f -c "fcollapse 0 $((SZ / 2))" $TESTDIR/file3
+"$XFS_IO_PROG" -f -c "fcollapse $((SZ / 2)) $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file4
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Collpase nearly all the files"
+"$XFS_IO_PROG" -f -c "fcollapse 0 $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file3
+"$XFS_IO_PROG" -f -c "fcollapse 0 $((SZ / 2))" $TESTDIR/file4
+"$XFS_IO_PROG" -f -c "fcollapse 0 $(( (BLKS - 1) * BLKSZ))" $TESTDIR/file1
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3
+
+_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after fcollapsing some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v
+
+_within_tolerance "free blocks after fcollapsing all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/153.out b/tests/generic/153.out
new file mode 100644
index 0000000..c9ff37c
--- /dev/null
+++ b/tests/generic/153.out
@@ -0,0 +1,8 @@
+QA output created by 153
+Create the original file blocks
+Create the reflink copies
+Collapse most of the blocks
+Collpase nearly all the files
+free blocks after reflink is in range
+free blocks after fcollapsing some reflink copies is in range
+free blocks after fcollapsing all copies is in range
diff --git a/tests/generic/154 b/tests/generic/154
new file mode 100755
index 0000000..173b981
--- /dev/null
+++ b/tests/generic/154
@@ -0,0 +1,110 @@
+#! /bin/bash
+# FS QA Test No. 154
+#
+# Ensure that CoW on all copies of a file reflinked N times increases block count
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - CoW some blocks of the copies
+#   - Record fs block usage (2)
+#   - CoW all the rest of the blocks of the copies
+#   - Compare fs block usage to (2), (1), and (0)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=4
+SZ=$((BLKS * BLKSZ))
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite some of the blocks"
+_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x63 0 $((SZ / 2)) "$TESTDIR/file3" >> "$seqres.full"
+_pwrite_byte 0x64 $((SZ / 2)) $((SZ / 2)) "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite all the files"
+_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x63 0 $SZ "$TESTDIR/file3" >> "$seqres.full"
+_pwrite_byte 0x64 0 $SZ "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite the original file"
+_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f')
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4
+
+_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v
+
+_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v
+
+_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/154.out b/tests/generic/154.out
new file mode 100644
index 0000000..726b819
--- /dev/null
+++ b/tests/generic/154.out
@@ -0,0 +1,11 @@
+QA output created by 154
+Create the original file blocks
+Create the reflink copies
+Rewrite some of the blocks
+Rewrite all the files
+Rewrite the original file
+free blocks after reflinking is in range
+free blocks after partially CoWing some copies is in range
+free blocks after CoWing all copies is in range
+free blocks after overwriting original is in range
+free blocks after all tests is in range
diff --git a/tests/generic/155 b/tests/generic/155
new file mode 100755
index 0000000..2551295
--- /dev/null
+++ b/tests/generic/155
@@ -0,0 +1,114 @@
+#! /bin/bash
+# FS QA Test No. 155
+#
+# Ensure that CoW on all copies of a file reflinked N times increases block count
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - CoW some blocks of the copies
+#   - Record fs block usage (2)
+#   - CoW all the rest of the blocks of the copies
+#   - Compare fs block usage to (2), (1), and (0)
+#
+# The main difference from 834 is that we use zero range, directio, and
+# mmap to mix things up a bit.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "fzero"
+
+rm -f "$seqres.full"
+
+TESTDIR=$TEST_DIR/test-$seq
+rm -rf $TESTDIR
+mkdir $TESTDIR
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite some of the blocks"
+"$XFS_IO_PROG" -f -c "fzero 0 $SZ" "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x63 0 $((SZ / 2)) "$TESTDIR/file3" -d >> "$seqres.full"
+_mwrite_byte 0x64 $((SZ / 2)) $((SZ / 2)) $SZ "$TESTDIR/file4" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite all the files"
+_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" -d >> "$seqres.full"
+_mwrite_byte 0x63 0 $SZ $SZ "$TESTDIR/file3" >> "$seqres.full"
+"$XFS_IO_PROG" -f -c "fzero 0 $SZ" $TESTDIR/file4 >> "$seqres.full"
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite the original file"
+_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f')
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4
+
+_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v
+
+_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v
+
+_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/155.out b/tests/generic/155.out
new file mode 100644
index 0000000..efb8faf
--- /dev/null
+++ b/tests/generic/155.out
@@ -0,0 +1,11 @@
+QA output created by 155
+Create the original file blocks
+Create the reflink copies
+Rewrite some of the blocks
+Rewrite all the files
+Rewrite the original file
+free blocks after reflinking is in range
+free blocks after partially CoWing some copies is in range
+free blocks after CoWing all copies is in range
+free blocks after overwriting original is in range
+free blocks after all tests is in range
diff --git a/tests/generic/156 b/tests/generic/156
new file mode 100755
index 0000000..78b7e8c
--- /dev/null
+++ b/tests/generic/156
@@ -0,0 +1,124 @@
+#! /bin/bash
+# FS QA Test No. 156
+#
+# Ensure that fallocate on reflinked files actually CoWs the shared blocks.
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - funshare half of one of the copies
+#   - Record fs block usage (2)
+#   - funshare all of the copies
+#   - Record fs block usage (3)
+#   - rewrite the original file
+#   - Record fs block usage (4)
+#   - Compare fs block usage of 0-4 to ensure that block usage behaves as
+#     we expect.
+#
+# "funshare" refers to fallocate copy-on-writing the shared blocks
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+if [ $FSTYP = "btrfs" ]; then
+	_notrun "btrfs doesn't handle unshare on fallocate"
+fi
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_cp_reflink
+_require_xfs_io_command "falloc"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+echo "funshare part of a file"
+"$XFS_IO_PROG" -f -c "falloc 0 $((SZ / 2))" "$TESTDIR/file2"
+_test_remount
+
+echo "funshare some of the copies"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file3"
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+echo "funshare the rest of the files"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file4"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file1"
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Rewrite the original file"
+_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f')
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4
+
+_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after nocow'ing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v
+
+_within_tolerance "free blocks after nocow'ing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v
+
+_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/156.out b/tests/generic/156.out
new file mode 100644
index 0000000..d6fdc81
--- /dev/null
+++ b/tests/generic/156.out
@@ -0,0 +1,12 @@
+QA output created by 156
+Create the original file blocks
+Create the reflink copies
+funshare part of a file
+funshare some of the copies
+funshare the rest of the files
+Rewrite the original file
+free blocks after reflinking is in range
+free blocks after nocow'ing some copies is in range
+free blocks after nocow'ing all copies is in range
+free blocks after overwriting original is in range
+free blocks after all tests is in range
diff --git a/tests/generic/group b/tests/generic/group
index 477c52b..3141ae5 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -152,6 +152,13 @@
 147 auto quick clone
 148 auto quick clone
 149 auto quick clone
+150 auto quick clone
+151 auto quick clone
+152 auto quick clone
+153 auto quick clone
+154 auto quick clone
+155 auto quick clone
+156 auto quick clone
 169 rw metadata auto quick
 184 metadata auto quick
 192 atime auto

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/12] reflink: test error conditions due to bad inputs
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (6 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 07/12] reflink: test accuracy of free block counts Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 09/12] xfs: test xfs-specific reflink pieces Darrick J. Wong
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Check that we can feed bad inputs to reflink/dedupe and it'll reject
them.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/157     |  122 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/157.out |   25 ++++++++++
 tests/generic/158     |  123 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/158.out |   24 ++++++++++
 tests/generic/159     |   74 +++++++++++++++++++++++++++++
 tests/generic/159.out |    5 ++
 tests/generic/160     |   74 +++++++++++++++++++++++++++++
 tests/generic/160.out |    5 ++
 tests/generic/group   |    4 ++
 9 files changed, 456 insertions(+)
 create mode 100755 tests/generic/157
 create mode 100644 tests/generic/157.out
 create mode 100755 tests/generic/158
 create mode 100644 tests/generic/158.out
 create mode 100755 tests/generic/159
 create mode 100755 tests/generic/159.out
 create mode 100755 tests/generic/160
 create mode 100755 tests/generic/160.out


diff --git a/tests/generic/157 b/tests/generic/157
new file mode 100755
index 0000000..a43fb0d
--- /dev/null
+++ b/tests/generic/157
@@ -0,0 +1,122 @@
+#! /bin/bash
+# FS QA Test No. 157
+#
+# Check that various invalid reflink scenarios are rejected.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_scratch_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR1="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR1"
+mkdir "$TESTDIR1"
+
+TESTDIR2=$SCRATCH_MNT/test-$seq
+rm -rf "$TESTDIR2"
+mkdir "$TESTDIR2"
+
+echo "Create the original files"
+BLKSZ="$(stat -f $TESTDIR1 -c '%S')"
+BLKS=1000
+MARGIN=50
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file2" >> "$seqres.full"
+mkdir "$TESTDIR1/dir1"
+seq 1 $((2 * BLKSZ / 250)) | while read f; do
+	touch "$TESTDIR1/dir1/$f"
+done
+mknod "$TESTDIR1/dev1" b 8 0
+mkfifo "$TESTDIR1/fifo1"
+sync
+
+echo "Try cross-device reflink"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ
+
+echo "Try unaligned reflink"
+_reflink_range "$TESTDIR1/file1" 37 "$TESTDIR1/file1" 59 23
+
+echo "Try overlapping reflink"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file1" 1 $((BLKSZ * 2))
+
+echo "Try reflink past EOF"
+_reflink_range "$TESTDIR1/file1" $(( (BLKS + 10) * BLKSZ)) "$TESTDIR1/file1" 0 $BLKSZ
+
+echo "Try to reflink a dir"
+_reflink_range "$TESTDIR1/dir1" 0 "$TESTDIR1/file2" 0 $BLKSZ
+
+echo "Try to reflink a device"
+_reflink_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ
+
+echo "Try to reflink to a dir"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ
+
+echo "Try to reflink to a device"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ
+
+echo "Try to reflink to a fifo"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/fifo1" 0 $BLKSZ -n
+
+echo "Try to reflink an append-only file"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file3" 0 $BLKSZ -a
+
+echo "Reflink two files"
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ >> "$seqres.full"
+_reflink_range "$TESTDIR2/file1" 0 "$TESTDIR2/file2" 0 $BLKSZ >> "$seqres.full"
+
+echo "Check scratch fs"
+umount $SCRATCH_MNT
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/157.out b/tests/generic/157.out
new file mode 100644
index 0000000..177e7f8
--- /dev/null
+++ b/tests/generic/157.out
@@ -0,0 +1,25 @@
+QA output created by 157
+Format and mount
+Create the original files
+Try cross-device reflink
+XFS_IOC_CLONE_RANGE: Invalid cross-device link
+Try unaligned reflink
+XFS_IOC_CLONE_RANGE: Invalid argument
+Try overlapping reflink
+XFS_IOC_CLONE_RANGE: Invalid argument
+Try reflink past EOF
+XFS_IOC_CLONE_RANGE: Invalid argument
+Try to reflink a dir
+XFS_IOC_CLONE_RANGE: Is a directory
+Try to reflink a device
+XFS_IOC_CLONE_RANGE: Invalid argument
+Try to reflink to a dir
+/mnt/test-157/dir1: Is a directory
+Try to reflink to a device
+XFS_IOC_CLONE_RANGE: Operation not supported
+Try to reflink to a fifo
+XFS_IOC_CLONE_RANGE: Operation not supported
+Try to reflink an append-only file
+XFS_IOC_CLONE_RANGE: Bad file descriptor
+Reflink two files
+Check scratch fs
diff --git a/tests/generic/158 b/tests/generic/158
new file mode 100755
index 0000000..a499b21
--- /dev/null
+++ b/tests/generic/158
@@ -0,0 +1,123 @@
+#! /bin/bash
+# FS QA Test No. 158
+#
+# Check that various invalid dedupe scenarios are rejected.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_dedupe
+_require_scratch_dedupe
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR1="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR1"
+mkdir "$TESTDIR1"
+
+TESTDIR2=$SCRATCH_MNT/test-$seq
+rm -rf "$TESTDIR2"
+mkdir "$TESTDIR2"
+
+echo "Create the original files"
+BLKSZ="$(stat -f $TESTDIR1 -c '%S')"
+BLKS=1000
+MARGIN=50
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file3" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file2" >> "$seqres.full"
+mkdir "$TESTDIR1/dir1"
+seq 1 $((2 * BLKSZ / 250)) | while read f; do
+	touch "$TESTDIR1/dir1/$f"
+done
+mknod "$TESTDIR1/dev1" b 8 0
+mkfifo "$TESTDIR1/fifo1"
+sync
+
+echo "Try cross-device dedupe"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ
+
+echo "Try unaligned dedupe"
+_dedupe_range "$TESTDIR1/file1" 37 "$TESTDIR1/file1" 59 23
+
+echo "Try overlapping dedupe"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file1" 1 $((BLKSZ * 2))
+
+echo "Try dedupe past EOF"
+_dedupe_range "$TESTDIR1/file1" $(( (BLKS + 10) * BLKSZ)) "$TESTDIR1/file1" 0 $BLKSZ
+
+echo "Try to dedupe a dir"
+_dedupe_range "$TESTDIR1/dir1" 0 "$TESTDIR1/file2" 0 $BLKSZ
+
+echo "Try to dedupe a device"
+_dedupe_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ
+
+echo "Try to dedupe to a dir"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ
+
+echo "Try to dedupe to a device"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ
+
+echo "Try to dedupe to a fifo"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/fifo1" 0 $BLKSZ -n
+
+echo "Try to dedupe an append-only file"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file3" 0 $BLKSZ -a >> "$seqres.full"
+
+echo "Dedupe two files"
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ >> "$seqres.full"
+_dedupe_range "$TESTDIR2/file1" 0 "$TESTDIR2/file2" 0 $BLKSZ >> "$seqres.full"
+
+echo "Check scratch fs"
+umount $SCRATCH_MNT
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/158.out b/tests/generic/158.out
new file mode 100644
index 0000000..36a3f1f
--- /dev/null
+++ b/tests/generic/158.out
@@ -0,0 +1,24 @@
+QA output created by 158
+Format and mount
+Create the original files
+Try cross-device dedupe
+dedupe: Invalid cross-device link
+Try unaligned dedupe
+dedupe: Invalid argument
+Try overlapping dedupe
+dedupe: Invalid argument
+Try dedupe past EOF
+dedupe: Invalid argument
+Try to dedupe a dir
+XFS_IOC_FILE_EXTENT_SAME: Is a directory
+Try to dedupe a device
+XFS_IOC_FILE_EXTENT_SAME: Permission denied
+Try to dedupe to a dir
+/mnt/test-158/dir1: Is a directory
+Try to dedupe to a device
+dedupe: Permission denied
+Try to dedupe to a fifo
+dedupe: Permission denied
+Try to dedupe an append-only file
+Dedupe two files
+Check scratch fs
diff --git a/tests/generic/159 b/tests/generic/159
new file mode 100755
index 0000000..7944267
--- /dev/null
+++ b/tests/generic/159
@@ -0,0 +1,74 @@
+#! /bin/bash
+# FS QA Test No. 159
+#
+# Check that we can't reflink immutable files
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+ #   rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_lsattr
+_require_test_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+TESTDIR1="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR1"
+mkdir "$TESTDIR1"
+
+echo "Create the original files"
+BLKSZ="$(stat -f $TESTDIR1 -c '%S')"
+BLKS=1000
+MARGIN=50
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full"
+sync
+
+echo "Try reflink on immutable files"
+$CHATTR_PROG +i $TESTDIR1/file1 $TESTDIR1/file2
+_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_test_dir
+$CHATTR_PROG -i $TESTDIR1/file1 $TESTDIR1/file2
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/159.out b/tests/generic/159.out
new file mode 100755
index 0000000..92fe33a
--- /dev/null
+++ b/tests/generic/159.out
@@ -0,0 +1,5 @@
+QA output created by 159
+Format and mount
+Create the original files
+Try reflink on immutable files
+TEST_DIR/test-159/file2: Permission denied
diff --git a/tests/generic/160 b/tests/generic/160
new file mode 100755
index 0000000..e8c43df
--- /dev/null
+++ b/tests/generic/160
@@ -0,0 +1,74 @@
+#! /bin/bash
+# FS QA Test No. 160
+#
+# Check that we can't dedupe immutable files
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+ #   rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_lsattr
+_require_test_dedupe
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+TESTDIR1="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR1"
+mkdir "$TESTDIR1"
+
+echo "Create the original files"
+BLKSZ="$(stat -f $TESTDIR1 -c '%S')"
+BLKS=1000
+MARGIN=50
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full"
+sync
+
+echo "Try dedupe on immutable files"
+$CHATTR_PROG +i $TESTDIR1/file1 $TESTDIR1/file2
+_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_test_dir
+$CHATTR_PROG -i $TESTDIR1/file1 $TESTDIR1/file2
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/160.out b/tests/generic/160.out
new file mode 100755
index 0000000..a999a9c
--- /dev/null
+++ b/tests/generic/160.out
@@ -0,0 +1,5 @@
+QA output created by 160
+Format and mount
+Create the original files
+Try dedupe on immutable files
+TEST_DIR/test-160/file2: Permission denied
diff --git a/tests/generic/group b/tests/generic/group
index 3141ae5..0a20421 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -159,6 +159,10 @@
 154 auto quick clone
 155 auto quick clone
 156 auto quick clone
+157 auto quick clone
+158 auto quick clone
+159 auto quick clone
+160 auto quick clone
 169 rw metadata auto quick
 184 metadata auto quick
 192 atime auto

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/12] xfs: test xfs-specific reflink pieces
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (7 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 08/12] reflink: test error conditions due to bad inputs Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 10/12] reflink: concurrent operations tests Darrick J. Wong
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Check that the various XFS tools still work properly on reflinked XFSes.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/xfs/127     |   79 ++++++++++++++++++++++++++++
 tests/xfs/127.out |    6 ++
 tests/xfs/128     |  149 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/128.out |   27 ++++++++++
 tests/xfs/129     |   87 +++++++++++++++++++++++++++++++
 tests/xfs/129.out |    6 ++
 tests/xfs/130     |  109 +++++++++++++++++++++++++++++++++++++++
 tests/xfs/130.out |   13 +++++
 tests/xfs/131     |   76 +++++++++++++++++++++++++++
 tests/xfs/131.out |    6 ++
 tests/xfs/132     |  130 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/132.out |   32 +++++++++++
 tests/xfs/group   |    6 ++
 13 files changed, 726 insertions(+)
 create mode 100755 tests/xfs/127
 create mode 100644 tests/xfs/127.out
 create mode 100755 tests/xfs/128
 create mode 100644 tests/xfs/128.out
 create mode 100755 tests/xfs/129
 create mode 100644 tests/xfs/129.out
 create mode 100755 tests/xfs/130
 create mode 100644 tests/xfs/130.out
 create mode 100755 tests/xfs/131
 create mode 100644 tests/xfs/131.out
 create mode 100755 tests/xfs/132
 create mode 100644 tests/xfs/132.out


diff --git a/tests/xfs/127 b/tests/xfs/127
new file mode 100755
index 0000000..61301de
--- /dev/null
+++ b/tests/xfs/127
@@ -0,0 +1,79 @@
+#! /bin/bash
+# FS QA Test No. 127
+#
+# Tests xfs_growfs on a reflinked filesystem
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+#
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -f "$tmp".*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_supported_fs xfs
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs -d size=$((2 * 4096 * 4096)) -l size=4194304 > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file and reflink to copy1, copy2"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+_pwrite_byte 0x61 0 $((BLKSZ * 14 + 71)) "$TESTDIR/original" >> "$seqres.full"
+_cp_reflink "$TESTDIR/original" "$TESTDIR/copy1"
+_cp_reflink "$TESTDIR/copy1" "$TESTDIR/copy2"
+
+echo "Grow fs"
+"$XFS_GROWFS_PROG" "$SCRATCH_MNT" 2>&1 |  _filter_growfs >> "$seqres.full"
+_scratch_remount
+
+echo "Create more reflink copies"
+_cp_reflink "$TESTDIR/original" "$TESTDIR/copy3"
+
+xfs_info "$SCRATCH_MNT" >> "$seqres.full"
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/127.out b/tests/xfs/127.out
new file mode 100644
index 0000000..e4e76e2
--- /dev/null
+++ b/tests/xfs/127.out
@@ -0,0 +1,6 @@
+QA output created by 127
+Format and mount
+Create the original file and reflink to copy1, copy2
+Grow fs
+Create more reflink copies
+Check scratch fs
diff --git a/tests/xfs/128 b/tests/xfs/128
new file mode 100755
index 0000000..49652cb
--- /dev/null
+++ b/tests/xfs/128
@@ -0,0 +1,149 @@
+#! /bin/bash
+# FS QA Test No. 128
+#
+# Ensure that xfs_fsr un-reflinks files while defragmenting
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+#
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -f "$tmp".*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_supported_fs xfs
+_require_test_lsattr
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+
+echo "Create the original file and reflink to file2, file3"
+BLKS=2000
+MARGIN=100
+BLKSZ=65536
+REAL_BLKSZ="$(stat -f $TESTDIR -c '%S')"
+BLKSZ_FACTOR=$((BLKSZ / REAL_BLKSZ))
+_pwrite_byte 0x61 0 $((BLKS * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_cp_reflink "$TESTDIR/file2" "$TESTDIR/file3"
+_cp_reflink "$TESTDIR/file3" "$TESTDIR/file4"
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+
+md5sum "$TESTDIR/file1" | _filter_scratch
+md5sum "$TESTDIR/file2" | _filter_scratch
+md5sum "$TESTDIR/file3" | _filter_scratch
+md5sum "$TESTDIR/file4" | _filter_scratch
+
+C01=$(_md5_checksum "$TESTDIR/file1")
+C02=$(_md5_checksum "$TESTDIR/file2")
+C03=$(_md5_checksum "$TESTDIR/file3")
+C04=$(_md5_checksum "$TESTDIR/file4")
+
+echo "CoW the reflink copies"
+_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2" >> "$seqres.full"
+_pwrite_byte 0x63 $(( BLKSZ * (BLKS - 1) )) $BLKSZ "$TESTDIR/file3" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+
+md5sum "$TESTDIR/file1" | _filter_scratch
+md5sum "$TESTDIR/file2" | _filter_scratch
+md5sum "$TESTDIR/file3" | _filter_scratch
+md5sum "$TESTDIR/file4" | _filter_scratch
+
+C11=$(_md5_checksum "$TESTDIR/file1")
+C12=$(_md5_checksum "$TESTDIR/file2")
+C13=$(_md5_checksum "$TESTDIR/file3")
+C14=$(_md5_checksum "$TESTDIR/file4")
+
+echo "Defragment"
+lsattr -l "$TESTDIR/" | _filter_scratch
+xfs_fsr -v -d "$TESTDIR/file1" >> "$seqres.full"
+xfs_fsr -v -d "$TESTDIR/file2" >> "$seqres.full" # fsr probably breaks the link
+xfs_fsr -v -d "$TESTDIR/file3" >> "$seqres.full" # fsr probably breaks the link
+xfs_fsr -v -d "$TESTDIR/file4" >> "$seqres.full" # fsr probably ignores this file
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+
+md5sum "$TESTDIR/file1" | _filter_scratch
+md5sum "$TESTDIR/file2" | _filter_scratch
+md5sum "$TESTDIR/file3" | _filter_scratch
+md5sum "$TESTDIR/file4" | _filter_scratch
+
+C21=$(_md5_checksum "$TESTDIR/file1")
+C22=$(_md5_checksum "$TESTDIR/file2")
+C23=$(_md5_checksum "$TESTDIR/file3")
+C24=$(_md5_checksum "$TESTDIR/file4")
+
+echo "Check files"
+test $C01 = $C02 || echo "Files 1-2 do not match"
+test $C01 = $C03 || echo "Files 1-3 do not match"
+test $C01 = $C04 || echo "Files 1-4 do not match"
+test $C02 = $C03 || echo "Files 2-3 do not match"
+test $C02 = $C04 || echo "Files 2-4 do not match"
+test $C03 = $C04 || echo "Files 3-4 do not match"
+
+test $C01 = $C11 || echo "File1 should not be different after CoW"
+test $C02 != $C12 || echo "File2 should be different after CoW"
+test $C03 != $C13 || echo "File3 should be different after CoW"
+test $C04 = $C14 || echo "File4 should not be different after CoW"
+
+test $C11 = $C21 || echo "File1 changed by defrag"
+test $C12 = $C22 || echo "File2 changed by defrag"
+test $C13 = $C23 || echo "File3 changed by defrag"
+test $C14 = $C24 || echo "File4 changed by defrag"
+
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3
+
+_within_tolerance "free blocks after creating some reflink copies" $FREE_BLOCKS1 $((FREE_BLOCKS0 - (BLKS * BLKSZ_FACTOR) )) $MARGIN -v
+_within_tolerance "free blocks after CoW some reflink copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - 2)) $MARGIN -v
+_within_tolerance "free blocks after defragging all reflink copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - (BLKS * 2 * BLKSZ_FACTOR))) $MARGIN -v
+_within_tolerance "free blocks after all tests" $FREE_BLOCKS3 $((FREE_BLOCKS0 - (BLKS * 3 * BLKSZ_FACTOR))) $MARGIN -v
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/128.out b/tests/xfs/128.out
new file mode 100644
index 0000000..7e72dcd
--- /dev/null
+++ b/tests/xfs/128.out
@@ -0,0 +1,27 @@
+QA output created by 128
+Format and mount
+Create the original file and reflink to file2, file3
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file1
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file2
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file3
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file4
+CoW the reflink copies
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file1
+c650f1cf6c9f07b22e3e21ec7d49ded5  SCRATCH_MNT/test-128/file2
+56ed2f712c91e035adeeb26ed105a982  SCRATCH_MNT/test-128/file3
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file4
+Defragment
+SCRATCH_MNT/test-128/file1          ---
+SCRATCH_MNT/test-128/file2          ---
+SCRATCH_MNT/test-128/file3          ---
+SCRATCH_MNT/test-128/file4          ---
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file1
+c650f1cf6c9f07b22e3e21ec7d49ded5  SCRATCH_MNT/test-128/file2
+56ed2f712c91e035adeeb26ed105a982  SCRATCH_MNT/test-128/file3
+b81534f439aac5c34ce3ed60a03eba70  SCRATCH_MNT/test-128/file4
+Check files
+free blocks after creating some reflink copies is in range
+free blocks after CoW some reflink copies is in range
+free blocks after defragging all reflink copies is in range
+free blocks after all tests is in range
+Check scratch fs
diff --git a/tests/xfs/129 b/tests/xfs/129
new file mode 100755
index 0000000..6279d69
--- /dev/null
+++ b/tests/xfs/129
@@ -0,0 +1,87 @@
+#! /bin/bash
+# FS QA Test No. 129
+#
+# Ensure that we can create enough distinct reflink entries to force creation
+# of a multi-level refcount btree, and that metadump will successfully copy
+# said block.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    umount "$SCRATCH_MNT" > /dev/null 2>&1
+    rm -rf "$tmp".* "$TESTDIR" "$METADUMP_FILE"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_supported_fs xfs
+_require_scratch_reflink
+
+rm -f "$seqres.full"
+
+_scratch_mkfs >/dev/null 2>&1
+_scratch_mount
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+METADUMP_FILE="$TEST_DIR/${seq}_metadump"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+NR_BLKS=$((4 * BLKSZ / 12))
+_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/file1" >> "$seqres.full"
+
+echo "Reflink every other block"
+seq 1 $((NR_BLKS / 2)) | while read nr; do
+	_reflink_range  "$TESTDIR/file1" $((nr * 2 * BLKSZ)) \
+			"$TESTDIR/file2" $((nr * 2 * BLKSZ)) $BLKSZ >> "$seqres.full"
+done
+
+echo "Create metadump file"
+_scratch_unmount
+_scratch_metadump "$METADUMP_FILE"
+
+# Now restore the obfuscated one back and take a look around
+echo "Restore metadump"
+xfs_mdrestore "$METADUMP_FILE" "$TEST_DIR/image"
+_mount -t $FSTYP "$TEST_DIR/image" "$SCRATCH_MNT"
+umount "$SCRATCH_MNT"
+
+echo "Check restored fs"
+_check_generic_filesystem "$METADUMP_FILE"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/129.out b/tests/xfs/129.out
new file mode 100644
index 0000000..da6f43f
--- /dev/null
+++ b/tests/xfs/129.out
@@ -0,0 +1,6 @@
+QA output created by 129
+Create the original file blocks
+Reflink every other block
+Create metadump file
+Restore metadump
+Check restored fs
diff --git a/tests/xfs/130 b/tests/xfs/130
new file mode 100755
index 0000000..b64ea8c
--- /dev/null
+++ b/tests/xfs/130
@@ -0,0 +1,109 @@
+#! /bin/bash
+# FS QA Test No. 130
+#
+# Create and populate an XFS filesystem, corrupt the refcount btree,
+# then see how the kernel and xfs_repair deal with it.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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 15
+
+_cleanup()
+{
+    cd /
+    #rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_supported_fs xfs
+_require_scratch_reflink
+_require_cp_reflink
+test -n "${FORCE_FUZZ}" || _require_scratch_xfs_crc
+
+rm -f "$seqres.full"
+
+echo "+ create scratch fs"
+_scratch_mkfs_xfs > /dev/null
+
+echo "+ mount fs image"
+_scratch_mount
+blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
+agcount="$(xfs_info "${SCRATCH_MNT}" | grep agcount= | sed -e 's/^.*agcount=\([0-9]*\),.*$/\1/g')"
+
+echo "+ make some files"
+_pwrite_byte 0x62 0 $((blksz * 64)) "${SCRATCH_MNT}/file0" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((blksz * 64)) "${SCRATCH_MNT}/file1" >> "$seqres.full"
+_cp_reflink "${SCRATCH_MNT}/file0" "${SCRATCH_MNT}/file2"
+_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file3"
+umount "${SCRATCH_MNT}"
+
+echo "+ check fs"
+_scratch_xfs_repair -n >> "$seqres.full" 2>&1 || \
+	_fail "xfs_repair should not fail"
+
+echo "+ corrupt image"
+seq 0 $((agcount - 1)) | while read ag; do
+	$XFS_DB_PROG -x -c "agf ${ag}" -c "agf ${ag}" -c "addr refcntroot" \
+		-c "stack" -c "blocktrash -x 4096 -y 4096 -z -n 8 -3" \
+		"${SCRATCH_DEV}" >> "$seqres.full" 2>&1
+done
+
+echo "+ mount image"
+_scratch_mount
+
+echo "+ reflink more"
+_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file4" 2> /dev/null && \
+	_fail "should not be able to reflink with busted refcount btree"
+umount "${SCRATCH_MNT}"
+
+echo "+ repair fs"
+_scratch_xfs_repair >> "$seqres.full" 2>&1
+_scratch_xfs_repair >> "$seqres.full" 2>&1
+
+echo "+ mount image (2)"
+_scratch_mount
+
+echo "+ chattr -R -i"
+chattr -R -f -i "${SCRATCH_MNT}/"
+
+echo "+ reflink more (2)"
+_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file5" || \
+	_fail "modified refcount tree"
+umount "${SCRATCH_MNT}"
+
+echo "+ check fs (2)"
+_scratch_xfs_repair -n >> "$seqres.full" 2>&1 || \
+	_fail "xfs_repair should not fail"
+
+status=0
+exit
diff --git a/tests/xfs/130.out b/tests/xfs/130.out
new file mode 100644
index 0000000..58d153b
--- /dev/null
+++ b/tests/xfs/130.out
@@ -0,0 +1,13 @@
+QA output created by 130
++ create scratch fs
++ mount fs image
++ make some files
++ check fs
++ corrupt image
++ mount image
++ reflink more
++ repair fs
++ mount image (2)
++ chattr -R -i
++ reflink more (2)
++ check fs (2)
diff --git a/tests/xfs/131 b/tests/xfs/131
new file mode 100755
index 0000000..5d092f1
--- /dev/null
+++ b/tests/xfs/131
@@ -0,0 +1,76 @@
+#! /bin/bash
+# FS QA Test No. 131
+#
+# Ensure that we can't reflink realtime files.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    umount "$SCRATCH_MNT" > /dev/null 2>&1
+    rm -rf "$tmp".* "$TESTDIR" "$METADUMP_FILE"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount scratch device"
+_scratch_mkfs >> "$seqres.full"
+_scratch_mount
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ=65536
+$XFS_IO_PROG -R -f -c "truncate $BLKSZ" "$TESTDIR/file1"
+
+echo "Reflink every block"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" 2>&1 | _filter_scratch
+
+test -s "$TESTDIR/file2" && _fail "Should not be able to reflink a realtime file."
+
+echo "Check restored fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/131.out b/tests/xfs/131.out
new file mode 100644
index 0000000..7b700c9
--- /dev/null
+++ b/tests/xfs/131.out
@@ -0,0 +1,6 @@
+QA output created by 131
+Format and mount scratch device
+Create the original file blocks
+Reflink every block
+cp: failed to clone 'SCRATCH_MNT/test-131/file2' from 'SCRATCH_MNT/test-131/file1': Invalid argument
+Check restored fs
diff --git a/tests/xfs/132 b/tests/xfs/132
new file mode 100755
index 0000000..ec7b178
--- /dev/null
+++ b/tests/xfs/132
@@ -0,0 +1,130 @@
+#! /bin/bash
+# FS QA Test No. 132
+#
+# Ensure that fallocate on reflinked files actually CoWs the shared blocks.
+#   - Record fs block usage (0)
+#   - Create a file and some reflink copies
+#   - Record fs block usage (1)
+#   - funshare half of one of the copies
+#   - Record fs block usage (2)
+#   - funshare all of the copies
+#   - Record fs block usage (3)
+#   - rewrite the original file
+#   - Record fs block usage (4)
+#   - Compare fs block usage of 0-4 to ensure that block usage behaves as
+#     we expect.
+#   - Compare the status of the inode reflink flag at each step.
+#
+# "funshare" refers to fallocate copy-on-writing the shared blocks
+#
+# This is the same test as generic/156 except that we also check the inode
+# reflink flag.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_test_reflink
+_require_test_lsattr
+_require_cp_reflink
+_require_xfs_io_command "falloc"
+
+rm -f "$seqres.full"
+
+TESTDIR="$TEST_DIR/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create the original file blocks"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+BLKS=2000
+MARGIN=100
+SZ=$((BLKSZ * BLKS))
+FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f')
+NR=4
+_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+
+echo "Create the reflink copies"
+for i in `seq 2 $NR`; do
+	_cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i"
+done
+_test_remount
+FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f')
+lsattr -l $TESTDIR/ | _filter_test_dir
+
+echo "funshare part of a file"
+"$XFS_IO_PROG" -f -c "falloc 0 $((SZ / 2))" "$TESTDIR/file2"
+_test_remount
+lsattr -l $TESTDIR/ | _filter_test_dir
+
+echo "funshare some of the copies"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file2"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file3"
+_test_remount
+FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f')
+lsattr -l $TESTDIR/ | _filter_test_dir
+
+echo "funshare the rest of the files"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file4"
+"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file1"
+_test_remount
+FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f')
+lsattr -l $TESTDIR/ | _filter_test_dir
+
+echo "Rewrite the original file"
+_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full"
+_test_remount
+FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f')
+lsattr -l $TESTDIR/ | _filter_test_dir
+#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4
+
+_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after nocow'ing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v
+
+_within_tolerance "free blocks after nocow'ing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v
+
+_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v
+
+_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/132.out b/tests/xfs/132.out
new file mode 100644
index 0000000..fd2b7bd
--- /dev/null
+++ b/tests/xfs/132.out
@@ -0,0 +1,32 @@
+QA output created by 132
+Create the original file blocks
+Create the reflink copies
+TEST_DIR/test-132/file1          ---
+TEST_DIR/test-132/file2          ---
+TEST_DIR/test-132/file3          ---
+TEST_DIR/test-132/file4          ---
+funshare part of a file
+TEST_DIR/test-132/file1          ---
+TEST_DIR/test-132/file2          ---
+TEST_DIR/test-132/file3          ---
+TEST_DIR/test-132/file4          ---
+funshare some of the copies
+TEST_DIR/test-132/file1          ---
+TEST_DIR/test-132/file2          No_COW
+TEST_DIR/test-132/file3          No_COW
+TEST_DIR/test-132/file4          ---
+funshare the rest of the files
+TEST_DIR/test-132/file1          No_COW
+TEST_DIR/test-132/file2          No_COW
+TEST_DIR/test-132/file3          No_COW
+TEST_DIR/test-132/file4          No_COW
+Rewrite the original file
+TEST_DIR/test-132/file1          No_COW
+TEST_DIR/test-132/file2          No_COW
+TEST_DIR/test-132/file3          No_COW
+TEST_DIR/test-132/file4          No_COW
+free blocks after reflinking is in range
+free blocks after nocow'ing some copies is in range
+free blocks after nocow'ing all copies is in range
+free blocks after overwriting original is in range
+free blocks after all tests is in range
diff --git a/tests/xfs/group b/tests/xfs/group
index 8261f86..9884329 100644
--- a/tests/xfs/group
+++ b/tests/xfs/group
@@ -124,6 +124,12 @@
 124 fuzzers
 125 fuzzers
 126 fuzzers
+127 auto quick clone
+128 auto quick clone
+129 auto quick clone
+130 fuzzers
+131 auto quick clone
+132 auto quick clone
 134 quota auto quick
 136 attr2
 142 dmapi

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/12] reflink: concurrent operations tests
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (8 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 09/12] xfs: test xfs-specific reflink pieces Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:37 ` [PATCH 11/12] reflink: test that CoW writes fail when we're out of space Darrick J. Wong
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Make sure that running reflink ops while other IO is ongoing doesn't
break the filesystem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/161     |   79 +++++++++++++++++++++++++++++++++++++
 tests/generic/161.out |    6 +++
 tests/generic/162     |   95 ++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/162.out |    7 +++
 tests/generic/163     |   95 ++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/163.out |    7 +++
 tests/generic/164     |  105 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/164.out |    7 +++
 tests/generic/165     |  105 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/165.out |    7 +++
 tests/generic/166     |   93 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/166.out |    6 +++
 tests/generic/167     |   93 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/167.out |    6 +++
 tests/generic/168     |   97 +++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/168.out |    6 +++
 tests/generic/170     |   97 +++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/170.out |    6 +++
 tests/generic/group   |    9 ++++
 19 files changed, 926 insertions(+)
 create mode 100755 tests/generic/161
 create mode 100644 tests/generic/161.out
 create mode 100755 tests/generic/162
 create mode 100644 tests/generic/162.out
 create mode 100755 tests/generic/163
 create mode 100644 tests/generic/163.out
 create mode 100755 tests/generic/164
 create mode 100644 tests/generic/164.out
 create mode 100755 tests/generic/165
 create mode 100644 tests/generic/165.out
 create mode 100755 tests/generic/166
 create mode 100644 tests/generic/166.out
 create mode 100755 tests/generic/167
 create mode 100644 tests/generic/167.out
 create mode 100755 tests/generic/168
 create mode 100644 tests/generic/168.out
 create mode 100755 tests/generic/170
 create mode 100644 tests/generic/170.out


diff --git a/tests/generic/161 b/tests/generic/161
new file mode 100755
index 0000000..efb137c
--- /dev/null
+++ b/tests/generic/161
@@ -0,0 +1,79 @@
+#! /bin/bash
+# FS QA Test No. 161
+#
+# Test for race between delete a file while rewriting its reflinked twin
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=4096
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2"
+_scratch_remount
+
+echo "Delete while rewriting"
+rm -rf "$TESTDIR/file1" &
+_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+wait
+
+echo "Check fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+# success, all done
+status=0
+exit
diff --git a/tests/generic/161.out b/tests/generic/161.out
new file mode 100644
index 0000000..1db11c3
--- /dev/null
+++ b/tests/generic/161.out
@@ -0,0 +1,6 @@
+QA output created by 161
+Format and mount
+Initialize files
+Delete while rewriting
+Check fs
+Done
diff --git a/tests/generic/162 b/tests/generic/162
new file mode 100755
index 0000000..6bd3a33
--- /dev/null
+++ b/tests/generic/162
@@ -0,0 +1,95 @@
+#! /bin/bash
+# FS QA Test No. 162
+#
+# Test for race between dedupe and writing the dest file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_dedupe
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=512
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full"
+_scratch_remount
+
+overwrite() {
+	while [ ! -e "$TESTDIR/finished" ]; do
+		seq $nr_loops -1 0 | while read i; do
+			_pwrite_byte 0x61 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file2" >> "$seqres.full"
+		done
+	done
+}
+
+echo "Dedupe and rewrite the file!"
+overwrite &
+for i in `seq 1 2`; do
+	seq $nr_loops -1 0 | while read i; do
+		_dedupe_range   "$TESTDIR/file1" $((i * BLKSZ)) \
+				"$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && break
+	done
+done
+echo "Finished dedupeing"
+touch "$TESTDIR/finished"
+wait
+
+echo "Check fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+# success, all done
+status=0
+exit
diff --git a/tests/generic/162.out b/tests/generic/162.out
new file mode 100644
index 0000000..4481f8c
--- /dev/null
+++ b/tests/generic/162.out
@@ -0,0 +1,7 @@
+QA output created by 162
+Format and mount
+Initialize files
+Dedupe and rewrite the file!
+Finished dedupeing
+Check fs
+Done
diff --git a/tests/generic/163 b/tests/generic/163
new file mode 100755
index 0000000..1f5042f
--- /dev/null
+++ b/tests/generic/163
@@ -0,0 +1,95 @@
+#! /bin/bash
+# FS QA Test No. 163
+#
+# Test for race between dedupe and writing the source file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_dedupe
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=512
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full"
+_scratch_remount
+
+overwrite() {
+	while [ ! -e "$TESTDIR/finished" ]; do
+		seq $nr_loops -1 0 | while read i; do
+			_pwrite_byte 0x61 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+		done
+	done
+}
+
+echo "Dedupe and rewrite the file!"
+overwrite &
+for i in `seq 1 2`; do
+	seq $nr_loops -1 0 | while read i; do
+		_dedupe_range   "$TESTDIR/file1" $((i * BLKSZ)) \
+				"$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && break
+	done
+done
+echo "Finished dedupeing"
+touch "$TESTDIR/finished"
+wait
+
+echo "Check fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+# success, all done
+status=0
+exit
diff --git a/tests/generic/163.out b/tests/generic/163.out
new file mode 100644
index 0000000..2d27d1b
--- /dev/null
+++ b/tests/generic/163.out
@@ -0,0 +1,7 @@
+QA output created by 163
+Format and mount
+Initialize files
+Dedupe and rewrite the file!
+Finished dedupeing
+Check fs
+Done
diff --git a/tests/generic/164 b/tests/generic/164
new file mode 100755
index 0000000..4df953d
--- /dev/null
+++ b/tests/generic/164
@@ -0,0 +1,105 @@
+#! /bin/bash
+# FS QA Test No. 164
+#
+# Test for races or FS corruption between reflink and buffered I/O reading the
+# target file.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=512
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3"
+_scratch_remount
+
+fbytes() {
+	egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)'
+}
+
+reader() {
+	while [ ! -e "$TESTDIR/finished" ]; do
+		_read_range "$TESTDIR/file3" 0 $((loops * BLKSZ)) | fbytes
+	done
+}
+
+echo "Reflink and reread the files!"
+reader &
+for i in `seq 1 2`; do
+	seq $nr_loops -1 0 | while read i; do
+		_reflink_range  "$TESTDIR/file1" $((i * BLKSZ)) \
+				"$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && break
+	done
+	seq $nr_loops -1 0 | while read i; do
+		_reflink_range  "$TESTDIR/file2" $((i * BLKSZ)) \
+				"$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && break
+	done
+done
+echo "Finished reflinking"
+touch "$TESTDIR/finished"
+wait
+
+echo "Check fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+# success, all done
+status=0
+exit
diff --git a/tests/generic/164.out b/tests/generic/164.out
new file mode 100644
index 0000000..0b4ed70
--- /dev/null
+++ b/tests/generic/164.out
@@ -0,0 +1,7 @@
+QA output created by 164
+Format and mount
+Initialize files
+Reflink and reread the files!
+Finished reflinking
+Check fs
+Done
diff --git a/tests/generic/165 b/tests/generic/165
new file mode 100755
index 0000000..49187ec
--- /dev/null
+++ b/tests/generic/165
@@ -0,0 +1,105 @@
+#! /bin/bash
+# FS QA Test No. 165
+#
+# Test for races or FS corruption between reflink and direct I/O reading the
+# target file.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=512
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full"
+_cp_reflink $TESTDIR/file1 $TESTDIR/file3
+_scratch_remount
+
+fbytes() {
+	egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)'
+}
+
+reader() {
+	while [ ! -e "$TESTDIR/finished" ]; do
+		_read_range "$TESTDIR/file3" 0 $((loops * BLKSZ)) -d | fbytes
+	done
+}
+
+echo "Reflink and dio reread the files!"
+reader &
+for i in `seq 1 2`; do
+	seq $nr_loops -1 0 | while read i; do
+		_reflink_range  "$TESTDIR/file1" $((i * BLKSZ)) \
+				"$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && break
+	done
+	seq $nr_loops -1 0 | while read i; do
+		_reflink_range  "$TESTDIR/file2" $((i * BLKSZ)) \
+				"$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && break
+	done
+done
+echo "Finished reflinking"
+touch "$TESTDIR/finished"
+wait
+
+echo "Check fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+# success, all done
+status=0
+exit
diff --git a/tests/generic/165.out b/tests/generic/165.out
new file mode 100644
index 0000000..a89071d
--- /dev/null
+++ b/tests/generic/165.out
@@ -0,0 +1,7 @@
+QA output created by 165
+Format and mount
+Initialize files
+Reflink and dio reread the files!
+Finished reflinking
+Check fs
+Done
diff --git a/tests/generic/166 b/tests/generic/166
new file mode 100755
index 0000000..71eb2ab
--- /dev/null
+++ b/tests/generic/166
@@ -0,0 +1,93 @@
+#! /bin/bash
+# FS QA Test No. 166
+#
+# Test for races or FS corruption when DIO writing to a file that's also
+# the source of a reflink operation.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=1024
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize file"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_scratch_remount
+
+# Snapshot creator...
+snappy() {
+	n=0
+	while [ ! -e "$TESTDIR/finished" ]; do
+		_cp_reflink "$TESTDIR/file1" "$TESTDIR/snap_$n" || break
+		n=$((n + 1))
+	done
+}
+
+echo "Snapshot a file undergoing directio rewrite"
+snappy &
+seq $nr_loops -1 0 | while read i; do
+	_pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ -d "$TESTDIR/file1" >> "$seqres.full"
+done
+touch $TESTDIR/finished
+wait
+
+echo "Check for damage"
+umount $SCRATCH_MNT
+_check_scratch_fs
+
+echo "Done"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/166.out b/tests/generic/166.out
new file mode 100644
index 0000000..a2ba34e
--- /dev/null
+++ b/tests/generic/166.out
@@ -0,0 +1,6 @@
+QA output created by 166
+Format and mount
+Initialize file
+Snapshot a file undergoing directio rewrite
+Check for damage
+Done
diff --git a/tests/generic/167 b/tests/generic/167
new file mode 100755
index 0000000..c4e6ce8
--- /dev/null
+++ b/tests/generic/167
@@ -0,0 +1,93 @@
+#! /bin/bash
+# FS QA Test No. 167
+#
+# Test for races or FS corruption when writing to a file that's also
+# the source of a reflink operation.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=1024
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize file"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_scratch_remount
+
+# Snapshot creator...
+snappy() {
+	n=0
+	while [ ! -e "$TESTDIR/finished" ]; do
+		_cp_reflink "$TESTDIR/file1" "$TESTDIR/snap_$n" || break
+		n=$((n + 1))
+	done
+}
+
+echo "Snapshot a file undergoing buffered rewrite"
+snappy &
+seq $nr_loops -1 0 | while read i; do
+	_pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+done
+touch $TESTDIR/finished
+wait
+
+echo "Check for damage"
+umount $SCRATCH_MNT
+_check_scratch_fs
+
+echo "Done"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/167.out b/tests/generic/167.out
new file mode 100644
index 0000000..7cfb14e
--- /dev/null
+++ b/tests/generic/167.out
@@ -0,0 +1,6 @@
+QA output created by 167
+Format and mount
+Initialize file
+Snapshot a file undergoing buffered rewrite
+Check for damage
+Done
diff --git a/tests/generic/168 b/tests/generic/168
new file mode 100755
index 0000000..414dcb0
--- /dev/null
+++ b/tests/generic/168
@@ -0,0 +1,97 @@
+#! /bin/bash
+# FS QA Test No. 168
+#
+# Test for races or FS corruption when writing to a file that's also
+# the target of a reflink operation.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=1024
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full"
+_scratch_remount
+
+# Direct I/O overwriter...
+overwrite() {
+	while [ ! -e "$TESTDIR/finished" ]; do
+		seq $nr_loops -1 0 | while read i; do
+			_pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file2" >> "$seqres.full"
+		done
+	done
+}
+
+echo "Reflink and write the target"
+overwrite &
+seq 1 10 | while read j; do
+	seq 0 $nr_loops | while read i; do
+		_reflink_range  "$TESTDIR/file1" $((i * BLKSZ)) \
+				"$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && exit
+	done
+done
+touch "$TESTDIR/finished"
+wait
+
+echo "Check for damage"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/168.out b/tests/generic/168.out
new file mode 100644
index 0000000..d0dd08e
--- /dev/null
+++ b/tests/generic/168.out
@@ -0,0 +1,6 @@
+QA output created by 168
+Format and mount
+Initialize files
+Reflink and write the target
+Check for damage
+Done
diff --git a/tests/generic/170 b/tests/generic/170
new file mode 100755
index 0000000..704b646
--- /dev/null
+++ b/tests/generic/170
@@ -0,0 +1,97 @@
+#! /bin/bash
+# FS QA Test No. 170
+#
+# Test for races or FS corruption when DIO writing to a file that's also
+# the target of a reflink operation.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle, Inc.  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
+#-----------------------------------------------------------------------
+#
+
+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".*
+    wait
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+loops=1024
+nr_loops=$((loops - 1))
+BLKSZ=65536
+
+echo "Initialize files"
+echo > "$seqres.full"
+_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full"
+_scratch_remount
+
+# Direct I/O overwriter...
+overwrite() {
+	while [ ! -e "$TESTDIR/finished" ]; do
+		seq $nr_loops -1 0 | while read i; do
+			_pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ -d "$TESTDIR/file2" >> "$seqres.full"
+		done
+	done
+}
+
+echo "Reflink and dio write the target"
+overwrite &
+seq 1 10 | while read j; do
+	seq 0 $nr_loops | while read i; do
+		_reflink_range  "$TESTDIR/file1" $((i * BLKSZ)) \
+				"$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full"
+		[ $? -ne 0 ] && exit
+	done
+done
+touch "$TESTDIR/finished"
+wait
+
+echo "Check for damage"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Done"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/170.out b/tests/generic/170.out
new file mode 100644
index 0000000..103aaa5
--- /dev/null
+++ b/tests/generic/170.out
@@ -0,0 +1,6 @@
+QA output created by 170
+Format and mount
+Initialize files
+Reflink and dio write the target
+Check for damage
+Done
diff --git a/tests/generic/group b/tests/generic/group
index 0a20421..6ae3105 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -163,7 +163,16 @@
 158 auto quick clone
 159 auto quick clone
 160 auto quick clone
+161 auto quick clone
+162 auto quick clone
+163 auto quick clone
+164 auto quick clone
+165 auto quick clone
+166 auto quick clone
+167 auto quick clone
+168 auto quick clone
 169 rw metadata auto quick
+170 auto quick clone
 184 metadata auto quick
 192 atime auto
 193 metadata auto quick

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/12] reflink: test that CoW writes fail when we're out of space
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (9 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 10/12] reflink: concurrent operations tests Darrick J. Wong
@ 2015-11-13 21:37 ` Darrick J. Wong
  2015-11-13 21:38 ` [PATCH 12/12] reflink: test what happens when we hit resource limits Darrick J. Wong
  2015-11-14  8:41 ` [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Christoph Hellwig
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:37 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Ensure that copy-on-writing a reflinked file when there's no free disk
space reflects the desired ENOSPC back to userspace during the write
call.  Tests the buffered IO, direct IO, and mmap write paths.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/171     |  107 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/171.out |   10 ++++
 tests/generic/172     |  107 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/172.out |   10 ++++
 tests/generic/173     |  109 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/173.out |    8 ++++
 tests/generic/174     |  107 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/174.out |   10 ++++
 tests/generic/group   |    4 ++
 9 files changed, 472 insertions(+)
 create mode 100755 tests/generic/171
 create mode 100644 tests/generic/171.out
 create mode 100755 tests/generic/172
 create mode 100644 tests/generic/172.out
 create mode 100755 tests/generic/173
 create mode 100644 tests/generic/173.out
 create mode 100755 tests/generic/174
 create mode 100644 tests/generic/174.out


diff --git a/tests/generic/171 b/tests/generic/171
new file mode 100755
index 0000000..99e4d5e
--- /dev/null
+++ b/tests/generic/171
@@ -0,0 +1,107 @@
+#! /bin/bash
+# FS QA Test No. 171
+#
+# Reflink a file, use up the rest of the space, then try to observe ENOSPC
+# while copy-on-writing the file via the page cache.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Reformat with appropriate size"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+NR_BLKS=10240
+umount "$SCRATCH_MNT"
+SZ_BYTES=$((NR_BLKS * 8 * BLKSZ))
+if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then
+	SZ_BYTES=$((32 * 1048576))
+fi
+_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create a big file and reflink it"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1
+_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile"
+sync
+
+echo "Allocate the rest of the space"
+NR_FREE="$(stat -f -c '%f' "$TESTDIR")"
+touch "$TESTDIR/file0" "$TESTDIR/file1"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1
+sync
+
+echo "CoW the big file"
+out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)"
+echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC"
+echo "${out}" >> "$seqres.full" 2>&1
+echo "${out}"
+
+echo "Remount and try CoW again"
+_scratch_remount
+
+out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)"
+echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC"
+echo "${out}" >> "$seqres.full" 2>&1
+echo "${out}"
+
+#filefrag -v $TESTDIR/bigfile
+#filefrag -v $TESTDIR/clonefile
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/171.out b/tests/generic/171.out
new file mode 100644
index 0000000..c2b0ddd
--- /dev/null
+++ b/tests/generic/171.out
@@ -0,0 +1,10 @@
+QA output created by 171
+Format and mount
+Reformat with appropriate size
+Create a big file and reflink it
+Allocate the rest of the space
+CoW the big file
+pwrite64: No space left on device
+Remount and try CoW again
+pwrite64: No space left on device
+Check scratch fs
diff --git a/tests/generic/172 b/tests/generic/172
new file mode 100755
index 0000000..eb00f0a
--- /dev/null
+++ b/tests/generic/172
@@ -0,0 +1,107 @@
+#! /bin/bash
+# FS QA Test No. 172
+#
+# Reflink a file that uses more than half of the space, then try to observe
+# ENOSPC while copy-on-writing the file via the page cache.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Reformat with appropriate size"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+NR_BLKS=10240
+umount "$SCRATCH_MNT"
+SZ_BYTES=$((NR_BLKS * 3 / 2 * BLKSZ))
+if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then
+	SZ_BYTES=$((32 * 1048576))
+fi
+_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create a big file and reflink it"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1
+_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile"
+sync
+
+echo "Allocate the rest of the space"
+NR_FREE="$(stat -f -c '%f' "$TESTDIR")"
+touch "$TESTDIR/file0" "$TESTDIR/file1"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1
+sync
+
+echo "CoW the big file"
+out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)"
+echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC"
+echo "${out}" >> "$seqres.full" 2>&1
+echo "${out}"
+
+echo "Remount and try CoW again"
+_scratch_remount
+
+out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)"
+echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC"
+echo "${out}" >> "$seqres.full" 2>&1
+echo "${out}"
+
+#filefrag -v $TESTDIR/bigfile
+#filefrag -v $TESTDIR/clonefile
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/172.out b/tests/generic/172.out
new file mode 100644
index 0000000..3913dd7
--- /dev/null
+++ b/tests/generic/172.out
@@ -0,0 +1,10 @@
+QA output created by 172
+Format and mount
+Reformat with appropriate size
+Create a big file and reflink it
+Allocate the rest of the space
+CoW the big file
+pwrite64: No space left on device
+Remount and try CoW again
+pwrite64: No space left on device
+Check scratch fs
diff --git a/tests/generic/173 b/tests/generic/173
new file mode 100755
index 0000000..76463d2
--- /dev/null
+++ b/tests/generic/173
@@ -0,0 +1,109 @@
+#! /bin/bash
+# FS QA Test No. 173
+#
+# Reflink a file, use up the rest of the space, then try to observe ENOSPC
+# while copy-on-writing the file via mmap.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Reformat with appropriate size"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+NR_BLKS=10240
+umount "$SCRATCH_MNT"
+SZ_BYTES=$((NR_BLKS * 8 * BLKSZ))
+if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then
+	SZ_BYTES=$((32 * 1048576))
+fi
+_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create a big file and reflink it"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1
+_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile"
+sync
+
+echo "Allocate the rest of the space"
+NR_FREE="$(stat -f -c '%f' "$TESTDIR")"
+touch "$TESTDIR/file0" "$TESTDIR/file1"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1
+sync
+
+echo "mmap CoW the big file"
+out="$(_mwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)"
+err="$?"
+if [ "$err" -lt 128 ]; then
+	echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)"
+fi
+
+echo "Remount and try CoW again"
+_scratch_remount
+
+out="$(_mwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)"
+err="$?"
+if [ "$err" -lt 128 ]; then
+	echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)"
+fi
+
+#filefrag -v $TESTDIR/bigfile
+#filefrag -v $TESTDIR/clonefile
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/173.out b/tests/generic/173.out
new file mode 100644
index 0000000..49abb17
--- /dev/null
+++ b/tests/generic/173.out
@@ -0,0 +1,8 @@
+QA output created by 173
+Format and mount
+Reformat with appropriate size
+Create a big file and reflink it
+Allocate the rest of the space
+mmap CoW the big file
+Remount and try CoW again
+Check scratch fs
diff --git a/tests/generic/174 b/tests/generic/174
new file mode 100755
index 0000000..8df292a
--- /dev/null
+++ b/tests/generic/174
@@ -0,0 +1,107 @@
+#! /bin/bash
+# FS QA Test No. 174
+#
+# Reflink a file, use up the rest of the space, then try to observe ENOSPC
+# while copy-on-writing the file via direct-io.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Reformat with appropriate size"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+NR_BLKS=10240
+umount "$SCRATCH_MNT"
+SZ_BYTES=$((NR_BLKS * 8 * BLKSZ))
+if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then
+	SZ_BYTES=$((32 * 1048576))
+fi
+_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+echo "Create a big file and reflink it"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1
+_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile"
+sync
+
+echo "Allocate the rest of the space"
+NR_FREE="$(stat -f -c '%f' "$TESTDIR")"
+touch "$TESTDIR/file0" "$TESTDIR/file1"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1
+sync
+
+echo "CoW the big file"
+out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" -d 2>&1)"
+echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC"
+echo "${out}" >> "$seqres.full" 2>&1
+echo "${out}"
+
+echo "Remount and try CoW again"
+_scratch_remount
+
+out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" -d 2>&1)"
+echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC"
+echo "${out}" >> "$seqres.full" 2>&1
+echo "${out}"
+
+#filefrag -v $TESTDIR/bigfile
+#filefrag -v $TESTDIR/clonefile
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/174.out b/tests/generic/174.out
new file mode 100644
index 0000000..702d067
--- /dev/null
+++ b/tests/generic/174.out
@@ -0,0 +1,10 @@
+QA output created by 174
+Format and mount
+Reformat with appropriate size
+Create a big file and reflink it
+Allocate the rest of the space
+CoW the big file
+pwrite64: No space left on device
+Remount and try CoW again
+pwrite64: No space left on device
+Check scratch fs
diff --git a/tests/generic/group b/tests/generic/group
index 6ae3105..09a7828 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -173,6 +173,10 @@
 168 auto quick clone
 169 rw metadata auto quick
 170 auto quick clone
+171 auto quick clone
+172 auto quick clone
+173 auto quick clone
+174 auto quick clone
 184 metadata auto quick
 192 atime auto
 193 metadata auto quick

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/12] reflink: test what happens when we hit resource limits
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (10 preceding siblings ...)
  2015-11-13 21:37 ` [PATCH 11/12] reflink: test that CoW writes fail when we're out of space Darrick J. Wong
@ 2015-11-13 21:38 ` Darrick J. Wong
  2015-11-14  8:41 ` [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Christoph Hellwig
  12 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-13 21:38 UTC (permalink / raw)
  To: david, darrick.wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Add a few horrible opt-in stress tests to see what happens if we try
to reflink the same block billions of times, and what happens if we
run out of space while reflinking a file.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/generic/175     |   99 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/175.out |    0 
 tests/generic/176     |   81 ++++++++++++++++++++++++++++++++++++++++
 tests/generic/176.out |    5 ++
 tests/generic/group   |    2 +
 5 files changed, 187 insertions(+)
 create mode 100755 tests/generic/175
 create mode 100644 tests/generic/175.out
 create mode 100755 tests/generic/176
 create mode 100644 tests/generic/176.out


diff --git a/tests/generic/175 b/tests/generic/175
new file mode 100755
index 0000000..a7da533
--- /dev/null
+++ b/tests/generic/175
@@ -0,0 +1,99 @@
+#! /bin/bash
+# FS QA Test No. 175
+#
+# Try to hit the maximum reference count (eek!)
+#
+# This test runs extremely slowly, so it's not automatically run anywhere.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+_require_cp_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+# Well let's hope the maximum reflink count is (less than (ha!)) 2^32...
+
+echo "Create a one block file"
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full"
+_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2" >> "$seqres.full"
+_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full"
+
+nr=32
+fnr=32
+for i in $(seq 0 $fnr); do
+	echo " ++ Reflink size $i, $(( (2 ** i) * BLKSZ)) bytes" | tee -a "$seqres.full"
+	n=$(( (2 ** i) * BLKSZ))
+	_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file1" $n $n >> "$seqres.full" || break
+done
+
+nrf=$((nr - fnr))
+echo "Clone $((2 ** nrf)) files"
+seq 0 $((2 ** nrf)) | while read i; do
+	_cp-reflink "$TESTDIR/file1" "$TESTDIR/file1-$i"
+done
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Remove big file and recheck"
+_scratch_mount >> "$seqres.full" 2>&1
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+echo "Remove all files and recheck"
+_scratch_mount >> "$seqres.full" 2>&1
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/175.out b/tests/generic/175.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/generic/176 b/tests/generic/176
new file mode 100755
index 0000000..bf930b7
--- /dev/null
+++ b/tests/generic/176
@@ -0,0 +1,81 @@
+#! /bin/bash
+# FS QA Test No. 176
+#
+# Try to run out of space while cloning?
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2015, Oracle and/or its affiliates.  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
+#-----------------------------------------------------------------------
+
+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 15
+
+_cleanup()
+{
+    cd /
+    rm -rf "$tmp".* "$TESTDIR1"
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+. ./common/reflink
+
+# real QA test starts here
+_supported_os Linux
+_require_scratch_reflink
+
+rm -f "$seqres.full"
+
+echo "Format and mount"
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount >> "$seqres.full" 2>&1
+
+TESTDIR="$SCRATCH_MNT/test-$seq"
+rm -rf "$TESTDIR"
+mkdir "$TESTDIR"
+
+BLKSZ="$(stat -f "$TESTDIR" -c '%S')"
+NR_FREE="$(stat -f -c '%f' "$TESTDIR")"
+echo "Create a big file"
+touch "$TESTDIR/file0" "$TESTDIR/file1"
+_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1
+_scratch_remount
+sz="$(stat -c '%s' "$TESTDIR/bigfile")"
+
+blks="$((sz / BLKSZ))"
+echo "Try to reflink"
+seq 0 $blks | while read lblk; do
+	fname="$TESTDIR/file$((lblk % 2))"
+	out="$(_reflink_range "$TESTDIR/bigfile" $((lblk * BLKSZ)) "$fname" $((lblk * BLKSZ)) $BLKSZ 2>&1)"
+	echo "$fname: $out" >> "$seqres.full"
+	echo "$out" | grep -q "No space left on device" && break
+done
+
+echo "Check scratch fs"
+umount "$SCRATCH_MNT"
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/176.out b/tests/generic/176.out
new file mode 100644
index 0000000..eec98eb
--- /dev/null
+++ b/tests/generic/176.out
@@ -0,0 +1,5 @@
+QA output created by 176
+Format and mount
+Create a big file
+Try to reflink
+Check scratch fs
diff --git a/tests/generic/group b/tests/generic/group
index 09a7828..8a40797 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -177,6 +177,8 @@
 172 auto quick clone
 173 auto quick clone
 174 auto quick clone
+175 clone_stress
+176 clone_stress
 184 metadata auto quick
 192 atime auto
 193 metadata auto quick

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls
  2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
                   ` (11 preceding siblings ...)
  2015-11-13 21:38 ` [PATCH 12/12] reflink: test what happens when we hit resource limits Darrick J. Wong
@ 2015-11-14  8:41 ` Christoph Hellwig
  12 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2015-11-14  8:41 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: david, fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

Looks good,

Acked-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 01/12] test-scripts: test migration scripts
  2015-11-13 21:36 ` [PATCH 01/12] test-scripts: test migration scripts Darrick J. Wong
@ 2015-11-16 20:58   ` Dave Chinner
  2015-11-16 23:51     ` Darrick J. Wong
  0 siblings, 1 reply; 17+ messages in thread
From: Dave Chinner @ 2015-11-16 20:58 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

On Fri, Nov 13, 2015 at 01:36:50PM -0800, Darrick J. Wong wrote:
> Add two scripts: "nextid" finds the next available test ID number in a
> group, and "mvtest" relocates a test, fixes the golden output, and
> moves the group entry for that test.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  mvtest |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  nextid |   35 +++++++++++++++++++++++++++++++++++

These should be placed in the "tools" directory.

>  create mode 100755 mvtest
>  create mode 100755 nextid
> 
> 
> diff --git a/mvtest b/mvtest
> new file mode 100755
> index 0000000..b5406d1
> --- /dev/null
> +++ b/mvtest
> @@ -0,0 +1,58 @@
> +#!/bin/sh
> +
> +# Renumber a test
> +
> +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> +	echo "Usage: $0 path_to_test new_path_to_test"
> +	exit 1
> +fi
> +
> +src="$1"
> +dest="$2"
> +
> +die() {
> +	echo "$@"
> +	exit 1
> +}
> +
> +nsort() {
> +	sort -g < "$1" > "$2"
> +}
> +
> +append() {
> +	out="$1"
> +	shift
> +	echo "$@" >> "${out}"
> +}
> +
> +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest."
> +test -e "tests/${src}" || die "Test \"${src}\" does not exist."
> +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists."
> +
> +sid="$(basename "${src}")"
> +did="$(basename "${dest}")"
> +
> +sgroup="$(basename "$(dirname "tests/${src}")")"
> +dgroup="$(basename "$(dirname "tests/${dest}")")"
> +
> +sgroupfile="tests/${sgroup}/group"
> +dgroupfile="tests/${sgroup}/group"
> +
> +$DBG git mv "tests/${src}" "tests/${dest}"

$DBG?

....
> +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}"
> +$DBG cp "${dgroupfile}" "${dgroupfile}.new"
> +$DBG append "${dgroupfile}.new" "${newgrpline}"
> +$DBG nsort "${dgroupfile}.new" "${dgroupfile}"

What does this do to comments in the group file?

...

> diff --git a/nextid b/nextid
> new file mode 100755
> index 0000000..285b549
> --- /dev/null
> +++ b/nextid
> @@ -0,0 +1,35 @@
> +#!/bin/sh
> +
> +# Given a group name, find the next available test number.
> +
> +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> +	echo "Usage: $0 groupname[/start_looking_at_this_number]"
> +	exit 1
> +fi
> +
> +die() {
> +	echo "$@"
> +	exit 1
> +}
> +
> +if [ "$(basename "$1")" != "$1" ]; then
> +	group="$(dirname "$1")"
> +	id="$(basename "$1")"
> +else
> +	group="$1"
> +	id=1
> +fi
> +test -e "tests/${group}/group" || die "Unknown group \"${group}\"."
> +
> +while test "${id}" -lt 1000; do
> +	name="$(printf "%.03d" "${id}")"
> +	if [ ! -e "tests/${group}/${name}" ]; then
> +		echo "${group}/${name}"
> +		exit 0
> +	fi
> +	id=$((id + 1))
> +done
> +
> +echo "No free IDs less than ${id} in group \"${group}\"."

So the "new" script does this differently, by reading the group
file and looking for the first non-contiguous ID in the file. It
doesn't need scan ID limits because EOF triggers that. Wouldn't it
be better to to factor the code out of the "new" script to find the
next id, and then have the new script call that?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 01/12] test-scripts: test migration scripts
  2015-11-16 20:58   ` Dave Chinner
@ 2015-11-16 23:51     ` Darrick J. Wong
  2015-11-17 21:16       ` Darrick J. Wong
  0 siblings, 1 reply; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-16 23:51 UTC (permalink / raw)
  To: Dave Chinner
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

On Tue, Nov 17, 2015 at 07:58:45AM +1100, Dave Chinner wrote:
> On Fri, Nov 13, 2015 at 01:36:50PM -0800, Darrick J. Wong wrote:
> > Add two scripts: "nextid" finds the next available test ID number in a
> > group, and "mvtest" relocates a test, fixes the golden output, and
> > moves the group entry for that test.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  mvtest |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  nextid |   35 +++++++++++++++++++++++++++++++++++
> 
> These should be placed in the "tools" directory.

<nod>

> 
> >  create mode 100755 mvtest
> >  create mode 100755 nextid
> > 
> > 
> > diff --git a/mvtest b/mvtest
> > new file mode 100755
> > index 0000000..b5406d1
> > --- /dev/null
> > +++ b/mvtest
> > @@ -0,0 +1,58 @@
> > +#!/bin/sh
> > +
> > +# Renumber a test
> > +
> > +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> > +	echo "Usage: $0 path_to_test new_path_to_test"
> > +	exit 1
> > +fi
> > +
> > +src="$1"
> > +dest="$2"
> > +
> > +die() {
> > +	echo "$@"
> > +	exit 1
> > +}
> > +
> > +nsort() {
> > +	sort -g < "$1" > "$2"
> > +}
> > +
> > +append() {
> > +	out="$1"
> > +	shift
> > +	echo "$@" >> "${out}"
> > +}
> > +
> > +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest."
> > +test -e "tests/${src}" || die "Test \"${src}\" does not exist."
> > +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists."
> > +
> > +sid="$(basename "${src}")"
> > +did="$(basename "${dest}")"
> > +
> > +sgroup="$(basename "$(dirname "tests/${src}")")"
> > +dgroup="$(basename "$(dirname "tests/${dest}")")"
> > +
> > +sgroupfile="tests/${sgroup}/group"
> > +dgroupfile="tests/${sgroup}/group"
> > +
> > +$DBG git mv "tests/${src}" "tests/${dest}"
> 
> $DBG?

"DBG=echo ./mvtest foo bar" to see what it would have run, more or less.

(I suppose I could getopt a --dry-run, but I could also just get rid of them.)

> 
> ....
> > +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}"
> > +$DBG cp "${dgroupfile}" "${dgroupfile}.new"
> > +$DBG append "${dgroupfile}.new" "${newgrpline}"
> > +$DBG nsort "${dgroupfile}.new" "${dgroupfile}"
> 
> What does this do to comments in the group file?

Eats them.  I don't know of a good way to sort just the uncommented lines
in the file, short of writing a python script to do that.

I guess it's not that hard; I've sort of needed one here and there over
the years, but never wrote one, and $google doesn't immediately provide
any such thing.

> 
> ...
> 
> > diff --git a/nextid b/nextid
> > new file mode 100755
> > index 0000000..285b549
> > --- /dev/null
> > +++ b/nextid
> > @@ -0,0 +1,35 @@
> > +#!/bin/sh
> > +
> > +# Given a group name, find the next available test number.
> > +
> > +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> > +	echo "Usage: $0 groupname[/start_looking_at_this_number]"
> > +	exit 1
> > +fi
> > +
> > +die() {
> > +	echo "$@"
> > +	exit 1
> > +}
> > +
> > +if [ "$(basename "$1")" != "$1" ]; then
> > +	group="$(dirname "$1")"
> > +	id="$(basename "$1")"
> > +else
> > +	group="$1"
> > +	id=1
> > +fi
> > +test -e "tests/${group}/group" || die "Unknown group \"${group}\"."
> > +
> > +while test "${id}" -lt 1000; do
> > +	name="$(printf "%.03d" "${id}")"
> > +	if [ ! -e "tests/${group}/${name}" ]; then
> > +		echo "${group}/${name}"
> > +		exit 0
> > +	fi
> > +	id=$((id + 1))
> > +done
> > +
> > +echo "No free IDs less than ${id} in group \"${group}\"."
> 
> So the "new" script does this differently, by reading the group
> file and looking for the first non-contiguous ID in the file. It
> doesn't need scan ID limits because EOF triggers that. Wouldn't it
> be better to to factor the code out of the "new" script to find the
> next id, and then have the new script call that?

Sure!

--D

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 01/12] test-scripts: test migration scripts
  2015-11-16 23:51     ` Darrick J. Wong
@ 2015-11-17 21:16       ` Darrick J. Wong
  0 siblings, 0 replies; 17+ messages in thread
From: Darrick J. Wong @ 2015-11-17 21:16 UTC (permalink / raw)
  To: Dave Chinner
  Cc: fstests, xfs, hch, tao.peng, linux-ext4, Anna.Schumaker,
	linux-btrfs

On Mon, Nov 16, 2015 at 03:51:11PM -0800, Darrick J. Wong wrote:
> On Tue, Nov 17, 2015 at 07:58:45AM +1100, Dave Chinner wrote:
> > On Fri, Nov 13, 2015 at 01:36:50PM -0800, Darrick J. Wong wrote:
> > > Add two scripts: "nextid" finds the next available test ID number in a
> > > group, and "mvtest" relocates a test, fixes the golden output, and
> > > moves the group entry for that test.
> > > 
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > ---
> > >  mvtest |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  nextid |   35 +++++++++++++++++++++++++++++++++++
> > 
> > These should be placed in the "tools" directory.
> 
> <nod>
> 
> > 
> > >  create mode 100755 mvtest
> > >  create mode 100755 nextid
> > > 
> > > 
> > > diff --git a/mvtest b/mvtest
> > > new file mode 100755
> > > index 0000000..b5406d1
> > > --- /dev/null
> > > +++ b/mvtest
> > > @@ -0,0 +1,58 @@
> > > +#!/bin/sh
> > > +
> > > +# Renumber a test
> > > +
> > > +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> > > +	echo "Usage: $0 path_to_test new_path_to_test"
> > > +	exit 1
> > > +fi
> > > +
> > > +src="$1"
> > > +dest="$2"
> > > +
> > > +die() {
> > > +	echo "$@"
> > > +	exit 1
> > > +}
> > > +
> > > +nsort() {
> > > +	sort -g < "$1" > "$2"
> > > +}
> > > +
> > > +append() {
> > > +	out="$1"
> > > +	shift
> > > +	echo "$@" >> "${out}"
> > > +}
> > > +
> > > +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest."
> > > +test -e "tests/${src}" || die "Test \"${src}\" does not exist."
> > > +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists."
> > > +
> > > +sid="$(basename "${src}")"
> > > +did="$(basename "${dest}")"
> > > +
> > > +sgroup="$(basename "$(dirname "tests/${src}")")"
> > > +dgroup="$(basename "$(dirname "tests/${dest}")")"
> > > +
> > > +sgroupfile="tests/${sgroup}/group"
> > > +dgroupfile="tests/${sgroup}/group"
> > > +
> > > +$DBG git mv "tests/${src}" "tests/${dest}"
> > 
> > $DBG?
> 
> "DBG=echo ./mvtest foo bar" to see what it would have run, more or less.
> 
> (I suppose I could getopt a --dry-run, but I could also just get rid of them.)
> 
> > 
> > ....
> > > +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}"
> > > +$DBG cp "${dgroupfile}" "${dgroupfile}.new"
> > > +$DBG append "${dgroupfile}.new" "${newgrpline}"
> > > +$DBG nsort "${dgroupfile}.new" "${dgroupfile}"
> > 
> > What does this do to comments in the group file?
> 
> Eats them.  I don't know of a good way to sort just the uncommented lines
> in the file, short of writing a python script to do that.
> 
> I guess it's not that hard; I've sort of needed one here and there over
> the years, but never wrote one, and $google doesn't immediately provide
> any such thing.
> 
> > 
> > ...
> > 
> > > diff --git a/nextid b/nextid
> > > new file mode 100755
> > > index 0000000..285b549
> > > --- /dev/null
> > > +++ b/nextid
> > > @@ -0,0 +1,35 @@
> > > +#!/bin/sh
> > > +
> > > +# Given a group name, find the next available test number.
> > > +
> > > +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> > > +	echo "Usage: $0 groupname[/start_looking_at_this_number]"
> > > +	exit 1
> > > +fi
> > > +
> > > +die() {
> > > +	echo "$@"
> > > +	exit 1
> > > +}
> > > +
> > > +if [ "$(basename "$1")" != "$1" ]; then
> > > +	group="$(dirname "$1")"
> > > +	id="$(basename "$1")"
> > > +else
> > > +	group="$1"
> > > +	id=1
> > > +fi
> > > +test -e "tests/${group}/group" || die "Unknown group \"${group}\"."
> > > +
> > > +while test "${id}" -lt 1000; do
> > > +	name="$(printf "%.03d" "${id}")"
> > > +	if [ ! -e "tests/${group}/${name}" ]; then
> > > +		echo "${group}/${name}"
> > > +		exit 0
> > > +	fi
> > > +	id=$((id + 1))
> > > +done
> > > +
> > > +echo "No free IDs less than ${id} in group \"${group}\"."
> > 
> > So the "new" script does this differently, by reading the group
> > file and looking for the first non-contiguous ID in the file. It
> > doesn't need scan ID limits because EOF triggers that. Wouldn't it
> > be better to to factor the code out of the "new" script to find the
> > next id, and then have the new script call that?
> 
> Sure!

In the end I wrote a short Python program to sort group files and it wasn't
much harder to reuse the code to implement nextid, so I did that instead.

I'll probably post this and a patch to fix the error codes in generic/157
later this week.

--D

> 
> --D
> 
> > 
> > Cheers,
> > 
> > Dave.
> > -- 
> > Dave Chinner
> > david@fromorbit.com
> > 
> > _______________________________________________
> > xfs mailing list
> > xfs@oss.sgi.com
> > http://oss.sgi.com/mailman/listinfo/xfs
> --
> To unsubscribe from this list: send the line "unsubscribe fstests" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-11-17 21:16 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-13 21:36 [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Darrick J. Wong
2015-11-13 21:36 ` [PATCH 01/12] test-scripts: test migration scripts Darrick J. Wong
2015-11-16 20:58   ` Dave Chinner
2015-11-16 23:51     ` Darrick J. Wong
2015-11-17 21:16       ` Darrick J. Wong
2015-11-13 21:36 ` [PATCH 02/12] btrfs: move btrfs reflink tests to generic Darrick J. Wong
2015-11-13 21:37 ` [PATCH 03/12] reflink: add test support routines to a separate file Darrick J. Wong
2015-11-13 21:37 ` [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls Darrick J. Wong
2015-11-13 21:37 ` [PATCH 05/12] reflink: test CoW behaviors of reflinked files Darrick J. Wong
2015-11-13 21:37 ` [PATCH 06/12] reflink: test the various fallocate modes Darrick J. Wong
2015-11-13 21:37 ` [PATCH 07/12] reflink: test accuracy of free block counts Darrick J. Wong
2015-11-13 21:37 ` [PATCH 08/12] reflink: test error conditions due to bad inputs Darrick J. Wong
2015-11-13 21:37 ` [PATCH 09/12] xfs: test xfs-specific reflink pieces Darrick J. Wong
2015-11-13 21:37 ` [PATCH 10/12] reflink: concurrent operations tests Darrick J. Wong
2015-11-13 21:37 ` [PATCH 11/12] reflink: test that CoW writes fail when we're out of space Darrick J. Wong
2015-11-13 21:38 ` [PATCH 12/12] reflink: test what happens when we hit resource limits Darrick J. Wong
2015-11-14  8:41 ` [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).