Whamcloud - gitweb
LU-14541 llite: Check vmpage in releasepage
[fs/lustre-release.git] / lustre / tests / sanityn.sh
1 #!/bin/bash
2
3 set -e
4
5 ONLY=${ONLY:-"$*"}
6
7 SIZE=${SIZE:-40960}
8 OPENFILE=${OPENFILE:-openfile}
9 OPENUNLINK=${OPENUNLINK:-openunlink}
10 export TMP=${TMP:-/tmp}
11 MOUNT_2=${MOUNT_2:-"yes"}
12 CHECK_GRANT=${CHECK_GRANT:-"yes"}
13 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
14
15 LUSTRE=${LUSTRE:-$(dirname $0)/..}
16 . $LUSTRE/tests/test-framework.sh
17 init_test_env $@
18 init_logging
19
20 ALWAYS_EXCEPT="$SANITYN_EXCEPT "
21 # bug number for skipped test:  LU-7105 LU-14541
22 ALWAYS_EXCEPT+="                28      16f"
23 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
24
25 # skip tests for PPC until they are fixed
26 if [[ $(uname -m) = ppc64 ]]; then
27         # bug number:    LU-11787
28         ALWAYS_EXCEPT+=" 71a"
29 fi
30
31 if [ $mds1_FSTYPE = "zfs" ]; then
32         # bug number:    LU-15757 (test_102() causes crash in umount later)
33         ALWAYS_EXCEPT+=" 102"
34         # LU-2829 / LU-2887 - make allowances for ZFS slowness
35         TEST33_NFILES=${TEST33_NFILES:-1000}
36 fi
37
38 #                                  23   (min)"
39 [ "$SLOW" = "no" ] && EXCEPT_SLOW="33a"
40
41 build_test_filter
42
43 FAIL_ON_ERROR=false
44
45 SETUP=${SETUP:-:}
46 TRACE=${TRACE:-""}
47
48 check_and_setup_lustre
49
50 OSC=${OSC:-"osc"}
51
52 assert_DIR
53 rm -rf $DIR1/[df][0-9]* $DIR1/lnk $DIR/[df].${TESTSUITE}*
54
55 SAMPLE_FILE=$TMP/$(basename $0 .sh).junk
56 dd if=/dev/urandom of=$SAMPLE_FILE bs=1M count=1
57
58 # $RUNAS_ID may get set incorrectly somewhere else
59 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] && error "\$RUNAS_ID set to 0, but \$UID is also 0!"
60
61 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
62
63 test_1() {
64         touch $DIR1/$tfile
65         [ -f $DIR2/$tfile ] || error "Check create"
66         chmod 777 $DIR2/$tfile
67         $CHECKSTAT -t file -p 0777 $DIR1/$tfile ||
68                 error "Check attribute update for 0777"
69
70         chmod a-x $DIR2/$tfile
71         $CHECKSTAT -t file -p 0666 $DIR1/$tfile ||
72                 error "Check attribute update for 0666"
73
74         rm $DIR2/$tfile
75         $CHECKSTAT -a $DIR1/$tfile ||
76                 error "Check unlink - removes file on other mountpoint"
77 }
78 run_test 1 "Check attribute updates on 2 mount points"
79
80 test_2a() {
81         touch $DIR1/f2a
82         ls -l $DIR2/f2a
83         chmod 777 $DIR2/f2a
84         $CHECKSTAT -t file -p 0777 $DIR1/f2a ||
85                 error "Either not file type or perms not 0777"
86 }
87 run_test 2a "check cached attribute updates on 2 mtpt's ========"
88
89 test_2b() {
90         touch $DIR1/f2b
91         ls -l $DIR2/f2b
92         chmod 777 $DIR1/f2b
93         $CHECKSTAT -t file -p 0777 $DIR2/f2b ||
94                 error "Either not file type or perms not 0777"
95 }
96 run_test 2b "check cached attribute updates on 2 mtpt's ========"
97
98 # NEED TO SAVE ROOT DIR MODE
99 test_2c() {
100         chmod 777 $DIR1
101         $CHECKSTAT -t dir -p 0777 $DIR2 ||
102                 error "Either not dir type or perms not 0777"
103 }
104 run_test 2c "check cached attribute updates on 2 mtpt's root ==="
105
106 test_2d() {
107         chmod 755 $DIR1
108         $CHECKSTAT -t dir -p 0755 $DIR2 ||
109                 error "Either not file type or perms not 0775"
110 }
111 run_test 2d "check cached attribute updates on 2 mtpt's root ==="
112
113 test_2e() {
114         chmod 755 $DIR1
115         ls -l $DIR1
116         ls -l $DIR2
117         chmod 777 $DIR1
118                 $RUNAS dd if=/dev/zero of=$DIR2/$tfile count=1 ||
119                         error "dd failed"
120 }
121 run_test 2e "check chmod on root is propagated to others"
122
123 test_2f() {
124         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
125         local MDTIDX=1
126         local remote_dir=$tdir/remote_dir
127
128         mkdir -p $DIR1/$tdir
129         $LFS mkdir -i $MDTIDX $DIR1/$remote_dir ||
130                    error "Create remote directory failed"
131
132         touch $DIR1/$remote_dir/$tfile ||
133                 error "Create file under remote directory failed"
134         chmod 777 $DIR1/$remote_dir/$tfile ||
135                 error "Chmod file under remote directory failed"
136
137         $CHECKSTAT -t file -p 0777 $DIR2/$remote_dir/$tfile ||
138                 error "Check attr of file under remote directory failed"
139
140         chown $RUNAS_ID:$RUNAS_GID $DIR1/$remote_dir/$tfile ||
141                 error "Chown file under remote directory failed"
142
143         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR2/$remote_dir/$tfile ||
144                 error "Check owner of file under remote directory failed"
145
146         cd $DIR2/$remote_dir || error "enter remote dir"
147         rm -rf $DIR1/$remote_dir/$tfile ||
148                 error "Unlink remote directory failed"
149
150         $CHECKSTAT -t file $DIR2/$remote_dir/$tfile &&
151                 error "unlink file still exists!"
152
153         cd $DIR2/$tdir || error "exit remote dir"
154         rm -rf $DIR1/$tdir || error "unlink directory failed"
155 }
156 run_test 2f "check attr/owner updates on DNE with 2 mtpt's"
157
158 test_2g() {
159         dd if=/dev/zero of=$DIR1/$tfile oflag=sync bs=1M count=2
160
161         local block1=$(stat $DIR1/$tfile | awk '/Blocks/ {print $4} ')
162         cancel_lru_locks osc
163         local block2=$(stat $DIR2/$tfile | awk '/Blocks/ {print $4} ')
164         echo "$DIR1/$tfile has $block1 blocks"
165         echo "$DIR2/$tfile has $block2 blocks"
166         [ $block1 -eq $block2 ] || error "$block1 not equal to $block2"
167 }
168 run_test 2g "check blocks update on sync write"
169
170 test_3() {
171         local target="this/is/good"
172         ln -s $target $DIR1/$tfile || error "ln -s $target $DIR1/$tfile failed"
173         [ "$(ls -l $DIR2/$tfile | sed -e 's/.* -> //')" = "$target" ] ||
174                 error "link $DIR2/$tfile not as expected"
175 }
176 run_test 3 "symlink on one mtpt, readlink on another ==========="
177
178 test_4() {
179         multifstat $DIR1/f4 $DIR2/f4
180 }
181 run_test 4 "fstat validation on multiple mount points =========="
182
183 test_5() {
184         mcreate $DIR1/f5
185         $TRUNCATE $DIR2/f5 100
186         $CHECKSTAT -t file -s 100 $DIR1/f5 ||
187                 error "Either not file type or size not equal to 100 bytes"
188         rm $DIR1/f5
189 }
190 run_test 5 "create a file on one mount, truncate it on the other"
191
192 test_6() {
193         openunlink $DIR1/$tfile $DIR2/$tfile || \
194                 error "openunlink $DIR1/$tfile $DIR2/$tfile"
195 }
196 run_test 6 "remove of open file on other node =================="
197
198 test_7() {
199         local dir=d7
200         opendirunlink $DIR1/$dir $DIR2/$dir || \
201                 error "opendirunlink $DIR1/$dir $DIR2/$dir"
202 }
203 run_test 7 "remove of open directory on other node ============="
204
205 test_8() {
206         opendevunlink $DIR1/$tfile $DIR2/$tfile || \
207                 error "opendevunlink $DIR1/$tfile $DIR2/$tfile"
208 }
209 run_test 8 "remove of open special file on other node =========="
210
211 test_9a() {
212         MTPT=1
213         local dir
214         > $DIR2/f9
215         for C in a b c d e f g h i j k l; do
216                 dir=`eval echo \\$DIR$MTPT`
217                 echo -n $C >> $dir/f9
218                 [ "$MTPT" -eq 1 ] && MTPT=2 || MTPT=1
219         done
220         [ "`cat $DIR1/f9`" = "abcdefghijkl" ] || \
221                 error "`od -a $DIR1/f9` != abcdefghijkl"
222 }
223 run_test 9a "append of file with sub-page size on multiple mounts"
224
225 #LU-10681 - tiny writes & appending to sparse striped file
226 test_9b() {
227         [[ $OSTCOUNT -ge 2 ]] || { skip "needs >= 2 OSTs"; return; }
228
229         $LFS setstripe -c 2 -S 1M $DIR/$tfile
230         echo "foo" >> $DIR/$tfile
231         dd if=/dev/zero of=$DIR2/$tfile bs=1M count=1 seek=1 conv=notrunc ||
232                 error "sparse dd $DIR2/$tfile failed"
233         echo "foo" >> $DIR/$tfile
234
235         data=$(dd if=$DIR2/$tfile bs=1 count=3 skip=$((2 * 1048576)) conv=notrunc)
236         echo "Data read (expecting 'foo')": $data
237         [ "$data" = "foo" ] || error "append to sparse striped file failed"
238 }
239 run_test 9b "append to striped sparse file"
240
241 test_10a() {
242         MTPT=1
243         local dir
244         OFFSET=0
245         > $DIR2/f10
246         for C in a b c d e f g h i j k l; do
247                 dir=`eval echo \\$DIR$MTPT`
248                 echo -n $C | dd of=$dir/f10 bs=1 seek=$OFFSET count=1
249                 [ "$MTPT" -eq 1 ] && MTPT=2 || MTPT=1
250                 OFFSET=`expr $OFFSET + 1`
251         done
252         [ "`cat $DIR1/f10`" = "abcdefghijkl" ] || \
253                 error "`od -a $DIR1/f10` != abcdefghijkl"
254 }
255 run_test 10a "write of file with sub-page size on multiple mounts "
256
257 test_10b() {
258         # create a seed file
259         yes "R" | head -c 4000 >$TMP/f10b-seed
260         dd if=$TMP/f10b-seed of=$DIR1/f10b bs=3k count=1 || error "dd $DIR1"
261
262         $TRUNCATE $DIR1/f10b 4096 || error "truncate 4096"
263
264         dd if=$DIR2/f10b of=$TMP/f10b-lustre bs=4k count=1 || error "dd $DIR2"
265
266         # create a test file locally to compare
267         dd if=$TMP/f10b-seed of=$TMP/f10b bs=3k count=1 || error "dd random"
268         $TRUNCATE $TMP/f10b 4096 || error "truncate 4096"
269         cmp $TMP/f10b $TMP/f10b-lustre || error "file miscompare"
270         rm $TMP/f10b $TMP/f10b-lustre $TMP/f10b-seed
271 }
272 run_test 10b "write of file with sub-page size on multiple mounts "
273
274 test_11() {
275         test_mkdir $DIR1/d11
276         multiop_bg_pause $DIR1/d11/f O_c || return 1
277         MULTIPID=$!
278         cp -p /bin/ls $DIR1/d11/f
279         $DIR2/d11/f
280         RC=$?
281         kill -USR1 $MULTIPID
282         wait $MULTIPID || error "wait for PID $MULTIPID failed"
283         [ $RC -eq 0 ] && error || true
284 }
285 run_test 11 "execution of file opened for write should return error ===="
286
287 test_12() {
288         DIR=$DIR DIR2=$DIR2 bash lockorder.sh
289 }
290 run_test 12 "test lock ordering (link, stat, unlink)"
291
292 test_13() {     # bug 2451 - directory coherency
293         test_mkdir $DIR1/d13
294         cd $DIR1/d13 || error "cd to $DIR1/d13 failed"
295         ls
296         ( touch $DIR1/d13/f13 ) # needs to be a separate shell
297         ls
298         rm -f $DIR2/d13/f13 || error "Cannot remove $DIR2/d13/f13"
299         ls 2>&1 | grep f13 && error "f13 shouldn't return an error (1)" || true
300         # need to run it twice
301         ( touch $DIR1/d13/f13 ) # needs to be a separate shell
302         ls
303         rm -f $DIR2/d13/f13 || error "Cannot remove $DIR2/d13/f13"
304         ls 2>&1 | grep f13 && error "f13 shouldn't return an error (2)" || true
305 }
306 run_test 13 "test directory page revocation"
307
308 test_14aa() {
309         test_mkdir $DIR1/$tdir
310         cp -p /bin/ls $DIR1/$tdir/$tfile
311         multiop_bg_pause $DIR1/$tdir/$tfile Ow_c || return 1
312         MULTIPID=$!
313
314         $DIR2/$tdir/$tfile && error || true
315         kill $MULTIPID
316 }
317 run_test 14aa "execution of file open for write returns -ETXTBSY"
318
319 test_14ab() {
320         test_mkdir $DIR1/$tdir
321         cp -p $(which sleep) $DIR1/$tdir/sleep || error "cp failed"
322         $DIR1/$tdir/sleep 60 &
323         SLEEP_PID=$!
324         $MULTIOP $DIR2/$tdir/sleep Oc && error "expected error, got success"
325         kill $SLEEP_PID
326 }
327 run_test 14ab "open(RDWR) of executing file returns -ETXTBSY"
328
329 test_14b() { # bug 3192, 7040
330         test_mkdir $DIR1/$tdir
331         cp -p $(which sleep) $DIR1/$tdir/sleep || error "cp failed"
332         $DIR1/$tdir/sleep 60 &
333         SLEEP_PID=$!
334         $TRUNCATE $DIR2/$tdir/sleep 60 && kill -9 $SLEEP_PID && \
335                 error "expected truncate error, got success"
336         kill $SLEEP_PID
337         cmp $(which sleep) $DIR1/$tdir/sleep || error "binary changed"
338 }
339 run_test 14b "truncate of executing file returns -ETXTBSY ======"
340
341 test_14c() { # bug 3430, 7040
342         test_mkdir $DIR1/$tdir
343         cp -p $(which sleep) $DIR1/$tdir/sleep || error "cp failed"
344         $DIR1/$tdir/sleep 60 &
345         SLEEP_PID=$!
346         cp /etc/hosts $DIR2/$tdir/sleep && error "expected error, got success"
347         kill $SLEEP_PID
348         cmp $(which sleep) $DIR1/$tdir/sleep || error "binary changed"
349 }
350 run_test 14c "open(O_TRUNC) of executing file return -ETXTBSY =="
351
352 test_14d() { # bug 10921
353         test_mkdir $DIR1/$tdir
354         cp -p $(which sleep) $DIR1/$tdir/sleep || error "cp failed"
355         $DIR1/$tdir/sleep 60 &
356         SLEEP_PID=$!
357         log chmod
358         chmod 600 $DIR1/$tdir/sleep || error "chmod failed"
359         kill $SLEEP_PID
360         cmp $(which sleep) $DIR1/$tdir/sleep || error "binary changed"
361 }
362 run_test 14d "chmod of executing file is still possible ========"
363
364 test_15() {     # bug 974 - ENOSPC
365         echo "PATH=$PATH"
366         bash oos2.sh $MOUNT1 $MOUNT2
367         wait_delete_completed
368         grant_error=$(dmesg | grep "< tot_grant")
369         [ -z "$grant_error" ] || error "$grant_error"
370 }
371 run_test 15 "test out-of-space with multiple writers ==========="
372
373 COUNT=${COUNT:-2500}
374 # The FSXNUM reduction for ZFS is needed until ORI-487 is fixed.
375 # We don't want to skip it entirely, but ZFS is VERY slow and cannot
376 # pass a 2500 operation dual-mount run within the time limit.
377 if [ "$ost1_FSTYPE" = "zfs" ]; then
378         FSXNUM=$((COUNT / 5))
379         FSXP=1
380 elif [ "$SLOW" = "yes" ]; then
381         FSXNUM=$((COUNT * 5))
382         FSXP=500
383 else
384         FSXNUM=$COUNT
385         FSXP=100
386 fi
387
388 test_16a() {
389         local file1=$DIR1/$tfile
390         local file2=$DIR2/$tfile
391         local stripe_size=$(do_facet $SINGLEMDS \
392                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
393
394         check_set_fallocate
395
396         # to allocate grant because it may run out due to test_15.
397         $LFS setstripe -c -1 $file1
398         dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync
399         dd if=/dev/zero of=$file2 bs=$stripe_size count=$OSTCOUNT oflag=sync
400         rm -f $file1
401
402         $LFS setstripe -c -1 $file1 # b=10919
403         $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 $file1 $file2 ||
404                 error "fsx failed"
405         rm -f $file1
406
407         # O_DIRECT reads and writes must be aligned to the PAGE_SIZE.
408         $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 -Z -r $PAGE_SIZE \
409                 -w $PAGE_SIZE $file1 $file2 || error "fsx with O_DIRECT failed."
410 }
411 run_test 16a "$FSXNUM iterations of dual-mount fsx"
412
413 # Consistency check for tiny writes, LU-9409
414 test_16b() {
415         local file1=$DIR1/$tfile
416         local file2=$DIR2/$tfile
417         local stripe_size=($($LFS getstripe -S $DIR))
418
419         check_set_fallocate
420
421         # to allocate grant because it may run out due to test_15.
422         lfs setstripe -c -1 $file1
423         dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync ||
424                 error "dd failed writing to file=$file1"
425         dd if=/dev/zero of=$file2 bs=$stripe_size count=$OSTCOUNT oflag=sync ||
426                 error "dd failed writing to file=$file2"
427         rm -f $file1
428
429         lfs setstripe -c -1 $file1 # b=10919
430         # -o is set to 8192 because writes < 1 page and between 1 and 2 pages
431         # create a mix of tiny writes & normal writes
432         $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -o 8192 -S 0 \
433                 $file1 $file2 || error "fsx with tiny write failed."
434 }
435 run_test 16b "$FSXNUM iterations of dual-mount fsx at small size"
436
437 test_16c() {
438         local file1=$DIR1/$tfile
439         local file2=$DIR2/$tfile
440         local stripe_size=$(do_facet $SINGLEMDS \
441                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
442
443         [ "$ost1_FSTYPE" != ldiskfs ] && skip "dio on ldiskfs only"
444
445         check_set_fallocate
446
447         # to allocate grant because it may run out due to test_15.
448         $LFS setstripe -c -1 $file1
449         dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync
450         dd if=/dev/zero of=$file2 bs=$stripe_size count=$OSTCOUNT oflag=sync
451         rm -f $file1
452         wait_delete_completed
453
454         local list=$(comma_list $(osts_nodes))
455         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
456                 skip "not cache-capable obdfilter"
457         fi
458
459         set_osd_param $list '' read_cache_enable 0
460         set_osd_param $list '' writethrough_cache_enable 0
461
462         $LFS setstripe -c -1 $file1 # b=10919
463         $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 $file1 $file2 ||
464                 error "fsx failed"
465         rm -f $file1
466
467         set_osd_param $list '' read_cache_enable 1
468         set_osd_param $list '' writethrough_cache_enable 1
469
470         return 0
471 }
472 run_test 16c "verify data consistency on ldiskfs with cache disabled (b=17397)"
473
474 test_16d() {
475         local file1=$DIR1/$tfile
476         local file2=$DIR2/$tfile
477         local file3=$DIR1/file
478         local tmpfile=$(mktemp)
479         local stripe_size=$(do_facet $SINGLEMDS \
480                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
481
482         # to allocate grant because it may run out due to test_15.
483         $LFS setstripe -c -1 $file1
484         stack_trap "rm -f $file1 $file2 $file3 $tmpfile"
485         dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync
486         dd if=/dev/zero of=$file2 bs=$stripe_size count=$OSTCOUNT oflag=sync
487         rm -f $file1
488
489         $LFS setstripe -c -1 $file1 # b=10919
490         $LCTL set_param ldlm.namespaces.*.lru_size=clear
491         
492         # direct write on one client and direct read from another
493         dd if=/dev/urandom of=$file1 bs=1M count=100 oflag=direct
494         dd if=$file2 of=$tmpfile iflag=direct bs=1M
495         diff $file1 $tmpfile || error "file different(1)"
496         rm -f $file1
497
498         # buffer write on one client, but direct read from another
499         dd if=$tmpfile of=$file1 bs=1M count=100
500         dd if=$file2 of=$file3 bs=1M iflag=direct count=100
501         diff $file3 $tmpfile || error "file different(2)"
502
503         rm -f $file3 $file2 $file1
504         # direct write on one client
505         dd if=$tmpfile of=$file1 bs=1M count=100 oflag=direct
506         # buffer read from another client
507         dd if=$file2 of=$file3 bs=1M count=100
508         diff $file3 $tmpfile || error "file different(3)"
509 }
510 run_test 16d "Verify DIO and buffer IO with two clients"
511
512 test_16e() { # LU-13227
513         # issue:        LU-14314
514
515         (( "$MDS1_VERSION" >= $(version_code 2.13.53) )) ||
516                 skip "Need MDS version at least 2.13.53"
517
518         local file1=$DIR1/$tfile
519         local file2=$DIR2/$tfile
520
521         # client1 write 10M data
522         dd if=/dev/zero of=$file1 bs=1M count=10
523         # drop locks
524         cancel_lru_locks osc > /dev/null
525         # use lockahead to generate one PW lock to keep LVB loaded.
526         $LFS ladvise -a lockahead --start 0 --length 1M \
527                 --mode WRITE $file1
528         # direct write to extend file size on client2
529         dd if=/dev/zero of=$file2 bs=1M seek=20 count=1 \
530                 oflag=direct conv=notrunc
531         local filesize=$(stat -c %s $file2)
532         [ "$filesize" -eq 22020096 ] ||
533                 error "expected filesize 22020096 got $filesize"
534         rm -f $file1
535 }
536 run_test 16e "Verify size consistency for O_DIRECT write"
537
538 test_16f() { # LU-14541
539         local file1=$DIR1/$tfile
540         local file2=$DIR2/$tfile
541         local duration=20
542         local status
543
544         timeout --preserve-status --signal=USR1 $duration \
545                 rw_seq_cst_vs_drop_caches $file1 $file2
546         status=$?
547
548         case $((status & 0x7f)) in
549                 0)
550                         echo OK # Computers must be fast now.
551                         ;;
552                 6) # SIGABRT
553                         error "sequential consistency violation detected"
554                         ;;
555                 10) # SIGUSR1
556                         echo TIMEOUT # This is fine.
557                         ;;
558                 *)
559                         error "strange status '$status'"
560                         ;;
561         esac
562
563         rm -f $file1
564 }
565 run_test 16f "rw sequential consistency vs drop_caches"
566
567 test_17() { # bug 3513, 3667
568         remote_ost_nodsh && skip "remote OST with nodsh" && return
569
570         lfs setstripe $DIR1/$tfile -i 0 -c 1
571         cp $SAMPLE_FILE $DIR1/$tfile
572         cancel_lru_locks osc > /dev/null
573         #define OBD_FAIL_ONCE|OBD_FAIL_LDLM_CREATE_RESOURCE    0x30a
574         do_facet ost1 lctl set_param fail_loc=0x8000030a
575         ls -ls $DIR1/$tfile | awk '{ print $1,$6 }' > $DIR1/$tfile-1 & \
576         ls -ls $DIR2/$tfile | awk '{ print $1,$6 }' > $DIR2/$tfile-2
577         wait
578         diff -u $DIR1/$tfile-1 $DIR2/$tfile-2 || error "files are different"
579 }
580 run_test 17 "resource creation/LVB creation race ==============="
581
582 test_18() {
583         # turn e.g. ALWAYS_EXCEPT="18c" into "-e 3"
584         local idx
585         local excepts=
586         for idx in {a..z}; do
587                 local ptr=EXCEPT_ALWAYS_18$idx
588                 [ x${!ptr} = xtrue ] || continue
589
590                 excepts="$excepts -e $(($(printf %d \'$idx)-96))"
591         done
592
593         excepts="$excepts -e 7 -e 8 -e 9"
594         $LUSTRE/tests/mmap_sanity -d $MOUNT1 -m $MOUNT2 $excepts ||
595                 error "mmap_sanity test failed"
596         sync; sleep 1; sync
597 }
598 run_test 18 "mmap sanity check ================================="
599
600 test_19() { # bug3811
601         local node=$(facet_active_host ost1)
602         local device="$FSNAME-OST*"
603
604         [ "x$DOM" = "xyes" ] && node=$(facet_active_host $SINGLEMDS) &&
605                 device="$FSNAME-MDT*"
606
607         # check whether obdfilter is cache capable at all
608         get_osd_param $node $device read_cache_enable >/dev/null ||
609                 skip "not cache-capable obdfilter"
610
611         local max=$(get_osd_param $node $device readcache_max_filesize |\
612                 head -n 1)
613         set_osd_param $node $device readcache_max_filesize 4096
614         dd if=/dev/urandom of=$TMP/$tfile bs=512k count=32
615         local SUM=$(cksum $TMP/$tfile | cut -d" " -f 1,2)
616         cp $TMP/$tfile $DIR1/$tfile
617         for i in `seq 1 20`; do
618                 [ $((i % 5)) -eq 0 ] && log "$testname loop $i"
619                 cancel_lru_locks $OSC > /dev/null
620                 cksum $DIR1/$tfile | cut -d" " -f 1,2 > $TMP/sum1 & \
621                 cksum $DIR2/$tfile | cut -d" " -f 1,2 > $TMP/sum2
622                 wait
623                 [ "$(cat $TMP/sum1)" = "$SUM" ] || \
624                         error "$DIR1/$tfile $(cat $TMP/sum1) != $SUM"
625                 [ "$(cat $TMP/sum2)" = "$SUM" ] || \
626                         error "$DIR2/$tfile $(cat $TMP/sum2) != $SUM"
627         done
628         set_osd_param $node $device readcache_max_filesize $max
629         rm $DIR1/$tfile
630 }
631 run_test 19 "test concurrent uncached read races ==============="
632
633 test_20() {
634         test_mkdir $DIR1/$tdir
635         cancel_lru_locks
636         CNT=$($LCTL get_param -n llite.*.dump_page_cache | wc -l)
637         $MULTIOP $DIR1/$tdir/$tfile Ow8190c
638         $MULTIOP $DIR2/$tdir/$tfile Oz8194w8190c
639         $MULTIOP $DIR1/$tdir/$tfile Oz0r8190c
640         cancel_lru_locks
641         CNT2=$($LCTL get_param -n llite.*.dump_page_cache | wc -l)
642         [[ $CNT2 == $CNT ]] ||
643                 error $((CNT2 - CNT))" page left in cache after lock cancel"
644 }
645 run_test 20 "test extra readahead page left in cache ===="
646
647 cleanup_21() {
648         trap 0
649         umount $DIR1/$tdir
650 }
651
652 test_21() { # Bug 5907
653         test_mkdir $DIR1/$tdir
654         mount /etc $DIR1/$tdir --bind || error "mount failed" # Poor man's mount.
655         trap cleanup_21 EXIT
656         rmdir -v $DIR1/$tdir && error "Removed mounted directory"
657         rmdir -v $DIR2/$tdir && echo "Removed mounted directory from another mountpoint, needs to be fixed"
658         test -d $DIR1/$tdir || error "Mounted directory disappeared"
659         cleanup_21
660         test -d $DIR2/$tdir || test -d $DIR1/$tdir && error "Removed dir still visible after umount"
661         true
662 }
663 run_test 21 " Try to remove mountpoint on another dir ===="
664
665 test_23() { # Bug 5972
666         local at_diff=$(do_facet $SINGLEMDS \
667                 $LCTL get_param -n mdd.*MDT0000*.atime_diff | head -n1)
668         echo "atime should be updated while another read" > $DIR1/$tfile
669
670         # clear the lock(mode: LCK_PW) gotten from creating operation
671         cancel_lru_locks $OSC
672         time1=$(date +%s)
673         echo "now is $time1"
674         sleep $((at_diff + 1))
675
676         echo "starting reads"
677         multiop_bg_pause $DIR1/$tfile or20_c || return 1
678         # with SOM and opencache enabled, we need to close a file and cancel
679         # open lock to get atime propogated to MDS
680         kill -USR1 $! || return 2
681         cancel_lru_locks mdc
682
683         time2=$(stat -c "%X" $DIR/$tfile)
684         echo "new atime is $time2"
685
686         [ $time2 -gt $time1 ] || error "atime was not updated"
687         rm -f $DIR1/$tfile || error "rm -f $DIR1/$tfile failed"
688         true
689 }
690 run_test 23 " others should see updated atime while another read===="
691
692 test_24a() {
693         touch $DIR1/$tfile
694         lfs df || error "lfs df failed"
695         lfs df -ih || error "lfs df -ih failed"
696         lfs df -h $DIR1 || error "lfs df -h $DIR1 failed"
697         lfs df -i $DIR2 || error "lfs df -i $DIR2 failed"
698         lfs df $DIR1/$tfile || error "lfs df $DIR1/$tfile failed"
699         lfs df -ih $DIR2/$tfile || error "lfs df -ih $DIR2/$tfile failed"
700
701         OSC=`lctl dl | awk '/-osc-|OSC.*MNT/ {print $4}' | head -n 1`
702 #       OSC=`lctl dl | awk '/-osc-/ {print $4}' | head -n 1`
703         lctl --device %osc deactivate
704         lfs df -i || error "lfs df -i with deactivated OSC failed"
705         lctl --device %osc activate
706         lfs df || error "lfs df with reactivated OSC failed"
707 }
708 run_test 24a "lfs df [-ih] [path] test ========================="
709
710 test_24b() {
711         touch $DIR1/$tfile
712         fsnum=$(lfs_df | grep -c "summary")
713         [ $fsnum -eq 2 ] || error "lfs df shows $fsnum != 2 filesystems."
714 }
715 run_test 24b "lfs df should show both filesystems ==============="
716
717 test_25a() {
718         local acl=$(lctl get_param -n mdc.*MDT0000-mdc-*.connect_flags |
719                                                                 grep -c acl)
720         [ "$acl" -lt 1 ] && skip "must have acl, skipping" && return
721
722         mkdir -p $DIR1/$tdir
723         touch $DIR1/$tdir/f1 || error "touch $DIR1/$tdir/f1"
724         chmod 0755 $DIR1/$tdir/f1 || error "chmod 0755 $DIR1/$tdir/f1"
725
726         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 || error "checkstat $DIR2/$tdir/f1 #1"
727         setfacl -m u:$RUNAS_ID:--- -m g:$RUNAS_GID:--- $DIR1/$tdir ||
728                 error "setfacl $DIR2/$tdir #1"
729         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 && error "checkstat $DIR2/$tdir/f1 #2"
730         setfacl -m u:$RUNAS_ID:r-x -m g:$RUNAS_GID:r-x $DIR1/$tdir ||
731                 error "setfacl $DIR2/$tdir #2"
732         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 || error "checkstat $DIR2/$tdir/f1 #3"
733         setfacl -m u:$RUNAS_ID:--- -m g:$RUNAS_GID:--- $DIR1/$tdir ||
734                 error "setfacl $DIR2/$tdir #3"
735         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 && error "checkstat $DIR2/$tdir/f1 #4"
736         setfacl -x u:$RUNAS_ID: -x g:$RUNAS_GID: $DIR1/$tdir ||
737                 error "setfacl $DIR2/$tdir #4"
738         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 || error "checkstat $DIR2/$tdir/f1 #5"
739
740         rm -rf $DIR1/$tdir
741 }
742 run_test 25a "change ACL on one mountpoint be seen on another ==="
743
744 test_25b() {
745         local acl=$(lctl get_param -n mdc.*MDT0000-mdc-*.connect_flags |
746                                                         grep -c acl)
747         [ "$acl" -lt 1 ] && skip "must have acl, skipping" && return
748
749         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
750
751         rm -rf $DIR1/$tdir
752         $LFS mkdir -i 1 $DIR1/$tdir
753         touch $DIR1/$tdir/f1 || error "touch $DIR1/$tdir/f1"
754         chmod 0755 $DIR1/$tdir/f1 || error "chmod 0755 $DIR1/$tdir/f1"
755
756         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 || error "checkstat $DIR2/$tdir/f1 #1"
757         setfacl -m u:$RUNAS_ID:--- -m g:$RUNAS_GID:--- $DIR1/$tdir ||
758                 error "setfacl $DIR2/$tdir #1"
759         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 && error "checkstat $DIR2/$tdir/f1 #2"
760         setfacl -m u:$RUNAS_ID:r-x -m g:$RUNAS_GID:r-x $DIR1/$tdir ||
761                 error "setfacl $DIR2/$tdir #2"
762         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 || error "checkstat $DIR2/$tdir/f1 #3"
763         setfacl -m u:$RUNAS_ID:--- -m g:$RUNAS_GID:--- $DIR1/$tdir ||
764                 error "setfacl $DIR2/$tdir #3"
765         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 && error "checkstat $DIR2/$tdir/f1 #4"
766         setfacl -x u:$RUNAS_ID: -x g:$RUNAS_GID: $DIR1/$tdir ||
767                 error "setfacl $DIR2/$tdir #4"
768         $RUNAS $CHECKSTAT $DIR2/$tdir/f1 || error "checkstat $DIR2/$tdir/f1 #5"
769
770         rm -rf $DIR1/$tdir
771 }
772 run_test 25b "change ACL under remote dir on one mountpoint be seen on another"
773
774 test_26a() {
775         utime $DIR1/f26a -s $DIR2/f26a || error "utime failed for $DIR1/f26a"
776 }
777 run_test 26a "allow mtime to get older"
778
779 test_26b() {
780         touch $DIR1/$tfile
781         sleep 1
782         echo "aaa" >> $DIR1/$tfile
783         sleep 1
784         chmod a+x $DIR2/$tfile
785         mt1=`stat -c %Y $DIR1/$tfile`
786         mt2=`stat -c %Y $DIR2/$tfile`
787
788         if [ x"$mt1" != x"$mt2" ]; then
789                 error "not equal mtime, client1: "$mt1", client2: "$mt2"."
790         fi
791 }
792 run_test 26b "sync mtime between ost and mds"
793
794 test_27() {
795         cancel_lru_locks $OSC
796         lctl clear
797         dd if=/dev/zero of=$DIR2/$tfile bs=$((4096+4))k conv=notrunc count=4 seek=3 &
798         DD2_PID=$!
799         sleep 0.5
800         log "dd 1 started"
801
802         dd if=/dev/zero of=$DIR1/$tfile bs=$((16384-1024))k conv=notrunc count=1 seek=4 &
803         DD1_PID=$!
804         log "dd 2 started"
805
806         sleep 1
807         dd if=/dev/zero of=$DIR1/$tfile bs=8k conv=notrunc count=1 seek=0
808         log "dd 3 finished"
809         lctl set_param -n ldlm.dump_namespaces ""
810         wait $DD1_PID $DD2_PID
811         [ $? -ne 0 ] && lctl dk $TMP/debug || true
812 }
813 run_test 27 "align non-overlapping extent locks from request ==="
814
815 test_28() { # bug 9977
816         ECHO_UUID="ECHO_osc1_UUID"
817         tOST=$($LCTL dl | awk '/-osc-|OSC.*MNT/ { print $4 }' | head -n1)
818
819         $LFS setstripe $DIR1/$tfile -S 1048576 -i 0 -c 2
820         tOBJID=`$LFS getstripe $DIR1/$tfile | awk '$1 == 1 {print $2}'`
821         dd if=/dev/zero of=$DIR1/$tfile bs=1024k count=2
822
823         $LCTL <<-EOF
824                 newdev
825                 attach echo_client ECHO_osc1 $ECHO_UUID
826                 setup $tOST
827         EOF
828
829         tECHOID=`$LCTL dl | grep $ECHO_UUID | awk '{ print $1 }'`
830         $LCTL --device $tECHOID destroy "${tOBJID}:0"
831
832         $LCTL <<-EOF
833                 cfg_device ECHO_osc1
834                 cleanup
835                 detach
836         EOF
837
838         # reading of 1st stripe should pass
839         dd if=$DIR2/$tfile of=/dev/null bs=1024k count=1 || error "dd failed"
840         # reading of 2nd stripe should fail (this stripe was destroyed)
841         dd if=$DIR2/$tfile of=/dev/null bs=1024k count=1 skip=1 && error
842
843         # now, recreating test file
844         dd if=/dev/zero of=$DIR1/$tfile bs=1024k count=2 || error "dd failed"
845         # reading of 1st stripe should pass
846         dd if=$DIR2/$tfile of=/dev/null bs=1024k count=1 || error "dd failed"
847         # reading of 2nd stripe should pass
848         dd if=$DIR2/$tfile of=/dev/null bs=1024k count=1 skip=1 ||
849                 error "dd failed"
850 }
851 run_test 28 "read/write/truncate file with lost stripes"
852
853 test_30() { #b=11110, LU-2523
854         test_mkdir $DIR1/$tdir
855         cp -f /bin/bash $DIR1/$tdir/bash
856         bash -c 'sleep 1; rm -f $DIR2/$tdir/bash; cp /bin/bash $DIR2/$tdir' &
857         $DIR1/$tdir/bash -c 'sleep 2;
858                 openfile -f O_RDONLY /proc/$$/exe >& /dev/null; echo $?'
859         wait
860         true
861 }
862 run_test 30 "recreate file race"
863
864 test_31a() {
865         test_mkdir $DIR1/$tdir
866         local writes=$(LANG=C dd if=/dev/zero of=$DIR/$tdir/$tfile \
867                        count=1 2>&1 | awk 'BEGIN { FS="+" } /out/ {print $1}')
868         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE   0x314
869         lctl set_param fail_loc=0x314
870         local reads=$(LANG=C dd if=$DIR2/$tdir/$tfile of=/dev/null 2>&1 |
871                       awk 'BEGIN { FS="+" } /in/ {print $1}')
872         [ $reads -eq $writes ] || error "read" $reads "blocks, must be" $writes
873 }
874 run_test 31a "voluntary cancel / blocking ast race=============="
875
876 test_31b() {
877         remote_ost || { skip "local OST" && return 0; }
878         remote_ost_nodsh && skip "remote OST w/o dsh" && return 0
879
880         # make sure there is no local locks due to destroy
881         wait_mds_ost_sync || error "wait_mds_ost_sync()"
882         wait_delete_completed || error "wait_delete_completed()"
883
884         test_mkdir $DIR1/$tdir
885         lfs setstripe $DIR/$tdir/$tfile -i 0 -c 1
886         cp /etc/hosts $DIR/$tdir/$tfile
887         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE   0x314
888         lctl set_param fail_loc=0x314
889         #define OBD_FAIL_LDLM_OST_FAIL_RACE      0x316
890         do_facet ost1 lctl set_param fail_loc=0x316
891         # Don't crash kernel
892         cat $DIR2/$tdir/$tfile > /dev/null 2>&1
893         lctl set_param fail_loc=0
894         do_facet ost1 lctl set_param fail_loc=0
895         # cleanup: reconnect the client back
896         df $DIR2
897 }
898 run_test 31b "voluntary OST cancel / blocking ast race=============="
899
900 #LU-14949 - multi-client version of the test 31r in sanity.
901 test_31r() {
902         touch $DIR/$tfile.target
903         touch $DIR/$tfile.source
904
905         ls -l $DIR/$tfile.target # cache it for sure
906
907         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
908         $LCTL set_param fail_loc=0x1419 fail_val=3
909         cat $DIR/$tfile.target &
910         CATPID=$!
911
912         # Guarantee open is waiting before we get here
913         sleep 1
914         mv $DIR2/$tfile.source $DIR2/$tfile.target
915
916         wait $CATPID
917         RC=$?
918         if [[ $RC -ne 0 ]]; then
919                 error "open with cat failed, rc=$RC"
920         fi
921 }
922 run_test 31r "open-rename(replace) race"
923
924 test_32b() { # bug 11270
925         remote_ost_nodsh && skip "remote OST with nodsh" && return
926
927         local node
928         local facets=$(get_facets OST)
929         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
930
931         save_lustre_params client "osc.*.contention_seconds" > $p
932         save_lustre_params $facets \
933                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
934         save_lustre_params $facets \
935                 "ldlm.namespaces.filter-*.contended_locks" >> $p
936         save_lustre_params $facets \
937                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
938         clear_stats $OSC.*.${OSC}_stats
939
940         # agressive lockless i/o settings
941         do_nodes $(comma_list $(osts_nodes)) \
942                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
943                         ldlm.namespaces.filter-*.contended_locks=0 \
944                         ldlm.namespaces.filter-*.contention_seconds=60"
945         lctl set_param -n $OSC.*.contention_seconds=60
946         for i in {1..5}; do
947                 dd if=/dev/zero of=$DIR1/$tfile bs=4k count=1 conv=notrunc > \
948                         /dev/null 2>&1
949                 dd if=/dev/zero of=$DIR2/$tfile bs=4k count=1 conv=notrunc > \
950                         /dev/null 2>&1
951         done
952         [ $(calc_stats $OSC.*.${OSC}_stats lockless_write_bytes) -ne 0 ] ||
953                 error "lockless i/o was not triggered"
954         # disable lockless i/o (it is disabled by default)
955         do_nodes $(comma_list $(osts_nodes)) \
956                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
957                         ldlm.namespaces.filter-*.contended_locks=32 \
958                         ldlm.namespaces.filter-*.contention_seconds=0"
959         # set contention_seconds to 0 at client too, otherwise Lustre still
960         # remembers lock contention
961         lctl set_param -n $OSC.*.contention_seconds=0
962         clear_stats $OSC.*.${OSC}_stats
963         for i in {1..1}; do
964                 dd if=/dev/zero of=$DIR1/$tfile bs=4k count=1 conv=notrunc > \
965                         /dev/null 2>&1
966                 dd if=/dev/zero of=$DIR2/$tfile bs=4k count=1 conv=notrunc > \
967                         /dev/null 2>&1
968         done
969         [ $(calc_stats $OSC.*.${OSC}_stats lockless_write_bytes) -eq 0 ] ||
970                 error "lockless i/o works when disabled"
971         rm -f $DIR1/$tfile
972         restore_lustre_params <$p
973         rm -f $p
974 }
975 # Disable test 32b prior to full removal
976 #run_test 32b "lockless i/o"
977
978 print_jbd_stat () {
979         local mdts=$(get_facets MDS)
980         local stat=0
981         local varsvc
982         local dev
983         local mds
984
985         for mds in ${mdts//,/ }; do
986                 varsvc=${mds}_svc
987
988                 dev=$(basename $(do_facet $mds "lctl get_param -n \
989                         osd*.${!varsvc}.mntdev | xargs readlink -f"))
990                 val=$(do_facet $mds "cat /proc/fs/jbd*/${dev}{,:*,-*}/info \
991                         2>/dev/null | head -n1")
992                 val=${val%% *};
993                 stat=$((stat + val))
994         done
995         echo $stat
996 }
997
998 # commit on sharing tests
999 test_33a() {
1000         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1001
1002         [ -z "$CLIENTS" ] && skip "Need two or more clients, have $CLIENTS"
1003         [ $CLIENTCOUNT -lt 2 ] &&
1004                 skip "Need two or more clients, have $CLIENTCOUNT"
1005
1006         local nfiles=${TEST33_NFILES:-10000}
1007         local param_file=$TMP/$tfile-params
1008         local COS
1009         local jbdold="N/A"
1010         local jbdnew="N/A"
1011         local jbd
1012
1013         save_lustre_params $(get_facets MDS) \
1014                 "mdt.*.commit_on_sharing" > $param_file
1015
1016         for COS in 0 1; do
1017                 do_facet $SINGLEMDS lctl set_param mdt.*.commit_on_sharing=$COS
1018                 avgjbd=0
1019                 avgtime=0
1020                 for i in 1 2 3; do
1021                         do_nodes $CLIENT1,$CLIENT2 "mkdir -p $DIR1/$tdir-\\\$(hostname)-$i"
1022
1023                 [ "$mds1_FSTYPE" = ldiskfs ] && jbdold=$(print_jbd_stat)
1024                 echo "=== START createmany old: $jbdold transaction"
1025                 local elapsed=$(do_and_time "do_nodes $CLIENT1,$CLIENT2 createmany -o $DIR1/$tdir-\\\$(hostname)-$i/f- -r$DIR2/$tdir-\\\$(hostname)-$i/f- $nfiles > /dev/null 2>&1")
1026                 [ "$mds1_FSTYPE" = ldiskfs ] && jbdnew=$(print_jbd_stat)
1027                 [ "$mds1_FSTYPE" = ldiskfs ] && jbd=$(( jbdnew - jbdold ))
1028                 echo "=== END   createmany new: $jbdnew transaction :  $jbd transactions  nfiles $nfiles time $elapsed COS=$COS"
1029                 [ "$mds1_FSTYPE" = ldiskfs ] && avgjbd=$(( avgjbd + jbd ))
1030                 avgtime=$(( avgtime + elapsed ))
1031                 done
1032         eval cos${COS}_jbd=$((avgjbd / 3))
1033         eval cos${COS}_time=$((avgtime / 3))
1034         done
1035
1036         echo "COS=0 transactions (avg): $cos0_jbd  time (avg): $cos0_time"
1037         echo "COS=1 transactions (avg): $cos1_jbd  time (avg): $cos1_time"
1038         [ "$cos0_jbd" != 0 ] &&
1039                 echo "COS=1 vs COS=0 jbd:  $((((cos1_jbd/cos0_jbd - 1)) * 100 )) %"
1040         [ "$cos0_time" != 0 ] &&
1041                 echo "COS=1 vs COS=0 time: $((((cos1_time/cos0_time - 1)) * 100 )) %"
1042
1043         restore_lustre_params < $param_file
1044         rm -f $param_file
1045         return 0
1046 }
1047 run_test 33a "commit on sharing, cross crete/delete, 2 clients, benchmark"
1048
1049 # commit on sharing tests
1050 test_33b() {
1051         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1052
1053         [ -n "$CLIENTS" ] || { skip "Need two or more clients" && return 0; }
1054         [ $CLIENTCOUNT -ge 2 ] ||
1055                 { skip "Need two or more clients, have $CLIENTCOUNT" &&
1056                                                                 return 0; }
1057         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1058
1059         local nfiles=${TEST33_NFILES:-10000}
1060         local param_file=$TMP/$tfile-params
1061
1062         save_lustre_params $(get_facets MDS) \
1063                 "mdt.*.commit_on_sharing" > $param_file
1064
1065         local COS
1066         local jbdold
1067         local jbdnew
1068         local jbd
1069         local MDTIDX=1
1070
1071         for COS in 0 1; do
1072                 do_facet $SINGLEMDS lctl set_param mdt.*.commit_on_sharing=$COS
1073                 avgjbd=0
1074                 avgtime=0
1075                 for i in 1 2 3; do
1076                         do_node $CLIENT1 "$LFS mkdir -i $MDTIDX \
1077                                           $DIR1/$tdir-\\\$(hostname)-$i"
1078
1079                         jbdold=$(print_jbd_stat)
1080                         echo "=== START createmany old: $jbdold transaction"
1081                         local elapsed=$(do_and_time "do_nodes $CLIENT1,$CLIENT2\
1082                                 createmany -o $DIR1/$tdir-\\\$(hostname)-$i/f- \
1083                                 -r$DIR2/$tdir-\\\$(hostname)-$i/f- $nfiles > \
1084                                                                 /dev/null 2>&1")
1085                         jbdnew=$(print_jbd_stat)
1086                         jbd=$(( jbdnew - jbdold ))
1087                         echo "=== END   createmany new: $jbdnew transaction : \
1088                         $jbd transactions nfiles $nfiles time $elapsed COS=$COS"
1089                         avgjbd=$(( avgjbd + jbd ))
1090                         avgtime=$(( avgtime + elapsed ))
1091                 done
1092                 eval cos${COS}_jbd=$((avgjbd / 3))
1093                 eval cos${COS}_time=$((avgtime / 3))
1094         done
1095
1096         echo "COS=0 transactions (avg): $cos0_jbd  time (avg): $cos0_time"
1097         echo "COS=1 transactions (avg): $cos1_jbd  time (avg): $cos1_time"
1098         [ "$cos0_jbd" != 0 ] &&
1099             echo "COS=1 vs COS=0 jbd: $(((cos1_jbd/cos0_jbd - 1) * 100)) %"
1100         [ "$cos0_time" != 0 ] &&
1101             echo "COS=1 vs COS=0 time: $(((cos1_time/cos0_time - 1) * 100)) %"
1102
1103         restore_lustre_params < $param_file
1104         rm -f $param_file
1105         return 0
1106 }
1107 run_test 33b "COS: cross create/delete, 2 clients, benchmark under remote dir"
1108
1109 test_33c() {
1110         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1111         [ "$MDS1_VERSION" -lt $(version_code 2.7.63) ] &&
1112                 skip "DNE CoS not supported"
1113
1114         # LU-13522
1115         stop mds1
1116         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS || error "start mds1 failed"
1117
1118         local sync_count
1119
1120         mkdir_on_mdt0 $DIR/$tdir
1121         sync_all_data
1122         do_facet mds1 "lctl set_param -n mdt.*.sync_count=0"
1123         # do twice in case transaction is committed before unlock, see LU-8200
1124         for i in 1 2; do
1125                 # remote dir is created on MDT1, which enqueued lock of $tdir on
1126                 # MDT0
1127                 $LFS mkdir -i 1 $DIR/$tdir/remote.$i
1128                 mkdir $DIR/$tdir/local.$i
1129         done
1130         sync_count=$(do_facet mds1 "lctl get_param -n mdt.*MDT0000.sync_count")
1131         echo "sync_count $sync_count"
1132         [ $sync_count -eq 0 ] && error "Sync-Lock-Cancel not triggered"
1133
1134         sync_all_data
1135         do_facet mds1 "lctl set_param -n mdt.*.sync_count=0"
1136         $LFS mkdir -i 1 $DIR/$tdir/remote.3
1137         # during sleep remote mkdir should have been committed and canceled
1138         # remote lock spontaneously, which shouldn't trigger sync
1139         sleep 6
1140         mkdir $DIR/$tdir/local.3
1141         sync_count=$(do_facet mds1 "lctl get_param -n mdt.*MDT0000.sync_count")
1142         echo "sync_count $sync_count"
1143         [ $sync_count -eq 0 ] || error "Sync-Lock-Cancel triggered"
1144 }
1145 run_test 33c "Cancel cross-MDT lock should trigger Sync-Lock-Cancel"
1146
1147 # arg1 is operations done before CoS, arg2 is the operation that triggers CoS
1148 op_trigger_cos() {
1149         local commit_nr
1150         local total=0
1151         local nodes=$(comma_list $(mdts_nodes))
1152
1153         sync_all_data
1154
1155         # trigger CoS twice in case transaction commit before unlock
1156         for i in 1 2; do
1157                 bash -c "$1"
1158                 do_nodes $nodes "lctl set_param -n mdt.*.async_commit_count=0"
1159                 bash -c "$2"
1160                 commit_nr=$(do_nodes $nodes \
1161                         "lctl get_param -n mdt.*.async_commit_count" | calc_sum)
1162                 total=$((total + commit_nr));
1163                 rm -rf $DIR/$tdir
1164                 sync_all_data
1165         done
1166
1167         echo "CoS count $total"
1168         [ $total -gt 0 ] || error "$2 didn't trigger CoS"
1169 }
1170
1171 test_33d() {
1172         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1173         [ "$MDS1_VERSION" -lt $(version_code 2.7.63) ] &&
1174                 skip "DNE CoS not supported"
1175
1176         # remote directory create
1177         op_trigger_cos "$LFS mkdir -i 0 $DIR/$tdir" "$LFS mkdir -i 1 $DIR/$tdir/subdir"
1178         # remote directory unlink
1179         op_trigger_cos "$LFS mkdir -i 1 $DIR/$tdir" "rmdir $DIR/$tdir"
1180         # striped directory create
1181         op_trigger_cos "mkdir $DIR/$tdir" "$LFS mkdir -c 2 $DIR/$tdir/subdir"
1182         # striped directory setattr
1183         op_trigger_cos "$LFS mkdir -c 2 $DIR/$tdir; touch $DIR/$tdir" \
1184                 "chmod 713 $DIR/$tdir"
1185         # striped directory unlink
1186         op_trigger_cos "$LFS mkdir -c 2 $DIR/$tdir; touch $DIR/$tdir" \
1187                 "rmdir $DIR/$tdir"
1188         # cross-MDT link
1189         op_trigger_cos "$LFS mkdir -c 2 $DIR/$tdir; \
1190                         $LFS mkdir -i 0 $DIR/$tdir/d1; \
1191                         $LFS mkdir -i 1 $DIR/$tdir/d2; \
1192                         touch $DIR/$tdir/d1/tgt" \
1193                 "ln $DIR/$tdir/d1/tgt $DIR/$tdir/d2/src"
1194         # cross-MDT rename
1195         op_trigger_cos "$LFS mkdir -c 2 $DIR/$tdir; \
1196                         $LFS mkdir -i 0 $DIR/$tdir/d1; \
1197                         $LFS mkdir -i 1 $DIR/$tdir/d2; \
1198                         touch $DIR/$tdir/d1/src" \
1199                 "mv $DIR/$tdir/d1/src $DIR/$tdir/d2/tgt"
1200         # migrate
1201         op_trigger_cos "$LFS mkdir -i 0 $DIR/$tdir" \
1202                 "$LFS migrate -m 1 $DIR/$tdir"
1203
1204         return 0
1205 }
1206 run_test 33d "DNE distributed operation should trigger COS"
1207
1208 test_33e() {
1209         [ -n "$CLIENTS" ] || skip "Need two or more clients"
1210         [ $CLIENTCOUNT -ge 2 ] ||
1211                 skip "Need two or more clients, have $CLIENTCOUNT"
1212         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1213         [ "$MDS1_VERSION" -lt $(version_code 2.7.63) ] &&
1214                 skip "DNE CoS not supported"
1215
1216         local client2=${CLIENT2:-$(hostname)}
1217
1218         sync
1219
1220         local nodes=$(comma_list $(mdts_nodes))
1221         do_nodes $nodes "lctl set_param -n mdt.*.async_commit_count=0"
1222
1223         $LFS mkdir -c 2 $DIR/$tdir
1224         mkdir $DIR/$tdir/subdir
1225         echo abc > $DIR/$tdir/$tfile
1226         do_node $client2 echo dfg >> $DIR/$tdir/$tfile
1227         do_node $client2 touch $DIR/$tdir/subdir
1228
1229         local async_commit_count=$(do_nodes $nodes \
1230                 "lctl get_param -n mdt.*.async_commit_count" | calc_sum)
1231         [ $async_commit_count -gt 0 ] && error "CoS triggerred"
1232
1233         return 0
1234 }
1235 run_test 33e "DNE local operation shouldn't trigger COS"
1236
1237 # End commit on sharing tests
1238
1239 get_ost_lock_timeouts() {
1240     local nodes=${1:-$(comma_list $(osts_nodes))}
1241
1242     local locks=$(do_nodes $nodes \
1243         "lctl get_param -n ldlm.namespaces.filter-*.lock_timeouts" | calc_sum)
1244
1245     echo $locks
1246 }
1247
1248 cleanup_34() {
1249         local i
1250         trap 0
1251         do_nodes $(comma_list $(osts_nodes)) \
1252                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1253         for i in $(seq $OSTCOUNT); do
1254                 wait_osc_import_ready client ost$i
1255         done
1256 }
1257
1258 test_34() { #16129
1259         remote_ost_nodsh && skip "remote OST with nodsh" && return
1260         local OPER
1261         local lock_in
1262         local lock_out
1263         trap cleanup_34 EXIT RETURN
1264         for OPER in notimeout timeout ; do
1265                 rm $DIR1/$tfile 2>/dev/null
1266                 lock_in=$(get_ost_lock_timeouts)
1267                 if [ $OPER == "timeout" ] ; then
1268                         for j in `seq $OSTCOUNT`; do
1269                                 #define OBD_FAIL_PTLRPC_HPREQ_TIMEOUT    0x511
1270                                 do_facet ost$j lctl set_param fail_loc=0x511
1271                         done
1272                         echo lock should expire
1273                 else
1274                         for j in `seq $OSTCOUNT`; do
1275                                 #define OBD_FAIL_PTLRPC_HPREQ_NOTIMEOUT  0x512
1276                                 do_facet ost$j lctl set_param fail_loc=0x512
1277                         done
1278                         echo lock should not expire
1279                 fi
1280                 echo writing on client1
1281                 dd if=/dev/zero of=$DIR1/$tfile count=100 conv=notrunc > /dev/null 2>&1
1282                 sync &
1283                 echo reading on client2
1284                 dd of=/dev/null if=$DIR2/$tfile > /dev/null 2>&1
1285                 # wait for a lock timeout
1286                 sleep 4
1287                 lock_out=$(get_ost_lock_timeouts)
1288                 if [ $OPER == "timeout" ] ; then
1289                         if [ $lock_in == $lock_out ]; then
1290                                 error "no lock timeout happened"
1291                         else
1292                                 echo "success"
1293                         fi
1294                 else
1295                         if [ $lock_in != $lock_out ]; then
1296                                 error "lock timeout happened"
1297                         else
1298                                 echo "success"
1299                         fi
1300                 fi
1301         done
1302         cleanup_34
1303 }
1304 run_test 34 "no lock timeout under IO"
1305
1306 test_35() { # bug 17645
1307         local generation=[]
1308         local count=0
1309         gen=$(lctl get_param mdc.$FSNAME-MDT*-mdc-*.import | grep generation |
1310               awk '/generation/{print $2}')
1311         for g in $gen; do
1312                 generation[count]=$g
1313                 let count=count+1
1314         done
1315
1316         test_mkdir $MOUNT1/$tdir
1317         cancel_lru_locks mdc
1318
1319         # Let's initiate -EINTR situation by setting fail_loc and take
1320         # write lock on same file from same client. This will not cause
1321         # bl_ast yet as lock is already in local cache.
1322         #define OBD_FAIL_LDLM_INTR_CP_AST        0x317
1323         do_facet client "lctl set_param fail_loc=0x80000317"
1324         local timeout=$(do_facet $SINGLEMDS lctl get_param  -n timeout)
1325         let timeout=timeout*3
1326         local nr=0
1327         while test $nr -lt 10; do
1328                 log "Race attempt $nr"
1329                 local blk1=$(lctl get_param -n ldlm.services.ldlm_cbd.stats |
1330                              awk '/ldlm_bl_callback/ { print $2 }')
1331                 test "x$blk1" = "x" && blk1=0
1332                 createmany -o $MOUNT2/$tdir/a 4000 &
1333                 pid1=$!
1334                 sleep 1
1335
1336                 # Let's make conflict and bl_ast
1337                 ls -la $MOUNT1/$tdir > /dev/null &
1338                 pid2=$!
1339
1340                 log "Wait for $pid1 $pid2 for $timeout sec..."
1341                 sleep $timeout
1342                 kill -9 $pid1 $pid2 > /dev/null 2>&1
1343                 wait
1344                 local blk2=$(lctl get_param -n ldlm.services.ldlm_cbd.stats |
1345                              awk '/ldlm_bl_callback/ { print $2 }')
1346                 test "x$blk2" = "x" && blk2=0
1347                 test $blk2 -gt $blk1 && break
1348                 rm -fr $MOUNT1/$tdir
1349                 cancel_lru_locks mdc
1350                 let nr=nr+1
1351         done
1352         do_facet client "lctl set_param fail_loc=0x0"
1353         df -h $MOUNT1 $MOUNT2
1354         count=0
1355         gen=$(lctl get_param mdc.$FSNAME-MDT*-mdc-*.import | grep generation |
1356                 awk '/generation/{print $2}')
1357         for g in $gen; do
1358             if ! test "$g" -eq "${generation[count]}"; then
1359                 list=$(lctl list_param mdc.$FSNAME-MDT*-mdc-*.import)
1360                 local c=0
1361                 for imp in $list; do
1362                         if [ $c = $count ]; then
1363                                 break
1364                         fi
1365                         c=c+1
1366                 done
1367                 imp=$(echo "$imp" | awk -F"." '{print $2}')
1368                 error "Eviction happened on import $imp"
1369             fi
1370             let count=count+1
1371         done
1372 }
1373 run_test 35 "-EINTR cp_ast vs. bl_ast race does not evict client"
1374
1375 test_36() { #bug 16417
1376         local SIZE
1377         local SIZE_B
1378         local i
1379
1380         test_mkdir $DIR1/$tdir
1381         $LFS setstripe -c -1 $DIR1/$tdir
1382         i=0
1383         SIZE=50
1384         let SIZE_B=SIZE*1024*1024
1385         sync; sleep 2; sync # wait for delete thread
1386         wait_mds_ost_sync || error "wait_mds_ost_sync failed"
1387         wait_destroy_complete || error "wait_destroy_complete failed"
1388
1389         while [ $i -le 10 ]; do
1390                 lctl mark "start test - cycle ($i)"
1391                 local before=$(lfs_df $MOUNT1 | awk '/^filesystem/{ print $4; exit }')
1392                 dd if=/dev/zero of=$DIR1/$tdir/$tfile bs=1M count=$SIZE ||
1393                         error "dd $DIR1/$tdir/$tfile ${SIZE}MB failed"
1394                 sync          # sync data from client cache
1395                 sync_all_data # sync data from server cache (delayed allocation)
1396                 sleep 2
1397                 local after_dd=$(lfs_df $MOUNT1 | awk '/^filesystem/{ print $4; exit }')
1398                 multiop_bg_pause $DIR2/$tdir/$tfile O_r${SIZE_B}c || return 3
1399                 read_pid=$!
1400                 rm -f $DIR1/$tdir/$tfile
1401                 kill -USR1 $read_pid
1402                 wait $read_pid
1403                 sync; sleep 2; sync # Ensure new statfs
1404                 wait_delete_completed
1405                 local after=$(lfs_df $MOUNT1 | awk '/^filesystem/{ print $4; exit }')
1406                 echo "*** cycle($i) *** before($before) after_dd($after_dd)" \
1407                         "after($after)"
1408                 # this free space! not used
1409                 (( $after_dd <= $after)) ||
1410                         error "space leaked after_dd:$after_dd > after:$after"
1411                 let i=i+1
1412         done
1413 }
1414 run_test 36 "handle ESTALE/open-unlink correctly"
1415
1416 test_37() { # bug 18695
1417         test_mkdir $DIR1/$tdir
1418         multiop_bg_pause $DIR1/$tdir D_c || return 1
1419         MULTIPID=$!
1420         # create large directory (32kB seems enough from e2fsck, ~= 1000 files)
1421         createmany -m $DIR2/$tdir/f 10000
1422         # set mtime/atime backward
1423         touch -t 198001010000 $DIR2/$tdir
1424         kill -USR1 $MULTIPID
1425         nr_files=`lfs find $DIR1/$tdir -type f | wc -l`
1426         [ $nr_files -eq 10000 ] || error "$nr_files != 10000 truncated directory?"
1427
1428 }
1429 run_test 37 "check i_size is not updated for directory on close (bug 18695) =============="
1430
1431 # this should be set to past
1432 TEST_39_MTIME=`date -d "1 year ago" +%s`
1433
1434 # bug 11063
1435 test_39a() {
1436         local client1=${CLIENT1:-`hostname`}
1437         local client2=${CLIENT2:-`hostname`}
1438
1439         do_node $client1 "touch $DIR1/$tfile"
1440
1441         do_node $client1 "touch -m -d @$TEST_39_MTIME $DIR1/$tfile"
1442         local mtime1=`do_node $client2 "stat -c %Y $DIR1/$tfile"`
1443         [ "$mtime1" = $TEST_39_MTIME ] || \
1444                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
1445
1446         local d1=`do_node $client1 date +%s`
1447         do_node $client1 'echo hello >> '$DIR1/$tfile
1448         local d2=`do_node $client1 date +%s`
1449
1450         local mtime2=`do_node $client2 "stat -c %Y $DIR1/$tfile"`
1451         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
1452                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
1453
1454         do_node $client1 "mv $DIR1/$tfile $DIR1/$tfile-1"
1455
1456         for (( i=0; i < 2; i++ )) ; do
1457                 local mtime3=`do_node $client2 "stat -c %Y $DIR1/$tfile-1"`
1458                 [ "$mtime2" = "$mtime3" ] || \
1459                         error "mtime ($mtime2) changed (to $mtime3) on rename"
1460
1461                 cancel_lru_locks osc
1462                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
1463         done
1464 }
1465 run_test 39a "test from 11063 =================================="
1466
1467 test_39b() {
1468         local client1=${CLIENT1:-`hostname`}
1469         local client2=${CLIENT2:-`hostname`}
1470
1471         touch $DIR1/$tfile
1472
1473         local mtime1=`stat -c %Y $DIR1/$tfile`
1474         local mtime2=`do_node $client2 "stat -c %Y $DIR1/$tfile"`
1475
1476         sleep 1
1477         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
1478
1479         for (( i=0; i < 2; i++ )) ; do
1480                 local mtime3=`stat -c %Y $DIR1/$tfile`
1481                 local mtime4=`do_node $client2 "stat -c %Y $DIR1/$tfile"`
1482
1483                 [ "$mtime3" = "$mtime4" ] || \
1484                         error "different mtime on clients: $mtime3, $mtime4"
1485                 [ "$mtime3" = $TEST_39_MTIME ] || \
1486                         error "lost mtime: $mtime3, should be $TEST_39_MTIME"
1487
1488                 cancel_lru_locks osc
1489                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
1490         done
1491 }
1492 run_test 39b "11063 problem 1 =================================="
1493
1494 test_39c() {
1495         local client1=${CLIENT1:-`hostname`}
1496         local client2=${CLIENT2:-`hostname`}
1497
1498         echo hello > $DIR1/$tfile
1499
1500         local mtime1=`stat -c %Y $DIR1/$tfile`
1501         local mtime2=`do_node $client2 "stat -c %Y $DIR1/$tfile"`
1502         [ "$mtime1" = "$mtime2" ] || \
1503                 error "create: different mtime on clients: $mtime1, $mtime2"
1504
1505         sleep 1
1506         $TRUNCATE $DIR1/$tfile 1
1507
1508         for (( i=0; i < 2; i++ )) ; do
1509                 local mtime3=`stat -c %Y $DIR1/$tfile`
1510                 local mtime4=`do_node $client2 "stat -c %Y $DIR1/$tfile"`
1511
1512                 [ "$mtime3" = "$mtime4" ] || \
1513                         error "different mtime on clients: $mtime3, $mtime4"
1514                 [ "$mtime3" -gt $mtime2 ] || \
1515                         error "truncate did not update mtime: $mtime2, $mtime3"
1516
1517                 cancel_lru_locks osc
1518                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
1519         done
1520 }
1521 run_test 39c "check truncate mtime update ======================"
1522
1523 test_39d() { # LU-7310
1524         touch $DIR1/$tfile
1525         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
1526
1527         local mtime1=$(stat -c %Y $DIR2/$tfile)
1528         [ "$mtime1" = $TEST_39_MTIME ] ||
1529                 error "mtime: $mtime1, should be $TEST_39_MTIME"
1530
1531         # force sync write
1532         # define OBD_FAIL_OSC_NO_GRANT 0x411
1533         $LCTL set_param fail_loc=0x411
1534
1535         local d1=$(date +%s)
1536         echo hello >> $DIR1/$tfile
1537         local d2=$(date +%s)
1538
1539         $LCTL set_param fail_loc=0
1540
1541         cancel_lru_locks $OSC
1542
1543         local mtime2=$(stat -c %Y $DIR2/$tfile)
1544         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] ||
1545                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
1546 }
1547 run_test 39d "sync write should update mtime"
1548
1549 pdo_sched() {
1550         # how long 40-47 take with specific delay
1551         # sleep 0.1 # 78s
1552         # sleep 0.2 # 103s
1553         # sleep 0.3 # 124s
1554         sleep 0.5 # 164s
1555 }
1556
1557 # for pdo testing, we must cancel MDT-MDT locks as well as client locks to
1558 # avoid unexpected delays due to previous tests
1559 pdo_lru_clear() {
1560         cancel_lru_locks mdc
1561         do_nodes $(comma_list $(mdts_nodes)) \
1562                 $LCTL set_param -n ldlm.namespaces.*mdt*.lru_size=clear
1563         do_nodes $(comma_list $(mdts_nodes)) \
1564                 $LCTL get_param ldlm.namespaces.*mdt*.lock_unused_count \
1565                         ldlm.namespaces.*mdt*.lock_count | grep -v '=0'
1566 }
1567
1568 # check that pid exists hence second operation wasn't blocked by first one
1569 # if it is so then there is no conflict, return 0
1570 # else second operation is conflicting with first one, return 1
1571 check_pdo_conflict() {
1572         local pid=$1
1573         local conflict=0
1574         pdo_sched # to ensure OP1 is finished on client if OP2 is blocked by OP1
1575         if [[ `ps --pid $pid | wc -l` == 1 ]]; then
1576                 conflict=1
1577                 echo "Conflict"
1578         else
1579                 echo "No conflict"
1580         fi
1581         return $conflict
1582 }
1583
1584 # pdirop tests
1585 # test 40: check non-blocking operations
1586 test_40a() {
1587         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1588
1589         mkdir_on_mdt0 $DIR2/$tdir
1590         pdo_lru_clear
1591 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1592         do_nodes $(comma_list $(mdts_nodes)) \
1593                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1594         mkdir $DIR1/$tdir/$tfile &
1595         PID1=$!; pdo_sched
1596         touch $DIR2/$tdir/$tfile-2
1597         check_pdo_conflict $PID1 || error "create is blocked"
1598         mkdir $DIR2/$tdir/$tfile-3
1599         check_pdo_conflict $PID1 || error "mkdir is blocked"
1600         link $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-4
1601         check_pdo_conflict $PID1 || error "link is blocked"
1602         mv $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-5
1603         check_pdo_conflict $PID1 || error "rename is blocked"
1604         stat $DIR2/$tdir/$tfile-3 $DIR2/$tdir/$tfile-4 > /dev/null
1605         check_pdo_conflict $PID1 || error "getattr is blocked"
1606         rm $DIR2/$tdir/$tfile-4 $DIR2/$tdir/$tfile-5
1607         rmdir $DIR2/$tdir/$tfile-3
1608         check_pdo_conflict $PID1 || error "unlink is blocked"
1609
1610         #  all operations above shouldn't wait the first one
1611         check_pdo_conflict $PID1 || error "parallel operation is blocked"
1612         do_nodes $(comma_list $(mdts_nodes)) \
1613                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1614         wait $PID1
1615         rm -rf $DIR/$tdir
1616         return 0
1617 }
1618 run_test 40a "pdirops: create vs others =============="
1619
1620 test_40b() {
1621         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1622
1623         mkdir_on_mdt0 $DIR2/$tdir
1624         pdo_lru_clear
1625 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1626         do_nodes $(comma_list $(mdts_nodes)) \
1627                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1628         touch $DIR1/$tdir/$tfile &
1629         PID1=$!; pdo_sched
1630         # open|create
1631         touch $DIR2/$tdir/$tfile-2
1632         check_pdo_conflict $PID1 || error "create is blocked"
1633         mkdir $DIR2/$tdir/$tfile-3
1634         check_pdo_conflict $PID1 || error "mkdir is blocked"
1635         link $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-4
1636         check_pdo_conflict $PID1 || error "link is blocked"
1637         mv $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-5
1638         check_pdo_conflict $PID1 || error "rename is blocked"
1639         stat $DIR2/$tdir/$tfile-3 $DIR2/$tdir/$tfile-4 > /dev/null
1640         check_pdo_conflict $PID1 || error "getattr is blocked"
1641         rm $DIR2/$tdir/$tfile-4 $DIR2/$tdir/$tfile-5
1642         rmdir $DIR2/$tdir/$tfile-3
1643         check_pdo_conflict $PID1 || error "unlink is blocked"
1644         # all operations above shouldn't wait the first one
1645
1646         check_pdo_conflict $PID1 || error "parallel operation is blocked"
1647         do_nodes $(comma_list $(mdts_nodes)) \
1648                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1649         wait $PID1
1650         rm -rf $DIR/$tdir
1651         return 0
1652 }
1653 run_test 40b "pdirops: open|create and others =============="
1654
1655 test_40c() {
1656         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1657
1658         mkdir_on_mdt0 $DIR2/$tdir
1659         pdo_lru_clear
1660         touch $DIR1/$tdir/$tfile
1661 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1662         do_nodes $(comma_list $(mdts_nodes)) \
1663                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1664         link $DIR1/$tdir/$tfile $DIR1/$tdir/$tfile-0 &
1665         PID1=$!; pdo_sched
1666         # open|create
1667         touch $DIR2/$tdir/$tfile-2
1668         check_pdo_conflict $PID1 || error "create is blocked"
1669         mkdir $DIR2/$tdir/$tfile-3
1670         check_pdo_conflict $PID1 || error "mkdir is blocked"
1671         link $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-4
1672         check_pdo_conflict $PID1 || error "link is blocked"
1673         mv $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-5
1674         check_pdo_conflict $PID1 || error "rename is blocked"
1675         stat $DIR2/$tdir/$tfile-3 $DIR2/$tdir/$tfile-4 > /dev/null
1676         check_pdo_conflict $PID1 || error "getattr is blocked"
1677         rm $DIR2/$tdir/$tfile-4 $DIR2/$tdir/$tfile-5
1678         rmdir $DIR2/$tdir/$tfile-3
1679         check_pdo_conflict $PID1 || error "unlink is blocked"
1680
1681         # all operations above shouldn't wait the first one
1682         check_pdo_conflict $PID1 || error "parallel operation is blocked"
1683         do_nodes $(comma_list $(mdts_nodes)) \
1684                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1685         wait $PID1
1686         rm -rf $DIR/$tdir
1687         return 0
1688 }
1689 run_test 40c "pdirops: link and others =============="
1690
1691 test_40d() {
1692         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1693
1694         mkdir_on_mdt0 $DIR2/$tdir
1695         pdo_lru_clear
1696         touch $DIR1/$tdir/$tfile
1697 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1698         do_nodes $(comma_list $(mdts_nodes)) \
1699                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1700         rm $DIR1/$tdir/$tfile &
1701         PID1=$!; pdo_sched
1702         # open|create
1703         touch $DIR2/$tdir/$tfile-2
1704         check_pdo_conflict $PID1 || error "create is blocked"
1705         mkdir $DIR2/$tdir/$tfile-3
1706         check_pdo_conflict $PID1 || error "mkdir is blocked"
1707         link $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-4
1708         check_pdo_conflict $PID1 || error "link is blocked"
1709         mv $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-5
1710         check_pdo_conflict $PID1 || error "rename is blocked"
1711         stat $DIR2/$tdir/$tfile-3 $DIR2/$tdir/$tfile-4 > /dev/null
1712         check_pdo_conflict $PID1 || error "getattr is blocked"
1713         rm $DIR2/$tdir/$tfile-4 $DIR2/$tdir/$tfile-5
1714         rmdir $DIR2/$tdir/$tfile-3
1715         check_pdo_conflict $PID1 || error "unlink is blocked"
1716
1717         # all operations above shouldn't wait the first one
1718         check_pdo_conflict $PID1 || error "parallel operation is blocked"
1719         do_nodes $(comma_list $(mdts_nodes)) \
1720                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1721         wait $PID1
1722         return 0
1723 }
1724 run_test 40d "pdirops: unlink and others =============="
1725
1726 test_40e() {
1727         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1728
1729         mkdir_on_mdt0 $DIR2/$tdir
1730         pdo_lru_clear
1731         touch $DIR1/$tdir/$tfile
1732 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1733         do_nodes $(comma_list $(mdts_nodes)) \
1734                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1735         mv $DIR1/$tdir/$tfile $DIR1/$tdir/$tfile-0 &
1736         PID1=$!; pdo_sched
1737         # open|create
1738         touch $DIR2/$tdir/$tfile-2
1739         check_pdo_conflict $PID1 || error "create is blocked"
1740         mkdir $DIR2/$tdir/$tfile-3
1741         check_pdo_conflict $PID1 || error "mkdir is blocked"
1742         link $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile-4
1743         check_pdo_conflict $PID1 || error "link is blocked"
1744         stat $DIR2/$tdir/$tfile-3 $DIR2/$tdir/$tfile-4 > /dev/null
1745         check_pdo_conflict $PID1 || error "getattr is blocked"
1746         rm $DIR2/$tdir/$tfile-4 $DIR2/$tdir/$tfile-2
1747         rmdir $DIR2/$tdir/$tfile-3
1748         check_pdo_conflict $PID1 || error "unlink is blocked"
1749
1750        # all operations above shouldn't wait the first one
1751         check_pdo_conflict $PID1 || error "parallel operation is blocked"
1752         do_nodes $(comma_list $(mdts_nodes)) \
1753                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1754         wait $PID1
1755         rm -rf $DIR/$tdir
1756         return 0
1757 }
1758 run_test 40e "pdirops: rename and others =============="
1759
1760 # test 41: create blocking operations
1761 test_41a() {
1762         pdo_lru_clear
1763 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1764         do_nodes $(comma_list $(mdts_nodes)) \
1765                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1766         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1767         PID1=$! ; pdo_sched
1768         mkdir $DIR2/$tfile &
1769         PID2=$! ; pdo_sched
1770         do_nodes $(comma_list $(mdts_nodes)) \
1771                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1772         check_pdo_conflict $PID1 && { wait $PID1; echo "mkdir isn't blocked"; }
1773         wait $PID2 ; [ $? -ne 0 ] || error "mkdir must fail"
1774         rm -rf $DIR/$tfile*
1775         return 0
1776 }
1777 run_test 41a "pdirops: create vs mkdir =============="
1778
1779 test_41b() {
1780         pdo_lru_clear
1781 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1782         do_nodes $(comma_list $(mdts_nodes)) \
1783                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1784         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1785         PID1=$! ; pdo_sched
1786         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c &
1787         PID2=$! ; pdo_sched
1788         do_nodes $(comma_list $(mdts_nodes)) \
1789                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1790         check_pdo_conflict $PID1 && { wait $PID1; error "create isn't blocked"; }
1791         wait $PID2 ; [ $? -ne 0 ] || error "create must fail"
1792         rm -rf $DIR/$tfile*
1793         return 0
1794 }
1795 run_test 41b "pdirops: create vs create =============="
1796
1797 test_41c() {
1798         pdo_lru_clear
1799         touch $DIR1/$tfile-2
1800 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1801         do_nodes $(comma_list $(mdts_nodes)) \
1802                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1803         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1804         PID1=$! ; pdo_sched
1805         link $DIR2/$tfile-2 $DIR2/$tfile &
1806         PID2=$! ; pdo_sched
1807         do_nodes $(comma_list $(mdts_nodes)) \
1808                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1809         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
1810         wait $PID2 ; [ $? -ne 0 ] || error "link must fail"
1811         rm -rf $DIR/$tfile*
1812         return 0
1813 }
1814 run_test 41c "pdirops: create vs link =============="
1815
1816 test_41d() {
1817         pdo_lru_clear
1818 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1819         do_nodes $(comma_list $(mdts_nodes)) \
1820                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1821         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1822         PID1=$! ; pdo_sched
1823         rm $DIR2/$tfile &
1824         PID2=$! ; pdo_sched
1825         do_nodes $(comma_list $(mdts_nodes)) \
1826                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1827         check_pdo_conflict $PID1 && { wait $PID1; error "unlink isn't blocked"; }
1828         wait $PID2 ; [ $? -eq 0 ] || error "unlink must succeed"
1829         rm -rf $DIR/$tfile*
1830         return 0
1831 }
1832 run_test 41d "pdirops: create vs unlink =============="
1833
1834 test_41e() {
1835         pdo_lru_clear
1836         touch $DIR1/$tfile-2
1837 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1838         do_nodes $(comma_list $(mdts_nodes)) \
1839                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1840         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1841         PID1=$! ; pdo_sched
1842         mv $DIR2/$tfile-2 $DIR2/$tfile &
1843         PID2=$! ; pdo_sched
1844         do_nodes $(comma_list $(mdts_nodes)) \
1845                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1846         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
1847         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
1848         rm -rf $DIR/$tfile*
1849         return 0
1850 }
1851 run_test 41e "pdirops: create and rename (tgt) =============="
1852
1853 test_41f() {
1854         pdo_lru_clear
1855 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1856         do_nodes $(comma_list $(mdts_nodes)) \
1857                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1858         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1859         PID1=$! ; pdo_sched
1860         mv $DIR2/$tfile $DIR2/$tfile-2 &
1861         PID2=$! ; pdo_sched
1862         do_nodes $(comma_list $(mdts_nodes)) \
1863                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1864         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
1865         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
1866         rm -rf $DIR/$tfile*
1867         return 0
1868 }
1869 run_test 41f "pdirops: create and rename (src) =============="
1870
1871 test_41g() {
1872         pdo_lru_clear
1873 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1874         do_nodes $(comma_list $(mdts_nodes)) \
1875                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1876         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1877         PID1=$! ; pdo_sched
1878         stat $DIR2/$tfile > /dev/null &
1879         PID2=$! ; pdo_sched
1880         do_nodes $(comma_list $(mdts_nodes)) \
1881                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1882         check_pdo_conflict $PID1 && { wait $PID1; error "getattr isn't blocked"; }
1883         wait $PID2 ; [ $? -eq 0 ] || error "stat must succeed"
1884         rm -rf $DIR/$tfile*
1885         return 0
1886 }
1887 run_test 41g "pdirops: create vs getattr =============="
1888
1889 test_41h() {
1890         pdo_lru_clear
1891 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1892         do_nodes $(comma_list $(mdts_nodes)) \
1893                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1894         $MULTIOP $DIR1/$tfile oO_CREAT:O_RDWR:c &
1895         PID1=$! ; pdo_sched
1896         ls -lia $DIR2/ > /dev/null &
1897         PID2=$! ; pdo_sched
1898         do_nodes $(comma_list $(mdts_nodes)) \
1899                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1900         check_pdo_conflict $PID1 && { wait $PID1; error "readdir isn't blocked"; }
1901         wait $PID2
1902         rm -rf $DIR/$tfile*
1903         return 0
1904 }
1905 run_test 41h "pdirops: create vs readdir =============="
1906
1907 sub_test_41i() {
1908         local PID1 PID2
1909         local fail_loc="$1"
1910         local ret=0
1911
1912         do_nodes $(comma_list $(mdts_nodes)) \
1913                 "lctl set_param -n fail_loc=${fail_loc} || true" &>/dev/null
1914
1915         $MULTIOP $DIR1/$tfile oO_CREAT:O_EXCL:c 2>/dev/null &
1916         PID1=$!
1917         sleep 0.2
1918         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c 2>/dev/null &
1919         PID2=$!
1920
1921         if ! wait $PID1 && ! wait $PID2; then
1922                 echo "Both creates failed (1 should fail, 1 should succeed)"
1923                 ret=1
1924         elif wait $PID1 && wait $PID2; then
1925                 echo "Both creates succeeded (1 should fail, 1 should succeed)"
1926                 ret=2
1927         fi
1928
1929         #Clean
1930         do_nodes $(comma_list $(mdts_nodes)) \
1931                 "lctl set_param -n fail_loc=0x0 || true" &>/dev/null
1932         rm -f $DIR/$tfile
1933
1934         return $ret
1935 }
1936
1937 test_41i() {
1938         (( $MDS1_VERSION >= $(version_code 2.13.56) )) ||
1939                 skip "Need MDS version newer than 2.13.56"
1940         local msg fail_loc
1941
1942 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN         0x169
1943 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN2        0x16a
1944         for fail_loc in "0x80000169" "0x8000016a"; do
1945                 echo "Begin 100 tests with fail_loc=$fail_loc"
1946                 printf "Progress: "
1947                 for i in {1..100}; do
1948                         printf "*"
1949                         msg=$(sub_test_41i "$fail_loc") ||
1950                                 { echo; error "iter=$i : $msg"; }
1951                 done
1952                 echo
1953         done
1954 }
1955 run_test 41i "reint_open: create vs create"
1956
1957
1958 # test 42: unlink and blocking operations
1959 test_42a() {
1960         pdo_lru_clear
1961 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1962         do_nodes $(comma_list $(mdts_nodes)) \
1963                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1964         mkdir $DIR1/$tfile &
1965         PID1=$! ; pdo_sched
1966         mkdir $DIR2/$tfile &
1967         PID2=$! ; pdo_sched
1968         do_nodes $(comma_list $(mdts_nodes)) \
1969                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1970         check_pdo_conflict $PID1 && { wait $PID1; error "mkdir isn't blocked"; }
1971         wait $PID2 ; [ $? -ne 0 ] || error "mkdir must fail"
1972         rm -rf $DIR/$tfile*
1973         return 0
1974 }
1975 run_test 42a "pdirops: mkdir vs mkdir =============="
1976
1977 test_42b() {
1978         pdo_lru_clear
1979 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1980         do_nodes $(comma_list $(mdts_nodes)) \
1981                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
1982         mkdir $DIR1/$tfile &
1983         PID1=$! ; pdo_sched
1984         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c &
1985         PID2=$! ; pdo_sched
1986         do_nodes $(comma_list $(mdts_nodes)) \
1987                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
1988         check_pdo_conflict $PID1 && { wait $PID1; error "create isn't blocked"; }
1989         wait $PID2 ; [ $? -ne 0 ] || error "create must fail"
1990         rm -rf $DIR/$tfile*
1991         return 0
1992 }
1993 run_test 42b "pdirops: mkdir vs create =============="
1994
1995 test_42c() {
1996         pdo_lru_clear
1997         touch $DIR1/$tfile-2
1998 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
1999         do_nodes $(comma_list $(mdts_nodes)) \
2000                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2001         mkdir $DIR1/$tfile &
2002         PID1=$! ; pdo_sched
2003         link $DIR2/$tfile-2 $DIR2/$tfile &
2004         PID2=$! ; pdo_sched
2005         do_nodes $(comma_list $(mdts_nodes)) \
2006                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2007         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
2008         wait $PID2 ; [ $? -ne 0 ] || error "link must fail"
2009         rm -rf $DIR/$tfile*
2010         return 0
2011 }
2012 run_test 42c "pdirops: mkdir vs link =============="
2013
2014 test_42d() {
2015         pdo_lru_clear
2016 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2017         do_nodes $(comma_list $(mdts_nodes)) \
2018                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2019         mkdir $DIR1/$tfile &
2020         PID1=$! ; pdo_sched
2021         rmdir $DIR2/$tfile &
2022         PID2=$! ; pdo_sched
2023         do_nodes $(comma_list $(mdts_nodes)) \
2024                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2025         check_pdo_conflict $PID1 && { wait $PID1; error "unlink isn't blocked"; }
2026         wait $PID2 ; [ $? -eq 0 ] || error "unlink must succeed"
2027         rm -rf $DIR/$tfile*
2028         return 0
2029 }
2030 run_test 42d "pdirops: mkdir vs unlink =============="
2031
2032 test_42e() {
2033         pdo_lru_clear
2034         touch $DIR1/$tfile-2
2035 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2036         do_nodes $(comma_list $(mdts_nodes)) \
2037                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2038         mkdir $DIR1/$tfile &
2039         PID1=$! ; pdo_sched
2040         mv -T $DIR2/$tfile-2 $DIR2/$tfile &
2041         PID2=$! ; pdo_sched
2042         do_nodes $(comma_list $(mdts_nodes)) \
2043                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2044         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2045         wait $PID2 ; [ $? -ne 0 ] || error "rename must fail"
2046         rm -rf $DIR/$tfile*
2047         return 0
2048 }
2049 run_test 42e "pdirops: mkdir and rename (tgt) =============="
2050
2051 test_42f() {
2052         pdo_lru_clear
2053 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2054         do_nodes $(comma_list $(mdts_nodes)) \
2055                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2056         mkdir $DIR1/$tfile &
2057         PID1=$! ; pdo_sched
2058         mv $DIR2/$tfile $DIR2/$tfile-2 &
2059         PID2=$! ; pdo_sched
2060         do_nodes $(comma_list $(mdts_nodes)) \
2061                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2062         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2063         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2064         rm -rf $DIR/$tfile*
2065         return 0
2066 }
2067 run_test 42f "pdirops: mkdir and rename (src) =============="
2068
2069 test_42g() {
2070         mkdir_on_mdt0 $DIR1/$tdir
2071         pdo_lru_clear
2072 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2073         do_nodes $(comma_list $(mdts_nodes)) \
2074                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2075         mkdir $DIR1/$tdir/$tfile &
2076         PID1=$! ; pdo_sched
2077         stat $DIR2/$tdir/$tfile > /dev/null &
2078         PID2=$! ; pdo_sched
2079         do_nodes $(comma_list $(mdts_nodes)) \
2080                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2081         check_pdo_conflict $PID1 && { wait $PID1; error "getattr isn't blocked"; }
2082         wait $PID2 ; [ $? -eq 0 ] || error "stat must succeed"
2083         rm -rf $DIR/$tdir
2084 }
2085 run_test 42g "pdirops: mkdir vs getattr =============="
2086
2087 test_42h() {
2088         pdo_lru_clear
2089 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2090         do_nodes $(comma_list $(mdts_nodes)) \
2091                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2092         mkdir $DIR1/$tfile &
2093         PID1=$! ; pdo_sched
2094         ls -lia $DIR2/ > /dev/null &
2095         PID2=$! ; pdo_sched
2096         do_nodes $(comma_list $(mdts_nodes)) \
2097                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2098         check_pdo_conflict $PID1 && { wait $PID1; error "readdir isn't blocked"; }
2099         wait $PID2
2100         rm -rf $DIR/$tfile*
2101         return 0
2102 }
2103 run_test 42h "pdirops: mkdir vs readdir =============="
2104
2105 # test 43: rmdir,mkdir won't return -EEXIST
2106 test_43a() {
2107         for i in {1..1000}; do
2108                 mkdir $DIR1/$tdir || error "mkdir $tdir failed"
2109                 rmdir $DIR2/$tdir || error "rmdir $tdir failed"
2110         done
2111         return 0
2112 }
2113 run_test 43a "rmdir,mkdir doesn't return -EEXIST =============="
2114
2115 test_43b() {
2116         pdo_lru_clear
2117         touch $DIR1/$tfile
2118 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2119         do_nodes $(comma_list $(mdts_nodes)) \
2120                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2121         rm $DIR1/$tfile &
2122         PID1=$! ; pdo_sched
2123         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c &
2124         PID2=$! ; pdo_sched
2125         do_nodes $(comma_list $(mdts_nodes)) \
2126                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2127         check_pdo_conflict $PID1 && { wait $PID1; error "create isn't blocked"; }
2128         wait $PID2 ; [ $? -eq 0 ] || error "create must succeed"
2129         rm -rf $DIR/$tfile*
2130         return 0
2131 }
2132 run_test 43b "pdirops: unlink vs create =============="
2133
2134 test_43c() {
2135         pdo_lru_clear
2136         touch $DIR1/$tfile
2137         touch $DIR1/$tfile-2
2138 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2139         do_nodes $(comma_list $(mdts_nodes)) \
2140                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2141         rm $DIR1/$tfile &
2142         PID1=$! ; pdo_sched
2143         link $DIR2/$tfile-2 $DIR2/$tfile &
2144         PID2=$! ; pdo_sched
2145         do_nodes $(comma_list $(mdts_nodes)) \
2146                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2147         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
2148         wait $PID2 ; [ $? -eq 0 ] || error "link must succeed"
2149         rm -rf $DIR/$tfile*
2150         return 0
2151 }
2152 run_test 43c "pdirops: unlink vs link =============="
2153
2154 test_43d() {
2155         pdo_lru_clear
2156         touch $DIR1/$tfile
2157 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2158         do_nodes $(comma_list $(mdts_nodes)) \
2159                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2160         rm $DIR1/$tfile &
2161         PID1=$! ; pdo_sched
2162         rm $DIR2/$tfile &
2163         PID2=$! ; pdo_sched
2164         do_nodes $(comma_list $(mdts_nodes)) \
2165                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2166         check_pdo_conflict $PID1 && { wait $PID1; error "unlink isn't blocked"; }
2167         wait $PID2 ; [ $? -ne 0 ] || error "unlink must fail"
2168         rm -rf $DIR/$tfile*
2169         return 0
2170 }
2171 run_test 43d "pdirops: unlink vs unlink =============="
2172
2173 test_43e() {
2174         pdo_lru_clear
2175         touch $DIR1/$tfile
2176         touch $DIR1/$tfile-2
2177 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2178         do_nodes $(comma_list $(mdts_nodes)) \
2179                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2180         rm $DIR1/$tfile &
2181         PID1=$! ; pdo_sched
2182         mv -u $DIR2/$tfile-2 $DIR2/$tfile &
2183         PID2=$! ; pdo_sched
2184         do_nodes $(comma_list $(mdts_nodes)) \
2185                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2186         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2187         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2188         rm -rf $DIR/$tfile*
2189         return 0
2190 }
2191 run_test 43e "pdirops: unlink and rename (tgt) =============="
2192
2193 test_43f() {
2194         pdo_lru_clear
2195         touch $DIR1/$tfile
2196 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2197         do_nodes $(comma_list $(mdts_nodes)) \
2198                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2199         rm $DIR1/$tfile &
2200         PID1=$! ; pdo_sched
2201         mv $DIR2/$tfile $DIR2/$tfile-2 &
2202         PID2=$! ; pdo_sched
2203         do_nodes $(comma_list $(mdts_nodes)) \
2204                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2205         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2206         wait $PID2 ; [ $? -ne 0 ] || error "rename must fail"
2207         rm -rf $DIR/$tfile*
2208         return 0
2209 }
2210 run_test 43f "pdirops: unlink and rename (src) =============="
2211
2212 test_43g() {
2213         pdo_lru_clear
2214         touch $DIR1/$tfile
2215 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2216         do_nodes $(comma_list $(mdts_nodes)) \
2217                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2218         rm $DIR1/$tfile &
2219         PID1=$! ; pdo_sched
2220         stat $DIR2/$tfile > /dev/null &
2221         PID2=$! ; pdo_sched
2222         do_nodes $(comma_list $(mdts_nodes)) \
2223                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2224         check_pdo_conflict $PID1 && { wait $PID1; error "getattr isn't blocked"; }
2225         wait $PID2 ; [ $? -ne 0 ] || error "stat must fail"
2226         rm -rf $DIR/$tfile*
2227         return 0
2228 }
2229 run_test 43g "pdirops: unlink vs getattr =============="
2230
2231 test_43h() {
2232         pdo_lru_clear
2233         touch $DIR1/$tfile
2234 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2235         do_nodes $(comma_list $(mdts_nodes)) \
2236                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2237         rm $DIR1/$tfile &
2238         PID1=$! ; pdo_sched
2239         ls -lia $DIR2/ > /dev/null &
2240         PID2=$! ; pdo_sched
2241         do_nodes $(comma_list $(mdts_nodes)) \
2242                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2243         check_pdo_conflict $PID1 && { wait $PID1; error "readdir isn't blocked"; }
2244         wait $PID2
2245         rm -rf $DIR/$tfile*
2246         return 0
2247 }
2248 run_test 43h "pdirops: unlink vs readdir =============="
2249
2250 test_43i() {
2251         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2252         pdo_lru_clear
2253         touch $DIR1/$tfile
2254 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2255         do_nodes $(comma_list $(mdts_nodes)) \
2256                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2257         rm $DIR1/$tfile &
2258         PID1=$! ; pdo_sched
2259         $LFS mkdir -i 1 $DIR2/$tfile &
2260         PID2=$! ; pdo_sched
2261         do_nodes $(comma_list $(mdts_nodes)) \
2262                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2263         check_pdo_conflict $PID1 &&
2264                 { wait $PID1; error "remote mkdir isn't blocked"; }
2265         wait $PID2 ; [ $? -eq 0 ] || error "remote mkdir must succeed"
2266         rm -rf $DIR/$tfile*
2267         return 0
2268 }
2269 run_test 43i "pdirops: unlink vs remote mkdir"
2270
2271 test_43j() {
2272         [[ $MDS1_VERSION -lt $(version_code 2.13.52) ]] &&
2273                 skip "Need MDS version newer than 2.13.52"
2274
2275         mkdir_on_mdt0 $DIR1/$tdir
2276         for i in {1..100}; do
2277 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_CREATE_RACE         0x167
2278                 do_nodes $(comma_list $(mdts_nodes)) \
2279                         "lctl set_param -n fail_loc=0x80000167 2>/dev/null ||
2280                                 true"
2281                 OK=0
2282                 mkdir $DIR1/$tdir/sub &
2283                 PID1=$!
2284                 mkdir $DIR2/$tdir/sub && ((OK++))
2285                 wait $PID1 && ((OK++))
2286                 (( OK == 1 )) || error "exactly one mkdir should succeed"
2287
2288                 rmdir $DIR1/$tdir/sub || error "rmdir failed"
2289         done
2290         return 0
2291 }
2292 run_test 43j "racy mkdir return EEXIST =============="
2293
2294 sub_test_43k() {
2295         local PID1 PID2
2296         local fail_loc="$1"
2297         local ret=0
2298
2299         # We test in a separate directory to be able to unblock server thread in
2300         # cfs_race() if LCK_PW is taken on the parent by mdt_reint_unlink.
2301         test_mkdir $DIR2/$tdir
2302         touch $DIR2/$tdir/$tfile
2303         pdo_lru_clear
2304
2305         do_nodes $(comma_list $(mdts_nodes)) \
2306                 "lctl set_param -n fail_loc=${fail_loc} || true" &>/dev/null
2307         echo content > $DIR1/$tdir/$tfile & PID1=$!
2308         pdo_sched
2309         multiop $DIR2/$tdir/$tfile u & PID2=$!
2310
2311         wait $PID1 ||
2312                 { ret=$?; \
2313                 echo -n "overwriting $tfile should succeed (err=$ret); "; }
2314         wait $PID2 ||
2315                 { ret=$?; \
2316                 echo -n "unlinking $tfile should succeed (err=$ret);"; }
2317
2318         #Clean
2319         do_nodes $(comma_list $(mdts_nodes)) \
2320                 "lctl set_param -n fail_loc=0x0 || true" &>/dev/null
2321         rm -rf $DIR/$tdir
2322
2323         return $ret
2324 }
2325
2326 test_43k() {
2327         (( $MDS1_VERSION >= $(version_code 2.13.56) )) ||
2328                 skip "Need MDS version newer than 2.13.56"
2329         local msg fail_loc
2330
2331 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN         0x169
2332 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN2        0x16a
2333         for fail_loc in "0x80000169" "0x8000016a"; do
2334                 echo "Begin 100 tests with fail_loc=$fail_loc"
2335                 printf "Progress: "
2336                 for i in {1..100}; do
2337                         printf "*"
2338                         msg=$(sub_test_43k "$fail_loc") ||
2339                                 { echo; error "iter=$i : $msg"; }
2340                 done
2341                 echo
2342         done
2343
2344         #Clean
2345         reset_fail_loc
2346
2347         return 0
2348 }
2349 run_test 43k "unlink vs create"
2350
2351 # test 44: rename tgt and blocking operations
2352 test_44a() {
2353         pdo_lru_clear
2354         touch $DIR1/$tfile-2
2355 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2   0x146
2356         do_nodes $(comma_list $(mdts_nodes)) \
2357                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2358         mv $DIR1/$tfile-2 $DIR1/$tfile &
2359         PID1=$! ; pdo_sched
2360         mkdir $DIR2/$tfile &
2361         PID2=$! ; pdo_sched
2362         do_nodes $(comma_list $(mdts_nodes)) \
2363                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2364         check_pdo_conflict $PID1 && { wait $PID1; date;error "mkdir isn't blocked"; }
2365         wait $PID2 ; [ $? -ne 0 ] || error "mkdir must fail"
2366         date
2367         rm -rf $DIR/$tfile*
2368         return 0
2369 }
2370 run_test 44a "pdirops: rename tgt vs mkdir =============="
2371
2372 test_44b() {
2373         pdo_lru_clear
2374         touch $DIR1/$tfile-2
2375 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2376         do_nodes $(comma_list $(mdts_nodes)) \
2377                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2378         mv $DIR1/$tfile-2 $DIR1/$tfile &
2379         PID1=$! ; pdo_sched
2380         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c &
2381         PID2=$! ; pdo_sched
2382         do_nodes $(comma_list $(mdts_nodes)) \
2383                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2384         check_pdo_conflict $PID1 && { wait $PID1; error "create isn't blocked"; }
2385         wait $PID2 ; [ $? -ne 0 ] || error "create must fail"
2386         rm -rf $DIR/$tfile*
2387         return 0
2388 }
2389 run_test 44b "pdirops: rename tgt vs create =============="
2390
2391 test_44c() {
2392         pdo_lru_clear
2393         touch $DIR1/$tfile-2
2394         touch $DIR1/$tfile-3
2395 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2396         do_nodes $(comma_list $(mdts_nodes)) \
2397                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2398         mv $DIR1/$tfile-2 $DIR1/$tfile &
2399         PID1=$! ; pdo_sched
2400         link $DIR2/$tfile-3 $DIR2/$tfile &
2401         PID2=$! ; pdo_sched
2402         do_nodes $(comma_list $(mdts_nodes)) \
2403                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2404         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
2405         wait $PID2 ; [ $? -ne 0 ] || error "link must fail"
2406         rm -rf $DIR/$tfile*
2407         return 0
2408 }
2409 run_test 44c "pdirops: rename tgt vs link =============="
2410
2411 test_44d() {
2412         pdo_lru_clear
2413         touch $DIR1/$tfile-2
2414 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2415         do_nodes $(comma_list $(mdts_nodes)) \
2416                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2417         mv $DIR1/$tfile-2 $DIR1/$tfile &
2418         PID1=$! ; pdo_sched
2419         rm $DIR2/$tfile &
2420         PID2=$! ; pdo_sched
2421         do_nodes $(comma_list $(mdts_nodes)) \
2422                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2423         check_pdo_conflict $PID1 && { wait $PID1; error "unlink isn't blocked"; }
2424         wait $PID2 ; [ $? -eq 0 ] || error "unlink must succeed"
2425         rm -rf $DIR/$tfile*
2426         return 0
2427 }
2428 run_test 44d "pdirops: rename tgt vs unlink =============="
2429
2430 test_44e() {
2431         pdo_lru_clear
2432         touch $DIR1/$tfile
2433         touch $DIR1/$tfile-2
2434         touch $DIR1/$tfile-3
2435 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2436         do_nodes $(comma_list $(mdts_nodes)) \
2437                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2438         mv $DIR1/$tfile-2 $DIR1/$tfile &
2439         PID1=$! ; pdo_sched
2440         mv $DIR2/$tfile-3 $DIR2/$tfile &
2441         PID2=$! ; pdo_sched
2442         do_nodes $(comma_list $(mdts_nodes)) \
2443                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2444         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2445         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2446         rm -rf $DIR/$tfile*
2447         return 0
2448 }
2449 run_test 44e "pdirops: rename tgt and rename (tgt) =============="
2450
2451 test_44f() {
2452         pdo_lru_clear
2453         touch $DIR1/$tfile-2
2454         touch $DIR1/$tfile-3
2455 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2456         do_nodes $(comma_list $(mdts_nodes)) \
2457                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2458         mv $DIR1/$tfile-2 $DIR1/$tfile &
2459         PID1=$! ; pdo_sched
2460         mv $DIR2/$tfile $DIR2/$tfile-3 &
2461         PID2=$! ; pdo_sched
2462         do_nodes $(comma_list $(mdts_nodes)) \
2463                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2464         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2465         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2466         rm -rf $DIR/$tfile*
2467         return 0
2468 }
2469 run_test 44f "pdirops: rename tgt and rename (src) =============="
2470
2471 test_44g() {
2472         pdo_lru_clear
2473         touch $DIR1/$tfile-2
2474 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2475         do_nodes $(comma_list $(mdts_nodes)) \
2476                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2477         mv $DIR1/$tfile-2 $DIR1/$tfile &
2478         PID1=$! ; pdo_sched
2479         stat $DIR2/$tfile > /dev/null &
2480         PID2=$! ; pdo_sched
2481         do_nodes $(comma_list $(mdts_nodes)) \
2482                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2483         check_pdo_conflict $PID1 && { wait $PID1; error "getattr isn't blocked"; }
2484         wait $PID2 ; [ $? -eq 0 ] || error "stat must succeed"
2485         rm -rf $DIR/$tfile*
2486         return 0
2487 }
2488 run_test 44g "pdirops: rename tgt vs getattr =============="
2489
2490 test_44h() {
2491         pdo_lru_clear
2492         touch $DIR1/$tfile-2
2493 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2    0x146
2494         do_nodes $(comma_list $(mdts_nodes)) \
2495                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2496         mv $DIR1/$tfile-2 $DIR1/$tfile &
2497         PID1=$! ; pdo_sched
2498         ls -lia $DIR2/ > /dev/null &
2499         PID2=$! ; pdo_sched
2500         do_nodes $(comma_list $(mdts_nodes)) \
2501                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2502         check_pdo_conflict $PID1 && { wait $PID1; error "readdir isn't blocked"; }
2503         wait $PID2
2504         rm -rf $DIR/$tfile*
2505         return 0
2506 }
2507 run_test 44h "pdirops: rename tgt vs readdir =============="
2508
2509 # test 44: rename tgt and blocking operations
2510 test_44i() {
2511         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2512         pdo_lru_clear
2513         touch $DIR1/$tfile-2
2514 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK2   0x146
2515         do_nodes $(comma_list $(mdts_nodes)) \
2516                 "lctl set_param -n fail_loc=0x80000146 2>/dev/null || true"
2517         mv $DIR1/$tfile-2 $DIR1/$tfile &
2518         PID1=$! ; pdo_sched
2519         $LFS mkdir -i 1 $DIR2/$tfile &
2520         PID2=$! ; pdo_sched
2521         do_nodes $(comma_list $(mdts_nodes)) \
2522                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2523         check_pdo_conflict $PID1 && { wait $PID1;
2524                                 error "remote mkdir isn't blocked"; }
2525         wait $PID2 ; [ $? -ne 0 ] || error "remote mkdir must fail"
2526         rm -rf $DIR/$tfile*
2527         return 0
2528 }
2529 run_test 44i "pdirops: rename tgt vs remote mkdir"
2530
2531 # test 45: rename,mkdir doesn't fail with -EEXIST
2532 test_45a() {
2533         for i in {1..1000}; do
2534                 mkdir $DIR1/$tdir || error "mkdir $tdir failed"
2535                 mrename $DIR2/$tdir $DIR2/$tdir.$i > /dev/null ||
2536                         error "mrename to $tdir.$i failed"
2537         done
2538         rm -rf $DIR/$tdir*
2539         return 0
2540 }
2541 run_test 45a "rename,mkdir doesn't return -EEXIST =============="
2542
2543 test_45b() {
2544         pdo_lru_clear
2545         touch $DIR1/$tfile
2546 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2547         do_nodes $(comma_list $(mdts_nodes)) \
2548                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2549         mv $DIR1/$tfile $DIR1/$tfile-2 &
2550         PID1=$! ; pdo_sched
2551         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c &
2552         PID2=$! ; pdo_sched
2553         do_nodes $(comma_list $(mdts_nodes)) \
2554                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2555         check_pdo_conflict $PID1 && { wait $PID1; error "create isn't blocked"; }
2556         wait $PID2 ; [ $? -eq 0 ] || error "create must succeed"
2557         rm -rf $DIR/$tfile*
2558         return 0
2559 }
2560 run_test 45b "pdirops: rename src vs create =============="
2561
2562 test_45c() {
2563         pdo_lru_clear
2564         touch $DIR1/$tfile
2565         touch $DIR1/$tfile-3
2566 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2567         do_nodes $(comma_list $(mdts_nodes)) \
2568                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2569         mv $DIR1/$tfile $DIR1/$tfile-2 &
2570         PID1=$! ; pdo_sched
2571         link $DIR2/$tfile-3 $DIR2/$tfile &
2572         PID2=$! ; pdo_sched
2573         do_nodes $(comma_list $(mdts_nodes)) \
2574                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2575         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
2576         wait $PID2 ; [ $? -eq 0 ] || error "link must succeed"
2577         rm -rf $DIR/$tfile*
2578         return 0
2579 }
2580 run_test 45c "pdirops: rename src vs link =============="
2581
2582 test_45d() {
2583         pdo_lru_clear
2584         touch $DIR1/$tfile
2585 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2586         do_nodes $(comma_list $(mdts_nodes)) \
2587                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2588         mv $DIR1/$tfile $DIR1/$tfile-2 &
2589         PID1=$! ; pdo_sched
2590         rm $DIR2/$tfile &
2591         PID2=$! ; pdo_sched
2592         do_nodes $(comma_list $(mdts_nodes)) \
2593                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2594         check_pdo_conflict $PID1 && { wait $PID1; error "unlink isn't blocked"; }
2595         wait $PID2 ; [ $? -ne 0 ] || error "unlink must fail"
2596         rm -rf $DIR/$tfile*
2597         return 0
2598 }
2599 run_test 45d "pdirops: rename src vs unlink =============="
2600
2601 test_45e() {
2602         pdo_lru_clear
2603         touch $DIR1/$tfile
2604         touch $DIR1/$tfile-3
2605 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2606         do_nodes $(comma_list $(mdts_nodes)) \
2607                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2608         mv $DIR1/$tfile $DIR1/$tfile-2 &
2609         PID1=$! ; pdo_sched
2610         mv $DIR2/$tfile-3 $DIR2/$tfile &
2611         PID2=$! ; pdo_sched
2612         do_nodes $(comma_list $(mdts_nodes)) \
2613                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2614         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2615         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2616         rm -rf $DIR/$tfile*
2617         return 0
2618 }
2619 run_test 45e "pdirops: rename src and rename (tgt) =============="
2620
2621 test_45f() {
2622         pdo_lru_clear
2623         touch $DIR1/$tfile
2624 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2625         do_nodes $(comma_list $(mdts_nodes)) \
2626                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2627         mv $DIR1/$tfile $DIR1/$tfile-2 &
2628         PID1=$! ; pdo_sched
2629         mv $DIR2/$tfile $DIR2/$tfile-3 &
2630         PID2=$! ; pdo_sched
2631         do_nodes $(comma_list $(mdts_nodes)) \
2632                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2633         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2634         wait $PID2 ; [ $? -ne 0 ] || error "rename must fail"
2635         rm -rf $DIR/$tfile*
2636         return 0
2637 }
2638 run_test 45f "pdirops: rename src and rename (src) =============="
2639
2640 test_45g() {
2641         pdo_lru_clear
2642         touch $DIR1/$tfile
2643 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2644         do_nodes $(comma_list $(mdts_nodes)) \
2645                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2646         mv $DIR1/$tfile $DIR1/$tfile-2 &
2647         PID1=$! ; pdo_sched
2648         stat $DIR2/$tfile > /dev/null &
2649         PID2=$! ; pdo_sched
2650         do_nodes $(comma_list $(mdts_nodes)) \
2651                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2652         check_pdo_conflict $PID1 && { wait $PID1; error "getattr isn't blocked"; }
2653         wait $PID2 ; [ $? -ne 0 ] || error "stat must fail"
2654         rm -rf $DIR/$tfile*
2655         return 0
2656 }
2657 run_test 45g "pdirops: rename src vs getattr =============="
2658
2659 test_45h() {
2660         pdo_lru_clear
2661         touch $DIR1/$tfile
2662 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2663         do_nodes $(comma_list $(mdts_nodes)) \
2664                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2665         mv $DIR1/$tfile $DIR1/$tfile-2 &
2666         PID1=$! ; pdo_sched
2667         ls -lia $DIR2/ > /dev/null &
2668         do_nodes $(comma_list $(mdts_nodes)) \
2669                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2670         check_pdo_conflict $PID1 && { wait $PID1; error "readdir isn't blocked"; }
2671         wait $PID2
2672         rm -rf $DIR/$tfile*
2673         return 0
2674 }
2675 run_test 45h "pdirops: unlink vs readdir =============="
2676
2677 test_45i() {
2678         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2679         pdo_lru_clear
2680         touch $DIR1/$tfile
2681 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2682         do_nodes $(comma_list $(mdts_nodes)) \
2683                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2684         mv $DIR1/$tfile $DIR1/$tfile-2 &
2685         PID1=$! ; pdo_sched
2686         $LFS mkdir -i 1 $DIR2/$tfile &
2687         PID2=$! ; pdo_sched
2688         do_nodes $(comma_list $(mdts_nodes)) \
2689                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2690         check_pdo_conflict $PID1 && { wait $PID1;
2691                                 error "create remote dir isn't blocked"; }
2692         wait $PID2 ; [ $? -eq 0 ] || error "create remote dir must succeed"
2693         rm -rf $DIR/$tfile*
2694         return 0
2695 }
2696 run_test 45i "pdirops: rename src vs remote mkdir"
2697
2698 sub_test_45j() {
2699         local PID1 PID2
2700         local fail_loc="$1"
2701         local ret=0
2702
2703         # We test in a sparate directory to be able to unblock server thread in
2704         # cfs_race if LCK_PW is taken on the parent by mdt_reint_rename.
2705         test_mkdir $DIR2/$tdir
2706         echo file1 > $DIR2/$tdir/$tfile
2707         echo file2 > $DIR2/$tdir/$tfile-2
2708         pdo_lru_clear
2709
2710         do_nodes $(comma_list $(mdts_nodes)) \
2711                 "lctl set_param -n fail_loc=${fail_loc} || true" &>/dev/null
2712
2713         cat $DIR1/$tdir/$tfile >/dev/null &
2714         PID1=$!
2715         pdo_sched
2716         mrename $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile > /dev/null &
2717         PID2=$!
2718
2719         wait $PID1 ||
2720                 { ret=$?; echo -n "cat $tfile should succeed (err=$ret); "; }
2721         wait $PID2 ||
2722                 { ret=$?; \
2723                 echo -n "mrename $tfile-2 to $tfile failed (err=$ret);"; }
2724
2725         #Clean
2726         do_nodes $(comma_list $(mdts_nodes)) \
2727                 "lctl set_param -n fail_loc=0x0 || true" &>/dev/null
2728         rm -rf $DIR/$tdir
2729
2730         return $ret
2731 }
2732
2733 test_45j() {
2734         (( $MDS1_VERSION >= $(version_code 2.13.56) )) ||
2735                 skip "Need MDS version newer than 2.13.56"
2736         local msg fail_loc
2737
2738 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN         0x169
2739 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN2        0x16a
2740         for fail_loc in "0x80000169" "0x8000016a"; do
2741                 echo "Begin 100 tests with fail_loc=$fail_loc"
2742                 printf "Progress: "
2743                 for i in {1..100}; do
2744                         printf "*"
2745                         msg=$(sub_test_45j "$fail_loc") ||
2746                                 { echo; error "iter=$i : $msg"; }
2747                 done
2748                 echo
2749         done
2750 }
2751 run_test 45j "read vs rename =============="
2752
2753 # test 46: link and blocking operations
2754 test_46a() {
2755         pdo_lru_clear
2756         touch $DIR1/$tfile-2
2757 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2758         do_nodes $(comma_list $(mdts_nodes)) \
2759                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2760         link $DIR1/$tfile-2 $DIR1/$tfile &
2761         PID1=$! ; pdo_sched
2762         mkdir $DIR2/$tfile &
2763         PID2=$! ; pdo_sched
2764         do_nodes $(comma_list $(mdts_nodes)) \
2765                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2766         check_pdo_conflict $PID1 && { wait $PID1; error "mkdir isn't blocked"; }
2767         wait $PID2 ; [ $? -ne 0 ] || error "mkdir must fail"
2768         rm -rf $DIR/$tfile*
2769         return 0
2770 }
2771 run_test 46a "pdirops: link vs mkdir =============="
2772
2773 test_46b() {
2774         pdo_lru_clear
2775         touch $DIR1/$tfile-2
2776 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2777         do_nodes $(comma_list $(mdts_nodes)) \
2778                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2779         link $DIR1/$tfile-2 $DIR1/$tfile &
2780         PID1=$! ; pdo_sched
2781         $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c &
2782         PID2=$! ; pdo_sched
2783         do_nodes $(comma_list $(mdts_nodes)) \
2784                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2785         check_pdo_conflict $PID1 && { wait $PID1; error "create isn't blocked"; }
2786         wait $PID2 ; [ $? -ne 0 ] || error "create must fail"
2787         rm -rf $DIR/$tfile*
2788         return 0
2789 }
2790 run_test 46b "pdirops: link vs create =============="
2791
2792 test_46c() {
2793         pdo_lru_clear
2794         touch $DIR1/$tfile-2
2795 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2796         do_nodes $(comma_list $(mdts_nodes)) \
2797                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2798         link $DIR1/$tfile-2 $DIR1/$tfile &
2799         PID1=$! ; pdo_sched
2800         link $DIR2/$tfile $DIR2/$tfile &
2801         PID2=$! ; pdo_sched
2802         do_nodes $(comma_list $(mdts_nodes)) \
2803                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2804         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
2805         wait $PID2 ; [ $? -ne 0 ] || error "link must fail"
2806         rm -rf $DIR/$tfile*
2807         return 0
2808 }
2809 run_test 46c "pdirops: link vs link =============="
2810
2811 test_46d() {
2812         pdo_lru_clear
2813         touch $DIR1/$tfile-2
2814 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2815         do_nodes $(comma_list $(mdts_nodes)) \
2816                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2817         link $DIR1/$tfile-2 $DIR1/$tfile &
2818         PID1=$! ; pdo_sched
2819         rm $DIR2/$tfile &
2820         PID2=$! ; pdo_sched
2821         do_nodes $(comma_list $(mdts_nodes)) \
2822                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2823         check_pdo_conflict $PID1 && { wait $PID1; error "unlink isn't blocked"; }
2824         wait $PID2 ; [ $? -eq 0 ] || error "unlink must succeed"
2825         rm -rf $DIR/$tfile*
2826         return 0
2827 }
2828 run_test 46d "pdirops: link vs unlink =============="
2829
2830 test_46e() {
2831         pdo_lru_clear
2832         touch $DIR1/$tfile-2
2833         touch $DIR1/$tfile-3
2834 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2835         do_nodes $(comma_list $(mdts_nodes)) \
2836                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2837         link $DIR1/$tfile-2 $DIR1/$tfile &
2838         PID1=$! ; pdo_sched
2839         mv $DIR2/$tfile-3 $DIR2/$tfile &
2840         PID2=$! ; pdo_sched
2841         do_nodes $(comma_list $(mdts_nodes)) \
2842                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2843         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2844         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2845         rm -rf $DIR/$tfile*
2846         return 0
2847 }
2848 run_test 46e "pdirops: link and rename (tgt) =============="
2849
2850 test_46f() {
2851         pdo_lru_clear
2852         touch $DIR1/$tfile-2
2853         touch $DIR1/$tfile-3
2854 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2855         do_nodes $(comma_list $(mdts_nodes)) \
2856                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2857         link $DIR1/$tfile-2 $DIR1/$tfile &
2858         PID1=$! ; pdo_sched
2859         mv $DIR2/$tfile $DIR2/$tfile-3 &
2860         PID2=$! ; pdo_sched
2861         do_nodes $(comma_list $(mdts_nodes)) \
2862                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2863         check_pdo_conflict $PID1 && { wait $PID1; error "rename isn't blocked"; }
2864         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
2865         rm -rf $DIR/$tfile*
2866         return 0
2867 }
2868 run_test 46f "pdirops: link and rename (src) =============="
2869
2870 test_46g() {
2871         pdo_lru_clear
2872         touch $DIR1/$tfile-2
2873 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2874         do_nodes $(comma_list $(mdts_nodes)) \
2875                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2876         link $DIR1/$tfile-2 $DIR1/$tfile &
2877         PID1=$! ; pdo_sched
2878         stat $DIR2/$tfile > /dev/null &
2879         PID2=$! ; pdo_sched
2880         do_nodes $(comma_list $(mdts_nodes)) \
2881                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2882         check_pdo_conflict $PID1 && { wait $PID1; error "getattr isn't blocked"; }
2883         wait $PID2 ; [ $? -eq 0 ] || error "stat must succeed"
2884         rm -rf $DIR/$tfile*
2885         return 0
2886 }
2887 run_test 46g "pdirops: link vs getattr =============="
2888
2889 test_46h() {
2890         pdo_lru_clear
2891         touch $DIR1/$tfile-2
2892 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2893         do_nodes $(comma_list $(mdts_nodes)) \
2894                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2895         link $DIR1/$tfile-2 $DIR1/$tfile &
2896         PID1=$! ; pdo_sched
2897         ls -lia $DIR2/ > /dev/null &
2898         PID2=$! ; pdo_sched
2899         do_nodes $(comma_list $(mdts_nodes)) \
2900                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2901         check_pdo_conflict $PID1 && { wait $PID1; error "readdir isn't blocked"; }
2902         wait $PID2
2903         rm -rf $DIR/$tfile*
2904         return 0
2905 }
2906 run_test 46h "pdirops: link vs readdir =============="
2907
2908 test_46i() {
2909         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2910         pdo_lru_clear
2911         touch $DIR1/$tfile-2
2912 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2913         do_nodes $(comma_list $(mdts_nodes)) \
2914                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2915         link $DIR1/$tfile-2 $DIR1/$tfile &
2916         PID1=$! ; pdo_sched
2917         $LFS mkdir -i 1 $DIR2/$tfile &
2918         PID2=$! ; pdo_sched
2919         do_nodes $(comma_list $(mdts_nodes)) \
2920                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2921         check_pdo_conflict $PID1 && { wait $PID1;
2922                                 error "remote mkdir isn't blocked"; }
2923         wait $PID2 ; [ $? -ne 0 ] || error "remote mkdir must fail"
2924         rm -rf $DIR/$tfile*
2925         return 0
2926 }
2927 run_test 46i "pdirops: link vs remote mkdir"
2928
2929 # test 47: remote mkdir and blocking operations
2930 test_47a() {
2931 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2932         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2933         pdo_lru_clear
2934         do_nodes $(comma_list $(mdts_nodes)) \
2935                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2936         $LFS mkdir -i 1 $DIR1/$tfile &
2937         PID1=$! ; pdo_sched
2938         mkdir $DIR2/$tfile &
2939         PID2=$! ; pdo_sched
2940         do_nodes $(comma_list $(mdts_nodes)) \
2941                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2942         check_pdo_conflict $PID1 && { wait $PID1; error "mkdir isn't blocked"; }
2943         wait $PID2 ; [ $? -ne 0 ] || error "mkdir must fail"
2944         rm -rf $DIR/$tfile*
2945         return 0
2946 }
2947 run_test 47a "pdirops: remote mkdir vs mkdir"
2948
2949 test_47b() {
2950 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2951         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2952         pdo_lru_clear
2953         do_nodes $(comma_list $(mdts_nodes)) \
2954                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2955         $LFS mkdir -i 1 $DIR1/$tfile &
2956         PID1=$! ; pdo_sched
2957         sleep 1 # please do not remove this sleep, see LU-10754
2958         multiop $DIR2/$tfile oO_CREAT:O_EXCL:c &
2959         PID2=$! ; pdo_sched
2960         do_nodes $(comma_list $(mdts_nodes)) \
2961                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2962         check_pdo_conflict $PID1 && { wait $PID1;
2963                                         error "create isn't blocked"; }
2964         wait $PID2 ; [ $? -ne 0 ] || error "create must fail"
2965         rm -rf $DIR/$tfile*
2966         return 0
2967 }
2968 run_test 47b "pdirops: remote mkdir vs create"
2969
2970 test_47c() {
2971         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2972         pdo_lru_clear
2973         touch $DIR1/$tfile-2
2974 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2975         do_nodes $(comma_list $(mdts_nodes)) \
2976                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2977         $LFS mkdir -i 1 $DIR1/$tfile &
2978         PID1=$! ; pdo_sched
2979         link $DIR2/$tfile-2 $DIR2/$tfile &
2980         PID2=$! ; pdo_sched
2981         do_nodes $(comma_list $(mdts_nodes)) \
2982                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
2983         check_pdo_conflict $PID1 && { wait $PID1; error "link isn't blocked"; }
2984         wait $PID2 ; [ $? -ne 0 ] || error "link must fail"
2985         rm -rf $DIR/$tfile*
2986         return 0
2987 }
2988 run_test 47c "pdirops: remote mkdir vs link"
2989
2990 test_47d() {
2991         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2992         pdo_lru_clear
2993 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
2994         do_nodes $(comma_list $(mdts_nodes)) \
2995                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
2996         $LFS mkdir -i 1 $DIR1/$tfile &
2997         PID1=$! ; pdo_sched
2998         rmdir $DIR2/$tfile &
2999         PID2=$! ; pdo_sched
3000         do_nodes $(comma_list $(mdts_nodes)) \
3001                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
3002         check_pdo_conflict $PID1 && { wait $PID1;
3003                                         error "unlink isn't blocked"; }
3004         wait $PID2 ; [ $? -eq 0 ] || error "rmdir must succeed"
3005         rm -rf $DIR/$tfile*
3006         return 0
3007 }
3008 run_test 47d "pdirops: remote mkdir vs unlink"
3009
3010 test_47e() {
3011         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3012         pdo_lru_clear
3013         touch $DIR1/$tfile-2
3014 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
3015         do_nodes $(comma_list $(mdts_nodes)) \
3016                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
3017         $LFS mkdir -i 1 $DIR1/$tfile &
3018         PID1=$! ; pdo_sched
3019         mv -T $DIR2/$tfile-2 $DIR2/$tfile &
3020         PID2=$! ; pdo_sched
3021         do_nodes $(comma_list $(mdts_nodes)) \
3022                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
3023         check_pdo_conflict $PID1 && { wait $PID1;
3024                                         error "rename isn't blocked"; }
3025         wait $PID2 ; [ $? -ne 0 ] || error "rename must fail"
3026         rm -rf $DIR/$tfile*
3027         return 0
3028 }
3029 run_test 47e "pdirops: remote mkdir and rename (tgt)"
3030
3031 test_47f() {
3032         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3033         pdo_lru_clear
3034 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
3035         do_nodes $(comma_list $(mdts_nodes)) \
3036                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
3037         $LFS mkdir -i 1 $DIR1/$tfile &
3038         PID1=$! ; pdo_sched
3039         mv $DIR2/$tfile $DIR2/$tfile-2 &
3040         PID2=$! ; pdo_sched
3041         do_nodes $(comma_list $(mdts_nodes)) \
3042                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
3043         check_pdo_conflict $PID1 && { wait $PID1;
3044                                         error "rename isn't blocked"; }
3045         wait $PID2 ; [ $? -eq 0 ] || error "rename must succeed"
3046         rm -rf $DIR/$tfile*
3047         return 0
3048 }
3049 run_test 47f "pdirops: remote mkdir and rename (src)"
3050
3051 test_47g() {
3052         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3053         sync
3054         sync_all_data
3055         pdo_lru_clear
3056 #define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK    0x145
3057         do_nodes $(comma_list $(mdts_nodes)) \
3058                 "lctl set_param -n fail_loc=0x80000145 2>/dev/null || true"
3059         $LFS mkdir -i 1 $DIR1/$tfile &
3060         PID1=$! ; pdo_sched
3061         stat $DIR2/$tfile > /dev/null &
3062         PID2=$! ; pdo_sched
3063         do_nodes $(comma_list $(mdts_nodes)) \
3064                 "lctl set_param -n fail_loc=0 2>/dev/null || true"
3065         check_pdo_conflict $PID1 && { wait $PID1;
3066                                         error "getattr isn't blocked"; }
3067         wait $PID2 ; [ $? -eq 0 ] || error "stat must succeed"
3068         rm -rf $DIR/$tfile*
3069         return 0
3070 }
3071 run_test 47g "pdirops: remote mkdir vs getattr"
3072
3073 test_50() {
3074         trunc_size=4096
3075         dd if=/dev/zero of=$DIR1/$tfile bs=1K count=10
3076 #define OBD_FAIL_OSC_CP_ENQ_RACE         0x410
3077         do_facet client "lctl set_param fail_loc=0x410"
3078         $TRUNCATE $DIR2/$tfile $trunc_size
3079         do_facet client "lctl set_param fail_loc=0x0"
3080         sleep 3
3081         size=`stat -c %s $DIR2/$tfile`
3082         [ $size -eq $trunc_size ] || error "wrong size"
3083 }
3084 run_test 50 "osc lvb attrs: enqueue vs. CP AST =============="
3085
3086 test_51a() {
3087         local filesize
3088         local origfile=/etc/hosts
3089
3090         filesize=$(stat -c %s $origfile)
3091
3092         # create an empty file
3093         $MCREATE $DIR1/$tfile || error "can't create $DIR1/$tfile"
3094         # cache layout lock on both mount point
3095         stat $DIR1/$tfile > /dev/null || error "stat $DIR1/$tfile failed"
3096         stat $DIR2/$tfile > /dev/null || error "stat $DIR2/$tfile failed"
3097
3098         # open and sleep 2 seconds then read
3099         $MULTIOP $DIR2/$tfile o_2r${filesize}c &
3100         local pid=$!
3101         sleep 1
3102
3103         # create the layout of testing file
3104         dd if=$origfile of=$DIR1/$tfile conv=notrunc > /dev/null ||
3105                 error "dd $DIR1/$tfile failed"
3106
3107         # MULTIOP proc should be able to read enough bytes and exit
3108         for ((i = 0; i < 6; i++)); do
3109                 sleep 1
3110                 kill -0 $pid || break
3111         done
3112         kill -0 $pid 2> /dev/null && error "multiop is still there"
3113         cmp $origfile $DIR2/$tfile || error "$origfile and $DIR2/$tfile differs"
3114
3115         rm -f $DIR1/$tfile
3116 }
3117 run_test 51a "layout lock: refresh layout should work"
3118
3119 test_51b() {
3120         (( $MDS1_VERSION >= $(version_code 2.3.59) )) ||
3121                 skip "Need MDS version at least 2.3.59"
3122
3123         local tmpfile=`mktemp`
3124
3125         $LFS setstripe -E 1m -S 1M -c 1 -E -1 -c 1 $DIR1/$tfile ||
3126                 error "Create $DIR1/$tfile failed"
3127
3128         dd if=/dev/zero of=$DIR1/$tfile bs=1k count=1 conv=notrunc ||
3129                 error "dd $DIR1/$tfile failed"
3130
3131         # delay glimpse so that layout has changed when glimpse finish
3132 #define OBD_FAIL_GLIMPSE_DELAY 0x1404
3133         $LCTL set_param fail_loc=0x1404 fail_val=4
3134         stat -c %s $DIR2/$tfile |tee $tmpfile &
3135         local pid=$!
3136         sleep 0.2
3137
3138         # extend layout of testing file
3139         dd if=/dev/zero of=$DIR1/$tfile bs=1M count=1 seek=2 conv=notrunc ||
3140                 error "dd $DIR1/$tfile failed"
3141
3142         wait $pid
3143         local fsize=$(cat $tmpfile)
3144
3145         [ x$fsize = x3145728 ] || error "file size is $fsize, should be 3145728"
3146
3147         rm -f $DIR1/$tfile $tmpfile
3148 }
3149 run_test 51b "layout lock: glimpse should be able to restart if layout changed"
3150
3151 test_51c() {
3152         [ $OSTCOUNT -ge 2 ] || { skip "needs >= 2 osts"; return; }
3153
3154         # set default layout to have 1 stripe
3155         mkdir $DIR1/$tdir
3156         $LFS setstripe -c 1 $DIR1/$tdir
3157
3158         # create a file with empty layout
3159         $MCREATE $DIR1/$tdir/$tfile ||
3160                 error "$MCREATE $DIR1/$tdir/$tfile failed"
3161
3162 #define OBD_FAIL_MDS_LL_BLOCK 0x172
3163         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x172
3164
3165         # change the layout of testing file
3166         echo "Setting layout to have $OSTCOUNT stripes ..."
3167         $LFS setstripe -c $OSTCOUNT $DIR1/$tdir/$tfile &
3168         pid=$!
3169         sleep 1
3170
3171         # write something to the file, it should be blocked on fetching layout
3172         dd if=/dev/zero of=$DIR2/$tdir/$tfile bs=1k count=1 conv=notrunc
3173         local stripe_count=$($LFS getstripe -c $DIR2/$tdir/$tfile)
3174         wait $pid
3175
3176         # lod_qos.c::min_stripe_count() allows setstripe with a default stripe
3177         # count to succeed with only 3/4 of the number of stripes (rounded up),
3178         # so creating striped files does not fail if an OST is offline or full
3179         [ $stripe_count -ge $((OSTCOUNT - $OSTCOUNT / 4)) ] ||
3180                 error "bad layout: getstripe -c $stripe_count < $OSTCOUNT * 3/4"
3181
3182         rm -fr $DIR1/$tdir
3183 }
3184 run_test 51c "layout lock: IT_LAYOUT blocked and correct layout can be returned"
3185
3186 test_51d() {
3187         dd if=/dev/zero of=/$DIR1/$tfile bs=1M count=1
3188         cancel_lru_locks mdc
3189
3190         # open should grant LAYOUT lock, mmap and read will install pages
3191         $MULTIOP $DIR1/$tfile oO_RDWR:SMR_Uc &
3192         local PID=$!
3193         sleep 1
3194
3195         # rss before revoking
3196         local br=$(grep -A 10 $tfile /proc/$PID/smaps | awk '/^Rss/{print $2}')
3197         echo "Before revoking layout lock: $br KB mapped"
3198
3199         # cancel layout lock manually
3200         cancel_lru_locks mdc
3201
3202         # rss after revoking
3203         local ar=$(grep -A 10 $tfile /proc/$PID/smaps | awk '/^Rss/{print $2}')
3204
3205         kill -USR1 $PID
3206         wait $PID || error "wait PID $PID failed"
3207
3208         [ $ar -eq 0 ] || error "rss before: $br, after $ar, some pages remained"
3209 }
3210 run_test 51d "layout lock: losing layout lock should clean up memory map region"
3211
3212 test_51e() {
3213         (( $MDS1_VERSION >= $(version_code 2.13.54.148) )) ||
3214                 skip "MDS version must be at least 2.13.54.148"
3215
3216         local pid
3217
3218         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
3219         pid=$!
3220         sleep 1
3221
3222         $LFS getstripe $DIR2/$tfile
3223         kill -USR1 $pid
3224         wait $pid || error "multiop failed"
3225
3226         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
3227         pid=$!
3228         sleep 1
3229
3230         $LFS getstripe $DIR2/$tfile
3231         kill -USR1 $pid
3232         wait $pid || error "multiop failed"
3233 }
3234 run_test 51e "lfs getstripe does not break leases, part 2"
3235
3236 test_54_part1()
3237 {
3238         echo "==> rename vs getattr vs setxattr should not deadlock"
3239         mkdir -p $DIR/d1/d2/d3 || error "(1) mkdir failed"
3240
3241         do_facet mds1 $LCTL set_param fail_loc=$1
3242
3243         mv -T $DIR/d1/d2/d3 $DIR/d1/d3 &
3244         PID1=$!
3245         sleep 1
3246
3247         stat $DIR/d1/d2 &
3248         PID2=$!
3249         sleep 1
3250
3251         setfattr -n user.attr1 -v value1 $DIR2/d1 || error "(2) setfattr failed"
3252         wait $PID1 || error "(3) mv failed"
3253         wait $PID2 || error "(4) stat failed"
3254         echo
3255
3256         rm -rf $DIR/d1
3257 }
3258
3259 test_54_part2() {
3260         echo "==> rename vs getattr vs open vs getattr should not deadlock"
3261         mkdir -p $DIR/d1/d2/d3 || error "(1) mkdir failed"
3262
3263         do_facet mds1 $LCTL set_param fail_loc=$1
3264
3265         mv -T $DIR/d1/d2/d3 $DIR/d1/d3 &
3266         PID1=$!
3267         sleep 1
3268
3269         stat $DIR/d1/d2 &
3270         PID2=$!
3271         sleep 1
3272
3273         $MULTIOP $DIR2/d1/d2 Oc &
3274         PID3=$!
3275         sleep 1
3276
3277         stat $DIR/d1 || error "(2) stat failed"
3278
3279         wait $PID1 || error "(3) mv failed"
3280         wait $PID2 || error "(4) stat failed"
3281         wait $PID3 && error "(5) multiop failed"
3282         echo
3283         rm -rf $DIR/d1
3284 }
3285
3286 test_54() {
3287         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
3288         save_lustre_params client "llite.*.xattr_cache" > $p
3289         lctl set_param llite.*.xattr_cache 1 ||
3290                 { skip "xattr cache is not supported"; return 0; }
3291
3292 #define OBD_FAIL_MDS_RENAME              0x153
3293 #define OBD_FAIL_MDS_RENAME2             0x154
3294         test_54_part1 0x80000153 || error 10
3295         test_54_part1 0x80000154 || error 11
3296         test_54_part2 0x80000153 || error 12
3297         test_54_part2 0x80000154 || error 13
3298
3299         restore_lustre_params < $p
3300         rm -f $p
3301 }
3302 run_test 54 "rename locking"
3303
3304 test_55a() {
3305         mkdir_on_mdt0 $DIR/$tdir
3306         mkdir -p $DIR/$tdir/d1/d2 $DIR/$tdir/d3 || error "(1) mkdir failed"
3307
3308 #define OBD_FAIL_MDS_RENAME4              0x156
3309         do_facet mds1 $LCTL set_param fail_loc=0x80000156
3310
3311         mv -T $DIR/$tdir/d1/d2 $DIR/$tdir/d3/d2 &
3312         PID1=$!
3313         sleep 1
3314
3315         rm -r $DIR2/$tdir/d3
3316         wait $PID1 && error "(2) mv succeeded"
3317
3318         rm -rf $DIR/$tdir
3319 }
3320 run_test 55a "rename vs unlink target dir"
3321
3322 test_55b()
3323 {
3324         mkdir_on_mdt0 $DIR/$tdir
3325         mkdir -p $DIR/$tdir/d1/d2 $DIR/$tdir/d3 || error "(1) mkdir failed"
3326
3327 #define OBD_FAIL_MDS_RENAME4             0x156
3328         do_facet mds1 $LCTL set_param fail_loc=0x80000156
3329
3330         mv -T $DIR/$tdir/d1/d2 $DIR/$tdir/d3/d2 &
3331         PID1=$!
3332         sleep 1
3333
3334         rm -r $DIR2/$tdir/d1
3335         wait $PID1 && error "(2) mv succeeded"
3336
3337         rm -rf $DIR/$tdir
3338 }
3339 run_test 55b "rename vs unlink source dir"
3340
3341 test_55c()
3342 {
3343         mkdir_on_mdt0 $DIR/$tdir
3344         mkdir -p $DIR/$tdir/d1/d2 $DIR/$tdir/d3 || error "(1) mkdir failed"
3345
3346 #define OBD_FAIL_MDS_RENAME4              0x156
3347         do_facet mds1 $LCTL set_param fail_loc=0x156
3348
3349         mv -T $DIR/$tdir/d1/d2 $DIR/$tdir/d3/d2 &
3350         PID1=$!
3351         sleep 1
3352
3353         # while rename is sleeping, open and remove d3
3354         $MULTIOP $DIR2/$tdir/d3 D_c &
3355         PID2=$!
3356         sleep 1
3357         rm -rf $DIR2/$tdir/d3
3358         sleep 5
3359
3360         # while rename is sleeping 2nd time, close d3
3361         kill -USR1 $PID2
3362         wait $PID2 || error "(3) multiop failed"
3363
3364         wait $PID1 && error "(2) mv succeeded"
3365
3366         rm -rf $DIR/$tdir
3367 }
3368 run_test 55c "rename vs unlink orphan target dir"
3369
3370 test_55d()
3371 {
3372         mkdir_on_mdt0 $DIR/$tdir
3373
3374         touch $DIR/$tdir/f1
3375
3376 #define OBD_FAIL_MDS_RENAME3              0x155
3377         do_facet mds1 $LCTL set_param fail_loc=0x155
3378         mv $DIR/$tdir/f1 $DIR/$tdir/$tdir &
3379         PID1=$!
3380         sleep 2
3381
3382         # while rename is sleeping, create $tdir, but as a directory
3383         mkdir -p $DIR2/$tdir/$tdir || error "(1) mkdir failed"
3384
3385         # link in reverse locking order
3386         ln $DIR2/$tdir/f1 $DIR2/$tdir/$tdir/
3387
3388         wait $PID1 && error "(2) mv succeeded"
3389         rm -rf $DIR/$tdir
3390 }
3391 run_test 55d "rename file vs link"
3392
3393 test_60() {
3394         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
3395                 skip "MDS version must be >= 2.3.0"
3396
3397         # Create a file
3398         test_mkdir $DIR1/$tdir
3399         file1=$DIR1/$tdir/file
3400         file2=$DIR2/$tdir/file
3401
3402         echo orig > $file2 || error "Could not create $file2"
3403         version=$($LFS data_version $file1)
3404
3405         # Append data
3406         echo append >> $file2 || error "Could not append to $file2"
3407         version2=$($LFS data_version $file1)
3408         [ "$version" != "$version2" ] ||
3409             error "append did not change data version: $version"
3410
3411         # Overwrite data
3412         echo overwrite > $file2 || error "Could not overwrite $file2"
3413         version3=$($LFS data_version $file1)
3414         [ "$version2" != "$version3" ] ||
3415             error "overwrite did not change data version: $version2"
3416
3417         # Truncate before EOF
3418         $TRUNCATE $file2 3 || error "Could not truncate $file2"
3419         version4=$($LFS data_version $file1)
3420         [ "$version3" != "$version4" ] ||
3421             error "truncate did not change data version: $version3"
3422
3423         # Truncate after EOF
3424         $TRUNCATE $file2 123456 || error "Could not truncate $file2"
3425         version5=$($LFS data_version $file1)
3426         [ "$version4" != "$version5" ] ||
3427             error "truncate did not change data version: $version4"
3428
3429         # Chmod do not change version
3430         chmod 400 $file2 || error "Could not chmod 400 $file2"
3431         version6=$($LFS data_version $file1)
3432         [ "$version5" == "$version6" ] ||
3433             error "chmod should not change data version: $version5 != $version6"
3434
3435         # Chown do not change version
3436         chown $RUNAS_ID $file2 || error "Could not chown $RUNAS_ID $file2"
3437         version7=$($LFS data_version $file1)
3438         [ "$version5" == "$version7" ] ||
3439             error "chown should not change data version: $version5 != $version7"
3440 }
3441 run_test 60 "Verify data_version behaviour"
3442
3443 test_70a() {
3444         local test_dir=$tdir/test_dir
3445
3446         mkdir -p $DIR1/$tdir
3447         if [ $MDSCOUNT -ge 2 ]; then
3448                 local MDTIDX=1
3449                 $LFS mkdir -i $MDTIDX $DIR1/$test_dir ||
3450                         error "Create remote directory failed"
3451         else
3452                 mkdir -p $DIR1/$test_dir
3453         fi
3454         cd $DIR2/$test_dir || error "cd directory failed"
3455         rm -rf $DIR1/$test_dir || error "unlink directory failed"
3456
3457         cd $DIR2/$tdir || error "exit directory"
3458 }
3459 run_test 70a "cd directory && rm directory"
3460
3461 test_70b() { # LU-2781
3462         local i
3463         mkdir -p $DIR1/$tdir
3464
3465         touch $DIR1/$tdir/file
3466         for ((i = 0; i < 32; i++)); do
3467             $LFS rm_entry $DIR1/$tdir/non_existent_dir &>/dev/null
3468         done
3469         rm $DIR1/$tdir/file || error "cannot remove file after rm_entry"
3470
3471         touch $DIR1/$tdir/file
3472         $LFS mkdir -i0 $DIR1/$tdir/test_dir
3473         $LFS rm_entry $DIR1/$tdir/test_dir &>/dev/null
3474         rm -rf $DIR1/$tdir/test_dir ||
3475                 error "cannot remove directory after rm_entry"
3476         rm $DIR1/$tdir/file || error "cannot remove file after rm_entry"
3477 }
3478 run_test 70b "remove files after calling rm_entry"
3479
3480 test_71a() {
3481         [[ "$MDS1_VERSION" -lt $(version_code 2.1.6) ]] &&
3482                 skip "Need MDS version at least 2.1.6"
3483
3484         # Patch not applied to 2.2 and 2.3 branches
3485         [[ "$MDS1_VERSION" -ge $(version_code 2.2.0) ]] &&
3486         [[ "$MDS1_VERSION" -lt $(version_code 2.4.0) ]] &&
3487                 skip "Need MDS version earlier than 2.2.0 or at least 2.4.0"
3488
3489         checkfiemap --test ||
3490                 skip "checkfiemap not runnable: $?"
3491         # write data this way: hole - data - hole - data
3492         dd if=/dev/urandom of=$DIR1/$tfile bs=40K seek=1 count=1
3493         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR1/$tfile) + 1)))" = \
3494                 "zfs" ] &&
3495                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return 0
3496         dd if=/dev/urandom of=$DIR1/$tfile bs=40K seek=3 count=1
3497         GET_STAT="lctl get_param -n ldlm.services.ldlm_cbd.stats"
3498         stat $DIR2/$tfile
3499         local can1=$($GET_STAT | awk '/ldlm_bl_callback/ {print $2}')
3500         echo $can1
3501         checkfiemap $DIR2/$tfile 81920 ||
3502                 error "data is not flushed from client"
3503         local can2=$($GET_STAT | awk '/ldlm_bl_callback/ {print $2}')
3504         echo $can2
3505
3506         # common case of "create file, copy file" on a single node
3507         # should not flush data from ost
3508         dd if=/dev/urandom of=$DIR1/$tfile bs=40K seek=1 count=1
3509         dd if=/dev/urandom of=$DIR1/$tfile bs=40K seek=3 count=1
3510         stat $DIR1/$tfile
3511         local can3=$($GET_STAT | awk '/ldlm_bl_callback/ {print $2}')
3512         echo $can3
3513         checkfiemap $DIR1/$tfile 81920 ||
3514         error 4
3515         local can4=$($GET_STAT | awk '/ldlm_bl_callback/ {print $2}')
3516         echo $can2
3517         [ $can3 -eq $can4 ] || error $((can2-can1)) "cancel RPC occured."
3518 }
3519 run_test 71a "correct file map just after write operation is finished"
3520
3521 test_71b() {
3522         [[ "$MDS1_VERSION" -lt $(version_code 2.1.6) ]] &&
3523                 skip "Need MDS version at least 2.1.6"
3524
3525         # Patch not applied to 2.2 and 2.3 branches
3526         [[ "$MDS1_VERSION" -ge $(version_code 2.2.0) ]] &&
3527         [[ "$MDS1_VERSION" -lt $(version_code 2.4.0) ]] &&
3528                 skip "Need MDS version earlier than 2.2.0 or at least 2.4.0"
3529         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
3530
3531         checkfiemap --test ||
3532                 skip "error $?: checkfiemap failed"
3533
3534         mkdir -p $DIR1/$tdir
3535
3536         $LFS setstripe -c -1 $DIR1/$tdir || error "setstripe failed"
3537         dd if=/dev/urandom of=$DIR1/$tdir/$tfile bs=40K count=1
3538         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR1/$tdir/$tfile) + 1)))" = \
3539                 "zfs" ] &&
3540                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return 0
3541         checkfiemap $DIR1/$tdir/$tfile 40960 || error "checkfiemap failed"
3542 }
3543 run_test 71b "check fiemap support for stripecount > 1"
3544
3545 test_72() {
3546         local p="$TMP/sanityN-$TESTNAME.parameters"
3547         local tlink1
3548         local tlink2
3549         save_lustre_params client "llite.*.xattr_cache" > $p
3550         lctl set_param llite.*.xattr_cache 1 ||
3551                 { skip "xattr cache is not supported"; return 0; }
3552
3553         touch $DIR1/$tfile
3554         setfattr -n user.attr1 -v value1 $DIR1/$tfile ||
3555                 error "setfattr1 failed"
3556         getfattr -n user.attr1 $DIR2/$tfile | grep value1 ||
3557                 error "getfattr1 failed"
3558         setfattr -n user.attr1 -v value2 $DIR2/$tfile ||
3559                 error "setfattr2 failed"
3560         getfattr -n user.attr1 $DIR1/$tfile | grep value2 ||
3561                 error "getfattr2 failed"
3562
3563         # check that trusted.link is consistent
3564         tlink1=$(getfattr -n trusted.link $DIR1/$tfile | md5sum)
3565         ln $DIR2/$tfile $DIR2/$tfile-2 || error "failed to link"
3566         tlink2=$(getfattr -n trusted.link $DIR1/$tfile | md5sum)
3567         echo "$tlink1 $tlink2"
3568         [ "$tlink1" = "$tlink2" ] && error "trusted.link should have changed!"
3569
3570         rm -f $DIR2/$tfile
3571
3572         restore_lustre_params < $p
3573         rm -f $p
3574 }
3575 run_test 72 "getxattr/setxattr cache should be consistent between nodes"
3576
3577 test_73() {
3578         local p="$TMP/sanityN-$TESTNAME.parameters"
3579         save_lustre_params client "llite.*.xattr_cache" > $p
3580         lctl set_param llite.*.xattr_cache 1 ||
3581                 { skip "xattr cache is not supported"; return 0; }
3582
3583         touch $DIR1/$tfile
3584         setfattr -n user.attr1 -v value1 $DIR1/$tfile ||
3585                 error "setfattr1 failed"
3586         getfattr -n user.attr1 $DIR2/$tfile || error "getfattr1 failed"
3587         getfattr -n user.attr1 $DIR1/$tfile || error "getfattr2 failed"
3588         clear_stats llite.*.stats
3589         # PR lock should be cached by now on both clients
3590         getfattr -n user.attr1 $DIR1/$tfile || error "getfattr3 failed"
3591         # 2 hits for getfattr(0)+getfattr(size)
3592         [ $(calc_stats llite.*.stats getxattr_hits) -eq 2 ] ||
3593                 error "not cached in $DIR1"
3594         getfattr -n user.attr1 $DIR2/$tfile || error "getfattr4 failed"
3595         # 4 hits for more getfattr(0)+getfattr(size)
3596         [ $(calc_stats llite.*.stats getxattr_hits) -eq 4 ] ||
3597                 error "not cached in $DIR2"
3598         rm -f $DIR2/$tfile
3599
3600         restore_lustre_params < $p
3601         rm -f $p
3602 }
3603 run_test 73 "getxattr should not cause xattr lock cancellation"
3604
3605 test_74() {
3606         [ "$MDS1_VERSION" -lt $(version_code 2.4.93) ] &&
3607                 skip "Need MDS version at least 2.4.93"
3608
3609         dd if=/dev/zero of=$DIR1/$tfile-1 bs=1K count=1
3610         dd if=/dev/zero of=$DIR1/$tfile-2 bs=1K count=1
3611         flocks_test 4 $DIR1/$tfile-1 $DIR2/$tfile-2
3612 }
3613 run_test 74 "flock deadlock: different mounts =============="
3614
3615 # LU-3889
3616 test_75() {
3617         $LFS setstripe -c 2 -S 1m -i 0 $DIR1/$tfile
3618         dd if=/dev/zero of=$DIR1/$tfile bs=1M count=2
3619         cancel_lru_locks osc
3620
3621         dd of=$DIR1/$tfile if=/dev/zero bs=1M count=1 seek=1 conv=notrunc
3622         sync
3623
3624         # define OBD_FAIL_LDLM_ENQUEUE_HANG 0x31d
3625         $LCTL set_param fail_loc=0x31d
3626         stat -c %s $DIR1/$tfile &
3627         local pid=$!
3628         sleep 1
3629         kill -9 $pid
3630
3631         # For bad lock error handler we should ASSERT and got kernel panic here
3632         sleep 4
3633         $LCTL set_param fail_loc=0
3634 }
3635 run_test 75 "osc: upcall after unuse lock==================="
3636
3637 test_76() { #LU-946
3638         [[ "$MDS1_VERSION" -lt $(version_code 2.5.53) ]] &&
3639                 skip "Need MDS version at least 2.5.53"
3640
3641         remote_mds_nodsh && skip "remote MDS with nodsh"
3642         local fcount=$((MDSCOUNT * 256))
3643         declare -a fd_list
3644         declare -a fid_list
3645
3646         if remote_mds; then
3647                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
3648         else
3649                 nid="0@lo"
3650         fi
3651
3652         rm -rf $DIR/$tdir
3653         test_mkdir $DIR/$tdir
3654
3655         # drop all open locks and close any cached "open" files on the client
3656         cancel_lru_locks mdc
3657
3658         local open_fids_cmd="$LCTL get_param -n mdt.*.exports.'$nid'.open_files"
3659         local fid_list=($(do_nodes $(comma_list $(mdts_nodes)) $open_fids_cmd))
3660         local already=${#fid_list[@]}
3661         for (( i = 0; i < $already; i++ )) ; do
3662                 log "already open[$i]: $($LFS fid2path $DIR2 ${fid_list[i]})"
3663         done
3664
3665         echo -n "opening files: "
3666         ulimit -n $((fcount + 50))
3667         for ((i = 0; i < $fcount; i++)); do
3668                 touch $DIR/$tdir/f_$i
3669                 local fd=$(free_fd ${fd_list[i]})
3670                 local open_cmd="exec $fd<$DIR/$tdir/f_$i"
3671                 eval $open_cmd
3672
3673                 fd_list[i]=$fd
3674
3675                 (( $i % 32 == 0 )) && echo -n "."
3676         done
3677         echo
3678
3679         fid_list=($(do_nodes $(comma_list $(mdts_nodes)) $open_fids_cmd))
3680
3681         # Possible errors in openfiles FID list.
3682         # 1. Missing FIDs. Check 1
3683         # 2. Extra FIDs. Check 1
3684         # 3. Duplicated FID. Check 2
3685         # 4. Invalid FIDs. Check 2
3686         # 5. Valid FID, points to some other file. Check 3
3687
3688         # Check 1
3689         [ ${#fid_list[@]} -ne $((fcount + already)) ] &&
3690                 error "${#fid_list[@]} != $fcount (+$already old) open files"
3691
3692         echo -n "closing files: "
3693         for (( fd = 0, fid = 0; fd < $fcount; fd++, fid++ )) ; do
3694                 local close_cmd="exec ${fd_list[fd]}<&-"
3695                 eval $close_cmd
3696                 filename=$($LFS fid2path $DIR2 ${fid_list[fid]})
3697
3698                 while [[ ! "$filename" =~ "$DIR2/$tdir/f_" ]]; do
3699                         echo "skip old open file $filename"
3700                         ((fid++))
3701                         filename=$($LFS fid2path $DIR2 ${fid_list[fid]})
3702                 done
3703
3704                 # Check 2
3705                 rm --interactive=no $filename
3706                 [ $? -ne 0 ] &&
3707                         error "Nonexisting fid ${fid_list[fid]} listed."
3708                 (( $fd % 32 == 0 )) && echo -n "."
3709         done
3710         echo
3711
3712         # Check 3
3713         ls_op=$(ls $DIR2/$tdir | wc -l)
3714         [ $ls_op -ne 0 ] &&
3715                 error "Some openfiles are missing in lproc output"
3716
3717         rm -rf $DIR/$tdir
3718 }
3719 run_test 76 "Verify MDT open_files listing"
3720
3721 nrs_write_read() {
3722         local n=16
3723         local dir=$DIR/$tdir
3724         local myRUNAS="$1"
3725
3726         mkdir $dir || error "mkdir $dir failed"
3727         $LFS setstripe -c $OSTCOUNT $dir || error "setstripe to $dir failed"
3728         chmod 777 $dir
3729
3730         do_nodes $CLIENTS $myRUNAS \
3731                 dd if=/dev/zero of="$dir/nrs_r_\$HOSTNAME" bs=1M count=$n ||
3732                 error "dd at 0 on client failed (1)"
3733
3734         do_nodes $CLIENTS $myRUNAS \
3735                 "declare -a pids_w;
3736                 for ((i = 0; i < $n; i++)); do
3737                         dd if=/dev/zero of=$dir/nrs_w_\$HOSTNAME bs=1M \
3738 seek=\\\$i count=1 conv=notrunc &
3739                         pids_w[\\\$i]=\\\$!;
3740                 done;
3741                 rc_w=0;
3742                 for ((i = 0; i < $n; i++)); do
3743                         wait \\\${pids_w[\\\$i]};
3744                         newrc=\\\$?;
3745                         [ \\\$newrc -gt \\\$rc_w ] && rc_w=\\\$newrc;
3746                 done;
3747                 exit \\\$rc_w" &
3748         local pid_w=$!
3749         do_nodes $CLIENTS sync;
3750         cancel_lru_locks osc
3751
3752         do_nodes $CLIENTS $myRUNAS \
3753                 "declare -a pids_r;
3754                 for ((i = 0; i < $n; i++)); do
3755                         dd if=$dir/nrs_r_\$HOSTNAME bs=1M of=/dev/null \
3756 seek=\\\$i count=1 &
3757                         pids_r[\\\$i]=\\\$!;
3758                 done;
3759                 rc_r=0;
3760                 for ((i = 0; i < $n; i++)); do
3761                         wait \\\${pids_r[\\\$i]};
3762                         newrc=\\\$?;
3763                         [ \\\$newrc -gt \\\$rc_r ] && rc_r=\\\$newrc;
3764                 done;
3765                 exit \\\$rc_r" &
3766         local pid_r=$!
3767         cancel_lru_locks osc
3768
3769         wait $pid_w || error "dd (write) failed (2)"
3770         wait $pid_r || error "dd (read) failed (3)"
3771         rm -rvf $dir || error "rm -rf $dir failed"
3772 }
3773
3774 test_77a() { #LU-3266
3775         local rc
3776
3777         oss=$(comma_list $(osts_nodes))
3778         do_nodes $oss lctl set_param ost.OSS.*.nrs_policies="fifo" ||
3779                 rc=$?
3780         [[ $rc -eq 3 ]] && skip "no NRS exists" && return
3781         [[ $rc -ne 0 ]] && error "failed to set fifo policy"
3782         nrs_write_read
3783
3784         return 0
3785 }
3786 run_test 77a "check FIFO NRS policy"
3787
3788 test_77b() { #LU-3266
3789         local rc
3790
3791         oss=$(comma_list $(osts_nodes))
3792
3793         do_nodes $oss lctl set_param ost.OSS.*.nrs_policies="crrn" \
3794                 ost.OSS.*.nrs_crrn_quantum=1 || rc=$?
3795         [[ $rc -eq 3 ]] && skip "no NRS exists" && return
3796         [[ $rc -ne 0 ]] && error "failed to set crrn_quantum to 1"
3797
3798         echo "policy: crr-n, crrn_quantum 1"
3799         nrs_write_read
3800
3801         do_nodes $oss lctl set_param \
3802                 ost.OSS.*.nrs_crrn_quantum=64 || rc=$?
3803         [[ $rc -ne 0 ]] && error "failed to set crrn_quantum to 64"
3804
3805         echo "policy: crr-n, crrn_quantum 64"
3806         nrs_write_read
3807
3808         # cleanup
3809         do_nodes $oss lctl set_param \
3810                 ost.OSS.ost_io.nrs_policies="fifo" || rc=$?
3811         [[ $rc -ne 0 ]] && error "failed to set fifo policy"
3812         return 0
3813 }
3814 run_test 77b "check CRR-N NRS policy"
3815
3816 orr_trr() {
3817         local policy=$1
3818
3819         oss=$(comma_list $(osts_nodes))
3820
3821         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies=$policy \
3822                 ost.OSS.*.nrs_"$policy"_quantum=1 \
3823                 ost.OSS.*.nrs_"$policy"_offset_type="physical" \
3824                 ost.OSS.*.nrs_"$policy"_supported="reads" || return $?
3825
3826         echo "policy: $policy, ${policy}_quantum 1, ${policy}_offset_type " \
3827                 "physical, ${policy}_supported reads"
3828         nrs_write_read
3829
3830         do_nodes $oss lctl set_param \
3831                 ost.OSS.*.nrs_${policy}_supported="writes" \
3832                 ost.OSS.*.nrs_${policy}_quantum=64 || return $?
3833
3834         echo "policy: $policy, ${policy}_quantum 64, ${policy}_offset_type " \
3835                 "physical, ${policy}_supported writes"
3836         nrs_write_read
3837
3838         do_nodes $oss lctl set_param \
3839                 ost.OSS.*.nrs_${policy}_supported="reads_and_writes" \
3840                 ost.OSS.*.nrs_${policy}_offset_type="logical" || return $?
3841         echo "policy: $policy, ${policy}_quantum 64, ${policy}_offset_type " \
3842                 "logical, ${policy}_supported reads_and_writes"
3843         nrs_write_read
3844
3845         # cleanup
3846         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="fifo" ||
3847                 return $?
3848         return 0
3849 }
3850
3851 test_77c() { #LU-3266
3852         local rc
3853         orr_trr "orr" || rc=$?
3854         [[ $rc -eq 3 ]] && skip "no NRS exists" && return
3855         [[ $rc -ne 0 ]] && error "orr_trr failed rc:$rc"
3856         return 0
3857 }
3858 run_test 77c "check ORR NRS policy"
3859
3860 test_77d() { #LU-3266
3861         local rc
3862         orr_trr "trr" || rc=$?
3863         [[ $rc -eq 3 ]] && skip "no NRS exists" && return
3864         [[ $rc -ne 0 ]] && error "orr_trr failed rc:$rc"
3865         return 0
3866 }
3867 run_test 77d "check TRR nrs policy"
3868
3869 tbf_rule_operate()
3870 {
3871         local facet=$1
3872         shift 1
3873
3874         do_facet $facet lctl set_param \
3875                 ost.OSS.ost_io.nrs_tbf_rule="$*"
3876         [ $? -ne 0 ] &&
3877                 error "failed to run operate '$*' on TBF rules"
3878 }
3879
3880 cleanup_tbf_verify()
3881 {
3882         local rc=0
3883         trap 0
3884         echo "cleanup_tbf $DIR/$tdir"
3885         rm -rf $DIR/$tdir
3886         rc=$?
3887         wait_delete_completed
3888         return $rc
3889 }
3890
3891 tbf_verify() {
3892         local dir=$DIR/$tdir
3893         local client1=${CLIENT1:-$(hostname)}
3894         local myRUNAS="$3"
3895
3896         local np=$(check_cpt_number ost1)
3897         [ $np -gt 0 ] || error "CPU partitions should not be $np."
3898         echo "cpu_npartitions on ost1 is $np"
3899
3900         mkdir $dir || error "mkdir $dir failed"
3901         $LFS setstripe -c 1 -i 0 $dir || error "setstripe to $dir failed"
3902         chmod 777 $dir
3903
3904         trap cleanup_tbf_verify EXIT
3905         echo "Limited write rate: $1, read rate: $2"
3906         echo "Verify the write rate is under TBF control"
3907         local start=$SECONDS
3908         do_node $client1 $myRUNAS dd if=/dev/zero of=$dir/tbf \
3909                 bs=1M count=100 oflag=direct 2>&1
3910         local runtime=$((SECONDS - start + 1))
3911         local rate=$(bc <<< "scale=6; 100 / $runtime")
3912         echo "Write runtime is $runtime s, speed is $rate IOPS"
3913
3914         # verify the write rate does not exceed TBF rate limit
3915         [ $(bc <<< "$rate < 1.1 * $np * $1") -eq 1 ] ||
3916                 error "The write rate ($rate) exceeds 110% of rate limit ($1 * $np)"
3917
3918         cancel_lru_locks osc
3919
3920         echo "Verify the read rate is under TBF control"
3921         start=$SECONDS
3922         do_node $client1 $myRUNAS dd if=$dir/tbf of=/dev/null \
3923                 bs=1M count=100 iflag=direct 2>&1
3924         runtime=$((SECONDS - start + 1))
3925         rate=$(bc <<< "scale=6; 100 / $runtime")
3926         echo "Read runtime is $runtime s, speed is $rate IOPS"
3927
3928         # verify the read rate does not exceed TBF rate limit
3929         [ $(bc <<< "$rate < 1.1 * $np * $2") -eq 1 ] ||
3930                 error "The read rate ($rate) exceeds 110% of rate limit ($2 * $np)"
3931
3932         cancel_lru_locks osc
3933         cleanup_tbf_verify || error "rm -rf $dir failed"
3934 }
3935
3936 test_77e() {
3937         local rc
3938
3939         oss=$(comma_list $(osts_nodes))
3940
3941         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="tbf\ nid" ||
3942                 rc=$?
3943         [[ $rc -eq 3 ]] && skip "no NRS TBF exists" && return
3944         [[ $rc -ne 0 ]] && error "failed to set TBF NID policy"
3945
3946         local idis
3947         local rateis
3948         if [ "$OST1_VERSION" -ge $(version_code 2.8.54) ]; then
3949                 idis="nid="
3950                 rateis="rate="
3951         fi
3952
3953         # Only operate rules on ost1 since OSTs might run on the same OSS
3954         # Add some rules
3955         tbf_rule_operate ost1 "start\ localhost\ ${idis}{0@lo}\ ${rateis}1000"
3956         local address=$(comma_list "$(host_nids_address $CLIENTS $NETTYPE)")
3957         local client_nids=$(nids_list $address "\\")
3958         tbf_rule_operate ost1 "start\ clients\ ${idis}{$client_nids}\ ${rateis}100"
3959         tbf_rule_operate ost1 "start\ others\ ${idis}{*.*.*.*@$NETTYPE}\ ${rateis}50"
3960         nrs_write_read
3961
3962         # Change the rules
3963         tbf_rule_operate ost1 "change\ localhost\ ${rateis}1001"
3964         tbf_rule_operate ost1 "change\ clients\ ${rateis}101"
3965         tbf_rule_operate ost1 "change\ others\ ${rateis}51"
3966         nrs_write_read
3967
3968         # Stop the rules
3969         tbf_rule_operate ost1 "stop\ localhost"
3970         tbf_rule_operate ost1 "stop\ clients"
3971         tbf_rule_operate ost1 "stop\ others"
3972         nrs_write_read
3973
3974         # Cleanup the TBF policy
3975         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="fifo"
3976         [ $? -ne 0 ] && error "failed to set policy back to fifo"
3977         nrs_write_read
3978         return 0
3979 }
3980 run_test 77e "check TBF NID nrs policy"
3981
3982 test_77f() {
3983         local rc
3984
3985         oss=$(comma_list $(osts_nodes))
3986
3987         do_nodes $oss $LCTL set_param \
3988                 ost.OSS.ost_io.nrs_policies="tbf\ jobid" || rc=$?
3989         [[ $rc -eq 3 ]] && skip "no NRS TBF exists" && return
3990         [[ $rc -ne 0 ]] && error "failed to set TBF JOBID policy"
3991
3992         # Configure jobid_var
3993         local saved_jobid_var=$($LCTL get_param -n jobid_var)
3994         rc=$?
3995         [[ $rc -eq 3 ]] && skip "jobid_var not found" && return
3996         [[ $rc -ne 0 ]] && error "failed to get param jobid_var"
3997         if [ $saved_jobid_var != procname_uid ]; then
3998                 set_persistent_param_and_check client \
3999                         "jobid_var" "$FSNAME.sys.jobid_var" procname_uid
4000         fi
4001
4002         local idis
4003         local rateis
4004         if [ "$OST1_VERSION" -ge $(version_code 2.8.54) ]; then
4005                 idis="jobid="
4006                 rateis="rate="
4007         fi
4008
4009         # Only operate rules on ost1 since OSTs might run on the same OSS
4010         # Add some rules
4011         tbf_rule_operate ost1 "start\ runas\ ${idis}{iozone.$RUNAS_ID\ dd.$RUNAS_ID\ tiotest.$RUNAS_ID}\ ${rateis}1000"
4012         tbf_rule_operate ost1 "start\ iozone_runas\ ${idis}{iozone.$RUNAS_ID}\ ${rateis}100"
4013         tbf_rule_operate ost1 "start\ dd_runas\ ${idis}{dd.$RUNAS_ID}\ ${rateis}50"
4014         nrs_write_read "$RUNAS"
4015
4016         # Change the rules
4017         tbf_rule_operate ost1 "change\ runas\ ${rateis}1001"
4018         tbf_rule_operate ost1 "change\ iozone_runas\ ${rateis}101"
4019         tbf_rule_operate ost1 "change\ dd_runas\ ${rateis}51"
4020         nrs_write_read "$RUNAS"
4021
4022         # Stop the rules
4023         tbf_rule_operate ost1 "stop\ runas"
4024         tbf_rule_operate ost1 "stop\ iozone_runas"
4025         tbf_rule_operate ost1 "stop\ dd_runas"
4026         nrs_write_read "$RUNAS"
4027
4028         # Cleanup the TBF policy
4029         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="fifo"
4030         [ $? -ne 0 ] && error "failed to set policy back to fifo"
4031         nrs_write_read "$RUNAS"
4032
4033         local current_jobid_var=$($LCTL get_param -n jobid_var)
4034         [[ $? -ne 0 ]] && error "failed to get param jobid_var"
4035         if [ $saved_jobid_var != $current_jobid_var ]; then
4036                 set_persistent_param_and_check client \
4037                         "jobid_var" "$FSNAME.sys.jobid_var" $saved_jobid_var
4038         fi
4039         return 0
4040 }
4041 run_test 77f "check TBF JobID nrs policy"
4042
4043 test_77g() {
4044         local rc=0
4045
4046         oss=$(comma_list $(osts_nodes))
4047
4048         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="tbf\ nid" ||
4049                 rc=$?
4050         [[ $rc -eq 3 ]] && skip "no NRS TBF exists" && return
4051         [[ $rc -ne 0 ]] && error "failed to set TBF NID policy"
4052
4053         do_nodes $oss lctl set_param \
4054                 ost.OSS.ost_io.nrs_policies="tbf\ jobid" || rc=$?
4055         [[ $rc -ne 0 ]] && error "failed to set TBF JOBID policy"
4056
4057         local idis
4058         local rateis
4059         if [ "$OST1_VERSION" -ge $(version_code 2.8.54) ]; then
4060                 idis="jobid="
4061                 rateis="rate="
4062         fi
4063
4064         # Add a rule that only valid for Jobid TBF. If direct change between
4065         # TBF types is not supported, this operation will fail.
4066         tbf_rule_operate ost1 "start\ dd_runas\ ${idis}{dd.$RUNAS_ID}\ ${rateis}50"
4067
4068         # Cleanup the TBF policy
4069         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="fifo"
4070         [ $? -ne 0 ] && error "failed to set policy back to fifo"
4071         return 0
4072 }
4073 run_test 77g "Change TBF type directly"
4074
4075 test_77h() {
4076         [ "$OST1_VERSION" -ge $(version_code 2.8.55) ] ||
4077                 skip "Need OST version at least 2.8.55"
4078
4079         local old_policy=$(do_facet ost1 \
4080                 lctl get_param ost.OSS.ost_io.nrs_policies)
4081         local new_policy
4082
4083         do_facet ost1 lctl set_param \
4084                 ost.OSS.ost_io.nrs_policies="abc"
4085         [ $? -eq 0 ] && error "should return error"
4086
4087         do_facet ost1 lctl set_param \
4088                 ost.OSS.ost_io.nrs_policies="tbf\ abc"
4089         [ $? -eq 0 ] && error "should return error"
4090
4091         do_facet ost1 lctl set_param \
4092                 ost.OSS.ost_io.nrs_policies="tbf\ reg\ abc"
4093         [ $? -eq 0 ] && error "should return error"
4094
4095         do_facet ost1 lctl set_param \
4096                 ost.OSS.ost_io.nrs_policies="tbf\ abc\ efg"
4097         [ $? -eq 0 ] && error "should return error"
4098
4099         new_policy=$(do_facet ost1 lctl get_param ost.OSS.ost_io.nrs_policies)
4100         [ $? -eq 0 ] || error "shouldn't LBUG"
4101
4102         [ "$old_policy" = "$new_policy" ] || error "NRS policy should be same"
4103
4104         return 0
4105 }
4106 run_test 77h "Wrong policy name should report error, not LBUG"
4107
4108 tbf_rule_check()
4109 {
4110         local facet=$1
4111         local expected=$2
4112         local error_message=$3
4113         local rule_number=0
4114         for rule in $expected; do
4115                 rule_number=$((rule_number + 1))
4116         done
4117         local stop_line=$(($rule_number + 3))
4118         local awk_command="awk 'NR >= 4 && NR <= $stop_line {print \$1}'"
4119
4120         local output=$(do_facet $facet lctl get_param \
4121                 ost.OSS.ost_io.nrs_tbf_rule |
4122                 eval $awk_command |
4123                 tr "\n" " " |
4124                 sed 's/[ ]*$//')
4125         if [ "$output" != "$expected" ]; then
4126                 error "$error_message, expected '$expected', got '$output'"
4127         fi
4128 }
4129
4130 test_77i() {
4131         [ "$OST1_VERSION" -ge $(version_code 2.8.55) ] ||
4132                 skip "Need OST version at least 2.8.55"
4133
4134         for i in $(seq 1 $OSTCOUNT)
4135         do
4136                 do_facet ost"$i" lctl set_param \
4137                         ost.OSS.ost_io.nrs_policies="tbf\ jobid"
4138                 [ $? -ne 0 ] &&
4139                         error "failed to set TBF policy"
4140         done
4141
4142         tbf_rule_check ost1 "default" "error before inserting any rule"
4143
4144         tbf_rule_operate ost1 "start\ before\ jobid={jobid}\ rate=1000"
4145         tbf_rule_check ost1 "before default" \
4146                 "error when inserting rule 'before'"
4147
4148         tbf_rule_operate ost1 "start\ after\ jobid={jobid}\ rate=1000\ rank=default"
4149         tbf_rule_check ost1 "before after default" \
4150                 "error when inserting rule 'after'"
4151
4152         tbf_rule_operate ost1 "start\ target\ jobid={jobid}\ rate=1000\ rank=after"
4153         tbf_rule_check ost1 "before target after default" \
4154                 "error when inserting rule 'target'"
4155
4156         echo "Move before itself"
4157         tbf_rule_operate ost1 "change\ target\ rank=target"
4158         tbf_rule_check ost1 "before target after default" \
4159                 "error when moving before itself"
4160
4161         echo "Move to higher rank"
4162         tbf_rule_operate ost1 "change\ target\ rank=before"
4163         tbf_rule_check ost1 "target before after default" \
4164                 "error when moving to higher rank"
4165
4166         echo "Move to lower rank"
4167         tbf_rule_operate ost1 "change\ target\ rank=after"
4168         tbf_rule_check ost1 "before target after default" \
4169                 "error when moving to lower rank"
4170
4171         echo "Move before default"
4172         tbf_rule_operate ost1 "change\ target\ rank=default"
4173         tbf_rule_check ost1 "before after target default" \
4174                 error "error when moving before default"
4175
4176         # Cleanup the TBF policy
4177         do_nodes $(comma_list $(osts_nodes)) \
4178                 $LCTL set_param ost.OSS.ost_io.nrs_policies=fifo
4179         return 0
4180 }
4181 run_test 77i "Change rank of TBF rule"
4182
4183 test_77j() {
4184         local idis
4185         local rateis
4186
4187         [ "$OST1_VERSION" -ge $(version_code 2.9.53) ] ||
4188                 skip "Need OST version at least 2.9.53"
4189         if [ "$OST1_VERSION" -ge $(version_code 2.8.60) ]; then
4190                 idis="opcode="
4191                 rateis="rate="
4192         fi
4193
4194         do_nodes $(comma_list $(osts_nodes)) \
4195                 lctl set_param jobid_var=procname_uid \
4196                         ost.OSS.ost_io.nrs_policies="tbf\ opcode" \
4197                         ost.OSS.ost_io.nrs_tbf_rule="start\ ost_r\ ${idis}{ost_read}\ ${rateis}5" \
4198                         ost.OSS.ost_io.nrs_tbf_rule="start\ ost_w\ ${idis}{ost_write}\ ${rateis}20"
4199         [ $? -ne 0 ] && error "failed to set TBF OPCode policy"
4200
4201         nrs_write_read
4202         tbf_verify 20 5
4203
4204         do_nodes $(comma_list $(osts_nodes)) \
4205                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ost_r" \
4206                         ost.OSS.ost_io.nrs_tbf_rule="stop\ ost_w" \
4207                         ost.OSS.ost_io.nrs_policies="fifo"
4208
4209         # sleep 3 seconds to wait the tbf policy stop completely,
4210         # or the next test case is possible get -EAGAIN when
4211         # setting the tbf policy
4212         sleep 3
4213 }
4214 run_test 77j "check TBF-OPCode NRS policy"
4215
4216 test_id() {
4217         local idstr="${1}id"
4218         local policy="${idstr}={$2}"
4219         local rate="rate=$3"
4220
4221         do_nodes $(comma_list $(osts_nodes)) \
4222                 lctl set_param jobid_var=procname_uid \
4223                         ost.OSS.ost_io.nrs_policies="tbf\ ${idstr}" \
4224                         ost.OSS.ost_io.nrs_tbf_rule="start\ ost_${idstr}\ ${policy}\ ${rate}"
4225         [ $? -ne 0 ] && error "failed to set tbf ${idstr} policy"
4226
4227         nrs_write_read "runas $4"
4228         tbf_verify $3 $3 "runas $4"
4229
4230         do_nodes $(comma_list $(osts_nodes)) \
4231                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ost_${idstr}" \
4232                         ost.OSS.ost_io.nrs_policies="fifo"
4233
4234         # sleep 3 seconds to wait the tbf policy stop completely,
4235         # or the next test case is possible get -eagain when
4236         # setting the tbf policy
4237         sleep 3
4238 }
4239
4240 test_77ja(){
4241         if [ "$OST1_VERSION" -lt $(version_code 2.11.50) ]; then
4242                 skip "Need OST version at least 2.11.50"
4243         fi
4244
4245         test_id "u" "500" "5" "-u 500"
4246         test_id "g" "500" "5" "-u 500 -g 500"
4247 }
4248 run_test 77ja "check TBF-UID/GID NRS policy"
4249
4250 cleanup_77k()
4251 {
4252         local rule_lists=$1
4253         local old_nrs=$2
4254
4255         trap 0
4256         for rule in $rule_lists; do
4257                 do_nodes $(comma_list $(osts_nodes)) \
4258                         lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ $rule"
4259         done
4260
4261         do_nodes $(comma_list $(osts_nodes)) \
4262                 lctl set_param ost.OSS.ost_io.nrs_policies="$old_nrs"
4263
4264         sleep 3
4265 }
4266
4267 test_77k() {
4268         [[ "$OST1_VERSION" -ge $(version_code 2.9.53) ]] ||
4269                 skip "Need OST version at least 2.9.53"
4270
4271         do_nodes $(comma_list $(osts_nodes)) \
4272                 lctl set_param ost.OSS.ost_io.nrs_policies="tbf" \
4273                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_w\ jobid={dd.$RUNAS_ID}\&opcode={ost_write}\ rate=20" \
4274                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_r\ jobid={dd.$RUNAS_ID}\&opcode={ost_read}\ rate=10"
4275
4276         nrs_write_read "$RUNAS"
4277         tbf_verify 20 10 "$RUNAS"
4278
4279         local address=$(comma_list "$(host_nids_address $CLIENTS $NETTYPE)")
4280         local client_nids=$(nids_list $address "\\")
4281         do_nodes $(comma_list $(osts_nodes)) \
4282                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_w" \
4283                         ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_r" \
4284                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_w\ nid={0@lo\ $client_nids}\&opcode={ost_write}\ rate=20" \
4285                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_r\ nid={0@lo\ $client_nids}\&opcode={ost_read}\ rate=10"
4286
4287         nrs_write_read
4288         tbf_verify 20 10
4289
4290         do_nodes $(comma_list $(osts_nodes)) \
4291                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_w" \
4292                         ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_r" \
4293                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext\ nid={0@lo\ $client_nids}\&jobid={dd.$RUNAS_ID}\ rate=20"
4294
4295         nrs_write_read "$RUNAS"
4296         tbf_verify 20 20 "$RUNAS"
4297
4298         do_nodes $(comma_list $(osts_nodes)) \
4299                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ext" \
4300                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_a\ jobid={dd.$RUNAS_ID},opcode={ost_write}\ rate=20" \
4301                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_b\ jobid={dd.$RUNAS_ID},opcode={ost_read}\ rate=10"
4302
4303         nrs_write_read "$RUNAS"
4304         # with parameter "RUNAS", it will match the latest rule
4305         # "ext_b" first, so the limited write rate is 10.
4306         tbf_verify 10 10 "$RUNAS"
4307         tbf_verify 20 10
4308
4309         trap "cleanup_77k \"ext_a ext_b\" \"fifo\"" EXIT
4310
4311         [[ "$OST1_VERSION" -ge $(version_code 2.10.58) ]] ||
4312                 skip "Need OST version at least 2.10.58"
4313
4314         do_nodes $(comma_list $(osts_nodes)) \
4315                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_a" \
4316                         ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_b" \
4317                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_ug\ uid={500}\&gid={1000}\ rate=5"
4318         nrs_write_read "runas -u 500 -g 1000"
4319         tbf_verify 5 5 "runas -u 500 -g 1000"
4320
4321         do_nodes $(comma_list $(osts_nodes)) \
4322                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_ug" \
4323                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_uw\ uid={500}\&opcode={ost_write}\ rate=20" \
4324                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_ur\ uid={500}\&opcode={ost_read}\ rate=10"
4325
4326         nrs_write_read "runas -u 500"
4327         tbf_verify 20 10 "runas -u 500"
4328
4329         do_nodes $(comma_list $(osts_nodes)) \
4330                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_uw" \
4331                         ost.OSS.ost_io.nrs_tbf_rule="stop\ ext_ur" \
4332                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_a\ uid={500},opcode={ost_write}\ rate=20" \
4333                         ost.OSS.ost_io.nrs_tbf_rule="start\ ext_b\ uid={500},opcode={ost_read}\ rate=10"
4334         nrs_write_read "runas -u 500"
4335         tbf_verify 10 10 "runas -u 500"
4336         tbf_verify 20 10 "runas -u 500"
4337         cleanup_77k "ext_a ext_b" "fifo"
4338 }
4339 run_test 77k "check TBF policy with NID/JobID/OPCode expression"
4340
4341 test_77l() {
4342         [[ "$OST1_VERSION" -ge $(version_code 2.10.56) ]] ||
4343                 skip "Need OST version at least 2.10.56"
4344
4345         do_facet ost1 lctl set_param ost.OSS.ost_io.nrs_policies="tbf\ nid"
4346         do_facet ost1 lctl set_param ost.OSS.ost_io.nrs_policies="tbf"
4347
4348         local output=$(do_facet ost1 lctl get_param \
4349                         ost.OSS.ost_io.nrs_policies | \
4350                         awk '/name: tbf/ {print;exit}' | \
4351                         awk -F ': ' '{print $2}')
4352
4353         if [ "$output" != "tbf" ]; then
4354                 error "The generic TBF output is '$output', not 'tbf'"
4355         fi
4356
4357         do_facet ost1 lctl set_param ost.OSS.ost_io.nrs_policies="fifo"
4358 }
4359 run_test 77l "check the output of NRS policies for generic TBF"
4360
4361 test_77m() {
4362         if [ "$OST1_VERSION" -lt $(version_code 2.9.54) ]; then
4363                 skip "Need OST version at least 2.9.54"
4364         fi
4365
4366         local dir=$DIR/$tdir
4367
4368         mkdir $dir || error "mkdir $dir failed"
4369         $LFS setstripe -c $OSTCOUNT $dir || error "setstripe to $dir failed"
4370         chmod 777 $dir
4371
4372         local nodes=$(comma_list $(osts_nodes))
4373         do_nodes $nodes lctl set_param ost.OSS.ost_io.nrs_policies=delay \
4374                                        ost.OSS.ost_io.nrs_delay_min=4 \
4375                                        ost.OSS.ost_io.nrs_delay_max=4 \
4376                                        ost.OSS.ost_io.nrs_delay_pct=100
4377         [ $? -ne 0 ] && error "Failed to set delay policy"
4378
4379         local start=$SECONDS
4380         do_nodes "${SINGLECLIENT:-$HOSTNAME}" "$RUNAS" \
4381                  dd if=/dev/zero of="$dir/nrs_delay_$HOSTNAME" bs=1M count=1 \
4382                    oflag=direct conv=fdatasync ||
4383                 { do_nodes $nodes lctl set_param ost.OSS.ost_io.nrs_policies="fifo";
4384                   error "dd on client failed (1)"; }
4385         local elapsed=$((SECONDS - start))
4386
4387         # NRS delay doesn't do sub-second timing, so a request enqueued at
4388         # 0.9 seconds can be dequeued at 4.0
4389         [ $elapsed -lt 3 ] &&
4390                 { do_nodes $nodes lctl set_param ost.OSS.ost_io.nrs_policies="fifo";
4391                   error "Single 1M write should take at least 3 seconds"; }
4392
4393         start=$SECONDS
4394         do_nodes "${SINGLECLIENT:-$HOSTNAME}" "$RUNAS" \
4395                  dd if=/dev/zero of="$dir/nrs_delay_$HOSTNAME" bs=1M count=10 \
4396                    oflag=direct conv=fdatasync ||
4397                 { do_nodes $nodes lctl set_param ost.OSS.ost_io.nrs_policies="fifo";
4398                   error "dd on client failed (2)"; }
4399         elapsed=$((SECONDS - start))
4400
4401         [ $elapsed -lt 30 ] &&
4402                 { do_nodes $nodes lctl set_param ost.OSS.ost_io.nrs_policies="fifo";
4403                   error "Ten 1M writes should take at least 30 seconds"; }
4404
4405         do_nodes $nodes lctl set_param ost.OSS.ost_io.nrs_policies="fifo"
4406         [ $? -ne 0 ] && error "failed to set policy back to fifo"
4407
4408         return 0
4409 }
4410 run_test 77m "check NRS Delay slows write RPC processing"
4411
4412 test_77n() { #LU-10802
4413         if [ "$OST1_VERSION" -lt $(version_code 2.10.58) ]; then
4414                 skip "Need OST version at least 2.10.58"
4415         fi
4416
4417         # Configure jobid_var
4418         local saved_jobid_var=$($LCTL get_param -n jobid_var)
4419         if [ $saved_jobid_var != procname_uid ]; then
4420                 set_persistent_param_and_check client \
4421                         "jobid_var" "$FSNAME.sys.jobid_var" procname_uid
4422         fi
4423
4424         do_nodes $(comma_list $(osts_nodes)) \
4425                 lctl set_param ost.OSS.ost_io.nrs_policies="tbf\ jobid" \
4426                         ost.OSS.ost_io.nrs_tbf_rule="stop\ dd_runas" \
4427                         ost.OSS.ost_io.nrs_tbf_rule="start\ dd_runas\ jobid={*.$RUNAS_ID}\ rate=20"
4428
4429         nrs_write_read
4430         tbf_verify 20 20 "$RUNAS"
4431
4432         do_nodes $(comma_list $(osts_nodes)) \
4433                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ dd_runas" \
4434                         ost.OSS.ost_io.nrs_tbf_rule="start\ dd_runas\ jobid={dd.*}\ rate=20"
4435
4436         nrs_write_read
4437         tbf_verify 20 20
4438
4439         do_nodes $(comma_list $(osts_nodes)) \
4440                 lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ dd_runas" \
4441                         ost.OSS.ost_io.nrs_policies="fifo"
4442
4443         sleep 3
4444
4445         local current_jobid_var=$($LCTL get_param -n jobid_var)
4446         if [ $saved_jobid_var != $current_jobid_var ]; then
4447                 set_persistent_param_and_check client \
4448                         "jobid_var" "$FSNAME.sys.jobid_var" $saved_jobid_var
4449         fi
4450 }
4451 run_test 77n "check wildcard support for TBF JobID NRS policy"
4452
4453 test_77o() {
4454         (( $OST1_VERSION > $(version_code 2.14.54) )) ||
4455                 skip "need OST > 2.14.54"
4456
4457         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_policies="tbf\ nid"
4458         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="start\ name\ nid={192.168.*.*@tcp}\ rate=10000"
4459         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="start\ name1\ nid={192.168.*.*@tcp}\ rate=10000"
4460         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="change\ name1\ rank=name"
4461         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="stop\ name"
4462         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_policies="fifo"
4463 }
4464 run_test 77o "Changing rank should not panic"
4465
4466 test_77q() {
4467         local i
4468
4469         (( $MDS1_VERSION > $(version_code 2.14.54) )) ||
4470                 skip "need MDS >= 2.14.54"
4471
4472         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_policies="tbf"
4473         stack_trap "do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_policies=fifo"
4474
4475         for i in {1..50}; do
4476                 local pid1 pid2
4477
4478                 do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="'start rule77q_1 uid={500}&gid={500} rate=100'" &
4479                 pid1=$!
4480                 do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="'start rule77q_2 uid={1000}&gid={1000} rate=100'" &
4481                 pid2=$!
4482                 wait $pid1 || error "$i: Fail to start TBF rule 'rule77q_1'"
4483                 wait $pid2 || error "$i: Fail to start TBF rule 'rule77q_2'"
4484
4485                 do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="'stop rule77q_1'" &
4486                 pid1=$!
4487                 do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="'stop rule77q_2'" &
4488                 pid2=$!
4489                 wait $pid1 || error "$i: Fail to stop TBF rule 'rule77q_1'"
4490                 wait $pid2 || error "$i: Fail to stop TBF rule 'rule77q_2'"
4491         done
4492 }
4493 run_test 77q "Parallel TBF rule definitions should not panic"
4494
4495 test_77p() {
4496         local c
4497         local -a spec_chars=(
4498                 '@' '.' '~' '#' '/' '^' '%' '*' ';' ',' '?' '<' '>' ':'
4499                 '+' '=' ')' '(' '{' '}' '|' '[' ']' '!' '&' '\$' '\`' '\\')
4500
4501         (( $MDS1_VERSION > $(version_code 2.14.54) )) ||
4502                 skip "need MDS >= 2.14.54"
4503
4504         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_policies="tbf"
4505         stack_trap "do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_policies=fifo"
4506
4507         # TBF rule name size is 16 bytes
4508         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="start\ test_77p_overflo\ uid={500}\ rate=500" &&
4509                 error "The length of tbf rule name is not checked" || true
4510         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="start\ \ uid={500}\ rate=500" &&
4511                 error "The server should not accept empty tbf rule name" || true
4512         do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="start\ test_77p_empty" &&
4513                 error "The server should not accept 'start <tbf_rule_name>' without an expression" || true
4514
4515         # Test with special chars
4516         for c in "${spec_chars[@]}"; do
4517                 do_facet mds1 $LCTL set_param mds.MDS.mdt.nrs_tbf_rule="'start test77p${c}spec uid={500} rate=500'" &&
4518                 error "Special char '${c}' should not be accepted in a tbf rule name" || true
4519         done
4520
4521 }
4522 run_test 77p "Check validity of rule names for TBF policies"
4523
4524 test_78() { #LU-6673
4525         local rc
4526
4527         oss=$(comma_list $(osts_nodes))
4528         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="orr" &
4529         do_nodes $oss lctl set_param ost.OSS.*.nrs_orr_quantum=1
4530         rc=$?
4531         [[ $rc -eq 3 ]] && skip "no NRS exists" && return
4532         # Valid return codes are:
4533         # 0: Tuning succeeded
4534         # ENODEV: Policy is still stopped
4535         # EAGAIN: Policy is being initialized
4536         [ $rc -eq 0 -o $rc -eq 19 -o $rc -eq 11 ] ||
4537                 error "Expected set_param to return 0|ENODEV|EAGAIN"
4538
4539         # Cleanup the ORR policy
4540         do_nodes $oss lctl set_param ost.OSS.ost_io.nrs_policies="fifo"
4541         [ $? -ne 0 ] && error "failed to set policy back to fifo"
4542         return 0
4543 }
4544 run_test 78 "Enable policy and specify tunings right away"
4545
4546 test_79() {
4547         remote_mds_nodsh && skip "remote MDS with nodsh" && return
4548         test_mkdir $DIR/$tdir
4549
4550         # Prevent interference from layout intent RPCs due to
4551         # asynchronous writeback. These will be tested in 130c below.
4552         do_nodes ${CLIENTS:-$HOSTNAME} sync
4553
4554         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
4555                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
4556
4557 #define OBD_FAIL_MDS_INTENT_DELAY               0x160
4558         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
4559         local facet=mds$((mdtidx + 1))
4560         stat $DIR/$tdir
4561         set_nodes_failloc $(facet_active_host $facet) 0x80000160
4562         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null  &
4563         local pid=$!
4564         sleep 2
4565
4566 #define OBD_FAIL_MDS_GETXATTR_PACK       0x131
4567         set_nodes_failloc $(facet_active_host $facet) 0x80000131
4568
4569         wait $pid
4570         return 0
4571 }
4572 run_test 79 "xattr: intent error"
4573
4574 test_80a() {
4575         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4576         local MDTIDX=1
4577         local mdt_index
4578         local i
4579         local file
4580         local pid
4581
4582         mkdir_on_mdt0 $DIR1/$tdir
4583         mkdir -p $DIR1/$tdir/dir
4584         createmany -o $DIR1/$tdir/dir/f 10 ||
4585                 error "create files under remote dir failed $i"
4586
4587         cp /etc/passwd $DIR1/$tdir/$tfile
4588
4589         #migrate open file should fails
4590         multiop_bg_pause $DIR2/$tdir/$tfile O_c || error "open $file failed"
4591         pid=$!
4592         # give multiop a chance to open
4593         sleep 1
4594
4595         $LFS migrate -m $MDTIDX $DIR1/$tdir &&
4596                 error "migrate open files should failed with open files"
4597
4598         kill -USR1 $pid
4599
4600         $LFS migrate -m $MDTIDX $DIR1/$tdir ||
4601                         error "migrate remote dir error"
4602
4603         echo "Finish migration, then checking.."
4604         for file in $(find $DIR1/$tdir); do
4605                 mdt_index=$($LFS getstripe -m $file)
4606                 [ $mdt_index == $MDTIDX ] ||
4607                         error "$file is not on MDT${MDTIDX}"
4608         done
4609
4610         diff /etc/passwd $DIR1/$tdir/$tfile ||
4611                 error "file different after migration"
4612
4613         rm -rf $DIR1/$tdir || error "rm dir failed after migration"
4614 }
4615 run_test 80a "migrate directory when some children is being opened"
4616
4617 cleanup_80b() {
4618         trap 0
4619         kill -9 $migrate_pid
4620 }
4621
4622 test_80b() {
4623         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4624         local migrate_dir1=$DIR1/$tdir/migrate_dir
4625         local migrate_dir2=$DIR2/$tdir/migrate_dir
4626         local migrate_run=$LUSTRE/tests/migrate.sh
4627         local start_time
4628         local show_time=1
4629         local mdt_idx
4630         local rc=0
4631         local rc1=0
4632
4633         trap cleanup_80b EXIT
4634         #prepare migrate directory
4635         mkdir -p $migrate_dir1
4636         for F in {1,2,3,4,5}; do
4637                 echo "$F$F$F$F$F" > $migrate_dir1/file$F
4638                 echo "$F$F$F$F$F" > $DIR/$tdir/file$F
4639         done
4640
4641         #migrate the directories among MDTs
4642         (
4643                 while true; do
4644                         mdt_idx=$((RANDOM % MDSCOUNT))
4645                         $LFS migrate -m $mdt_idx $migrate_dir1 &>/dev/null ||
4646                                 rc=$?
4647                         (( $rc != 0 && $rc != 16 )) || break
4648                 done
4649         ) &
4650         migrate_pid=$!
4651
4652         echo "start migration thread $migrate_pid"
4653         #Access the files at the same time
4654         start_time=$SECONDS
4655         echo "accessing the migrating directory for 5 minutes..."
4656         while true; do
4657                 ls $migrate_dir2 > /dev/null || {
4658                         echo "read dir fails"
4659                         break
4660                 }
4661                 diff -u $DIR2/$tdir/file1 $migrate_dir2/file1 || {
4662                         echo "access file1 fails"
4663                         break
4664                 }
4665
4666                 cat $migrate_dir2/file2 > $migrate_dir2/file3 || {
4667                         echo "access file2/3 fails"
4668                         break
4669                 }
4670
4671                 echo "aaaaa" > $migrate_dir2/file4 > /dev/null || {
4672                         echo "access file4 fails"
4673                         break
4674                 }
4675
4676                 stat $migrate_dir2/file5 > /dev/null || {
4677                         echo "stat file5 fails"
4678                         break
4679                 }
4680
4681                 touch $migrate_dir2/source_file > /dev/null || rc1=$?
4682                 (( $rc != 0 && $rc != 1 )) || {
4683                         echo "touch file failed with $rc1"
4684                         break;
4685                 }
4686
4687                 if [ -e $migrate_dir2/source_file ]; then
4688                         ln $migrate_dir2/source_file $migrate_dir2/link_file \
4689                                         &>/dev/null || rc1=$?
4690                         if [ -e $migrate_dir2/link_file ]; then
4691                                 rm -rf $migrate_dir2/link_file
4692                         fi
4693
4694                         mrename $migrate_dir2/source_file \
4695                                 $migrate_dir2/target_file &>/dev/null || rc1=$?
4696                         (( $rc != 0 && $rc != 1 )) || {
4697                                 echo "rename failed with $rc1"
4698                                 break
4699                         }
4700
4701                         if [ -e $migrate_dir2/target_file ]; then
4702                                 rm -rf $migrate_dir2/target_file &>/dev/null ||
4703                                                                 rc1=$?
4704                         else
4705                                 rm -rf $migrate_dir2/source_file &>/dev/null ||
4706                                                                 rc1=$?
4707                         fi
4708                         (( $rc != 0 && $rc != 1 )) || {
4709                                 echo "unlink failed with $rc1"
4710                                 break
4711                         }
4712                 fi
4713
4714                 local duration=$((SECONDS - start_time))
4715                 if (( duration % 10 == 0 )); then
4716                         if (( $show_time == 1 )); then
4717                                 echo "...$duration seconds"
4718                                 show_time=0
4719                         fi
4720                 else
4721                         show_time=1
4722                 fi
4723
4724                 kill -0 $migrate_pid || {
4725                         echo "migration stopped 1"
4726                         break
4727                 }
4728
4729                 (( $duration < 300 )) || break
4730         done
4731
4732         #check migration are still there
4733         kill -0 $migrate_pid || error "migration stopped 2"
4734         cleanup_80b
4735 }
4736 run_test 80b "Accessing directory during migration"
4737
4738 test_81a() {
4739         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4740
4741         rm -rf $DIR1/$tdir
4742
4743         mkdir -p $DIR1/$tdir
4744
4745         $LFS setdirstripe -i0 -c$MDSCOUNT  $DIR1/$tdir/d0
4746         $LFS setdirstripe -i0 -c$MDSCOUNT  $DIR1/$tdir/d1
4747
4748         cd $DIR1/$tdir
4749         touch d0/0      || error "create 0 failed"
4750         mv d0/0 d1/0    || error "rename d0/0 d1/0 failed"
4751         stat d0/0       && error "stat mv filed succeed"
4752         mv $DIR2/$tdir/d1/0 $DIR2/$tdir/d0/0 || error "rename d1/0 d0/0 failed"
4753         stat d0/0       || error "stat failed"
4754
4755         local t=$(ls -ai $DIR1/$tdir/d0 | sort -u | wc -l)
4756
4757         if [ $t -ne 3 ]; then
4758                 ls -ai $DIR1/$tdir/d0
4759                 error "expect 3 get $t"
4760         fi
4761
4762         return 0
4763 }
4764 run_test 81a "rename and stat under striped directory"
4765
4766 test_81b() {
4767         [ $MDSCOUNT -lt 2 ] &&
4768                 skip "We need at least 2 MDTs for this test"
4769
4770         local total
4771         local setattr_pid
4772
4773         total=1000
4774
4775         $LFS mkdir -c $MDSCOUNT $DIR1/$tdir || error "$LFS mkdir"
4776         createmany -o $DIR1/$tdir/$tfile. $total || error "createmany"
4777
4778         (
4779                 while true; do
4780                         touch $DIR1/$tdir
4781                 done
4782         ) &
4783         setattr_pid=$!
4784
4785         for i in $(seq $total); do
4786                 mrename $DIR2/$tdir/$tfile.$i $DIR2/$tdir/$tfile-new.$i \
4787                         > /dev/null
4788         done
4789
4790         kill -9 $setattr_pid
4791 }
4792 run_test 81b "rename under striped directory doesn't deadlock"
4793
4794 test_81c() {
4795         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
4796         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
4797                 skip "Need MDS version at least 2.13.52"
4798
4799         # source is local, source parent is remote
4800         $LFS mkdir -i 0 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
4801         $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
4802         $LFS mkdir -i 3 $DIR1/${tdir}_src/sub || error "mkdir sub"
4803         $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
4804         stat $DIR2/${tdir}_src/sub || error "stat sub failed"
4805         mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
4806         [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone"
4807         rm -rf $DIR1/${tdir}_src $DIR1/${tdir}_tgt
4808
4809         # source is remote, source parent is local
4810         $LFS mkdir -i 3 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
4811         $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
4812         $LFS mkdir -i 0 $DIR1/${tdir}_src/sub || error "mkdir sub"
4813         $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
4814         stat $DIR2/${tdir}_src/sub || error "stat sub failed"
4815         mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
4816         [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone"
4817         rm -rf $DIR1/${tdir}_src $DIR1/${tdir}_tgt
4818
4819         # source and source parent are remote
4820         $LFS mkdir -i 0 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
4821         $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
4822         mkdir $DIR1/${tdir}_src/sub || error "mkdir sub"
4823         $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
4824         stat $DIR2/${tdir}_src/sub || error "stat sub failed"
4825         mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
4826         [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone"
4827         rm -rf $DIR1/${tdir}_src $DIR1/${tdir}_tgt
4828
4829         # source and source parent are remote, and source is remote object
4830         $LFS mkdir -i 0 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
4831         $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
4832         $LFS mkdir -i 2 $DIR1/${tdir}_src/sub || error "mkdir sub"
4833         $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
4834         stat $DIR2/${tdir}_src/sub || error "stat sub failed"
4835         mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
4836         [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone" || true
4837 }
4838 run_test 81c "rename revoke LOOKUP lock for remote object"
4839
4840 test_82() {
4841         [[ "$MDS1_VERSION" -gt $(version_code 2.6.91) ]] ||
4842                 skip "Need MDS version at least 2.6.92"
4843
4844         # Client 1 creates a file.
4845         multiop_bg_pause $DIR1/$tfile O_ac || error "multiop_bg_pause 1"
4846         pid1=$!
4847         # Client 2 opens the file.
4848         multiop_bg_pause $DIR2/$tfile o_Ac || error "multiop_bg_pause 2"
4849         pid2=$!
4850         # Client 1 makes the file an orphan.
4851         rm $DIR1/$tfile || error "rm"
4852         # Client 2 sets EA "user.multiop".
4853         kill -s USR1 $pid2
4854         wait $pid2 || error "multiop 2"
4855         # Client 1 gets EA "user.multiop".  This used to fail because the EA
4856         # cache refill would get "trusted.link" from mdd_xattr_list() but
4857         # -ENOENT when trying to get "trusted.link"'s value.  See also sanity
4858         # 102q.
4859         kill -s USR1 $pid1
4860         wait $pid1 || error "multiop 1"
4861 }
4862 run_test 82 "fsetxattr and fgetxattr on orphan files"
4863
4864 test_83() {
4865         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4866         local pid1
4867         local pid2
4868
4869         (
4870                 cd $DIR1
4871                 while true; do
4872                         $LFS mkdir -i1 -c2 $tdir
4873                         rmdir $tdir
4874                 done
4875         ) &
4876         pid1=$!
4877         echo "start pid $pid1 to create/unlink striped directory"
4878
4879         # Access the directory at the same time
4880         (
4881                 cd $DIR2
4882                 while true; do
4883                         stat $tdir > /dev/null 2>&1
4884                 done
4885         ) &
4886         pid2=$!
4887         echo "start pid $pid2 to stat striped directory"
4888
4889         sleep 120
4890         kill $pid1 $pid2
4891         wait $pid1 $pid2
4892
4893         return 0
4894 }
4895 run_test 83 "access striped directory while it is being created/unlinked"
4896
4897 test_84() {
4898         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
4899                 skip "lustre < 2.12.55 does not contain LU-12485 fix"
4900
4901         local mtime
4902
4903         $MULTIOP $DIR/$tfile oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:c ||
4904                 error "create $tfile failed"
4905         mtime=$(stat -c%Y $DIR/$tfile)
4906         mtime=$((mtime + 200))
4907
4908         #define OBD_FAIL_OBD_0NLINK_RACE  0x60b
4909         do_facet mds1 $LCTL set_param fail_loc=0x8000060b
4910
4911         touch -c -m $mtime $DIR/$tfile &
4912         setattr_pid=$!
4913         # sleep a while to let 'touch' run first
4914         sleep 5
4915         rm -f $DIR2/$tfile || error "unlink $tfile failed"
4916
4917         # touch may fail
4918         wait $setattr_pid || true
4919 }
4920 run_test 84 "0-nlink race in lu_object_find()"
4921
4922 test_90() {
4923         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4924         local pid1
4925         local pid2
4926         local duration=180
4927
4928         [ "$SLOW" = "yes" ] && duration=600
4929         # Open/Create under striped directory
4930         (
4931                 cd $DIR1
4932                 while true; do
4933                         $LFS mkdir -c$MDSCOUNT $tdir > /dev/null 2>&1
4934                         touch $tdir/f{0..3} > /dev/null 2>&1
4935                 done
4936         ) &
4937         pid1=$!
4938         echo "start pid $pid1 to open/create under striped directory"
4939
4940         # unlink the striped directory at the same time
4941         (
4942                 cd $DIR2
4943                 while true; do
4944                         rm -rf $tdir > /dev/null 2>&1
4945                 done
4946         ) &
4947         pid2=$!
4948         echo "start pid $pid2 to unlink striped directory"
4949
4950         sleep $duration
4951
4952         kill $pid1 $pid2
4953         wait $pid1 $pid2
4954
4955         return 0
4956 }
4957 run_test 90 "open/create and unlink striped directory"
4958
4959 test_91() {
4960         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4961         local pid1
4962         local pid2
4963         local duration=180
4964
4965         [ "$SLOW" = "yes" ] && duration=600
4966         # chmod striped directory
4967         (
4968                 cd $DIR1
4969                 while true; do
4970                         $LFS mkdir -c$MDSCOUNT $tdir > /dev/null 2>&1
4971                         chmod go+w $tdir > /dev/null 2>&1
4972                 done
4973         ) &
4974         pid1=$!
4975         echo "start pid $pid1 to chmod striped directory"
4976
4977         # unlink the striped directory at the same time
4978         (
4979                 cd $DIR2
4980                 while true; do
4981                         rm -rf $tdir > /dev/null 2>&1
4982                 done
4983         ) &
4984         pid2=$!
4985         echo "start pid $pid2 to unlink striped directory"
4986
4987         sleep $duration
4988
4989         kill $pid1 $pid2
4990         wait $pid1 $pid2
4991
4992         return 0
4993 }
4994 run_test 91 "chmod and unlink striped directory"
4995
4996 test_92() {
4997         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4998
4999         local fd=$(free_fd)
5000         local cmd="exec $fd<$DIR1/$tdir"
5001         $LFS setdirstripe -c$MDSCOUNT $DIR1/$tdir || error "mkdir $tdir fails"
5002         eval $cmd
5003         cmd="exec $fd<&-"
5004         trap "eval $cmd" EXIT
5005         cd $DIR1/$tdir || error "cd $DIR1/$tdir fails"
5006         rmdir ../$tdir || error "rmdir ../$tdir fails"
5007
5008         #define OBD_FAIL_LLITE_NO_CHECK_DEAD  0x1408
5009         $LCTL set_param fail_loc=0x1408
5010         mkdir $DIR2/$tdir/dir && error "create dir succeeds"
5011         $LFS setdirstripe -i1 $DIR2/$tdir/remote_dir &&
5012                 error "create remote dir succeeds"
5013         $LCTL set_param fail_loc=0
5014         eval $cmd
5015         return 0
5016 }
5017 run_test 92 "create remote directory under orphan directory"
5018
5019 test_93() {
5020         local rc1=0
5021         local rc2=0
5022         local old_rr
5023
5024         mkdir -p $DIR1/$tfile-1/
5025         mkdir -p $DIR2/$tfile-2/
5026         local old_rr=$(do_facet $SINGLEMDS "$LCTL get_param -n \
5027                 lod.$FSNAME-MDT0000-*/qos_threshold_rr" | sed -e 's/%//')
5028         do_facet $SINGLEMDS "$LCTL set_param -n \
5029                 lod.$FSNAME-MDT0000-*/qos_threshold_rr=100"
5030         #define OBD_FAIL_MDS_LOV_CREATE_RACE     0x163
5031         do_facet $SINGLEMDS "$LCTL set_param fail_loc=0x00000163"
5032
5033         $LFS setstripe -c -1 $DIR1/$tfile-1/file1 &
5034         local PID1=$!
5035         sleep 1
5036         $LFS setstripe -c -1 $DIR2/$tfile-2/file2 &
5037         local PID2=$!
5038         wait $PID2
5039         wait $PID1
5040         do_facet $SINGLEMDS "$LCTL set_param fail_loc=0x0"
5041         do_facet $SINGLEMDS "$LCTL set_param -n \
5042                 lod.$FSNAME-MDT0000-*/qos_threshold_rr=$old_rr"
5043
5044         $LFS getstripe $DIR1/$tfile-1/file1
5045         rc1=$($LFS getstripe -q $DIR1/$tfile-1/file1 |
5046                 awk '{if (/[0-9]/) print $1 }' | sort | uniq -d | wc -l)
5047         $LFS getstripe $DIR2/$tfile-2/file2
5048         rc2=$($LFS getstripe -q $DIR2/$tfile-2/file2 |
5049                 awk '{if (/[0-9]/) print $1 }' | sort | uniq -d | wc -l)
5050         echo "rc1=$rc1 and rc2=$rc2 "
5051         [ $rc1 -eq 0 ] && [ $rc2 -eq 0 ] ||
5052                 error "object allocate on same ost detected"
5053 }
5054 run_test 93 "alloc_rr should not allocate on same ost"
5055
5056 test_94() {
5057         $LCTL set_param osc.*.idle_timeout=0
5058         dd if=/dev/zero of=$DIR2/$tfile bs=4k count=2 conv=fsync
5059
5060         local before=$(date +%s)
5061         local evict
5062
5063         $LCTL mark write
5064 #define OBD_FAIL_LDLM_PAUSE_CANCEL       0x312
5065         $LCTL set_param fail_val=5 fail_loc=0x80000312
5066         dd if=/dev/zero of=$DIR/$tfile conv=notrunc oflag=append bs=4k count=1 &
5067         local pid=$!
5068         sleep 2
5069
5070 #define OBD_FAIL_LDLM_PAUSE_CANCEL_LOCAL 0x329
5071         $LCTL set_param fail_val=6 fail_loc=0x80000329
5072         $LCTL mark kill $pid
5073         kill -ALRM $pid
5074
5075         dd if=/dev/zero of=$DIR2/$tfile conv=notrunc oflag=append bs=4k count=1
5076
5077         wait $pid
5078         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 conv=fsync
5079
5080         evict=$(do_facet client $LCTL get_param \
5081                 osc.$FSNAME-OST*-osc-*/state |
5082             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
5083
5084         [ -z "$evict" ] || [[ $evict -le $before ]] ||
5085                 (do_facet client $LCTL get_param \
5086                         osc.$FSNAME-OST*-osc-*/state;
5087                     error "eviction happened: $evict before:$before")
5088         $LCTL set_param osc.*.idle_timeout=debug
5089 }
5090 run_test 94 "signal vs CP callback race"
5091
5092 # Data-on-MDT tests
5093 test_100a() {
5094         skip "Reserved for glimpse-ahead" && return
5095         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5096                 skip "Need MDS version at least 2.10.55"
5097
5098         mkdir -p $DIR/$tdir
5099
5100         $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
5101
5102         lctl set_param -n mdc.*.stats=clear
5103         dd if=/dev/zero of=$DIR2/$tdir/dom bs=4096 count=1 || return 1
5104
5105         $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #1"
5106         # first stat from server should return size data and save glimpse
5107         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
5108         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
5109         # second stat to check size is NOT cached on client without IO lock
5110         $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #2"
5111
5112         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
5113         [ $gls -ge 1 ] || error "Expect glimpse RPCs but none"
5114         rm -f $dom
5115 }
5116 run_test 100a "DoM: glimpse RPCs for stat without IO lock (DoM only file)"
5117
5118 test_100b() {
5119         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5120                 skip "Need MDS version at least 2.10.55"
5121
5122         mkdir -p $DIR/$tdir
5123
5124         $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
5125
5126         lctl set_param -n mdc.*.stats=clear
5127         dd if=/dev/zero of=$DIR2/$tdir/dom bs=4096 count=1 || return 1
5128         cancel_lru_locks mdc
5129         # first stat data from server should have size
5130         $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #1"
5131         # second stat to check size is cached on client
5132         $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom || error "stat #2"
5133
5134         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
5135         # both stats should cause no glimpse requests
5136         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
5137         rm -f $dom
5138 }
5139 run_test 100b "DoM: no glimpse RPC for stat with IO lock (DoM only file)"
5140
5141 test_100c() {
5142         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5143                 skip "Need MDS version at least 2.10.55"
5144
5145         mkdir -p $DIR/$tdir
5146
5147         $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
5148
5149         lctl set_param -n mdc.*.stats=clear
5150         lctl set_param -n osc.*.stats=clear
5151         dd if=/dev/zero of=$DIR2/$tdir/dom bs=2048K count=1 || return 1
5152
5153         # check that size is merged from MDT and OST correctly
5154         $CHECKSTAT -t file -s 2097152 $DIR/$tdir/dom ||
5155                 error "Wrong size from stat #1"
5156
5157         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
5158         [ $gls -eq 0 ] && error "Expect OST glimpse RPCs but got none"
5159
5160         rm -f $dom
5161 }
5162 run_test 100c "DoM: write vs stat without IO lock (combined file)"
5163
5164 test_100d() {
5165         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5166                 skip "Need MDS version at least 2.10.55"
5167
5168         mkdir -p $DIR/$tdir
5169
5170         $LFS setstripe -E 1024K -L mdt -E EOF $DIR/$tdir/dom
5171
5172
5173         dd if=/dev/zero of=$DIR2/$tdir/dom bs=2048K count=1 || return 1
5174         lctl set_param -n mdc.*.stats=clear
5175         $TRUNCATE $DIR2/$tdir/dom 4096
5176
5177         # check that reported size is valid after file grows to OST and
5178         # is truncated back to MDT stripe size
5179         $CHECKSTAT -t file -s 4096 $DIR/$tdir/dom ||
5180                 error "Wrong size from stat #1"
5181
5182         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
5183         [ $gls -eq 0 ] && error "Expect OST glimpse but got none"
5184
5185         rm -f $dom
5186 }
5187 run_test 100d "DoM: write+truncate vs stat without IO lock (combined file)"
5188
5189 test_100e() {
5190         [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
5191                 skip "Need MDS version at least 2.11.50"
5192
5193         local dom=$DIR/$tdir/dom
5194         local dom2=$DIR2/$tdir/dom
5195         mkdir -p $DIR/$tdir
5196
5197         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
5198
5199         cancel_lru_locks mdc
5200         dd if=/dev/urandom of=$dom bs=12000 count=1
5201         $TRUNCATE $dom2 6000
5202         cancel_lru_locks mdc
5203         lctl set_param -n mdc.*.stats=clear
5204         # expect read-on-open to return all data before write
5205         cat /etc/hosts >> $dom
5206         local read=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
5207         [[ $read -eq 0 ]] || error "Unexpected $read READ RPCs"
5208 }
5209 run_test 100e "DoM: read on open and file size"
5210
5211 test_101a() {
5212         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5213                 skip "Need MDS version at least 2.10.55"
5214
5215         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
5216         # to get layout
5217         $CHECKSTAT -t file $DIR1/$tfile
5218
5219         local old_wb=$(sysctl -n vm.dirty_writeback_centisecs)
5220         sysctl -wq vm.dirty_writeback_centisecs=0
5221
5222         trap "sysctl -wq vm.dirty_writeback_centisecs=$old_wb" EXIT
5223
5224         # open + IO lock
5225         dd if=/dev/zero of=$DIR1/$tfile bs=4096 count=1 ||
5226                 error_noexit "Write fails"
5227         # must discard pages
5228         lctl set_param -n mdc.*.stats=clear
5229         rm $DIR2/$tfile || error "Unlink fails"
5230
5231         local writes=$(lctl get_param -n mdc.*.stats | grep -c ost_write)
5232         [ $writes -eq 0 ] || error "Found WRITE RPC but expect none"
5233 }
5234 run_test 101a "Discard DoM data on unlink"
5235
5236 test_101b() {
5237         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5238                 skip "Need MDS version at least 2.10.55"
5239
5240         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
5241         touch $DIR1/${tfile}_2
5242         # to get layout
5243         $CHECKSTAT -t file $DIR1/$tfile
5244
5245         local old_wb=$(sysctl -n vm.dirty_writeback_centisecs)
5246         sysctl -wq vm.dirty_writeback_centisecs=0
5247
5248         trap "sysctl -wq vm.dirty_writeback_centisecs=$old_wb" EXIT
5249
5250         # open + IO lock
5251         dd if=/dev/zero of=$DIR1/$tfile bs=4096 count=1 || error "Write fails"
5252         # must discard pages
5253         lctl set_param -n mdc.*.stats=clear
5254         mv $DIR2/${tfile}_2 $DIR2/$tfile || error "Rename fails"
5255
5256         local writes=$(lctl get_param -n mdc.*.stats | grep -c ost_write)
5257         [ $writes -eq 0 ] || error "Found WRITE RPC but expect none"
5258 }
5259 run_test 101b "Discard DoM data on rename"
5260
5261 test_101c() {
5262         [ "$MDS1_VERSION" -lt $(version_code 2.10.55) ] &&
5263                 skip "Need MDS version at least 2.10.55"
5264
5265         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
5266         # to get layout
5267         $CHECKSTAT -t file $DIR1/$tfile
5268
5269         local old_wb=$(sysctl -n vm.dirty_writeback_centisecs)
5270         sysctl -wq vm.dirty_writeback_centisecs=0
5271
5272         trap "sysctl -wq vm.dirty_writeback_centisecs=$old_wb" EXIT
5273
5274         # open + IO lock
5275         dd if=/dev/zero of=$DIR1/$tfile bs=4096 count=1 || error "Write fails"
5276         $MULTIOP $DIR1/$tfile O_c &
5277         MULTIOP_PID=$!
5278         sleep 1
5279         lctl set_param -n mdc.*.stats=clear
5280         rm $DIR2/$tfile > /dev/null || error "Unlink fails for opened file"
5281         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
5282
5283         local writes=$(lctl get_param -n mdc.*.stats | grep -c ost_write)
5284         [ $writes -eq 0 ] || error "Found WRITE RPC but expect none"
5285 }
5286 run_test 101c "Discard DoM data on close-unlink"
5287
5288 # test to verify file handle related system calls
5289 # (name_to_handle_at/open_by_handle_at)
5290 # The new system calls are supported in glibc >= 2.14.
5291
5292 # test to verify we can open by handle an unlinked file from > 1 client
5293 # This test opens the file normally on $DIR1, which is on one mount, and then
5294 # opens it by handle on $DIR2, which is on a different mount.
5295 test_102() {
5296         (( "$MDS1_VERSION" >= $(version_code 2.11.57) )) ||
5297                 skip "Needs MDS version 2.11.57 or later"
5298
5299         echo "Test file_handle syscalls" > $DIR/$tfile ||
5300                 error "write failed"
5301         check_fhandle_syscalls $DIR/$tfile $DIR2 ||
5302                 error "check_fhandle_syscalls $tfile failed"
5303
5304         # test this is working on DNE directories also
5305         if (( MDSCOUNT > 1 && MDS1_VERSION >= $(version_code 2.14.52) )); then
5306                 $LFS mkdir -i 1 $DIR/$tdir.remote
5307                 cancel_lru_locks mdc
5308                 check_fhandle_syscalls $DIR/$tdir.remote $DIR2 ||
5309                         error "check_fhandle_syscalls $tdir.remote failed"
5310                 $LFS mkdir -c -1 $DIR/$tdir.remote/subdir
5311                 cancel_lru_locks mdc
5312                 check_fhandle_syscalls $DIR/$tdir.remote/subdir $DIR2 ||
5313                         error "check_fhandle_syscalls $tdir.remote/subdir fail"
5314
5315                 $LFS mkdir -c -1 $DIR/$tdir.stripe
5316                 cancel_lru_locks mdc
5317                 check_fhandle_syscalls $DIR/$tdir.stripe $DIR2 ||
5318                         error "check_fhandle_syscalls $tdir.stripe failed"
5319                 $LFS mkdir -c -1 $DIR/$tdir.stripe/subdir
5320                 cancel_lru_locks mdc
5321                 check_fhandle_syscalls $DIR/$tdir.stripe/subdir $DIR2 ||
5322                         error "check_fhandle_syscalls $tdir.stripe/subdir fail"
5323         fi
5324 }
5325 run_test 102 "Test open by handle of unlinked file"
5326
5327 # Compare file size between first & second mount, ensuring the client correctly
5328 # glimpses even with unused speculative locks - LU-11670
5329 test_103() {
5330         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
5331                 skip "Lockahead needs OST version at least 2.10.50"
5332
5333         local locktest=23
5334
5335         test_mkdir -p $DIR/$tdir
5336
5337         # Force file on to OST0
5338         $LFS setstripe -i 0 $DIR/$tdir
5339
5340         # Do not check multiple locks on glimpse
5341         # OBD_FAIL_OSC_NO_SIZE_DATA 0x415
5342         $LCTL set_param fail_loc=0x415
5343
5344         # Delay write commit by 2 seconds to guarantee glimpse wins race
5345         # The same fail_loc is used on client & server so it can work in the
5346         # single node sanity setup
5347         do_facet ost1 $LCTL set_param fail_loc=0x415 fail_val=2
5348
5349         echo "Incorrect size expected (no glimpse fix):"
5350         lockahead_test -d $DIR/$tdir -D $DIR2/$tdir -t $locktest -f $tfile
5351         rc=$?
5352         if [ $rc -eq 0 ]; then
5353                 echo "This doesn't work 100%, but this is just reproducing the bug, not testing the fix, so OK to not fail test."
5354         fi
5355
5356         # guarantee write commit timeout has expired
5357         sleep 2
5358
5359         # Clear fail_loc on client
5360         $LCTL set_param fail_loc=0
5361
5362         # Delay write commit by 2 seconds to guarantee glimpse wins race
5363         # OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
5364         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
5365
5366         # Write commit is still delayed by 2 seconds
5367         lockahead_test -d $DIR/$tdir -D $DIR2/$tdir -t $locktest -f $tfile
5368         rc=$?
5369         [ $rc -eq 0 ] || error "Lockahead test$locktest failed, $rc"
5370
5371         # guarantee write commit timeout has expired
5372         sleep 2
5373
5374         rm -f $DIR/$tfile || error "unable to delete $DIR/$tfile"
5375 }
5376 run_test 103 "Test size correctness with lockahead"
5377
5378 get_stat_xtimes()
5379 {
5380         local xtimes
5381
5382         xtimes=$(stat -c "%X %Y %Z" $DIR/$tfile)
5383
5384         echo ${xtimes[*]}
5385 }
5386
5387 get_mdt_xtimes()
5388 {
5389         local mdtdev=$1
5390         local output
5391         local xtimes
5392
5393         output=$(do_facet mds1 "$DEBUGFS -c -R 'stat ROOT/$tfile' $mdtdev")
5394         ((xtimes[0]=$(awk -F ':' /atime/'{ print $2 }' <<< "$output")))
5395         ((xtimes[1]=$(awk -F ':' /mtime/'{ print $2 }' <<< "$output")))
5396         ((xtimes[2]=$(awk -F ':' /ctime/'{ print $2 }' <<< "$output")))
5397
5398         echo ${xtimes[*]}
5399 }
5400
5401 check_mdt_xtimes()
5402 {
5403         local mdtdev=$1
5404         local xtimes=($(get_stat_xtimes))
5405         local mdt_xtimes=($(get_mdt_xtimes $mdtdev))
5406
5407         echo "STAT a|m|ctime ${xtimes[*]}"
5408         echo "MDT a|m|ctime ${mdt_xtimes[*]}"
5409         [[ ${xtimes[0]} == ${mdt_xtimes[0]} ]] ||
5410                 error "$DIR/$tfile atime (${xtimes[0]}:${mdt_xtimes[0]}) diff"
5411         [[ ${xtimes[1]} == ${mdt_xtimes[1]} ]] ||
5412                 error "$DIR/$tfile mtime (${xtimes[1]}:${mdt_xtimes[1]}) diff"
5413         [[ ${xtimes[2]} == ${mdt_xtimes[2]} ]] ||
5414                 error "$DIR/$tfile ctime (${xtimes[2]}:${mdt_xtimes[2]}) diff"
5415 }
5416
5417 test_104() {
5418         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip_env "ldiskfs only test"
5419         [ $MDS1_VERSION -lt $(version_code 2.12.4) ] &&
5420                 skip "Need MDS version at least 2.12.4"
5421
5422         local pid
5423         local mdtdev=$(mdsdevname ${SINGLEMDS//mds/})
5424         local atime_diff=$(do_facet $SINGLEMDS \
5425                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5426
5427         do_facet $SINGLEMDS \
5428                 lctl set_param -n mdd.*MDT0000*.atime_diff=0
5429
5430         stack_trap "do_facet $SINGLEMDS \
5431                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff" EXIT
5432
5433         dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
5434         check_mdt_xtimes $mdtdev
5435         sleep 2
5436
5437         dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
5438         check_mdt_xtimes $mdtdev
5439         sleep 2
5440         $MULTIOP $DIR2/$tfile Oz8192w8192_c &
5441         pid=$!
5442         sleep 2
5443         dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
5444         sleep 2
5445         kill -USR1 $pid && wait $pid || error "multiop failure"
5446         check_mdt_xtimes $mdtdev
5447
5448         local xtimes
5449         local mdt_xtimes
5450
5451         # Verify mtime/ctime is NOT upated on MDS when there is no modification
5452         # on the client side
5453         xtimes=($(get_stat_xtimes))
5454         $MULTIOP $DIR/$tfile O_c &
5455         pid=$!
5456         sleep 2
5457         kill -USR1 $pid && wait $pid || error "multiop failure"
5458         mdt_xtimes=($(get_mdt_xtimes $mdtdev))
5459         [[ ${xtimes[1]} == ${mdt_xtimes[1]} ]] ||
5460                 error "$DIR/$tfile mtime (${xtimes[1]}:${mdt_xtimes[1]}) diff"
5461         [[ ${xtimes[2]} == ${mdt_xtimes[2]} ]] ||
5462                 error "$DIR/$tfile ctime (${xtimes[2]}:${mdt_xtimes[2]}) diff"
5463         check_mdt_xtimes $mdtdev
5464
5465         sleep 2
5466         # Change ctime via chmod
5467         $MULTIOP $DIR/$tfile o_tc &
5468         pid=$!
5469         sleep 2
5470         kill -USR1 $pid && wait $pid || error "multiop failure"
5471         check_mdt_xtimes $mdtdev
5472 }
5473 run_test 104 "Verify that MDS stores atime/mtime/ctime during close"
5474
5475 test_105() {
5476         test_mkdir -p $DIR/$tdir
5477         echo test > $DIR/$tdir/$tfile
5478         $LCTL set_param fail_loc=0x416
5479         cancel_lru_locks osc & sleep 1
5480         fsize1=$(stat -c %s $DIR2/$tdir/$tfile)
5481         wait
5482         [[ $fsize1 = 5 ]] ||  error "Glimpse returned wrong file size $fsize1"
5483 }
5484 run_test 105 "Glimpse and lock cancel race"
5485
5486 test_106a() {
5487         [ "$mds1_FSTYPE" == "ldiskfs" ] && statx_supported ||
5488                 skip_env "Test only for ldiskfs and statx() supported"
5489
5490         local btime
5491         local mdt_btime
5492         local output
5493         local mdtdev=$(mdsdevname ${SINGLEMDS//mds/})
5494
5495         dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
5496         btime=$($STATX -c %W $DIR/$tfile)
5497         output=$(do_facet mds1 "$DEBUGFS -c -R 'stat ROOT/$tfile' $mdtdev")
5498         echo $output
5499         ((mdt_btime=$(awk -F ':' /crtime/'{ print $2 }' <<< "$output")))
5500         [[ $btime == $mdt_btime ]] ||
5501                 error "$DIR/$tfile btime ($btime:$mdt_btime) diff"
5502
5503 }
5504 run_test 106a "Verify the btime via statx()"
5505
5506 test_106b() {
5507         statx_supported || skip_env "statx() only test"
5508
5509         local rpcs_before
5510         local rpcs_after
5511
5512         $LFS setstripe -c 1 $DIR/$tfile || error "$DIR/$tfile setstripe failed"
5513         dd if=/dev/zero of=$DIR/$tfile bs=1k count=1 conv=notrunc
5514         cancel_lru_locks $OSC
5515         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5516         $STATX $DIR/$tfile
5517         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5518         [ $rpcs_after -eq $((rpcs_before + 1)) ] ||
5519                 error "$STATX should send 1 glimpse RPC to $OSC"
5520
5521         cancel_lru_locks $OSC
5522         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5523         # %n: FILENAME; %i: STATX_INO; %A STATX_MODE; %h STATX_NLINK;
5524         # %u: STATX_UID; %g: STATX_GID; %W STATX_BTIME; %X STATX_ATIME;
5525         # %Z: STATX_CTIME
5526         $STATX -c "%n %i %A %h %u %g %W %X %Z" $DIR/$tfile
5527         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5528         [ $rpcs_after -eq $rpcs_before ] ||
5529                 error "$STATX should not send glimpse RPCs to $OSC"
5530
5531         cancel_lru_locks $OSC
5532         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5533         $STATX --cached=always $DIR/$tfile
5534         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5535         [ $rpcs_after -eq $rpcs_before ] ||
5536                 error "$STATX should not send glimpse RPCs to $OSC"
5537
5538         cancel_lru_locks $OSC
5539         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5540         $STATX -c %Y $DIR/$tfile
5541         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5542         [ $rpcs_after -eq $((rpcs_before + 1)) ] ||
5543                 error "$STATX -c %Y should send 1 glimpse RPC to $OSC"
5544
5545         cancel_lru_locks $OSC
5546         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5547         $STATX -c %s $DIR/$tfile
5548         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5549         [ $rpcs_after -eq $((rpcs_before + 1)) ] ||
5550                 error "$STATX -c %s should send 1 glimpse RPC to $OSC"
5551
5552         cancel_lru_locks $OSC
5553         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5554         $STATX -c %b $DIR/$tfile
5555         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5556         [ $rpcs_after -eq $((rpcs_before + 1)) ] ||
5557                 error "$STATX -c %b should send 1 glimpse RPC to $OSC"
5558 }
5559 run_test 106b "Glimpse RPCs test for statx"
5560
5561 test_106c() {
5562         statx_supported || skip_env "statx() only test"
5563
5564         local mask
5565
5566         touch $DIR/$tfile
5567         # Mask supported in stx_attributes by Lustre is
5568         # STATX_ATTR_IMMUTABLE(0x10) | STATX_ATTR_APPEND(0x20) : (0x30).
5569         mask=$($STATX -c %p $DIR/$tfile)
5570         [[ $mask == "30" ]] ||
5571                 error "supported stx_attributes: got '$mask', expected '30'"
5572         chattr +i $DIR/$tfile || error "chattr +i $DIR/$tfile failed"
5573         mask=$($STATX -c %r $DIR/$tfile)
5574         [[ $mask == "10" ]] ||
5575                 error "got immutable flags '$mask', expected '10'"
5576         chattr -i $DIR/$tfile || error "chattr -i $DIR/$tfile failed"
5577         mask=$($STATX -c %r $DIR/$tfile)
5578         [[ $mask == "0" ]] || error "got flags '$mask', expected '0'"
5579         chattr +a $DIR/$tfile || error "chattr +a $DIR/$tfile failed"
5580         mask=$($STATX -c %r $DIR/$tfile)
5581         [[ $mask == "20" ]] || error "got flags '$mask', expected '20'"
5582         chattr -a $DIR/$tfile || error "chattr -a $DIR/$tfile failed"
5583         mask=$($STATX -c %r $DIR/$tfile)
5584         [[ $mask == "0" ]] || error "got flags '$mask', expected '0'"
5585         chattr +ia $DIR/$tfile || error "chattr +ia $DIR/$tfile failed"
5586         mask=$($STATX -c %r $DIR/$tfile)
5587         [[ $mask == "30" ]] || error "got flags '$mask', expected '30'"
5588         chattr -ia $DIR/$tfile || error "chattr -ia $DIR/$tfile failed"
5589         mask=$($STATX -c %r $DIR/$tfile)
5590         [[ $mask == "0" ]] || error "got flags '$mask', expected '0'"
5591 }
5592 run_test 106c "Verify statx attributes mask"
5593
5594 test_107a() { # LU-1031
5595         dd if=/dev/zero of=$DIR1/$tfile bs=1M count=10
5596         local gid1=14091995
5597         local gid2=16022000
5598
5599         $LFS getstripe $DIR1/$tfile
5600
5601         multiop_bg_pause $DIR1/$tfile OG${gid1}_g${gid1}c || return 1
5602         local MULTIPID1=$!
5603         multiop_bg_pause $DIR2/$tfile O_G${gid2}r10g${gid2}c || return 2
5604         local MULTIPID2=$!
5605         kill -USR1 $MULTIPID2
5606         sleep 2
5607         if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
5608                 error "First grouplock does not block second one"
5609         else
5610                 echo "First grouplock blocks second one"
5611         fi
5612         kill -USR1 $MULTIPID1
5613         wait $MULTIPID1
5614         wait $MULTIPID2
5615 }
5616 run_test 107a "Basic grouplock conflict"
5617
5618 test_107b() {
5619         dd if=/dev/zero of=$DIR1/$tfile bs=1M count=10
5620         local gid1=14091995
5621         local gid2=16022000
5622
5623         $LFS getstripe $DIR1/$tfile
5624
5625         multiop_bg_pause $DIR1/$tfile OG${gid1}_g${gid1}c || return 1
5626         local MULTIPID1=$!
5627         multiop $DIR2/$tfile Or10c &
5628         local MULTIPID2=$!
5629         sleep 2
5630
5631         if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
5632                 error "Grouplock does not block IO"
5633         else
5634                 echo "Grouplock blocks IO"
5635         fi
5636
5637         multiop $DIR2/$tfile OG${gid2}_g${gid2}c &
5638         local MULTIPID3=$!
5639         sleep 2
5640         if [[ $(ps h -o comm -p $MULTIPID3) == "" ]]; then
5641                 error "First grouplock does not block second one"
5642         else
5643                 echo "First grouplock blocks second one"
5644         fi
5645
5646         kill -USR1 $MULTIPID1
5647         sleep 2
5648
5649         if [[ $(ps h -o comm -p $MULTIPID3) == "" ]]; then
5650                 error "Second grouplock thread disappeared"
5651         fi
5652
5653         if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
5654                 error "Second grouplock does not block IO"
5655         else
5656                 echo "Second grouplock blocks IO"
5657         fi
5658
5659         kill -USR1 $MULTIPID3
5660         wait $MULTIPID1
5661         wait $MULTIPID2
5662         wait $MULTIPID3
5663 }
5664 run_test 107b "Grouplock is added to the head of waiting list"
5665
5666 test_108a() {
5667         local offset
5668
5669         $LFS setstripe -E 1M -c 1 -E -1 $DIR1/$tfile ||
5670                 error "Create $DIR1/$tfile failed"
5671
5672         dd if=/dev/zero of=$DIR1/$tfile bs=10000 count=1 ||
5673                 error "dd $DIR1/$tfile failed"
5674         offset=$(lseek_test -d 5000 $DIR2/$tfile)
5675         [[ $offset == 5000 ]] || error "offset $offset != 5000"
5676
5677         $TRUNCATE $DIR1/$tfile 2000
5678         offset=$(lseek_test -l 1000 $DIR2/$tfile)
5679         [[ $offset == 2000 ]] || error "offset $offset != 2000"
5680
5681         #define OBD_FAIL_OSC_DELAY_IO 0x414
5682         $LCTL set_param fail_val=4 fail_loc=0x80000414
5683         dd if=/dev/zero of=$DIR1/$tfile count=1 bs=8M conv=notrunc oflag=dsync &
5684         local pid=$!
5685         sleep 2
5686
5687         offset=$(lseek_test -l 8000 $DIR2/$tfile)
5688         wait $pid
5689         [[ $offset == 8388608 ]] || error "offset $offset != 8388608"
5690 }
5691 run_test 108a "lseek: parallel updates"
5692
5693 # LU-14110
5694 test_109() {
5695         local i
5696         local pid1 pid2
5697
5698         ! local_mode ||
5699                 skip "Clients need to be on different nodes than the servers"
5700
5701         umount_client $MOUNT
5702         umount_client $MOUNT2
5703
5704         echo "Starting race between client mount instances (50 iterations):"
5705         for i in {1..50}; do
5706                 log "Iteration $i"
5707
5708 #define OBD_FAIL_ONCE|OBD_FAIL_LLITE_RACE_MOUNT        0x80001417
5709                 $LCTL set_param -n fail_loc=0x80001417
5710
5711                 mount_client $MOUNT  & pid1=$!
5712                 mount_client $MOUNT2 & pid2=$!
5713                 wait $pid1 || error "Mount $MOUNT fails with $?"
5714                 wait $pid2 || error "Mount $MOUNT2 fails with $?"
5715
5716                 umount_client $MOUNT  & pid1=$!
5717                 umount_client $MOUNT2 & pid2=$!
5718                 wait $pid1 || error "Umount $MOUNT fails with $?"
5719                 wait $pid2 || error "Umount $MOUNT2 fails with $?"
5720
5721                 $LUSTRE_RMMOD || error "Fail to remove lustre modules"
5722                 load_modules
5723                 echo
5724         done
5725
5726         mount_client $MOUNT
5727         mount_client $MOUNT2
5728 }
5729
5730 run_test 109 "Race with several mount instances on 1 node"
5731
5732 test_110() {
5733         local before=$(date +%s)
5734         local evict
5735
5736         mkdir -p $DIR/$tdir
5737         touch $DIR/$tdir/f1
5738         touch $DIR/$tfile
5739
5740         #define OBD_FAIL_PTLRPC_RESEND_RACE      0x525
5741         do_facet mds1 lctl set_param fail_loc=0x525 fail_val=3
5742
5743         # disable last_xid logic by dropping link reply
5744         ln $DIR/$tdir/f1 $DIR/$tdir/f2 &
5745         sleep 1
5746
5747         #define OBD_FAIL_PTLRPC_ENQ_RESEND      0x534
5748         do_facet mds1 lctl set_param fail_loc=0x534
5749
5750         # RPC will race with its Resend and the Resend will sleep to let
5751         # the original lock to get granted & cancelled.
5752         #
5753         # AST_SENT is set artificially, so an explicit conflict is not needed
5754         #
5755         # The woken up Resend gets a new lock, but client does not wait for it
5756         stat $DIR/$tfile
5757         sleep $TIMEOUT
5758         do_facet mds1 lctl set_param fail_loc=0 fail_val=0
5759
5760         # Take a conflict to wait long enough to see the eviction
5761         touch $DIR2/$tfile
5762
5763         # let the client reconnect
5764         client_reconnect
5765         evict=$(do_facet client $LCTL get_param mdc.$FSNAME-MDT*.state |
5766           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
5767
5768         [ -z "$evict" ] || [[ $evict -le $before ]] ||
5769                 (do_facet client $LCTL get_param mdc.$FSNAME-MDT*.state;
5770                     error "eviction happened: $evict before:$before")
5771 }
5772 run_test 110 "do not grant another lock on resend"
5773
5774 test_111() {
5775         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
5776         [[ $(facet_active_host mds1) = $(facet_active_host mds2) ]] ||
5777                 skip "MDT0 and MDT1 should be on the same node"
5778
5779         mkdir $DIR1/$tdir
5780         $LFS mkdir -i 0 $DIR1/$tdir/mdt0dir
5781         $LFS mkdir -i 1 $DIR1/$tdir/mdt1dir
5782
5783         mkdir $DIR1/$tdir/mdt0dir/foodir
5784         touch $DIR1/$tdir/mdt0dir/foodir/{file1,file2}
5785
5786         $MULTIOP $DIR2/$tdir/mdt0dir/foodir/file2 Ow4096_c &
5787         MULTIOP_PID=$!
5788         ln $DIR1/$tdir/mdt0dir/foodir/file2 $DIR1/$tdir/mdt1dir/file2
5789
5790         #define OBD_FAIL_MDS_LINK_RENAME_RACE   0x18a
5791         do_facet mds1 $LCTL set_param fail_loc=0x8000018a
5792
5793         ln $DIR1/$tdir/mdt0dir/foodir/file2 $DIR1/$tdir/mdt1dir/file2x &
5794         sleep 1
5795
5796         rm $DIR2/$tdir/mdt1dir/file2
5797         sleep 1
5798
5799         mv $DIR2/$tdir/mdt0dir/foodir/file1 $DIR2/$tdir/mdt0dir/foodir/file2
5800         sleep 1
5801
5802         kill $MULTIOP_PID
5803         wait
5804         rm -r $DIR1/$tdir || error "Removing test dir failed"
5805 }
5806 run_test 111 "A racy rename/link an open file should not cause fs corruption"
5807
5808 test_112() {
5809         (( MDSCOUNT >= 2 )) ||
5810                 skip "We need at least 2 MDTs for this test"
5811
5812         (( MDS1_VERSION >= $(version_code 2.14.54) )) ||
5813                 skip "Need server version at least 2.14.54"
5814
5815         local rr
5816         local count
5817
5818         rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
5819         rr=${rr%%%}
5820         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$rr > /dev/null"
5821
5822         mkdir -p $DIR1/$tdir/s1/s2 || error "mkdir s2 failed"
5823         $LFS mkdir -i 0 $DIR1/$tdir/s1/s2/s3 || error "mkdir s3 failed"
5824         $LFS setdirstripe -D -i -1 --max-inherit-rr=0 $DIR1/$tdir/s1/s2/s3 ||
5825                 error "setdirstripe s3 failed"
5826         $LCTL set_param lmv.*.qos_threshold_rr=90
5827         mkdir $DIR2/$tdir/s1/s2/s3/d{1..64}
5828         count=$($LFS getstripe -m $DIR2/$tdir/s1/s2/s3/d* | grep ^0 | wc -l)
5829         (( count == 64 )) || error "only $count subdirs created on MDT0"
5830
5831         $LFS setdirstripe -D -i -1 --max-inherit-rr=3 $DIR1/$tdir/s1/s2/s3 ||
5832                 error "setdirstripe s3 failed"
5833         mkdir $DIR2/$tdir/s1/s2/s3/s{1..64}
5834         count=$($LFS getstripe -m $DIR2/$tdir/s1/s2/s3/s* | grep ^0 | wc -l)
5835         (( count == 64 / MDSCOUNT )) || error "$count subdirs created on MDT0"
5836 }
5837 run_test 112 "update max-inherit in default LMV"
5838
5839 log "cleanup: ======================================================"
5840
5841 # kill and wait in each test only guarentee script finish, but command in script
5842 # like 'rm' 'chmod' may still be running, wait for all commands to finish
5843 # otherwise umount below will fail
5844 [ "$(mount | grep $MOUNT2)" ] && wait_update $HOSTNAME "fuser -m $MOUNT2" "" ||
5845         true
5846
5847 complete $SECONDS
5848 rm -f $SAMPLE_FILE
5849 check_and_cleanup_lustre
5850 exit_status