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