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