summaryrefslogtreecommitdiff
path: root/tests/generic/520
blob: ad6764c73407aad21721692ddd107082655271e0 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2018 The University of Texas at Austin.  All Rights Reserved.
#
# FS QA Test 520
#
# Test case created by CrashMonkey
#
# Test if we create a hard link to a file and persist either of the files, all
# the names persist.
#
. ./common/preamble
_begin_fstest auto quick log

# Override the default cleanup function.
_cleanup()
{
	_cleanup_flakey
	cd /
	rm -f $tmp.*
}

# Import common functions.
. ./common/filter
. ./common/dmflakey

# 256MB in byte
fssize=$((2**20 * 256))

# real QA test starts here
_supported_fs generic
_require_scratch_nocheck
_require_dm_target flakey

# initialize scratch device
_scratch_mkfs_sized $fssize >> $seqres.full 2>&1
_require_metadata_journaling $SCRATCH_DEV
_init_flakey

stat_opt='-c "blocks: %b size: %s inode: %i links: %h"'
before=""
after=""

# Using _scratch_mkfs instead of cleaning up the  working directory,
# adds about 10 seconds of delay in total for the 37 tests.
clean_dir()
{
	_mount_flakey
	rm -rf $(find $SCRATCH_MNT/* | grep -v "lost+found")
	_unmount_flakey
}

check_consistency()
{
	_flakey_drop_and_remount

	if [ -f $1 ]; then
		after=`stat "$stat_opt" $1`
	fi

	if [ "$before" != "$after" ] && [ $2 -ne 1 ]; then
		echo "Before: $before"
		echo "After: $after"
	fi

	_unmount_flakey
	_check_scratch_fs $FLAKEY_DEV
}

# create a hard link $2 to file $1, and fsync $3, followed by power-cut
test_link_fsync()
{
	local sibling=0
	local src=$SCRATCH_MNT/$1
	local dest=$SCRATCH_MNT/$2
	before=""
	after=""

	if [ "$3" == "./" ]; then
		fsync=$SCRATCH_MNT
	else
		fsync=$SCRATCH_MNT/$3
	fi

	echo -ne "\n=== link $src $dest  with fsync $fsync ===\n" | \
		_filter_scratch
	_mount_flakey

	# Now execute the workload
	# Create the directory in which the source and destination files
	# will be created
	mkdir -p "${src%/*}"
	mkdir -p "${dest%/*}"
	touch $src
	ln $src $dest

	# If the file being persisted is a sibling, create it first
	if [ ! -f $fsync ]; then
		sibling=1
		touch $fsync
	fi

	$XFS_IO_PROG -c "fsync" $fsync

	if [ $sibling -ne 1 ]; then
		before=`stat "$stat_opt" $src`
	fi

	check_consistency $src $sibling
	clean_dir
}

# create a hard link $2 to file $1, and sync, followed by power-cut
test_link_sync()
{
	local src=$SCRATCH_MNT/$1
	local dest=$SCRATCH_MNT/$2
	before=""
	after=""
	echo -ne "\n=== link $src $dest  with sync ===\n" | _filter_scratch
	_mount_flakey

	# now execute the workload
	# Create the directory in which the source and destination files
	# will be created
	mkdir -p "${src%/*}"
	mkdir -p "${dest%/*}"
	touch $src
	ln $src $dest
	sync
	before=`stat "$stat_opt" $src`

	check_consistency $src 0
	clean_dir
}

# Create different combinations to run the link test
# Group 0: Both files within root directory
file_names[0]="foo bar"
fsync_names[0]="./ foo bar"

# Group 1: Create hard link in a sub directory
file_names[1]="foo A/bar"
fsync_names[1]="./ foo bar A A/bar A/foo"

# Group 2: Create hard link in parent directory
file_names[2]="A/foo bar"
fsync_names[2]="./ foo bar A A/bar A/foo"

# Group 3: Both files within a directory other than root
file_names[3]="A/foo A/bar"
fsync_names[3]="./ A A/bar A/foo"

#Group 4: Exercise name reuse : Link file in sub-directory
file_names[4]="bar A/bar"
fsync_names[4]="./ foo bar A A/bar A/foo"

#Group 5: Exercise name reuse : Link file in parent directory
file_names[5]="A/bar bar"
fsync_names[5]="./ foo bar A A/bar A/foo"

for ((test_group = 0; test_group < 6; test_group++)); do
	for file in ${fsync_names[$test_group]}; do
		test_link_fsync ${file_names[$test_group]} $file
	done
	test_link_sync ${file_names[$test_group]}
done

# success, all done
status=0
exit