generic: test for file fsync after moving it to a new parent directory
[xfstests-dev.git] / tests / generic / 410
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2016 Red Hat Inc.  All Rights Reserved.
4 #
5 # FS QA Test 410
6 #
7 # Test mount shared subtrees, verify the state transition when use:
8 #   --make-shared
9 #   --make-slave
10 #   --make-private
11 #   --make-unbindable
12 #
13 # ------------------------------------------------------------------------
14 # |             |make-shared |  make-slave  | make-private |make-unbindab|
15 # --------------|------------|--------------|--------------|-------------|
16 # |shared       |shared      |*slave/private|   private    | unbindable  |
17 # |             |            |              |              |             |
18 # |-------------|------------|--------------|--------------|-------------|
19 # |slave        |shared      |    **slave   |    private   | unbindable  |
20 # |             |and slave   |              |              |             |
21 # |-------------|------------|--------------|--------------|-------------|
22 # |shared       |shared      |    slave     |    private   | unbindable  |
23 # |and slave    |and slave   |              |              |             |
24 # |-------------|------------|--------------|--------------|-------------|
25 # |private      |shared      |  **private   |    private   | unbindable  |
26 # |-------------|------------|--------------|--------------|-------------|
27 # |unbindable   |shared      |**unbindable  |    private   | unbindable  |
28 # ------------------------------------------------------------------------
29 #
30 seq=`basename $0`
31 seqres=$RESULT_DIR/$seq
32 echo "QA output created by $seq"
33
34 here=`pwd`
35 tmp=/tmp/$$
36 status=1        # failure is the default!
37 trap "_cleanup; exit \$status" 0 1 2 3 15
38
39 _cleanup()
40 {
41         cd /
42         rm -f $tmp.*
43         _clear_mount_stack
44         # make sure there's no bug cause dentry isn't be freed
45         rm -rf $MNTHEAD
46 }
47
48 # get standard environment, filters and checks
49 . ./common/rc
50 . ./common/filter
51
52 # remove previous $seqres.full before test
53 rm -f $seqres.full
54
55 # real QA test starts here
56 _supported_fs generic
57 _supported_os Linux
58 _require_test
59 _require_scratch
60 _require_local_device $SCRATCH_DEV
61
62 fs_stress()
63 {
64         local target=$1
65
66         $FSSTRESS_PROG -z -n 50 -p 3 \
67                        -f creat=5 \
68                        -f mkdir=5 \
69                        -f link=2 \
70                        -f rename=1 \
71                        -f rmdir=2 \
72                        -f unlink=1 \
73                        -f symlink=1 \
74                        -f write=1 \
75                        -f read=1 \
76                        -f chown=1 \
77                        -f getdents=1 \
78                        -f fiemap=1 \
79                        -d $target >/dev/null
80         sync
81 }
82
83 # prepare some mountpoint dir
84 MNTHEAD=$TEST_DIR/$seq
85 rm -rf $MNTHEAD
86 mkdir $MNTHEAD 2>>$seqres.full
87 mpA=$MNTHEAD/"$$"_mpA
88 mpB=$MNTHEAD/"$$"_mpB
89 mpC=$MNTHEAD/"$$"_mpC
90
91 find_mnt()
92 {
93         echo "------"
94         findmnt -n -o TARGET,SOURCE $SCRATCH_DEV | \
95                 sed -e "s;$mpA;mpA;g" \
96                     -e "s;$mpB;mpB;g" \
97                     -e "s;$mpC;mpC;g" | \
98                 _filter_spaces | _filter_testdir_and_scratch | sort
99         echo "======"
100 }
101
102 start_test()
103 {
104         local type=$1
105
106         _scratch_mkfs >$seqres.full 2>&1
107         _get_mount -t $FSTYP $SCRATCH_DEV $MNTHEAD
108         $MOUNT_PROG --make-"${type}" $MNTHEAD
109         mkdir $mpA $mpB $mpC
110 }
111
112 end_test()
113 {
114         _clear_mount_stack
115         rm -rf $mpA $mpB $mpC
116 }
117
118 run()
119 {
120         # command include make-shared/slave/private/unbindable
121         local cmd=$1
122         # orginal status include shared/slave/shared&slave/private/unbindable
123         local orgs="$2"
124
125         # bind anything on un-shared dest will keep the source type
126         # So use un-shared dest at here
127         start_test private
128
129         echo "make-$cmd a $orgs mount"
130         _get_mount -t $FSTYP $SCRATCH_DEV $mpA
131         mkdir -p $mpA/dir 2>/dev/null
132         $MOUNT_PROG --make-shared $mpA
133
134         # prepare the original status on mpB
135         _get_mount --bind $mpA $mpB
136         # shared&slave status need to do make-slave then make-shared
137         # two operations.
138         for t in $orgs; do
139                 $MOUNT_PROG --make-"$t" $mpB
140         done
141
142         # "before" for prepare and check original status
143         # "after" for check the impact of make-$cmd command
144         for i in before after; do
145                 echo "$i make-$cmd run on $orgs"
146                 # maybe unbindable at here
147                 _get_mount --bind $mpB $mpC 2>/dev/null
148                 if [ $? -ne 0 ];then
149                         find_mnt
150                 else
151                         for m in $mpA $mpB $mpC; do
152                                 _get_mount -t $FSTYP $SCRATCH_DEV $m/dir
153                                 fs_stress $m/dir
154                                 find_mnt
155                                 _put_mount
156                         done
157                         _put_mount # umount C
158                 fi
159                 if [ "$i" = "before" ];then
160                         $MOUNT_PROG --make-"${cmd}" $mpB
161                 fi
162         done
163
164         end_test
165 }
166
167 do_test()
168 {
169     #   operation  original_status
170     run shared     shared
171     run shared     slave
172     run shared     "slave shared"
173     run shared     private
174     run shared     unbindable
175
176     run slave      shared
177     run slave      slave
178     run slave      "slave shared"
179     run slave      private
180     run slave      unbindable
181
182     run private    shared
183     run private    slave
184     run private    "slave shared"
185     run private    private
186     run private    unbindable
187
188     run unbindable shared
189     run unbindable slave
190     run unbindable "slave shared"
191     run unbindable private
192     run unbindable unbindable
193 }
194
195 do_test
196
197 # success, all done
198 status=0
199 exit