blob: e732101195fb9145f3b7216095cbe3e182e45752 (
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test No. btrfs/222
#
# Test an incremental send operation after doing a series of changes in a tree
# such that one inode gets two hardlinks with names and locations swapped with
# two other inodes that correspond to different directories, and one of these
# directories is the parent of the other directory.
#
. ./common/preamble
_begin_fstest auto quick send
# Override the default cleanup function.
_cleanup()
{
cd /
rm -fr $send_files_dir
rm -f $tmp.*
}
. ./common/filter
_supported_fs btrfs
_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
touch $SCRATCH_MNT/f1
touch $SCRATCH_MNT/f2
mkdir $SCRATCH_MNT/d1
mkdir $SCRATCH_MNT/d1/d2
# Filesystem looks like:
#
# . (ino 256)
# |----- f1 (ino 257)
# |----- f2 (ino 258)
# |----- d1/ (ino 259)
# |----- d2/ (ino 260)
#
$BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT \
$SCRATCH_MNT/mysnap1 > /dev/null
$BTRFS_UTIL_PROG send -f $send_files_dir/1.snap \
$SCRATCH_MNT/mysnap1 2>&1 1>/dev/null | _filter_scratch
# Now do a series of changes such that:
#
# *) inode 258 has one new hardlink and the previous name changed
#
# *) both names conflict with the old names of two other inodes:
#
# 1) the new name "d1" conflicts with the old name of inode 259, under
# directory inode 256 (root)
#
# 2) the new name "d2" conflicts with the old name of inode 260 under
# directory inode 259
#
# *) inodes 259 and 260 now have the old names of inode 258
#
# *) inode 257 is now located under inode 260 - an inode with a number
# smaller than the inode (258) for which we created a second hard link
# and swapped its names with inodes 259 and 260
#
ln $SCRATCH_MNT/f2 $SCRATCH_MNT/d1/f2_link
mv $SCRATCH_MNT/f1 $SCRATCH_MNT/d1/d2/f1
# Swap d1 and f2.
mv $SCRATCH_MNT/d1 $SCRATCH_MNT/tmp
mv $SCRATCH_MNT/f2 $SCRATCH_MNT/d1
mv $SCRATCH_MNT/tmp $SCRATCH_MNT/f2
# Swap d2 and f2_link
mv $SCRATCH_MNT/f2/d2 $SCRATCH_MNT/tmp
mv $SCRATCH_MNT/f2/f2_link $SCRATCH_MNT/f2/d2
mv $SCRATCH_MNT/tmp $SCRATCH_MNT/f2/f2_link
# Filesystem now looks like:
#
# . (ino 256)
# |----- d1 (ino 258)
# |----- f2/ (ino 259)
# |----- f2_link/ (ino 260)
# | |----- f1 (ino 257)
# |
# |----- d2 (ino 258)
#
$BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT \
$SCRATCH_MNT/mysnap2 > /dev/null
$BTRFS_UTIL_PROG send -p $SCRATCH_MNT/mysnap1 -f $send_files_dir/2.snap \
$SCRATCH_MNT/mysnap2 2>&1 1>/dev/null | _filter_scratch
$FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
$FSSUM_PROG -A -f -w $send_files_dir/2.fssum \
-x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2
# Now 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
$BTRFS_UTIL_PROG receive -f $send_files_dir/1.snap $SCRATCH_MNT > /dev/null
# The receive operation below used to fail with the following error:
#
# ERROR: rename d1/d2 -> o260-6-0 failed: No such file or directory
#
# Because when processing inode 258, the kernel orphanized first inode 259,
# renaming it from "d1" to "o259-6-0", since it the new reference named "d1"
# for inode 258 conflicts with the old one of inode 259, which was not yet
# processed. After that, because the new reference named "d2" for inode 258
# conflicts with the old reference of the not yet processed inode 260, it
# tried to orphanize inode 260 - however the corresponding rename operation
# used a source path of "d1/d2", instead of "o259-6-0/d2".
#
$BTRFS_UTIL_PROG receive -f $send_files_dir/2.snap $SCRATCH_MNT > /dev/null
$FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1
$FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2
status=0
exit
|