4058262bdff8818f000a65292d454df11a39560a
[xfstests-dev.git] / tests / generic / 520
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2018 The University of Texas at Austin.  All Rights Reserved.
4 #
5 # FS QA Test 520
6 #
7 # Test case created by CrashMonkey
8 #
9 # Test if we create a hard link to a file and persist either of the files, all
10 # the names persist.
11 #
12 seq=`basename $0`
13 seqres=$RESULT_DIR/$seq
14 echo "QA output created by $seq"
15
16 here=`pwd`
17 tmp=/tmp/$$
18 status=1        # failure is the default!
19 trap "_cleanup; exit \$status" 0 1 2 3 15
20
21 _cleanup()
22 {
23         _cleanup_flakey
24         cd /
25         rm -f $tmp.*
26 }
27
28 # get standard environment, filters and checks
29 . ./common/rc
30 . ./common/filter
31 . ./common/dmflakey
32
33 # 256MB in byte
34 fssize=$((2**20 * 256))
35
36 # remove previous $seqres.full before test
37 rm -f $seqres.full
38
39 # real QA test starts here
40 _supported_fs generic
41 _supported_os Linux
42 _require_scratch_nocheck
43 _require_dm_target flakey
44
45 # initialize scratch device
46 _scratch_mkfs_sized $fssize >> $seqres.full 2>&1
47 _require_metadata_journaling $SCRATCH_DEV
48 _init_flakey
49
50 stat_opt='-c "blocks: %b size: %s inode: %i links: %h"'
51 before=""
52 after=""
53
54
55 # Using _scratch_mkfs instead of cleaning up the  working directory,
56 # adds about 10 seconds of delay in total for the 37 tests.
57 clean_dir()
58 {
59         _mount_flakey
60         rm -rf $SCRATCH_MNT/*
61         sync
62         _unmount_flakey
63 }
64
65 check_consistency()
66 {
67         _flakey_drop_and_remount
68
69         if [ -f $1 ]; then
70                 after=`stat "$stat_opt" $1`
71         fi
72
73         if [ "$before" != "$after" ] && [ $2 -ne 1 ]; then
74                 echo "Before: $before"
75                 echo "After: $after"
76         fi
77
78         _unmount_flakey
79         _check_scratch_fs $FLAKEY_DEV
80 }
81
82 # create a hard link $2 to file $1, and fsync $3, followed by power-cut
83 test_link_fsync()
84 {
85         local sibling=0
86         local src=$SCRATCH_MNT/$1
87         local dest=$SCRATCH_MNT/$2
88         before=""
89         after=""
90
91         if [ "$3" == "./" ]; then
92                 fsync=$SCRATCH_MNT
93         else
94                 fsync=$SCRATCH_MNT/$3
95         fi
96
97         echo -ne "\n=== link $src $dest  with fsync $fsync ===\n" | \
98                 _filter_scratch
99         _mount_flakey
100
101         # Now execute the workload
102         # Create the directory in which the source and destination files
103         # will be created
104         mkdir -p "${src%/*}"
105         mkdir -p "${dest%/*}"
106         touch $src
107         ln $src $dest
108
109         # If the file being persisted is a sibling, create it first
110         if [ ! -f $fsync ]; then
111                 sibling=1
112                 touch $fsync
113         fi
114
115         $XFS_IO_PROG -c "fsync" $fsync
116
117         if [ $sibling -ne 1 ]; then
118                 before=`stat "$stat_opt" $src`
119         fi
120
121         check_consistency $src $sibling
122         clean_dir
123 }
124
125 # create a hard link $2 to file $1, and sync, followed by power-cut
126 test_link_sync()
127 {
128         local src=$SCRATCH_MNT/$1
129         local dest=$SCRATCH_MNT/$2
130         before=""
131         after=""
132         echo -ne "\n=== link $src $dest  with sync ===\n" | _filter_scratch
133         _mount_flakey
134
135         # now execute the workload
136         # Create the directory in which the source and destination files
137         # will be created
138         mkdir -p "${src%/*}"
139         mkdir -p "${dest%/*}"
140         touch $src
141         ln $src $dest
142         sync
143         before=`stat "$stat_opt" $src`
144
145         check_consistency $src 0
146         clean_dir
147 }
148
149
150 # Create different combinations to run the link test
151 # Group 0: Both files within root directory
152 file_names[0]="foo bar"
153 fsync_names[0]="./ foo bar"
154
155 # Group 1: Create hard link in a sub directory
156 file_names[1]="foo A/bar"
157 fsync_names[1]="./ foo bar A A/bar A/foo"
158
159 # Group 2: Create hard link in parent directory
160 file_names[2]="A/foo bar"
161 fsync_names[2]="./ foo bar A A/bar A/foo"
162
163 # Group 3: Both files within a directory other than root
164 file_names[3]="A/foo A/bar"
165 fsync_names[3]="./ A A/bar A/foo"
166
167 #Group 4: Exercise name reuse : Link file in sub-directory
168 file_names[4]="bar A/bar"
169 fsync_names[4]="./ foo bar A A/bar A/foo"
170
171 #Group 5: Exercise name reuse : Link file in parent directory
172 file_names[5]="A/bar bar"
173 fsync_names[5]="./ foo bar A A/bar A/foo"
174
175 for ((test_group = 0; test_group < 6; test_group++)); do
176         for file in ${fsync_names[$test_group]}; do
177                 test_link_fsync ${file_names[$test_group]} $file
178         done
179         test_link_sync ${file_names[$test_group]}
180 done
181
182 # success, all done
183 status=0
184 exit