summaryrefslogtreecommitdiff
path: root/tests/btrfs/281
blob: 290ccaca623546a0d694c4871c54daf6f1158647 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2022 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test 281
#
# Test that if we have a snapshot with a compressed extent that is partially
# shared between two files, one of them has a size that is not sector size
# aligned, we create a v2 send stream for the snapshot with compressed data,
# and then apply that stream to another filesystem, the operation succeeds and
# no data is missing. Also check that the file that had a reference to the whole
# extent gets two compressed extents in the new filesystem, with only one of
# them being shared (reflinked).
#
. ./common/preamble
_begin_fstest auto quick send compress clone fiemap

. ./common/filter
. ./common/reflink
. ./common/punch # for _filter_fiemap_flags

_supported_fs btrfs
_require_test
_require_scratch_reflink
_require_btrfs_send_version 2
_require_xfs_io_command "fiemap"
_require_fssum
_require_btrfs_no_nodatacow

_fixed_by_kernel_commit a11452a3709e \
	"btrfs: send: avoid unaligned encoded writes when attempting to clone range"

send_files_dir=$TEST_DIR/btrfs-test-$seq
send_stream=$send_files_dir/snap.stream
snap_fssum=$send_files_dir/snap.fssum

rm -fr $send_files_dir
mkdir $send_files_dir

_scratch_mkfs >> $seqres.full 2>&1
_scratch_mount -o compress

# File foo has a size of 65K, which is not sector size aligned for any
# supported sector size on btrfs.
$XFS_IO_PROG -f -c "pwrite -S 0xab 0 65K" $SCRATCH_MNT/foo | _filter_xfs_io

# File bar has a compressed extent (and its size is sector size aligned).
$XFS_IO_PROG -f -c "pwrite -S 0xcd 0 128K" $SCRATCH_MNT/bar | _filter_xfs_io

# Now clone only half of bar's extent into foo.
$XFS_IO_PROG -c "reflink $SCRATCH_MNT/bar 0 0 64K" $SCRATCH_MNT/foo \
	| _filter_xfs_io

echo "Creating snapshot and a send stream for it..."
_btrfs subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/snap
$BTRFS_UTIL_PROG send --compressed-data -f $send_stream $SCRATCH_MNT/snap 2>&1 \
	| _filter_scratch

$FSSUM_PROG -A -f -w $snap_fssum $SCRATCH_MNT/snap

echo "Creating a new filesystem to receive the send stream..."
_scratch_unmount
_scratch_mkfs >> $seqres.full 2>&1
# Mount without compression, we created the stream with data compression enabled
# so we want to verify that applying the stream preserves the compression.
_scratch_mount

$BTRFS_UTIL_PROG receive -f $send_stream $SCRATCH_MNT

echo "Verifying data matches the original filesystem..."
$FSSUM_PROG -r $snap_fssum $SCRATCH_MNT/snap

# Now check that fiemap reports two extents for file bar:
#
# 1) The first extent should be encoded, because compression was enabled in the
#    original filesystem, and should also be flagged as shared, since that file
#    range was reflinked with file foo in the original filesystem;
#
# 2) The second extent should also be encoded (compression was enabled in the
#    original filesystem), but not shared since that file range was not
#    reflinked in the original filesystem. It should also have the "last" flag
#    set, as it's the last extent in the file.
#
echo "File bar fiemap output in the new filesystem:"
$XFS_IO_PROG -r -c "fiemap -v" $SCRATCH_MNT/snap/bar | _filter_fiemap_flags 1

# success, all done
status=0
exit