2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2018 Red Hat Inc. All Rights Reserved.
7 # Test OFD lock. fcntl F_OFD_SETLK to set lock, then F_OFD_GETLK
8 # to verify we are being given correct advice by kernel.
10 # OFD lock combines POSIX lock and BSD flock:
11 # + does not share between threads
13 # (both tested by LTP/fcntl3{4,6})
14 # + only release automatically after all open fd closed
16 # This test target the third one and expand a little bit.
18 # The basic idea is one setlk routine setting locks via fcntl
19 # *_SETLK, followed by operations like clone, dup then close fd;
20 # another routine getlk getting locks via fcntl *_GETLK.
22 # Firstly in setlk routine process P0, place a lock L0 on an
23 # opened testfile, then
25 # + clone() a child P1 to close the fd then tell getlk to go,
26 # parent P0 wait getlk done then close fd.
28 # + dup() fd to a newfd then close newfd then tell getlk to go,
29 # then wait getlk done then close fd.
31 # In getlk process P2, do fcntl *_GETLK with lock L1 after get
32 # notified by setlk routine.
34 # In the end, getlk routine check the returned struct flock.l_type
35 # to see if the lock mechanism works fine.
37 # When testing with clone,
38 # + CLONE_FILES set, close releases all locks;
39 # + CLONE_FILES not set, locks remain in P0;
41 # If L0 is a POSIX lock,
42 # + it is not inherited into P1
43 # + it is released after dup & close
45 # If L0 is a OFD lock,
46 # + it is inherited into P1
47 # + it is not released after dup & close
49 # setlk routine: * getlk routine:
52 # open file * open file
56 # wait init sem done * wait init sem done
60 # |---------clone()--------| * |
62 # |(child P1) (parent P0)| * | (P2)
66 # | set sem0=0 * wait sem0==0
70 # wait sem1==0 | * set sem1=0
78 # We can test combainations of:
79 # + shared or exclusive lock
80 # + these locks are conflicting or not
81 # + one OFD lock and one POSIX lock
82 # + that open testfile RDONLY or RDWR
83 # + clone with CLONE_FILES or not
84 # + dup and close newfd
87 _begin_fstest auto quick
89 # Import common functions.
92 # Modify as appropriate.
97 # real QA test starts here
98 # prepare a 4k testfile in TEST_DIR
99 $XFS_IO_PROG -f -c "pwrite -S 0xFF 0 4096" \
100 $TEST_DIR/testfile >> $seqres.full 2>&1
106 # print options and getlk output for debug
107 echo $* >> $seqres.full 2>&1
109 $here/src/t_ofd_locks $soptions $TEST_DIR/testfile &
111 $here/src/t_ofd_locks $goptions $TEST_DIR/testfile | \
115 # add -F to clone with CLONE_FILES
117 # with -F, new locks are always file to place
118 $here/src/t_ofd_locks $soptions $TEST_DIR/testfile &
119 $here/src/t_ofd_locks $goptions $TEST_DIR/testfile | \
123 # add -d to dup and close
125 $here/src/t_ofd_locks $soptions $TEST_DIR/testfile &
126 $here/src/t_ofd_locks $goptions $TEST_DIR/testfile | \
131 # Always setlk at range [0,9], getlk at range [0,9] [5,24] or [20,29].
132 # To open file RDONLY or RDWR should not break the locks.
133 # POSIX locks should be released after closed fd, so it wont conflict
134 # with other locks in tests
136 # -P : operate posix lock
137 # -w : operate on F_WRLCK
138 # -r : operate on F_RDLCK
139 # -R : open file RDONLY
140 # -W : open file RDWR
141 # -o : file offset where the lock starts
143 # -F : clone with CLONE_FILES in setlk
144 # -d : dup and close in setlk
146 # setlk wrlck [0,9], getlk wrlck [0,9], expect
147 # + wrlck when CLONE_FILES not set
148 # + unlck when CLONE_FILES set
149 # + wrlck when dup & close
150 do_test "-s -w -o 0 -l 10 -W" "-g -w -o 0 -l 10 -W" "wrlck" "unlck" "wrlck"
151 # setlk wrlck [0,9], getlk posix wrlck [5,24]
152 do_test "-s -w -o 0 -l 10 -W" "-g -w -o 5 -l 20 -W -P" "wrlck" "unlck" "wrlck"
153 # setlk wrlck [0,9], getlk wrlck [20,29]
154 do_test "-s -w -o 0 -l 10 -W" "-g -w -o 20 -l 10 -W" "unlck" "unlck" "unlck"
155 # setlk posix wrlck [0,9], getlk wrlck [5,24]
156 do_test "-s -w -o 0 -l 10 -W -P" "-g -w -o 5 -l 20 -W" "wrlck" "unlck" "unlck"
157 # setlk posix wrlck [0,9], getlk wrlck [20,29]
158 do_test "-s -w -o 0 -l 10 -W -P" "-g -w -o 20 -l 10 -W" "unlck" "unlck" "unlck"
160 # setlk wrlck [0,9], getlk rdlck [0,9]
161 do_test "-s -w -o 0 -l 10 -W" "-g -r -o 0 -l 10 -W" "wrlck" "unlck" "wrlck"
162 # setlk wrlck [0,9], getlk posix rdlck [5,24]
163 do_test "-s -w -o 0 -l 10" "-g -r -o 5 -l 20 -P" "wrlck" "unlck" "wrlck"
164 # setlk wrlck [0,9], getlk rdlck [20,29]
165 do_test "-s -w -o 0 -l 10" "-g -r -o 20 -l 10" "unlck" "unlck" "unlck"
166 # setlk posix wrlck [0,9], getlk rdlck [5,24]
167 do_test "-s -w -o 0 -l 10 -P" "-g -r -o 5 -l 20" "wrlck" "unlck" "unlck"
168 # setlk posix wrlck [0,9], getlk rdlck [20,29]
169 do_test "-s -w -o 0 -l 10 -P" "-g -r -o 20 -l 10" "unlck" "unlck" "unlck"
171 # setlk rdlck [0,9], getlk wrlck [0,9], open RDONLY
172 do_test "-s -r -o 0 -l 10 -R" "-g -w -o 0 -l 10 -R" "rdlck" "unlck" "rdlck"
173 # setlk rdlck [0,9], getlk wrlck [5,24], open RDONLY
174 do_test "-s -r -o 0 -l 10 -R" "-g -w -o 5 -l 20 -R -P" "rdlck" "unlck" "rdlck"
175 # setlk posix rdlck [0,9], getlk wrlck [5,24], open RDONLY
176 do_test "-s -r -o 0 -l 10 -R -P" "-g -w -o 5 -l 20 -R" "rdlck" "unlck" "unlck"
178 # setlk rdlck [0,9], getlk wrlck [0,9]
179 do_test "-s -r -o 0 -l 10" "-g -w -o 0 -l 10" "rdlck" "unlck" "rdlck"
180 # setlk rdlck [0,9], getlk posix wrlck [5,24]
181 do_test "-s -r -o 0 -l 10" "-g -w -o 5 -l 20 -P" "rdlck" "unlck" "rdlck"
182 # setlk posix rdlck [0,9], getlk wrlck [5,24]
183 do_test "-s -r -o 0 -l 10 -P" "-g -w -o 5 -l 20" "rdlck" "unlck" "unlck"
185 # setlk rdlck [0,9], getlk wrlck [20,29], open RDONLY
186 do_test "-s -r -o 0 -l 10 -R" "-g -w -o 20 -l 10 -R" "unlck" "unlck" "unlck"
187 # setlk posix rdlck [0,9], getlk wrlck [20,29], open RDONLY
188 do_test "-s -r -o 0 -l 10 -R -P" "-g -w -o 20 -l 10 -R" "unlck" "unlck" "unlck"
189 # setlk rdlck [0,9], getlk wrlck [20,29]
190 do_test "-s -r -o 0 -l 10" "-g -w -o 20 -l 10" "unlck" "unlck" "unlck"
191 # setlk posix rdlck [0,9], getlk wrlck [20,29]
192 do_test "-s -r -o 0 -l 10 -P" "-g -w -o 20 -l 10" "unlck" "unlck" "unlck"
194 # setlk rdlck [0,9], getlk rdlck [0,9], open RDONLY
195 do_test "-s -r -o 0 -l 10 -R" "-g -r -o 0 -l 10 -R" "unlck" "unlck" "unlck"
196 # setlk rdlck [0,9], getlk posix rdlck [0,9], open RDONLY
197 do_test "-s -r -o 0 -l 10 -R" "-g -r -o 0 -l 10 -R -P" "unlck" "unlck" "unlck"
198 # setlk posix rdlck [0,9], getlk rdlck [0,9], open RDONLY
199 do_test "-s -r -o 0 -l 10 -R -P" "-g -r -o 0 -l 10 -R" "unlck" "unlck" "unlck"
200 # setlk rdlck [0,9], getlk rdlck [0,9]
201 do_test "-s -r -o 0 -l 10" "-g -r -o 0 -l 10" "unlck" "unlck" "unlck"
202 # setlk posix rdlck [0,9], getlk rdlck [0,9]
203 do_test "-s -r -o 0 -l 10 -P" "-g -r -o 0 -l 10" "unlck" "unlck" "unlck"
205 # setlk rdlck [0,9], getlk rdlck [20,29], open RDONLY
206 do_test "-s -r -o 0 -l 10 -R" "-g -r -o 20 -l 10 -R" "unlck" "unlck" "unlck"
207 # setlk rdlck [0,9], getlk posix rdlck [20,29], open RDONLY
208 do_test "-s -r -o 0 -l 10 -R" "-g -r -o 20 -l 10 -R -P" "unlck" "unlck" "unlck"
209 # setlk posix rdlck [0,9], getlk rdlck [20,29], open RDONLY
210 do_test "-s -r -o 0 -l 10 -R -P" "-g -r -o 20 -l 10 -R" "unlck" "unlck" "unlck"
211 # setlk rdlck [0,9], getlk rdlck [20,29]
212 do_test "-s -r -o 0 -l 10" "-g -r -o 20 -l 10" "unlck" "unlck" "unlck"
213 # setlk posix rdlck [0,9], getlk rdlck [20,29]
214 do_test "-s -r -o 0 -l 10 -P" "-g -r -o 20 -l 10" "unlck" "unlck" "unlck"