generic: test for non-zero used blocks while writing into a file
[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 _require_test
58 _require_scratch
59 _require_local_device $SCRATCH_DEV
60
61 fs_stress()
62 {
63         local target=$1
64
65         $FSSTRESS_PROG -z -n 50 -p 3 \
66                        -f creat=5 \
67                        -f mkdir=5 \
68                        -f link=2 \
69                        -f rename=1 \
70                        -f rmdir=2 \
71                        -f unlink=1 \
72                        -f symlink=1 \
73                        -f write=1 \
74                        -f read=1 \
75                        -f chown=1 \
76                        -f getdents=1 \
77                        -f fiemap=1 \
78                        -d $target >/dev/null
79         sync
80 }
81
82 # prepare some mountpoint dir
83 MNTHEAD=$TEST_DIR/$seq
84 rm -rf $MNTHEAD
85 mkdir $MNTHEAD 2>>$seqres.full
86 mpA=$MNTHEAD/"$$"_mpA
87 mpB=$MNTHEAD/"$$"_mpB
88 mpC=$MNTHEAD/"$$"_mpC
89
90 find_mnt()
91 {
92         echo "------"
93         findmnt -n -o TARGET,SOURCE $SCRATCH_DEV | \
94                 sed -e "s;$mpA;mpA;g" \
95                     -e "s;$mpB;mpB;g" \
96                     -e "s;$mpC;mpC;g" | \
97                 _filter_spaces | _filter_testdir_and_scratch | sort
98         echo "======"
99 }
100
101 start_test()
102 {
103         local type=$1
104
105         _scratch_mkfs >$seqres.full 2>&1
106         _get_mount -t $FSTYP $SCRATCH_DEV $MNTHEAD
107         $MOUNT_PROG --make-"${type}" $MNTHEAD
108         mkdir $mpA $mpB $mpC
109 }
110
111 end_test()
112 {
113         _clear_mount_stack
114         rm -rf $mpA $mpB $mpC
115 }
116
117 run()
118 {
119         # command include make-shared/slave/private/unbindable
120         local cmd=$1
121         # orginal status include shared/slave/shared&slave/private/unbindable
122         local orgs="$2"
123
124         # bind anything on un-shared dest will keep the source type
125         # So use un-shared dest at here
126         start_test private
127
128         echo "make-$cmd a $orgs mount"
129         _get_mount -t $FSTYP $SCRATCH_DEV $mpA
130         mkdir -p $mpA/dir 2>/dev/null
131         $MOUNT_PROG --make-shared $mpA
132
133         # prepare the original status on mpB
134         _get_mount --bind $mpA $mpB
135         # shared&slave status need to do make-slave then make-shared
136         # two operations.
137         for t in $orgs; do
138                 $MOUNT_PROG --make-"$t" $mpB
139         done
140
141         # "before" for prepare and check original status
142         # "after" for check the impact of make-$cmd command
143         for i in before after; do
144                 echo "$i make-$cmd run on $orgs"
145                 # maybe unbindable at here
146                 _get_mount --bind $mpB $mpC 2>/dev/null
147                 if [ $? -ne 0 ];then
148                         find_mnt
149                 else
150                         for m in $mpA $mpB $mpC; do
151                                 _get_mount -t $FSTYP $SCRATCH_DEV $m/dir
152                                 fs_stress $m/dir
153                                 find_mnt
154                                 _put_mount
155                         done
156                         _put_mount # umount C
157                 fi
158                 if [ "$i" = "before" ];then
159                         $MOUNT_PROG --make-"${cmd}" $mpB
160                 fi
161         done
162
163         end_test
164 }
165
166 do_test()
167 {
168     #   operation  original_status
169     run shared     shared
170     run shared     slave
171     run shared     "slave shared"
172     run shared     private
173     run shared     unbindable
174
175     run slave      shared
176     run slave      slave
177     run slave      "slave shared"
178     run slave      private
179     run slave      unbindable
180
181     run private    shared
182     run private    slave
183     run private    "slave shared"
184     run private    private
185     run private    unbindable
186
187     run unbindable shared
188     run unbindable slave
189     run unbindable "slave shared"
190     run unbindable private
191     run unbindable unbindable
192 }
193
194 do_test
195
196 # success, all done
197 status=0
198 exit