summaryrefslogtreecommitdiff
path: root/tests/btrfs/272
blob: 4f799367c34e267c4535af734a8973d9d34db95e (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
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022 BingJing Chang.
#
# FS QA Test No. btrfs/272
#
# Regression test for btrfs incremental send issue where a link instruction
# is sent against an existing path, causing btrfs receive to fail.
#
# This issue is fixed by the following linux kernel btrfs patch:
#
#   commit 3aa5bd367fa5a3 ("btrfs: send: fix sending link commands for
#   existing file paths")
#
. ./common/preamble
_begin_fstest auto quick send

_supported_fs btrfs
_fixed_by_kernel_commit 3aa5bd367fa5a3 \
	"btrfs: send: fix sending link commands for existing file paths"
_require_test
_require_scratch
_require_fssum

send_files_dir=$TEST_DIR/btrfs-test-$seq

rm -fr $send_files_dir
mkdir $send_files_dir

_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount

# Create a file and 2000 hard links to the same inode
_btrfs subvolume create $SCRATCH_MNT/vol
touch $SCRATCH_MNT/vol/foo
for i in {1..2000}; do
	link $SCRATCH_MNT/vol/foo $SCRATCH_MNT/vol/$i
done

# Create a snapshot for a full send operation
_btrfs subvolume snapshot -r $SCRATCH_MNT/vol $SCRATCH_MNT/snap1
_btrfs send -f $send_files_dir/1.snap $SCRATCH_MNT/snap1

# Remove 2000 hard links and re-create the last 1000 links
for i in {1..2000}; do
	rm $SCRATCH_MNT/vol/$i
done
for i in {1001..2000}; do
	link $SCRATCH_MNT/vol/foo $SCRATCH_MNT/vol/$i
done

# Create another snapshot for an incremental send operation
_btrfs subvolume snapshot -r $SCRATCH_MNT/vol $SCRATCH_MNT/snap2
_btrfs send -p $SCRATCH_MNT/snap1 -f $send_files_dir/2.snap \
		     $SCRATCH_MNT/snap2

$FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/snap1
$FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
	-x $SCRATCH_MNT/snap2/snap1 $SCRATCH_MNT/snap2

# Recreate the filesystem by receiving both send streams and verify we get
# the same content that the original filesystem had.
_scratch_unmount
_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount

# Add the first snapshot to the new filesystem by applying the first send
# stream.
_btrfs receive -f $send_files_dir/1.snap $SCRATCH_MNT

# The incremental receive operation below used to fail with the following
# error:
#
#    ERROR: link 1238 -> foo failed: File exists
#
# This is because the path "1238" was stored as an extended ref item in the
# original snapshot but as a normal ref item in the next snapshot. The send
# operation cannot handle the duplicated paths, which are stored in
# different ways, well, so it decides to issue a link operation for the
# existing path. This results in the receiver to fail with the above error.
_btrfs receive -f $send_files_dir/2.snap $SCRATCH_MNT

$FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/snap1
$FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/snap2

status=0
exit