generic: hole punching followed by writes in the same range
[xfstests-dev.git] / common / renameat2
1 ######
2 #
3 # renameat2 helpers
4 #
5 #-----------------------------------------------------------------------
6 # Copyright (c) 2014 Miklos Szeredi.  All Rights Reserved.
7 #
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation.
11 #
12 # This program is distributed in the hope that it would be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write the Free Software Foundation,
19 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 #-----------------------------------------------------------------------
21 #
22
23 #
24 # Setup source or dest
25 #
26 _setup_one()
27 {
28         local path=$1
29         local type=$2
30
31         case $type in
32                 none)   ;;
33                 regu)   echo foo > $path;;
34                 symb)   ln -s foo $path;;
35                 dire)   mkdir $path;;
36                 tree)   mkdir $path; echo foo > $path/bar;;
37         esac
38 }
39
40 #
41 # Cleanup source or dest
42 #
43 _cleanup_one()
44 {
45         local path=$1
46
47         if test -d $path; then
48                 rm -f $path/bar
49                 rmdir $path
50         else
51                 rm -f $path
52         fi
53 }
54
55 #
56 # Check type of source or destination
57 #
58 _showtype_one()
59 {
60         local path=$1
61
62         if test -e $path -o -h $path; then
63                 if test -d $path -a -e $path/bar; then
64                         echo -n "tree"
65                 else
66                         echo -n `stat -c %F $path | cut -b-4`
67                 fi
68         else
69                 echo -n "none"
70         fi
71 }
72
73 #
74 # This runs renameat2 on all combinations of source and dest
75 #
76 _rename_tests_source_dest()
77 {
78         local source=$1
79         local dest=$2
80         local options=$3
81
82         for stype in none regu symb dire tree; do
83                 for dtype in none regu symb dire tree; do
84                         echo -n "$options $stype/$dtype -> "
85                         _setup_one $source $stype
86                         _setup_one $dest $dtype
87                         src/renameat2 $source $dest $flags
88                         if test $? == 0; then
89                                 _showtype_one $source
90                                 echo -n "/"
91                                 _showtype_one $dest
92                                 echo "."
93                         fi
94                         _cleanup_one $source
95                         _cleanup_one $dest
96                 done
97         done
98 }
99
100 #
101 # This runs _rename_tests_source_dest() for both same-directory and
102 # cross-directory renames
103 #
104 _rename_tests()
105 {
106         local testdir=$1
107         local flags=$2
108
109         #same directory renames
110         _rename_tests_source_dest $testdir/src $testdir/dst     "samedir "
111
112         #cross directory renames
113         mkdir $testdir/x $testdir/y
114         _rename_tests_source_dest $testdir/x/src $testdir/y/dst "crossdir"
115         rmdir $testdir/x $testdir/y
116 }
117
118 #
119 # This checks whether the renameat2 syscall is supported
120 #
121 _requires_renameat2()
122 {
123         if test ! -x src/renameat2; then
124                 _notrun "renameat2 binary not found"
125         fi
126         if ! src/renameat2 -t; then
127                 _notrun "kernel doesn't support renameat2 syscall"
128         fi
129 }