mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
0e6ead5591
The test currently verifies that cloning one file with an inline extent with a size of 10 bytes into a file with an inline extent that has a size of 20 bytes succeeds. But this results in data loss, because the btrfs clone operation drops the 20 bytes inline extent from the destination inode and then copies the 10 bytes inline extent from the source file into the destination file, resulting in data loss of the last 10 bytes of data that the destination file had. Fixing btrfs to correctly operate for this case (not resulting in data loss) is actually a lot of work and brings a lot of complexity, specially considering that any of the inline extents can be compressed. For the moment there's a fix to make the clone operation return the errno EOPNOTSUPP and not touch any of the inodes. This is the same approach we do for other cases involving operation against inline extents, so this just adds one more case that should have never been allowed. Cloning inline extents is a rare operation and pointless, since it involves copying them and not doing any actual deduplication or saving space. The btrfs patch for the linux kernel that prevents this data loss, and fixes some file corruption cases, is titled: "Btrfs: fix file corruption and data loss after cloning inline extents" Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
90 lines
2.7 KiB
Bash
Executable File
90 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# FS QA Test No. btrfs/035
|
|
#
|
|
# Regression test for overwriting clones
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
# Copyright (C) 2014 SUSE Linux Products GmbH. 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!
|
|
|
|
_cleanup()
|
|
{
|
|
rm -f $tmp.*
|
|
}
|
|
|
|
trap "_cleanup ; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
|
|
# real QA test starts here
|
|
_supported_fs btrfs
|
|
_supported_os Linux
|
|
_require_scratch
|
|
_require_cloner
|
|
|
|
_scratch_mkfs > /dev/null 2>&1
|
|
_scratch_mount
|
|
|
|
src_str="aaaaaaaaaa"
|
|
|
|
echo -n "$src_str" > $SCRATCH_MNT/src
|
|
|
|
$CLONER_PROG $SCRATCH_MNT/src $SCRATCH_MNT/src.clone1
|
|
|
|
src_str="bbbbbbbbbbcccccccccc"
|
|
|
|
echo -n "$src_str" > $SCRATCH_MNT/src
|
|
|
|
$CLONER_PROG $SCRATCH_MNT/src $SCRATCH_MNT/src.clone2
|
|
|
|
snap_src_sz=`ls -lah $SCRATCH_MNT/src.clone1 | awk '{print $5}'`
|
|
echo "attempting ioctl (src.clone1 src)"
|
|
$CLONER_PROG -s 0 -d 0 -l ${snap_src_sz} \
|
|
$SCRATCH_MNT/src.clone1 $SCRATCH_MNT/src
|
|
|
|
# The clone operation should have failed. If it did not it meant we had data
|
|
# loss, because file "src.clone1" has an inline extent which is 10 bytes long
|
|
# while file "src" has an inline extent which is 20 bytes long. The clone
|
|
# operation would remove the inline extent of "src" and then copy the inline
|
|
# extent from "src.clone1" into "src", which means we would lose the last 10
|
|
# bytes of data from "src" (on read we would get 0x00 as the value for any
|
|
# of those 10 bytes, because the file's size remains as 20 bytes).
|
|
echo "File src data after attempt to clone from src.clone1 into src:"
|
|
od -t x1 $SCRATCH_MNT/src
|
|
|
|
snap_src_sz=`ls -lah $SCRATCH_MNT/src.clone2 | awk '{print $5}'`
|
|
echo "attempting ioctl (src.clone2 src)"
|
|
$CLONER_PROG -s 0 -d 0 -l ${snap_src_sz} \
|
|
$SCRATCH_MNT/src.clone2 $SCRATCH_MNT/src
|
|
|
|
# The clone operation should have succeeded.
|
|
echo "File src data after attempt to clone from src.clone2 into src:"
|
|
od -t x1 $SCRATCH_MNT/src
|
|
|
|
status=0 ; exit
|