generic: test MADV_POPULATE_READ with IO errors
[xfstests-dev.git] / tests / generic / 409
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 409
6 #
7 # Test mount shared subtrees, verify the bind semantics:
8 #
9 # ---------------------------------------------------------------------------
10 # |         BIND MOUNT OPERATION                                            |
11 # |**************************************************************************
12 # |source(A)->| shared       |       private  |       slave    | unbindable |
13 # | dest(B)  |               |                |                |            |
14 # |   |      |               |                |                |            |
15 # |   v      |               |                |                |            |
16 # |**************************************************************************
17 # |  shared  | shared        |     shared     | shared & slave |  invalid   |
18 # |          |               |                |                |            |
19 # |non-shared| shared        |      private   |      slave     |  invalid   |
20 # ***************************************************************************
21 #
22 . ./common/preamble
23 _begin_fstest auto quick mount
24
25 # Override the default cleanup function.
26 _cleanup()
27 {
28         cd /
29         rm -f $tmp.*
30         _clear_mount_stack
31         # make sure there's no bug cause dentry isn't be freed
32         rm -rf $MNTHEAD
33 }
34
35 # Import common functions.
36 . ./common/filter
37
38 # real QA test starts here
39 _supported_fs generic
40 _require_test
41 _require_scratch
42 _require_local_device $SCRATCH_DEV
43
44 fs_stress()
45 {
46         local target=$1
47
48         $FSSTRESS_PROG -z -n 50 -p 3 \
49                        -f creat=5 \
50                        -f mkdir=5 \
51                        -f link=2 \
52                        -f rename=1 \
53                        -f rmdir=2 \
54                        -f unlink=1 \
55                        -f symlink=1 \
56                        -f write=1 \
57                        -f read=1 \
58                        -f chown=1 \
59                        -f getdents=1 \
60                        -f fiemap=1 \
61                        -d $target >/dev/null
62         sync
63 }
64
65 # prepare some mountpoint dir
66 MNTHEAD=$TEST_DIR/$seq
67 rm -rf $MNTHEAD
68 mkdir $MNTHEAD 2>>$seqres.full
69 mpA=$MNTHEAD/"$$"_mpA
70 mpB=$MNTHEAD/"$$"_mpB
71 mpC=$MNTHEAD/"$$"_mpC
72 mpD=$MNTHEAD/"$$"_mpD
73
74 find_mnt()
75 {
76         echo "------"
77         findmnt -n -o TARGET,SOURCE $SCRATCH_DEV | \
78                 sed -e "s;$mpA;mpA;g" \
79                     -e "s;$mpB;mpB;g" \
80                     -e "s;$mpC;mpC;g" \
81                     -e "s;$mpD;mpD;g" | \
82                 _filter_spaces | _filter_testdir_and_scratch | sort
83         echo "======"
84 }
85
86 start_test()
87 {
88         local type=$1
89
90         _scratch_mkfs >$seqres.full 2>&1
91         _get_mount -t $FSTYP $SCRATCH_DEV $MNTHEAD
92         $MOUNT_PROG --make-"${type}" $MNTHEAD
93         mkdir $mpA $mpB $mpC $mpD
94 }
95
96 end_test()
97 {
98         _clear_mount_stack
99         rm -rf $mpA $mpB $mpC $mpD
100 }
101
102 bind_run()
103 {
104         local source=$1
105         local dest=$2
106
107         start_test $dest
108
109         echo "bind $source on $dest"
110         _get_mount -t $FSTYP $SCRATCH_DEV $mpA
111         mkdir -p $mpA/dir 2>/dev/null
112         $MOUNT_PROG --make-shared $mpA
113         _get_mount --bind $mpA $mpB
114         $MOUNT_PROG --make-"$source" $mpB
115         # maybe unbindable at here
116         _get_mount --bind $mpB $mpC 2>/dev/null
117         if [ $? -ne 0 ]; then
118                 find_mnt
119                 end_test
120                 return 0
121         fi
122         _get_mount --bind $mpC $mpD
123         for m in $mpA $mpB $mpC $mpD; do
124                 _get_mount -t $FSTYP $SCRATCH_DEV $m/dir
125                 fs_stress $m/dir
126                 find_mnt
127                 _put_mount
128         done
129
130         end_test
131 }
132
133 bind_test()
134 {
135         #        source     dest
136         bind_run shared     shared
137         bind_run slave      shared
138         bind_run private    shared
139         bind_run unbindable shared
140
141         bind_run shared     slave
142         bind_run slave      slave
143         bind_run private    slave
144         bind_run unbindable slave
145
146         bind_run shared     private
147         bind_run slave      private
148         bind_run private    private
149         bind_run unbindable private
150 }
151
152 bind_test
153
154 # success, all done
155 status=0
156 exit