Whamcloud - gitweb
LU-14789 tests: make sanity 133f and 133g working
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_1() {
257         test_mkdir $DIR/$tdir
258         test_mkdir $DIR/$tdir/d2
259         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
260         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
261         rmdir $DIR/$tdir/d2
262         rmdir $DIR/$tdir
263         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
264 }
265 run_test 1 "mkdir; remkdir; rmdir"
266
267 test_2() {
268         test_mkdir $DIR/$tdir
269         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
273 }
274 run_test 2 "mkdir; touch; rmdir; check file"
275
276 test_3() {
277         test_mkdir $DIR/$tdir
278         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
279         touch $DIR/$tdir/$tfile
280         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
281         rm -r $DIR/$tdir
282         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
283 }
284 run_test 3 "mkdir; touch; rmdir; check dir"
285
286 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
287 test_4() {
288         test_mkdir -i 1 $DIR/$tdir
289
290         touch $DIR/$tdir/$tfile ||
291                 error "Create file under remote directory failed"
292
293         rmdir $DIR/$tdir &&
294                 error "Expect error removing in-use dir $DIR/$tdir"
295
296         test -d $DIR/$tdir || error "Remote directory disappeared"
297
298         rm -rf $DIR/$tdir || error "remove remote dir error"
299 }
300 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
301
302 test_5() {
303         test_mkdir $DIR/$tdir
304         test_mkdir $DIR/$tdir/d2
305         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
306         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
307         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
308 }
309 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
310
311 test_6a() {
312         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
313         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
314         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
315                 error "$tfile does not have perm 0666 or UID $UID"
316         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
317         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
318                 error "$tfile should be 0666 and owned by UID $UID"
319 }
320 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
321
322 test_6c() {
323         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
324
325         touch $DIR/$tfile
326         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
327         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
328                 error "$tfile should be owned by UID $RUNAS_ID"
329         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
330         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by UID $RUNAS_ID"
332 }
333 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
334
335 test_6e() {
336         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
337
338         touch $DIR/$tfile
339         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
340         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
341                 error "$tfile should be owned by GID $UID"
342         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
343         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
344                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
345 }
346 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
347
348 test_6g() {
349         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
350
351         test_mkdir $DIR/$tdir
352         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
353         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
354         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
355         test_mkdir $DIR/$tdir/d/subdir
356         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
357                 error "$tdir/d/subdir should be GID $RUNAS_GID"
358         if [[ $MDSCOUNT -gt 1 ]]; then
359                 # check remote dir sgid inherite
360                 $LFS mkdir -i 0 $DIR/$tdir.local ||
361                         error "mkdir $tdir.local failed"
362                 chmod g+s $DIR/$tdir.local ||
363                         error "chmod $tdir.local failed"
364                 chgrp $RUNAS_GID $DIR/$tdir.local ||
365                         error "chgrp $tdir.local failed"
366                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
367                         error "mkdir $tdir.remote failed"
368                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
370                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
371                         error "$tdir.remote should be mode 02755"
372         fi
373 }
374 run_test 6g "verify new dir in sgid dir inherits group"
375
376 test_6h() { # bug 7331
377         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
378
379         touch $DIR/$tfile || error "touch failed"
380         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
381         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
382                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
383         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
384                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
385 }
386 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
387
388 test_7a() {
389         test_mkdir $DIR/$tdir
390         $MCREATE $DIR/$tdir/$tfile
391         chmod 0666 $DIR/$tdir/$tfile
392         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
393                 error "$tdir/$tfile should be mode 0666"
394 }
395 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
396
397 test_7b() {
398         if [ ! -d $DIR/$tdir ]; then
399                 test_mkdir $DIR/$tdir
400         fi
401         $MCREATE $DIR/$tdir/$tfile
402         echo -n foo > $DIR/$tdir/$tfile
403         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
404         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
405 }
406 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
407
408 test_8() {
409         test_mkdir $DIR/$tdir
410         touch $DIR/$tdir/$tfile
411         chmod 0666 $DIR/$tdir/$tfile
412         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
413                 error "$tfile mode not 0666"
414 }
415 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
416
417 test_9() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         test_mkdir $DIR/$tdir/d2/d3
421         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
422 }
423 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
424
425 test_10() {
426         test_mkdir $DIR/$tdir
427         test_mkdir $DIR/$tdir/d2
428         touch $DIR/$tdir/d2/$tfile
429         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
430                 error "$tdir/d2/$tfile not a file"
431 }
432 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
433
434 test_11() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         chmod 0666 $DIR/$tdir/d2
438         chmod 0705 $DIR/$tdir/d2
439         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
440                 error "$tdir/d2 mode not 0705"
441 }
442 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
443
444 test_12() {
445         test_mkdir $DIR/$tdir
446         touch $DIR/$tdir/$tfile
447         chmod 0666 $DIR/$tdir/$tfile
448         chmod 0654 $DIR/$tdir/$tfile
449         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
450                 error "$tdir/d2 mode not 0654"
451 }
452 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
453
454 test_13() {
455         test_mkdir $DIR/$tdir
456         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
457         >  $DIR/$tdir/$tfile
458         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
459                 error "$tdir/$tfile size not 0 after truncate"
460 }
461 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
462
463 test_14() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
470
471 test_15() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
475         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
476                 error "$tdir/${tfile_2} not a file after rename"
477         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
478 }
479 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
480
481 test_16() {
482         test_mkdir $DIR/$tdir
483         touch $DIR/$tdir/$tfile
484         rm -rf $DIR/$tdir/$tfile
485         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
486 }
487 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
488
489 test_17a() {
490         test_mkdir $DIR/$tdir
491         touch $DIR/$tdir/$tfile
492         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
493         ls -l $DIR/$tdir
494         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not a symlink"
496         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
497                 error "$tdir/l-exist not referencing a file"
498         rm -f $DIR/$tdir/l-exist
499         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
500 }
501 run_test 17a "symlinks: create, remove (real)"
502
503 test_17b() {
504         test_mkdir $DIR/$tdir
505         ln -s no-such-file $DIR/$tdir/l-dangle
506         ls -l $DIR/$tdir
507         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing no-such-file"
509         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
510                 error "$tdir/l-dangle not referencing non-existent file"
511         rm -f $DIR/$tdir/l-dangle
512         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
513 }
514 run_test 17b "symlinks: create, remove (dangling)"
515
516 test_17c() { # bug 3440 - don't save failed open RPC for replay
517         test_mkdir $DIR/$tdir
518         ln -s foo $DIR/$tdir/$tfile
519         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
520 }
521 run_test 17c "symlinks: open dangling (should return error)"
522
523 test_17d() {
524         test_mkdir $DIR/$tdir
525         ln -s foo $DIR/$tdir/$tfile
526         touch $DIR/$tdir/$tfile || error "creating to new symlink"
527 }
528 run_test 17d "symlinks: create dangling"
529
530 test_17e() {
531         test_mkdir $DIR/$tdir
532         local foo=$DIR/$tdir/$tfile
533         ln -s $foo $foo || error "create symlink failed"
534         ls -l $foo || error "ls -l failed"
535         ls $foo && error "ls not failed" || true
536 }
537 run_test 17e "symlinks: create recursive symlink (should return error)"
538
539 test_17f() {
540         test_mkdir $DIR/$tdir
541         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
545         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
546         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
547         ls -l  $DIR/$tdir
548 }
549 run_test 17f "symlinks: long and very long symlink name"
550
551 # str_repeat(S, N) generate a string that is string S repeated N times
552 str_repeat() {
553         local s=$1
554         local n=$2
555         local ret=''
556         while [ $((n -= 1)) -ge 0 ]; do
557                 ret=$ret$s
558         done
559         echo $ret
560 }
561
562 # Long symlinks and LU-2241
563 test_17g() {
564         test_mkdir $DIR/$tdir
565         local TESTS="59 60 61 4094 4095"
566
567         # Fix for inode size boundary in 2.1.4
568         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
569                 TESTS="4094 4095"
570
571         # Patch not applied to 2.2 or 2.3 branches
572         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
573         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
574                 TESTS="4094 4095"
575
576         for i in $TESTS; do
577                 local SYMNAME=$(str_repeat 'x' $i)
578                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
579                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
580         done
581 }
582 run_test 17g "symlinks: really long symlink name and inode boundaries"
583
584 test_17h() { #bug 17378
585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
586         remote_mds_nodsh && skip "remote MDS with nodsh"
587
588         local mdt_idx
589
590         test_mkdir $DIR/$tdir
591         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
592         $LFS setstripe -c -1 $DIR/$tdir
593         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
594         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
595         touch $DIR/$tdir/$tfile || true
596 }
597 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
598
599 test_17i() { #bug 20018
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local foo=$DIR/$tdir/$tfile
604         local mdt_idx
605
606         test_mkdir -c1 $DIR/$tdir
607         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
608         ln -s $foo $foo || error "create symlink failed"
609 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
610         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
611         ls -l $foo && error "error not detected"
612         return 0
613 }
614 run_test 17i "don't panic on short symlink (should return error)"
615
616 test_17k() { #bug 22301
617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
618         [[ -z "$(which rsync 2>/dev/null)" ]] &&
619                 skip "no rsync command"
620         rsync --help | grep -q xattr ||
621                 skip_env "$(rsync --version | head -n1) does not support xattrs"
622         test_mkdir $DIR/$tdir
623         test_mkdir $DIR/$tdir.new
624         touch $DIR/$tdir/$tfile
625         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
626         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
627                 error "rsync failed with xattrs enabled"
628 }
629 run_test 17k "symlinks: rsync with xattrs enabled"
630
631 test_17l() { # LU-279
632         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
633                 skip "no getfattr command"
634
635         test_mkdir $DIR/$tdir
636         touch $DIR/$tdir/$tfile
637         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
638         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
639                 # -h to not follow symlinks. -m '' to list all the xattrs.
640                 # grep to remove first line: '# file: $path'.
641                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
642                 do
643                         lgetxattr_size_check $path $xattr ||
644                                 error "lgetxattr_size_check $path $xattr failed"
645                 done
646         done
647 }
648 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
649
650 # LU-1540
651 test_17m() {
652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
653         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
654         remote_mds_nodsh && skip "remote MDS with nodsh"
655         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
656         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
657                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
658
659         local short_sym="0123456789"
660         local wdir=$DIR/$tdir
661         local i
662
663         test_mkdir $wdir
664         long_sym=$short_sym
665         # create a long symlink file
666         for ((i = 0; i < 4; ++i)); do
667                 long_sym=${long_sym}${long_sym}
668         done
669
670         echo "create 512 short and long symlink files under $wdir"
671         for ((i = 0; i < 256; ++i)); do
672                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
673                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
674         done
675
676         echo "erase them"
677         rm -f $wdir/*
678         sync
679         wait_delete_completed
680
681         echo "recreate the 512 symlink files with a shorter string"
682         for ((i = 0; i < 512; ++i)); do
683                 # rewrite the symlink file with a shorter string
684                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
685                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
686         done
687
688         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
689         local devname=$(mdsdevname $mds_index)
690
691         echo "stop and checking mds${mds_index}:"
692         # e2fsck should not return error
693         stop mds${mds_index}
694         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
695         rc=$?
696
697         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
698                 error "start mds${mds_index} failed"
699         df $MOUNT > /dev/null 2>&1
700         [ $rc -eq 0 ] ||
701                 error "e2fsck detected error for short/long symlink: rc=$rc"
702         rm -f $wdir/*
703 }
704 run_test 17m "run e2fsck against MDT which contains short/long symlink"
705
706 check_fs_consistency_17n() {
707         local mdt_index
708         local rc=0
709
710         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
711         # so it only check MDT1/MDT2 instead of all of MDTs.
712         for mdt_index in 1 2; do
713                 local devname=$(mdsdevname $mdt_index)
714                 # e2fsck should not return error
715                 stop mds${mdt_index}
716                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
717                         rc=$((rc + $?))
718
719                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
720                         error "mount mds$mdt_index failed"
721                 df $MOUNT > /dev/null 2>&1
722         done
723         return $rc
724 }
725
726 test_17n() {
727         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
729         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
730         remote_mds_nodsh && skip "remote MDS with nodsh"
731         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
732         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
733                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
734
735         local i
736
737         test_mkdir $DIR/$tdir
738         for ((i=0; i<10; i++)); do
739                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
740                         error "create remote dir error $i"
741                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
742                         error "create files under remote dir failed $i"
743         done
744
745         check_fs_consistency_17n ||
746                 error "e2fsck report error after create files under remote dir"
747
748         for ((i = 0; i < 10; i++)); do
749                 rm -rf $DIR/$tdir/remote_dir_${i} ||
750                         error "destroy remote dir error $i"
751         done
752
753         check_fs_consistency_17n ||
754                 error "e2fsck report error after unlink files under remote dir"
755
756         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
757                 skip "lustre < 2.4.50 does not support migrate mv"
758
759         for ((i = 0; i < 10; i++)); do
760                 mkdir -p $DIR/$tdir/remote_dir_${i}
761                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
762                         error "create files under remote dir failed $i"
763                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
764                         error "migrate remote dir error $i"
765         done
766         check_fs_consistency_17n || error "e2fsck report error after migration"
767
768         for ((i = 0; i < 10; i++)); do
769                 rm -rf $DIR/$tdir/remote_dir_${i} ||
770                         error "destroy remote dir error $i"
771         done
772
773         check_fs_consistency_17n || error "e2fsck report error after unlink"
774 }
775 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
776
777 test_17o() {
778         remote_mds_nodsh && skip "remote MDS with nodsh"
779         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
780                 skip "Need MDS version at least 2.3.64"
781
782         local wdir=$DIR/${tdir}o
783         local mdt_index
784         local rc=0
785
786         test_mkdir $wdir
787         touch $wdir/$tfile
788         mdt_index=$($LFS getstripe -m $wdir/$tfile)
789         mdt_index=$((mdt_index + 1))
790
791         cancel_lru_locks mdc
792         #fail mds will wait the failover finish then set
793         #following fail_loc to avoid interfer the recovery process.
794         fail mds${mdt_index}
795
796         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
797         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
798         ls -l $wdir/$tfile && rc=1
799         do_facet mds${mdt_index} lctl set_param fail_loc=0
800         [[ $rc -eq 0 ]] || error "stat file should fail"
801 }
802 run_test 17o "stat file with incompat LMA feature"
803
804 test_18() {
805         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
806         ls $DIR || error "Failed to ls $DIR: $?"
807 }
808 run_test 18 "touch .../f ; ls ... =============================="
809
810 test_19a() {
811         touch $DIR/$tfile
812         ls -l $DIR
813         rm $DIR/$tfile
814         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
815 }
816 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
817
818 test_19b() {
819         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
820 }
821 run_test 19b "ls -l .../f19 (should return error) =============="
822
823 test_19c() {
824         [ $RUNAS_ID -eq $UID ] &&
825                 skip_env "RUNAS_ID = UID = $UID -- skipping"
826
827         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
828 }
829 run_test 19c "$RUNAS touch .../f19 (should return error) =="
830
831 test_19d() {
832         cat $DIR/f19 && error || true
833 }
834 run_test 19d "cat .../f19 (should return error) =============="
835
836 test_20() {
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         touch $DIR/$tfile
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 20 "touch .../f ; ls -l ..."
846
847 test_21() {
848         test_mkdir $DIR/$tdir
849         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
850         ln -s dangle $DIR/$tdir/link
851         echo foo >> $DIR/$tdir/link
852         cat $DIR/$tdir/dangle
853         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
854         $CHECKSTAT -f -t file $DIR/$tdir/link ||
855                 error "$tdir/link not linked to a file"
856 }
857 run_test 21 "write to dangling link"
858
859 test_22() {
860         local wdir=$DIR/$tdir
861         test_mkdir $wdir
862         chown $RUNAS_ID:$RUNAS_GID $wdir
863         (cd $wdir || error "cd $wdir failed";
864                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
865                 $RUNAS tar xf -)
866         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
867         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
868         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
869                 error "checkstat -u failed"
870 }
871 run_test 22 "unpack tar archive as non-root user"
872
873 # was test_23
874 test_23a() {
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
879         openfile -f O_CREAT:O_EXCL $file &&
880                 error "$file recreate succeeded" || true
881 }
882 run_test 23a "O_CREAT|O_EXCL in subdir"
883
884 test_23b() { # bug 18988
885         test_mkdir $DIR/$tdir
886         local file=$DIR/$tdir/$tfile
887
888         rm -f $file
889         echo foo > $file || error "write filed"
890         echo bar >> $file || error "append filed"
891         $CHECKSTAT -s 8 $file || error "wrong size"
892         rm $file
893 }
894 run_test 23b "O_APPEND check"
895
896 # LU-9409, size with O_APPEND and tiny writes
897 test_23c() {
898         local file=$DIR/$tfile
899
900         # single dd
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
902         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
903         rm -f $file
904
905         # racing tiny writes
906         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
908         wait
909         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
910         rm -f $file
911
912         #racing tiny & normal writes
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
914         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
915         wait
916         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
917         rm -f $file
918
919         #racing tiny & normal writes 2, ugly numbers
920         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
922         wait
923         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
924         rm -f $file
925 }
926 run_test 23c "O_APPEND size checks for tiny writes"
927
928 # LU-11069 file offset is correct after appending writes
929 test_23d() {
930         local file=$DIR/$tfile
931         local offset
932
933         echo CentaurHauls > $file
934         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
935         if ((offset != 26)); then
936                 error "wrong offset, expected 26, got '$offset'"
937         fi
938 }
939 run_test 23d "file offset is correct after appending writes"
940
941 # rename sanity
942 test_24a() {
943         echo '-- same directory rename'
944         test_mkdir $DIR/$tdir
945         touch $DIR/$tdir/$tfile.1
946         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
947         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
948 }
949 run_test 24a "rename file to non-existent target"
950
951 test_24b() {
952         test_mkdir $DIR/$tdir
953         touch $DIR/$tdir/$tfile.{1,2}
954         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
955         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
956         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
957 }
958 run_test 24b "rename file to existing target"
959
960 test_24c() {
961         test_mkdir $DIR/$tdir
962         test_mkdir $DIR/$tdir/d$testnum.1
963         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24c "rename directory to non-existent target"
968
969 test_24d() {
970         test_mkdir -c1 $DIR/$tdir
971         test_mkdir -c1 $DIR/$tdir/d$testnum.1
972         test_mkdir -c1 $DIR/$tdir/d$testnum.2
973         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
974         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
975         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
976 }
977 run_test 24d "rename directory to existing target"
978
979 test_24e() {
980         echo '-- cross directory renames --'
981         test_mkdir $DIR/R5a
982         test_mkdir $DIR/R5b
983         touch $DIR/R5a/f
984         mv $DIR/R5a/f $DIR/R5b/g
985         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
986         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
987 }
988 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
989
990 test_24f() {
991         test_mkdir $DIR/R6a
992         test_mkdir $DIR/R6b
993         touch $DIR/R6a/f $DIR/R6b/g
994         mv $DIR/R6a/f $DIR/R6b/g
995         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
996         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
997 }
998 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
999
1000 test_24g() {
1001         test_mkdir $DIR/R7a
1002         test_mkdir $DIR/R7b
1003         test_mkdir $DIR/R7a/d
1004         mv $DIR/R7a/d $DIR/R7b/e
1005         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1006         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1007 }
1008 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1009
1010 test_24h() {
1011         test_mkdir -c1 $DIR/R8a
1012         test_mkdir -c1 $DIR/R8b
1013         test_mkdir -c1 $DIR/R8a/d
1014         test_mkdir -c1 $DIR/R8b/e
1015         mrename $DIR/R8a/d $DIR/R8b/e
1016         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1017         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1018 }
1019 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1020
1021 test_24i() {
1022         echo "-- rename error cases"
1023         test_mkdir $DIR/R9
1024         test_mkdir $DIR/R9/a
1025         touch $DIR/R9/f
1026         mrename $DIR/R9/f $DIR/R9/a
1027         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1028         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1029         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1030 }
1031 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1032
1033 test_24j() {
1034         test_mkdir $DIR/R10
1035         mrename $DIR/R10/f $DIR/R10/g
1036         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1037         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1038         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1039 }
1040 run_test 24j "source does not exist ============================"
1041
1042 test_24k() {
1043         test_mkdir $DIR/R11a
1044         test_mkdir $DIR/R11a/d
1045         touch $DIR/R11a/f
1046         mv $DIR/R11a/f $DIR/R11a/d
1047         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1048         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1049 }
1050 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1051
1052 # bug 2429 - rename foo foo foo creates invalid file
1053 test_24l() {
1054         f="$DIR/f24l"
1055         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1056 }
1057 run_test 24l "Renaming a file to itself ========================"
1058
1059 test_24m() {
1060         f="$DIR/f24m"
1061         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1062         # on ext3 this does not remove either the source or target files
1063         # though the "expected" operation would be to remove the source
1064         $CHECKSTAT -t file ${f} || error "${f} missing"
1065         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1066 }
1067 run_test 24m "Renaming a file to a hard link to itself ========="
1068
1069 test_24n() {
1070     f="$DIR/f24n"
1071     # this stats the old file after it was renamed, so it should fail
1072     touch ${f}
1073     $CHECKSTAT ${f} || error "${f} missing"
1074     mv ${f} ${f}.rename
1075     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1076     $CHECKSTAT -a ${f} || error "${f} exists"
1077 }
1078 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1079
1080 test_24o() {
1081         test_mkdir $DIR/$tdir
1082         rename_many -s random -v -n 10 $DIR/$tdir
1083 }
1084 run_test 24o "rename of files during htree split"
1085
1086 test_24p() {
1087         test_mkdir $DIR/R12a
1088         test_mkdir $DIR/R12b
1089         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1090         mrename $DIR/R12a $DIR/R12b
1091         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1092         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1093         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1094         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1095 }
1096 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1097
1098 cleanup_multiop_pause() {
1099         trap 0
1100         kill -USR1 $MULTIPID
1101 }
1102
1103 test_24q() {
1104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1105
1106         test_mkdir $DIR/R13a
1107         test_mkdir $DIR/R13b
1108         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1109         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1110         MULTIPID=$!
1111
1112         trap cleanup_multiop_pause EXIT
1113         mrename $DIR/R13a $DIR/R13b
1114         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1115         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1116         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1117         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1118         cleanup_multiop_pause
1119         wait $MULTIPID || error "multiop close failed"
1120 }
1121 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1122
1123 test_24r() { #bug 3789
1124         test_mkdir $DIR/R14a
1125         test_mkdir $DIR/R14a/b
1126         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1128         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1129 }
1130 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1131
1132 test_24s() {
1133         test_mkdir $DIR/R15a
1134         test_mkdir $DIR/R15a/b
1135         test_mkdir $DIR/R15a/b/c
1136         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1137         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1138         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1139 }
1140 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1141 test_24t() {
1142         test_mkdir $DIR/R16a
1143         test_mkdir $DIR/R16a/b
1144         test_mkdir $DIR/R16a/b/c
1145         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1147         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1148 }
1149 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1150
1151 test_24u() { # bug12192
1152         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1153         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1154 }
1155 run_test 24u "create stripe file"
1156
1157 simple_cleanup_common() {
1158         local rc=0
1159         trap 0
1160         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1161
1162         local start=$SECONDS
1163         rm -rf $DIR/$tdir
1164         rc=$?
1165         wait_delete_completed
1166         echo "cleanup time $((SECONDS - start))"
1167         return $rc
1168 }
1169
1170 max_pages_per_rpc() {
1171         local mdtname="$(printf "MDT%04x" ${1:-0})"
1172         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1173 }
1174
1175 test_24v() {
1176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1177
1178         local nrfiles=${COUNT:-100000}
1179         local fname="$DIR/$tdir/$tfile"
1180
1181         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1182         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1183
1184         test_mkdir "$(dirname $fname)"
1185         # assume MDT0000 has the fewest inodes
1186         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1187         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1188         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1189
1190         trap simple_cleanup_common EXIT
1191
1192         createmany -m "$fname" $nrfiles
1193
1194         cancel_lru_locks mdc
1195         lctl set_param mdc.*.stats clear
1196
1197         # was previously test_24D: LU-6101
1198         # readdir() returns correct number of entries after cursor reload
1199         local num_ls=$(ls $DIR/$tdir | wc -l)
1200         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1201         local num_all=$(ls -a $DIR/$tdir | wc -l)
1202         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1203                 [ $num_all -ne $((nrfiles + 2)) ]; then
1204                         error "Expected $nrfiles files, got $num_ls " \
1205                                 "($num_uniq unique $num_all .&..)"
1206         fi
1207         # LU-5 large readdir
1208         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1209         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1210         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1211         # take into account of overhead in lu_dirpage header and end mark in
1212         # each page, plus one in rpc_num calculation.
1213         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1214         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1215         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1216         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1217         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1218         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1219         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1220         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1221                 error "large readdir doesn't take effect: " \
1222                       "$mds_readpage should be about $rpc_max"
1223
1224         simple_cleanup_common
1225 }
1226 run_test 24v "list large directory (test hash collision, b=17560)"
1227
1228 test_24w() { # bug21506
1229         SZ1=234852
1230         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1231         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1232         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1233         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1234         [[ "$SZ1" -eq "$SZ2" ]] ||
1235                 error "Error reading at the end of the file $tfile"
1236 }
1237 run_test 24w "Reading a file larger than 4Gb"
1238
1239 test_24x() {
1240         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1242         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1243                 skip "Need MDS version at least 2.7.56"
1244
1245         local MDTIDX=1
1246         local remote_dir=$DIR/$tdir/remote_dir
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $MDTIDX $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $DIR/$tdir/src_dir
1253         touch $DIR/$tdir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename dir cross MDT failed!"
1259
1260         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1261                 error "rename file cross MDT failed!"
1262
1263         touch $DIR/$tdir/ln_file
1264         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1265                 error "ln file cross MDT failed"
1266
1267         rm -rf $DIR/$tdir || error "Can not delete directories"
1268 }
1269 run_test 24x "cross MDT rename/link"
1270
1271 test_24y() {
1272         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1274
1275         local remote_dir=$DIR/$tdir/remote_dir
1276         local mdtidx=1
1277
1278         test_mkdir $DIR/$tdir
1279         $LFS mkdir -i $mdtidx $remote_dir ||
1280                 error "create remote directory failed"
1281
1282         test_mkdir $remote_dir/src_dir
1283         touch $remote_dir/src_file
1284         test_mkdir $remote_dir/tgt_dir
1285         touch $remote_dir/tgt_file
1286
1287         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1288                 error "rename subdir in the same remote dir failed!"
1289
1290         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1291                 error "rename files in the same remote dir failed!"
1292
1293         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1294                 error "link files in the same remote dir failed!"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24y "rename/link on the same dir should succeed"
1299
1300 test_24z() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1303                 skip "Need MDS version at least 2.12.51"
1304
1305         local index
1306
1307         for index in 0 1; do
1308                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1309                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1310         done
1311
1312         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1313
1314         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1315         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1316
1317         local mdts=$(comma_list $(mdts_nodes))
1318
1319         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1320         stack_trap "do_nodes $mdts $LCTL \
1321                 set_param mdt.*.enable_remote_rename=1" EXIT
1322
1323         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1326         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1327 }
1328 run_test 24z "cross-MDT rename is done as cp"
1329
1330 test_24A() { # LU-3182
1331         local NFILES=5000
1332
1333         rm -rf $DIR/$tdir
1334         test_mkdir $DIR/$tdir
1335         trap simple_cleanup_common EXIT
1336         createmany -m $DIR/$tdir/$tfile $NFILES
1337         local t=$(ls $DIR/$tdir | wc -l)
1338         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1339         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1340         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1341            [ $v -ne $((NFILES + 2)) ] ; then
1342                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1343         fi
1344
1345         simple_cleanup_common || error "Can not delete directories"
1346 }
1347 run_test 24A "readdir() returns correct number of entries."
1348
1349 test_24B() { # LU-4805
1350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1351
1352         local count
1353
1354         test_mkdir $DIR/$tdir
1355         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1356                 error "create striped dir failed"
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 2 ] || error "Expected 2, got $count"
1360
1361         touch $DIR/$tdir/striped_dir/a
1362
1363         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1364         [ $count -eq 3 ] || error "Expected 3, got $count"
1365
1366         touch $DIR/$tdir/striped_dir/.f
1367
1368         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1369         [ $count -eq 4 ] || error "Expected 4, got $count"
1370
1371         rm -rf $DIR/$tdir || error "Can not delete directories"
1372 }
1373 run_test 24B "readdir for striped dir return correct number of entries"
1374
1375 test_24C() {
1376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1377
1378         mkdir $DIR/$tdir
1379         mkdir $DIR/$tdir/d0
1380         mkdir $DIR/$tdir/d1
1381
1382         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1383                 error "create striped dir failed"
1384
1385         cd $DIR/$tdir/d0/striped_dir
1386
1387         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1388         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1389         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1390
1391         [ "$d0_ino" = "$parent_ino" ] ||
1392                 error ".. wrong, expect $d0_ino, get $parent_ino"
1393
1394         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1395                 error "mv striped dir failed"
1396
1397         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1398
1399         [ "$d1_ino" = "$parent_ino" ] ||
1400                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1401 }
1402 run_test 24C "check .. in striped dir"
1403
1404 test_24E() {
1405         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1407
1408         mkdir -p $DIR/$tdir
1409         mkdir $DIR/$tdir/src_dir
1410         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1411                 error "create remote source failed"
1412
1413         touch $DIR/$tdir/src_dir/src_child/a
1414
1415         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1416                 error "create remote target dir failed"
1417
1418         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1419                 error "create remote target child failed"
1420
1421         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1422                 error "rename dir cross MDT failed!"
1423
1424         find $DIR/$tdir
1425
1426         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1427                 error "src_child still exists after rename"
1428
1429         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1430                 error "missing file(a) after rename"
1431
1432         rm -rf $DIR/$tdir || error "Can not delete directories"
1433 }
1434 run_test 24E "cross MDT rename/link"
1435
1436 test_24F () {
1437         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1438
1439         local repeats=1000
1440         [ "$SLOW" = "no" ] && repeats=100
1441
1442         mkdir -p $DIR/$tdir
1443
1444         echo "$repeats repeats"
1445         for ((i = 0; i < repeats; i++)); do
1446                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1447                 touch $DIR/$tdir/test/a || error "touch fails"
1448                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1449                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1450         done
1451
1452         true
1453 }
1454 run_test 24F "hash order vs readdir (LU-11330)"
1455
1456 test_24G () {
1457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1458
1459         local ino1
1460         local ino2
1461
1462         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1463         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1464         touch $DIR/$tdir-0/f1 || error "touch f1"
1465         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1466         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1467         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1468         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1469         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1470 }
1471 run_test 24G "migrate symlink in rename"
1472
1473 test_25a() {
1474         echo '== symlink sanity ============================================='
1475
1476         test_mkdir $DIR/d25
1477         ln -s d25 $DIR/s25
1478         touch $DIR/s25/foo ||
1479                 error "File creation in symlinked directory failed"
1480 }
1481 run_test 25a "create file in symlinked directory ==============="
1482
1483 test_25b() {
1484         [ ! -d $DIR/d25 ] && test_25a
1485         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1486 }
1487 run_test 25b "lookup file in symlinked directory ==============="
1488
1489 test_26a() {
1490         test_mkdir $DIR/d26
1491         test_mkdir $DIR/d26/d26-2
1492         ln -s d26/d26-2 $DIR/s26
1493         touch $DIR/s26/foo || error "File creation failed"
1494 }
1495 run_test 26a "multiple component symlink ======================="
1496
1497 test_26b() {
1498         test_mkdir -p $DIR/$tdir/d26-2
1499         ln -s $tdir/d26-2/foo $DIR/s26-2
1500         touch $DIR/s26-2 || error "File creation failed"
1501 }
1502 run_test 26b "multiple component symlink at end of lookup ======"
1503
1504 test_26c() {
1505         test_mkdir $DIR/d26.2
1506         touch $DIR/d26.2/foo
1507         ln -s d26.2 $DIR/s26.2-1
1508         ln -s s26.2-1 $DIR/s26.2-2
1509         ln -s s26.2-2 $DIR/s26.2-3
1510         chmod 0666 $DIR/s26.2-3/foo
1511 }
1512 run_test 26c "chain of symlinks"
1513
1514 # recursive symlinks (bug 439)
1515 test_26d() {
1516         ln -s d26-3/foo $DIR/d26-3
1517 }
1518 run_test 26d "create multiple component recursive symlink"
1519
1520 test_26e() {
1521         [ ! -h $DIR/d26-3 ] && test_26d
1522         rm $DIR/d26-3
1523 }
1524 run_test 26e "unlink multiple component recursive symlink"
1525
1526 # recursive symlinks (bug 7022)
1527 test_26f() {
1528         test_mkdir $DIR/$tdir
1529         test_mkdir $DIR/$tdir/$tfile
1530         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1531         test_mkdir -p lndir/bar1
1532         test_mkdir $DIR/$tdir/$tfile/$tfile
1533         cd $tfile                || error "cd $tfile failed"
1534         ln -s .. dotdot          || error "ln dotdot failed"
1535         ln -s dotdot/lndir lndir || error "ln lndir failed"
1536         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1537         output=`ls $tfile/$tfile/lndir/bar1`
1538         [ "$output" = bar1 ] && error "unexpected output"
1539         rm -r $tfile             || error "rm $tfile failed"
1540         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1541 }
1542 run_test 26f "rm -r of a directory which has recursive symlink"
1543
1544 test_27a() {
1545         test_mkdir $DIR/$tdir
1546         $LFS getstripe $DIR/$tdir
1547         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1548         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1549         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1550 }
1551 run_test 27a "one stripe file"
1552
1553 test_27b() {
1554         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1555
1556         test_mkdir $DIR/$tdir
1557         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1558         $LFS getstripe -c $DIR/$tdir/$tfile
1559         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1560                 error "two-stripe file doesn't have two stripes"
1561
1562         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1563 }
1564 run_test 27b "create and write to two stripe file"
1565
1566 # 27c family tests specific striping, setstripe -o
1567 test_27ca() {
1568         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1569         test_mkdir -p $DIR/$tdir
1570         local osts="1"
1571
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1573         $LFS getstripe -i $DIR/$tdir/$tfile
1574         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1575                 error "stripe not on specified OST"
1576
1577         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1578 }
1579 run_test 27ca "one stripe on specified OST"
1580
1581 test_27cb() {
1582         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1583         test_mkdir -p $DIR/$tdir
1584         local osts="1,0"
1585         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1586         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1587         echo "$getstripe"
1588
1589         # Strip getstripe output to a space separated list of OSTs
1590         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1591                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1592         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1593                 error "stripes not on specified OSTs"
1594
1595         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1596 }
1597 run_test 27cb "two stripes on specified OSTs"
1598
1599 test_27cc() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1602                 skip "server does not support overstriping"
1603
1604         test_mkdir -p $DIR/$tdir
1605         local osts="0,0"
1606         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1607         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1608         echo "$getstripe"
1609
1610         # Strip getstripe output to a space separated list of OSTs
1611         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1612                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1613         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1614                 error "stripes not on specified OSTs"
1615
1616         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1617 }
1618 run_test 27cc "two stripes on the same OST"
1619
1620 test_27cd() {
1621         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1622         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1623                 skip "server does not support overstriping"
1624         test_mkdir -p $DIR/$tdir
1625         local osts="0,1,1,0"
1626         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1627         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1628         echo "$getstripe"
1629
1630         # Strip getstripe output to a space separated list of OSTs
1631         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1632                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1633         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1634                 error "stripes not on specified OSTs"
1635
1636         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1637 }
1638 run_test 27cd "four stripes on two OSTs"
1639
1640 test_27ce() {
1641         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1642                 skip_env "too many osts, skipping"
1643         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1644                 skip "server does not support overstriping"
1645         # We do one more stripe than we have OSTs
1646         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1647                 skip_env "ea_inode feature disabled"
1648
1649         test_mkdir -p $DIR/$tdir
1650         local osts=""
1651         for i in $(seq 0 $OSTCOUNT);
1652         do
1653                 osts=$osts"0"
1654                 if [ $i -ne $OSTCOUNT ]; then
1655                         osts=$osts","
1656                 fi
1657         done
1658         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1659         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1660         echo "$getstripe"
1661
1662         # Strip getstripe output to a space separated list of OSTs
1663         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1664                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1665         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1666                 error "stripes not on specified OSTs"
1667
1668         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1669 }
1670 run_test 27ce "more stripes than OSTs with -o"
1671
1672 test_27cf() {
1673         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1674         local pid=0
1675
1676         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1677         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1678         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1679         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1680                 error "failed to set $osp_proc=0"
1681
1682         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1683         pid=$!
1684         sleep 1
1685         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1686         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1687                 error "failed to set $osp_proc=1"
1688         wait $pid
1689         [[ $pid -ne 0 ]] ||
1690                 error "should return error due to $osp_proc=0"
1691 }
1692 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1693
1694 test_27d() {
1695         test_mkdir $DIR/$tdir
1696         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1697                 error "setstripe failed"
1698         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1699         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1700 }
1701 run_test 27d "create file with default settings"
1702
1703 test_27e() {
1704         # LU-5839 adds check for existed layout before setting it
1705         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1706                 skip "Need MDS version at least 2.7.56"
1707
1708         test_mkdir $DIR/$tdir
1709         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1710         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1711         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1712 }
1713 run_test 27e "setstripe existing file (should return error)"
1714
1715 test_27f() {
1716         test_mkdir $DIR/$tdir
1717         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1718                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1719         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1720                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1721         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1722         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1723 }
1724 run_test 27f "setstripe with bad stripe size (should return error)"
1725
1726 test_27g() {
1727         test_mkdir $DIR/$tdir
1728         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1729         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1730                 error "$DIR/$tdir/$tfile has object"
1731 }
1732 run_test 27g "$LFS getstripe with no objects"
1733
1734 test_27ga() {
1735         test_mkdir $DIR/$tdir
1736         touch $DIR/$tdir/$tfile || error "touch failed"
1737         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1738         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1739         local rc=$?
1740         (( rc == 2 )) || error "getstripe did not return ENOENT"
1741 }
1742 run_test 27ga "$LFS getstripe with missing file (should return error)"
1743
1744 test_27i() {
1745         test_mkdir $DIR/$tdir
1746         touch $DIR/$tdir/$tfile || error "touch failed"
1747         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1748                 error "missing objects"
1749 }
1750 run_test 27i "$LFS getstripe with some objects"
1751
1752 test_27j() {
1753         test_mkdir $DIR/$tdir
1754         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1755                 error "setstripe failed" || true
1756 }
1757 run_test 27j "setstripe with bad stripe offset (should return error)"
1758
1759 test_27k() { # bug 2844
1760         test_mkdir $DIR/$tdir
1761         local file=$DIR/$tdir/$tfile
1762         local ll_max_blksize=$((4 * 1024 * 1024))
1763         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1764         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1765         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1766         dd if=/dev/zero of=$file bs=4k count=1
1767         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1768         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1769 }
1770 run_test 27k "limit i_blksize for broken user apps"
1771
1772 test_27l() {
1773         mcreate $DIR/$tfile || error "creating file"
1774         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1775                 error "setstripe should have failed" || true
1776 }
1777 run_test 27l "check setstripe permissions (should return error)"
1778
1779 test_27m() {
1780         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1781
1782         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1783                 skip_env "multiple clients -- skipping"
1784
1785         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1786                    head -n1)
1787         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1788                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1789         fi
1790         trap simple_cleanup_common EXIT
1791         test_mkdir $DIR/$tdir
1792         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1793         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1794                 error "dd should fill OST0"
1795         i=2
1796         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1797                 i=$((i + 1))
1798                 [ $i -gt 256 ] && break
1799         done
1800         i=$((i + 1))
1801         touch $DIR/$tdir/$tfile.$i
1802         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1803             awk '{print $1}'| grep -w "0") ] &&
1804                 error "OST0 was full but new created file still use it"
1805         i=$((i + 1))
1806         touch $DIR/$tdir/$tfile.$i
1807         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1808             awk '{print $1}'| grep -w "0") ] &&
1809                 error "OST0 was full but new created file still use it"
1810         simple_cleanup_common
1811 }
1812 run_test 27m "create file while OST0 was full"
1813
1814 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1815 # if the OST isn't full anymore.
1816 reset_enospc() {
1817         local ostidx=${1:-""}
1818         local delay
1819         local ready
1820         local get_prealloc
1821
1822         local list=$(comma_list $(osts_nodes))
1823         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1824
1825         do_nodes $list lctl set_param fail_loc=0
1826         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1827         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1828                 awk '{print $1 * 2;exit;}')
1829         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1830                         grep -v \"^0$\""
1831         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1832 }
1833
1834 __exhaust_precreations() {
1835         local OSTIDX=$1
1836         local FAILLOC=$2
1837         local FAILIDX=${3:-$OSTIDX}
1838         local ofacet=ost$((OSTIDX + 1))
1839
1840         mkdir_on_mdt0 $DIR/$tdir
1841         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1842         local mfacet=mds$((mdtidx + 1))
1843         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1844
1845         local OST=$(ostname_from_index $OSTIDX)
1846
1847         # on the mdt's osc
1848         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1849         local last_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_last_id)
1851         local next_id=$(do_facet $mfacet lctl get_param -n \
1852                         osp.$mdtosc_proc1.prealloc_next_id)
1853
1854         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1855         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1856
1857         test_mkdir -p $DIR/$tdir/${OST}
1858         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1859 #define OBD_FAIL_OST_ENOSPC              0x215
1860         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1861         echo "Creating to objid $last_id on ost $OST..."
1862         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1863         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1864         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1865 }
1866
1867 exhaust_precreations() {
1868         __exhaust_precreations $1 $2 $3
1869         sleep_maxage
1870 }
1871
1872 exhaust_all_precreations() {
1873         local i
1874         for (( i=0; i < OSTCOUNT; i++ )) ; do
1875                 __exhaust_precreations $i $1 -1
1876         done
1877         sleep_maxage
1878 }
1879
1880 test_27n() {
1881         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1883         remote_mds_nodsh && skip "remote MDS with nodsh"
1884         remote_ost_nodsh && skip "remote OST with nodsh"
1885
1886         reset_enospc
1887         rm -f $DIR/$tdir/$tfile
1888         exhaust_precreations 0 0x80000215
1889         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1890         touch $DIR/$tdir/$tfile || error "touch failed"
1891         $LFS getstripe $DIR/$tdir/$tfile
1892         reset_enospc
1893 }
1894 run_test 27n "create file with some full OSTs"
1895
1896 test_27o() {
1897         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1899         remote_mds_nodsh && skip "remote MDS with nodsh"
1900         remote_ost_nodsh && skip "remote OST with nodsh"
1901
1902         reset_enospc
1903         rm -f $DIR/$tdir/$tfile
1904         exhaust_all_precreations 0x215
1905
1906         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1907
1908         reset_enospc
1909         rm -rf $DIR/$tdir/*
1910 }
1911 run_test 27o "create file with all full OSTs (should error)"
1912
1913 function create_and_checktime() {
1914         local fname=$1
1915         local loops=$2
1916         local i
1917
1918         for ((i=0; i < $loops; i++)); do
1919                 local start=$SECONDS
1920                 multiop $fname-$i Oc
1921                 ((SECONDS-start < TIMEOUT)) ||
1922                         error "creation took " $((SECONDS-$start)) && return 1
1923         done
1924 }
1925
1926 test_27oo() {
1927         local mdts=$(comma_list $(mdts_nodes))
1928
1929         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1930                 skip "Need MDS version at least 2.13.57"
1931
1932         local f0=$DIR/${tfile}-0
1933         local f1=$DIR/${tfile}-1
1934
1935         wait_delete_completed
1936
1937         # refill precreated objects
1938         $LFS setstripe -i0 -c1 $f0
1939
1940         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1941         # force QoS allocation policy
1942         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1943         stack_trap "do_nodes $mdts $LCTL set_param \
1944                 lov.*.qos_threshold_rr=$saved" EXIT
1945         sleep_maxage
1946
1947         # one OST is unavailable, but still have few objects preallocated
1948         stop ost1
1949         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1950                 rm -rf $f1 $DIR/$tdir*" EXIT
1951
1952         for ((i=0; i < 7; i++)); do
1953                 mkdir $DIR/$tdir$i || error "can't create dir"
1954                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1955                         error "can't set striping"
1956         done
1957         for ((i=0; i < 7; i++)); do
1958                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1959         done
1960         wait
1961 }
1962 run_test 27oo "don't let few threads to reserve too many objects"
1963
1964 test_27p() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972         test_mkdir $DIR/$tdir
1973
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1976         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1977
1978         exhaust_precreations 0 0x80000215
1979         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1980         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1981         $LFS getstripe $DIR/$tdir/$tfile
1982
1983         reset_enospc
1984 }
1985 run_test 27p "append to a truncated file with some full OSTs"
1986
1987 test_27q() {
1988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1990         remote_mds_nodsh && skip "remote MDS with nodsh"
1991         remote_ost_nodsh && skip "remote OST with nodsh"
1992
1993         reset_enospc
1994         rm -f $DIR/$tdir/$tfile
1995
1996         mkdir_on_mdt0 $DIR/$tdir
1997         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1998         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1999                 error "truncate $DIR/$tdir/$tfile failed"
2000         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2001
2002         exhaust_all_precreations 0x215
2003
2004         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2005         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2006
2007         reset_enospc
2008 }
2009 run_test 27q "append to truncated file with all OSTs full (should error)"
2010
2011 test_27r() {
2012         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2014         remote_mds_nodsh && skip "remote MDS with nodsh"
2015         remote_ost_nodsh && skip "remote OST with nodsh"
2016
2017         reset_enospc
2018         rm -f $DIR/$tdir/$tfile
2019         exhaust_precreations 0 0x80000215
2020
2021         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2022
2023         reset_enospc
2024 }
2025 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2026
2027 test_27s() { # bug 10725
2028         test_mkdir $DIR/$tdir
2029         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2030         local stripe_count=0
2031         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2032         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2033                 error "stripe width >= 2^32 succeeded" || true
2034
2035 }
2036 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2037
2038 test_27t() { # bug 10864
2039         WDIR=$(pwd)
2040         WLFS=$(which lfs)
2041         cd $DIR
2042         touch $tfile
2043         $WLFS getstripe $tfile
2044         cd $WDIR
2045 }
2046 run_test 27t "check that utils parse path correctly"
2047
2048 test_27u() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         remote_mds_nodsh && skip "remote MDS with nodsh"
2051
2052         local index
2053         local list=$(comma_list $(mdts_nodes))
2054
2055 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2056         do_nodes $list $LCTL set_param fail_loc=0x139
2057         test_mkdir -p $DIR/$tdir
2058         trap simple_cleanup_common EXIT
2059         createmany -o $DIR/$tdir/t- 1000
2060         do_nodes $list $LCTL set_param fail_loc=0
2061
2062         TLOG=$TMP/$tfile.getstripe
2063         $LFS getstripe $DIR/$tdir > $TLOG
2064         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2065         unlinkmany $DIR/$tdir/t- 1000
2066         trap 0
2067         [[ $OBJS -gt 0 ]] &&
2068                 error "$OBJS objects created on OST-0. See $TLOG" ||
2069                 rm -f $TLOG
2070 }
2071 run_test 27u "skip object creation on OSC w/o objects"
2072
2073 test_27v() { # bug 4900
2074         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2076         remote_mds_nodsh && skip "remote MDS with nodsh"
2077         remote_ost_nodsh && skip "remote OST with nodsh"
2078
2079         exhaust_all_precreations 0x215
2080         reset_enospc
2081
2082         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2083
2084         touch $DIR/$tdir/$tfile
2085         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2086         # all except ost1
2087         for (( i=1; i < OSTCOUNT; i++ )); do
2088                 do_facet ost$i lctl set_param fail_loc=0x705
2089         done
2090         local START=`date +%s`
2091         createmany -o $DIR/$tdir/$tfile 32
2092
2093         local FINISH=`date +%s`
2094         local TIMEOUT=`lctl get_param -n timeout`
2095         local PROCESS=$((FINISH - START))
2096         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2097                error "$FINISH - $START >= $TIMEOUT / 2"
2098         sleep $((TIMEOUT / 2 - PROCESS))
2099         reset_enospc
2100 }
2101 run_test 27v "skip object creation on slow OST"
2102
2103 test_27w() { # bug 10997
2104         test_mkdir $DIR/$tdir
2105         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2106         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2107                 error "stripe size $size != 65536" || true
2108         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2109                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2110 }
2111 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2112
2113 test_27wa() {
2114         [[ $OSTCOUNT -lt 2 ]] &&
2115                 skip_env "skipping multiple stripe count/offset test"
2116
2117         test_mkdir $DIR/$tdir
2118         for i in $(seq 1 $OSTCOUNT); do
2119                 offset=$((i - 1))
2120                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2121                         error "setstripe -c $i -i $offset failed"
2122                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2123                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2124                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2125                 [ $index -ne $offset ] &&
2126                         error "stripe offset $index != $offset" || true
2127         done
2128 }
2129 run_test 27wa "check $LFS setstripe -c -i options"
2130
2131 test_27x() {
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2135
2136         OFFSET=$(($OSTCOUNT - 1))
2137         OSTIDX=0
2138         local OST=$(ostname_from_index $OSTIDX)
2139
2140         test_mkdir $DIR/$tdir
2141         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2142         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2143         sleep_maxage
2144         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2145         for i in $(seq 0 $OFFSET); do
2146                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2147                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2148                 error "OST0 was degraded but new created file still use it"
2149         done
2150         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2151 }
2152 run_test 27x "create files while OST0 is degraded"
2153
2154 test_27y() {
2155         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2156         remote_mds_nodsh && skip "remote MDS with nodsh"
2157         remote_ost_nodsh && skip "remote OST with nodsh"
2158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2159
2160         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2161         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_last_id)
2163         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2164                 osp.$mdtosc.prealloc_next_id)
2165         local fcount=$((last_id - next_id))
2166         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2167         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2168
2169         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2170                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2171         local OST_DEACTIVE_IDX=-1
2172         local OSC
2173         local OSTIDX
2174         local OST
2175
2176         for OSC in $MDS_OSCS; do
2177                 OST=$(osc_to_ost $OSC)
2178                 OSTIDX=$(index_from_ostuuid $OST)
2179                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2180                         OST_DEACTIVE_IDX=$OSTIDX
2181                 fi
2182                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2183                         echo $OSC "is Deactivated:"
2184                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2185                 fi
2186         done
2187
2188         OSTIDX=$(index_from_ostuuid $OST)
2189         test_mkdir $DIR/$tdir
2190         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2191
2192         for OSC in $MDS_OSCS; do
2193                 OST=$(osc_to_ost $OSC)
2194                 OSTIDX=$(index_from_ostuuid $OST)
2195                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2196                         echo $OST "is degraded:"
2197                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2198                                                 obdfilter.$OST.degraded=1
2199                 fi
2200         done
2201
2202         sleep_maxage
2203         createmany -o $DIR/$tdir/$tfile $fcount
2204
2205         for OSC in $MDS_OSCS; do
2206                 OST=$(osc_to_ost $OSC)
2207                 OSTIDX=$(index_from_ostuuid $OST)
2208                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2209                         echo $OST "is recovered from degraded:"
2210                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2211                                                 obdfilter.$OST.degraded=0
2212                 else
2213                         do_facet $SINGLEMDS lctl --device %$OSC activate
2214                 fi
2215         done
2216
2217         # all osp devices get activated, hence -1 stripe count restored
2218         local stripe_count=0
2219
2220         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2221         # devices get activated.
2222         sleep_maxage
2223         $LFS setstripe -c -1 $DIR/$tfile
2224         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2225         rm -f $DIR/$tfile
2226         [ $stripe_count -ne $OSTCOUNT ] &&
2227                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2228         return 0
2229 }
2230 run_test 27y "create files while OST0 is degraded and the rest inactive"
2231
2232 check_seq_oid()
2233 {
2234         log "check file $1"
2235
2236         lmm_count=$($LFS getstripe -c $1)
2237         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2238         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2239
2240         local old_ifs="$IFS"
2241         IFS=$'[:]'
2242         fid=($($LFS path2fid $1))
2243         IFS="$old_ifs"
2244
2245         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2246         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2247
2248         # compare lmm_seq and lu_fid->f_seq
2249         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2250         # compare lmm_object_id and lu_fid->oid
2251         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2252
2253         # check the trusted.fid attribute of the OST objects of the file
2254         local have_obdidx=false
2255         local stripe_nr=0
2256         $LFS getstripe $1 | while read obdidx oid hex seq; do
2257                 # skip lines up to and including "obdidx"
2258                 [ -z "$obdidx" ] && break
2259                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2260                 $have_obdidx || continue
2261
2262                 local ost=$((obdidx + 1))
2263                 local dev=$(ostdevname $ost)
2264                 local oid_hex
2265
2266                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2267
2268                 seq=$(echo $seq | sed -e "s/^0x//g")
2269                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2270                         oid_hex=$(echo $oid)
2271                 else
2272                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2273                 fi
2274                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2275
2276                 local ff=""
2277                 #
2278                 # Don't unmount/remount the OSTs if we don't need to do that.
2279                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2280                 # update too, until that use mount/ll_decode_filter_fid/mount.
2281                 # Re-enable when debugfs will understand new filter_fid.
2282                 #
2283                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2284                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2285                                 $dev 2>/dev/null" | grep "parent=")
2286                 fi
2287                 if [ -z "$ff" ]; then
2288                         stop ost$ost
2289                         mount_fstype ost$ost
2290                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2291                                 $(facet_mntpt ost$ost)/$obj_file)
2292                         unmount_fstype ost$ost
2293                         start ost$ost $dev $OST_MOUNT_OPTS
2294                         clients_up
2295                 fi
2296
2297                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2298
2299                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2300
2301                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2302                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2303                 #
2304                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2305                 #       stripe_size=1048576 component_id=1 component_start=0 \
2306                 #       component_end=33554432
2307                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2308                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2309                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2310                 local ff_pstripe
2311                 if grep -q 'stripe=' <<<$ff; then
2312                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2313                 else
2314                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2315                         # into f_ver in this case.  See comment on ff_parent.
2316                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2317                 fi
2318
2319                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2320                 [ $ff_pseq = $lmm_seq ] ||
2321                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2322                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2323                 [ $ff_poid = $lmm_oid ] ||
2324                         error "FF parent OID $ff_poid != $lmm_oid"
2325                 (($ff_pstripe == $stripe_nr)) ||
2326                         error "FF stripe $ff_pstripe != $stripe_nr"
2327
2328                 stripe_nr=$((stripe_nr + 1))
2329                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2330                         continue
2331                 if grep -q 'stripe_count=' <<<$ff; then
2332                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2333                                             -e 's/ .*//' <<<$ff)
2334                         [ $lmm_count = $ff_scnt ] ||
2335                                 error "FF stripe count $lmm_count != $ff_scnt"
2336                 fi
2337         done
2338 }
2339
2340 test_27z() {
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342         remote_ost_nodsh && skip "remote OST with nodsh"
2343
2344         test_mkdir $DIR/$tdir
2345         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2346                 { error "setstripe -c -1 failed"; return 1; }
2347         # We need to send a write to every object to get parent FID info set.
2348         # This _should_ also work for setattr, but does not currently.
2349         # touch $DIR/$tdir/$tfile-1 ||
2350         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2351                 { error "dd $tfile-1 failed"; return 2; }
2352         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2353                 { error "setstripe -c -1 failed"; return 3; }
2354         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2355                 { error "dd $tfile-2 failed"; return 4; }
2356
2357         # make sure write RPCs have been sent to OSTs
2358         sync; sleep 5; sync
2359
2360         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2361         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2362 }
2363 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2364
2365 test_27A() { # b=19102
2366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2367
2368         save_layout_restore_at_exit $MOUNT
2369         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2370         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2371                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2372         local default_size=$($LFS getstripe -S $MOUNT)
2373         local default_offset=$($LFS getstripe -i $MOUNT)
2374         local dsize=$(do_facet $SINGLEMDS \
2375                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2376         [ $default_size -eq $dsize ] ||
2377                 error "stripe size $default_size != $dsize"
2378         [ $default_offset -eq -1 ] ||
2379                 error "stripe offset $default_offset != -1"
2380 }
2381 run_test 27A "check filesystem-wide default LOV EA values"
2382
2383 test_27B() { # LU-2523
2384         test_mkdir $DIR/$tdir
2385         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2386         touch $DIR/$tdir/f0
2387         # open f1 with O_LOV_DELAY_CREATE
2388         # rename f0 onto f1
2389         # call setstripe ioctl on open file descriptor for f1
2390         # close
2391         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2392                 $DIR/$tdir/f0
2393
2394         rm -f $DIR/$tdir/f1
2395         # open f1 with O_LOV_DELAY_CREATE
2396         # unlink f1
2397         # call setstripe ioctl on open file descriptor for f1
2398         # close
2399         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2400
2401         # Allow multiop to fail in imitation of NFS's busted semantics.
2402         true
2403 }
2404 run_test 27B "call setstripe on open unlinked file/rename victim"
2405
2406 # 27C family tests full striping and overstriping
2407 test_27Ca() { #LU-2871
2408         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2409
2410         declare -a ost_idx
2411         local index
2412         local found
2413         local i
2414         local j
2415
2416         test_mkdir $DIR/$tdir
2417         cd $DIR/$tdir
2418         for i in $(seq 0 $((OSTCOUNT - 1))); do
2419                 # set stripe across all OSTs starting from OST$i
2420                 $LFS setstripe -i $i -c -1 $tfile$i
2421                 # get striping information
2422                 ost_idx=($($LFS getstripe $tfile$i |
2423                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2424                 echo ${ost_idx[@]}
2425
2426                 # check the layout
2427                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2428                         error "${#ost_idx[@]} != $OSTCOUNT"
2429
2430                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2431                         found=0
2432                         for j in $(echo ${ost_idx[@]}); do
2433                                 if [ $index -eq $j ]; then
2434                                         found=1
2435                                         break
2436                                 fi
2437                         done
2438                         [ $found = 1 ] ||
2439                                 error "Can not find $index in ${ost_idx[@]}"
2440                 done
2441         done
2442 }
2443 run_test 27Ca "check full striping across all OSTs"
2444
2445 test_27Cb() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2449                 skip_env "too many osts, skipping"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT * 2))
2453         [ $setcount -lt 160 ] || large_xattr_enabled ||
2454                 skip_env "ea_inode feature disabled"
2455
2456         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2457                 error "setstripe failed"
2458
2459         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2460         [ $count -eq $setcount ] ||
2461                 error "stripe count $count, should be $setcount"
2462
2463         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2464                 error "overstriped should be set in pattern"
2465
2466         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2467                 error "dd failed"
2468 }
2469 run_test 27Cb "more stripes than OSTs with -C"
2470
2471 test_27Cc() {
2472         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2473                 skip "server does not support overstriping"
2474         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2475
2476         test_mkdir -p $DIR/$tdir
2477         local setcount=$(($OSTCOUNT - 1))
2478
2479         [ $setcount -lt 160 ] || large_xattr_enabled ||
2480                 skip_env "ea_inode feature disabled"
2481
2482         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2483                 error "setstripe failed"
2484
2485         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2486         [ $count -eq $setcount ] ||
2487                 error "stripe count $count, should be $setcount"
2488
2489         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2490                 error "overstriped should not be set in pattern"
2491
2492         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2493                 error "dd failed"
2494 }
2495 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2496
2497 test_27Cd() {
2498         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2499                 skip "server does not support overstriping"
2500         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2501         large_xattr_enabled || skip_env "ea_inode feature disabled"
2502
2503         test_mkdir -p $DIR/$tdir
2504         local setcount=$LOV_MAX_STRIPE_COUNT
2505
2506         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2507                 error "setstripe failed"
2508
2509         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2510         [ $count -eq $setcount ] ||
2511                 error "stripe count $count, should be $setcount"
2512
2513         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2514                 error "overstriped should be set in pattern"
2515
2516         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2517                 error "dd failed"
2518
2519         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2520 }
2521 run_test 27Cd "test maximum stripe count"
2522
2523 test_27Ce() {
2524         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2525                 skip "server does not support overstriping"
2526         test_mkdir -p $DIR/$tdir
2527
2528         pool_add $TESTNAME || error "Pool creation failed"
2529         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2530
2531         local setcount=8
2532
2533         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2534                 error "setstripe failed"
2535
2536         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2537         [ $count -eq $setcount ] ||
2538                 error "stripe count $count, should be $setcount"
2539
2540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2541                 error "overstriped should be set in pattern"
2542
2543         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2544                 error "dd failed"
2545
2546         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2547 }
2548 run_test 27Ce "test pool with overstriping"
2549
2550 test_27Cf() {
2551         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2552                 skip "server does not support overstriping"
2553         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2554                 skip_env "too many osts, skipping"
2555
2556         test_mkdir -p $DIR/$tdir
2557
2558         local setcount=$(($OSTCOUNT * 2))
2559         [ $setcount -lt 160 ] || large_xattr_enabled ||
2560                 skip_env "ea_inode feature disabled"
2561
2562         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2563                 error "setstripe failed"
2564
2565         echo 1 > $DIR/$tdir/$tfile
2566
2567         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2568         [ $count -eq $setcount ] ||
2569                 error "stripe count $count, should be $setcount"
2570
2571         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2572                 error "overstriped should be set in pattern"
2573
2574         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2575                 error "dd failed"
2576
2577         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2578 }
2579 run_test 27Cf "test default inheritance with overstriping"
2580
2581 test_27D() {
2582         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2583         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2584         remote_mds_nodsh && skip "remote MDS with nodsh"
2585
2586         local POOL=${POOL:-testpool}
2587         local first_ost=0
2588         local last_ost=$(($OSTCOUNT - 1))
2589         local ost_step=1
2590         local ost_list=$(seq $first_ost $ost_step $last_ost)
2591         local ost_range="$first_ost $last_ost $ost_step"
2592
2593         test_mkdir $DIR/$tdir
2594         pool_add $POOL || error "pool_add failed"
2595         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2596
2597         local skip27D
2598         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2599                 skip27D+="-s 29"
2600         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2601                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2602                         skip27D+=" -s 30,31"
2603         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2604           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2605                 skip27D+=" -s 32,33"
2606         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2607                 skip27D+=" -s 34"
2608         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2609                 error "llapi_layout_test failed"
2610
2611         destroy_test_pools || error "destroy test pools failed"
2612 }
2613 run_test 27D "validate llapi_layout API"
2614
2615 # Verify that default_easize is increased from its initial value after
2616 # accessing a widely striped file.
2617 test_27E() {
2618         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2619         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2620                 skip "client does not have LU-3338 fix"
2621
2622         # 72 bytes is the minimum space required to store striping
2623         # information for a file striped across one OST:
2624         # (sizeof(struct lov_user_md_v3) +
2625         #  sizeof(struct lov_user_ost_data_v1))
2626         local min_easize=72
2627         $LCTL set_param -n llite.*.default_easize $min_easize ||
2628                 error "lctl set_param failed"
2629         local easize=$($LCTL get_param -n llite.*.default_easize)
2630
2631         [ $easize -eq $min_easize ] ||
2632                 error "failed to set default_easize"
2633
2634         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2635                 error "setstripe failed"
2636         # In order to ensure stat() call actually talks to MDS we need to
2637         # do something drastic to this file to shake off all lock, e.g.
2638         # rename it (kills lookup lock forcing cache cleaning)
2639         mv $DIR/$tfile $DIR/${tfile}-1
2640         ls -l $DIR/${tfile}-1
2641         rm $DIR/${tfile}-1
2642
2643         easize=$($LCTL get_param -n llite.*.default_easize)
2644
2645         [ $easize -gt $min_easize ] ||
2646                 error "default_easize not updated"
2647 }
2648 run_test 27E "check that default extended attribute size properly increases"
2649
2650 test_27F() { # LU-5346/LU-7975
2651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2652         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2653         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2654                 skip "Need MDS version at least 2.8.51"
2655         remote_ost_nodsh && skip "remote OST with nodsh"
2656
2657         test_mkdir $DIR/$tdir
2658         rm -f $DIR/$tdir/f0
2659         $LFS setstripe -c 2 $DIR/$tdir
2660
2661         # stop all OSTs to reproduce situation for LU-7975 ticket
2662         for num in $(seq $OSTCOUNT); do
2663                 stop ost$num
2664         done
2665
2666         # open/create f0 with O_LOV_DELAY_CREATE
2667         # truncate f0 to a non-0 size
2668         # close
2669         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2670
2671         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2672         # open/write it again to force delayed layout creation
2673         cat /etc/hosts > $DIR/$tdir/f0 &
2674         catpid=$!
2675
2676         # restart OSTs
2677         for num in $(seq $OSTCOUNT); do
2678                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2679                         error "ost$num failed to start"
2680         done
2681
2682         wait $catpid || error "cat failed"
2683
2684         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2685         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2686                 error "wrong stripecount"
2687
2688 }
2689 run_test 27F "Client resend delayed layout creation with non-zero size"
2690
2691 test_27G() { #LU-10629
2692         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2693                 skip "Need MDS version at least 2.11.51"
2694         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2695         remote_mds_nodsh && skip "remote MDS with nodsh"
2696         local POOL=${POOL:-testpool}
2697         local ostrange="0 0 1"
2698
2699         test_mkdir $DIR/$tdir
2700         touch $DIR/$tdir/$tfile.nopool
2701         pool_add $POOL || error "pool_add failed"
2702         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2703         $LFS setstripe -p $POOL $DIR/$tdir
2704
2705         local pool=$($LFS getstripe -p $DIR/$tdir)
2706
2707         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2708         touch $DIR/$tdir/$tfile.default
2709         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2710         $LFS find $DIR/$tdir -type f --pool $POOL
2711         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2712         [[ "$found" == "2" ]] ||
2713                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2714
2715         $LFS setstripe -d $DIR/$tdir
2716
2717         pool=$($LFS getstripe -p -d $DIR/$tdir)
2718
2719         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2720 }
2721 run_test 27G "Clear OST pool from stripe"
2722
2723 test_27H() {
2724         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2725                 skip "Need MDS version newer than 2.11.54"
2726         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2727         test_mkdir $DIR/$tdir
2728         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2729         touch $DIR/$tdir/$tfile
2730         $LFS getstripe -c $DIR/$tdir/$tfile
2731         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2732                 error "two-stripe file doesn't have two stripes"
2733
2734         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2735         $LFS getstripe -y $DIR/$tdir/$tfile
2736         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2737              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2738                 error "expected l_ost_idx: [02]$ not matched"
2739
2740         # make sure ost list has been cleared
2741         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2742         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2743                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2744         touch $DIR/$tdir/f3
2745         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2746 }
2747 run_test 27H "Set specific OSTs stripe"
2748
2749 test_27I() {
2750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2751         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2752         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2753                 skip "Need MDS version newer than 2.12.52"
2754         local pool=$TESTNAME
2755         local ostrange="1 1 1"
2756
2757         save_layout_restore_at_exit $MOUNT
2758         $LFS setstripe -c 2 -i 0 $MOUNT
2759         pool_add $pool || error "pool_add failed"
2760         pool_add_targets $pool $ostrange ||
2761                 error "pool_add_targets failed"
2762         test_mkdir $DIR/$tdir
2763         $LFS setstripe -p $pool $DIR/$tdir
2764         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2765         $LFS getstripe $DIR/$tdir/$tfile
2766 }
2767 run_test 27I "check that root dir striping does not break parent dir one"
2768
2769 test_27J() {
2770         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2771                 skip "Need MDS version newer than 2.12.51"
2772
2773         test_mkdir $DIR/$tdir
2774         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2775         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2776
2777         # create foreign file (raw way)
2778         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2779                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2780
2781         ! $LFS setstripe --foreign --flags foo \
2782                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2783                         error "creating $tfile with '--flags foo' should fail"
2784
2785         ! $LFS setstripe --foreign --flags 0xffffffff \
2786                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2787                         error "creating $tfile w/ 0xffffffff flags should fail"
2788
2789         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2790                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2791
2792         # verify foreign file (raw way)
2793         parse_foreign_file -f $DIR/$tdir/$tfile |
2794                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2796         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_size: 73" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_type: 1" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2804         parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_flags: 0x0000DA08" ||
2806                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2807         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2808                 grep "lov_foreign_value: 0x" |
2809                 sed -e 's/lov_foreign_value: 0x//')
2810         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2811         [[ $lov = ${lov2// /} ]] ||
2812                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2813
2814         # create foreign file (lfs + API)
2815         $LFS setstripe --foreign=none --flags 0xda08 \
2816                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2817                 error "$DIR/$tdir/${tfile}2: create failed"
2818
2819         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2820                 grep "lfm_magic:.*0x0BD70BD0" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2822         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2824                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2825         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2827         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_flags:.*0x0000DA08" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2830         $LFS getstripe $DIR/$tdir/${tfile}2 |
2831                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2832                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2833
2834         # modify striping should fail
2835         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2836                 error "$DIR/$tdir/$tfile: setstripe should fail"
2837         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2838                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2839
2840         # R/W should fail
2841         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2842         cat $DIR/$tdir/${tfile}2 &&
2843                 error "$DIR/$tdir/${tfile}2: read should fail"
2844         cat /etc/passwd > $DIR/$tdir/$tfile &&
2845                 error "$DIR/$tdir/$tfile: write should fail"
2846         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2847                 error "$DIR/$tdir/${tfile}2: write should fail"
2848
2849         # chmod should work
2850         chmod 222 $DIR/$tdir/$tfile ||
2851                 error "$DIR/$tdir/$tfile: chmod failed"
2852         chmod 222 $DIR/$tdir/${tfile}2 ||
2853                 error "$DIR/$tdir/${tfile}2: chmod failed"
2854
2855         # chown should work
2856         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2857                 error "$DIR/$tdir/$tfile: chown failed"
2858         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2859                 error "$DIR/$tdir/${tfile}2: chown failed"
2860
2861         # rename should work
2862         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2863                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2864         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2865                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2866
2867         #remove foreign file
2868         rm $DIR/$tdir/${tfile}.new ||
2869                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2870         rm $DIR/$tdir/${tfile}2.new ||
2871                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2872 }
2873 run_test 27J "basic ops on file with foreign LOV"
2874
2875 test_27K() {
2876         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2877                 skip "Need MDS version newer than 2.12.49"
2878
2879         test_mkdir $DIR/$tdir
2880         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2881         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2882
2883         # create foreign dir (raw way)
2884         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2885                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2886
2887         ! $LFS setdirstripe --foreign --flags foo \
2888                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2889                         error "creating $tdir with '--flags foo' should fail"
2890
2891         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2892                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2893                         error "creating $tdir w/ 0xffffffff flags should fail"
2894
2895         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2896                 error "create_foreign_dir FAILED"
2897
2898         # verify foreign dir (raw way)
2899         parse_foreign_dir -d $DIR/$tdir/$tdir |
2900                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2901                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2902         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2903                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2904         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2906         parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_flags: 55813$" ||
2908                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2909         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2910                 grep "lmv_foreign_value: 0x" |
2911                 sed 's/lmv_foreign_value: 0x//')
2912         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2913                 sed 's/ //g')
2914         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2915
2916         # create foreign dir (lfs + API)
2917         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2918                 $DIR/$tdir/${tdir}2 ||
2919                 error "$DIR/$tdir/${tdir}2: create failed"
2920
2921         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2922                 grep "lfm_magic:.*0x0CD50CD0" ||
2923                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2924         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2925         # - sizeof(lfm_type) - sizeof(lfm_flags)
2926         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2927                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2928         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2930         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_flags:.*0x0000DA05" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2933         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2934                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2935                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2936
2937         # file create in dir should fail
2938         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2939         touch $DIR/$tdir/${tdir}2/$tfile &&
2940                 "$DIR/${tdir}2: file create should fail"
2941
2942         # chmod should work
2943         chmod 777 $DIR/$tdir/$tdir ||
2944                 error "$DIR/$tdir: chmod failed"
2945         chmod 777 $DIR/$tdir/${tdir}2 ||
2946                 error "$DIR/${tdir}2: chmod failed"
2947
2948         # chown should work
2949         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2950                 error "$DIR/$tdir: chown failed"
2951         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2952                 error "$DIR/${tdir}2: chown failed"
2953
2954         # rename should work
2955         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2956                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2957         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2958                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2959
2960         #remove foreign dir
2961         rmdir $DIR/$tdir/${tdir}.new ||
2962                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2963         rmdir $DIR/$tdir/${tdir}2.new ||
2964                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2965 }
2966 run_test 27K "basic ops on dir with foreign LMV"
2967
2968 test_27L() {
2969         remote_mds_nodsh && skip "remote MDS with nodsh"
2970
2971         local POOL=${POOL:-$TESTNAME}
2972
2973         pool_add $POOL || error "pool_add failed"
2974
2975         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2976                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2977                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2978 }
2979 run_test 27L "lfs pool_list gives correct pool name"
2980
2981 test_27M() {
2982         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2983                 skip "Need MDS version >= than 2.12.57"
2984         remote_mds_nodsh && skip "remote MDS with nodsh"
2985         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2986
2987         test_mkdir $DIR/$tdir
2988
2989         # Set default striping on directory
2990         $LFS setstripe -C 4 $DIR/$tdir
2991
2992         echo 1 > $DIR/$tdir/${tfile}.1
2993         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2994         local setcount=4
2995         [ $count -eq $setcount ] ||
2996                 error "(1) stripe count $count, should be $setcount"
2997
2998         # Capture existing append_stripe_count setting for restore
2999         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3000         local mdts=$(comma_list $(mdts_nodes))
3001         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3002
3003         local appendcount=$orig_count
3004         echo 1 >> $DIR/$tdir/${tfile}.2_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3006         [ $count -eq $appendcount ] ||
3007                 error "(2)stripe count $count, should be $appendcount for append"
3008
3009         # Disable O_APPEND striping, verify it works
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3011
3012         # Should now get the default striping, which is 4
3013         setcount=4
3014         echo 1 >> $DIR/$tdir/${tfile}.3_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3016         [ $count -eq $setcount ] ||
3017                 error "(3) stripe count $count, should be $setcount"
3018
3019         # Try changing the stripe count for append files
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3021
3022         # Append striping is now 2 (directory default is still 4)
3023         appendcount=2
3024         echo 1 >> $DIR/$tdir/${tfile}.4_append
3025         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3026         [ $count -eq $appendcount ] ||
3027                 error "(4) stripe count $count, should be $appendcount for append"
3028
3029         # Test append stripe count of -1
3030         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3031         appendcount=$OSTCOUNT
3032         echo 1 >> $DIR/$tdir/${tfile}.5
3033         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3034         [ $count -eq $appendcount ] ||
3035                 error "(5) stripe count $count, should be $appendcount for append"
3036
3037         # Set append striping back to default of 1
3038         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3039
3040         # Try a new default striping, PFL + DOM
3041         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3042
3043         # Create normal DOM file, DOM returns stripe count == 0
3044         setcount=0
3045         touch $DIR/$tdir/${tfile}.6
3046         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3047         [ $count -eq $setcount ] ||
3048                 error "(6) stripe count $count, should be $setcount"
3049
3050         # Show
3051         appendcount=1
3052         echo 1 >> $DIR/$tdir/${tfile}.7_append
3053         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3054         [ $count -eq $appendcount ] ||
3055                 error "(7) stripe count $count, should be $appendcount for append"
3056
3057         # Clean up DOM layout
3058         $LFS setstripe -d $DIR/$tdir
3059
3060         # Now test that append striping works when layout is from root
3061         $LFS setstripe -c 2 $MOUNT
3062         # Make a special directory for this
3063         mkdir $DIR/${tdir}/${tdir}.2
3064         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3065
3066         # Verify for normal file
3067         setcount=2
3068         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3069         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3070         [ $count -eq $setcount ] ||
3071                 error "(8) stripe count $count, should be $setcount"
3072
3073         appendcount=1
3074         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3075         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3076         [ $count -eq $appendcount ] ||
3077                 error "(9) stripe count $count, should be $appendcount for append"
3078
3079         # Now test O_APPEND striping with pools
3080         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3081         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3082
3083         # Create the pool
3084         pool_add $TESTNAME || error "pool creation failed"
3085         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3086
3087         echo 1 >> $DIR/$tdir/${tfile}.10_append
3088
3089         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3090         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3091
3092         # Check that count is still correct
3093         appendcount=1
3094         echo 1 >> $DIR/$tdir/${tfile}.11_append
3095         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3096         [ $count -eq $appendcount ] ||
3097                 error "(11) stripe count $count, should be $appendcount for append"
3098
3099         # Disable O_APPEND stripe count, verify pool works separately
3100         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3101
3102         echo 1 >> $DIR/$tdir/${tfile}.12_append
3103
3104         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3105         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3106
3107         # Remove pool setting, verify it's not applied
3108         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3109
3110         echo 1 >> $DIR/$tdir/${tfile}.13_append
3111
3112         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3113         [ "$pool" = "" ] || error "(13) pool found: $pool"
3114 }
3115 run_test 27M "test O_APPEND striping"
3116
3117 test_27N() {
3118         combined_mgs_mds && skip "needs separate MGS/MDT"
3119
3120         pool_add $TESTNAME || error "pool_add failed"
3121         do_facet mgs "$LCTL pool_list $FSNAME" |
3122                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3123                 error "lctl pool_list on MGS failed"
3124 }
3125 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3126
3127 clean_foreign_symlink() {
3128         trap 0
3129         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3130         for i in $DIR/$tdir/* ; do
3131                 $LFS unlink_foreign $i || true
3132         done
3133 }
3134
3135 test_27O() {
3136         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3137                 skip "Need MDS version newer than 2.12.51"
3138
3139         test_mkdir $DIR/$tdir
3140         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3141         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3142
3143         trap clean_foreign_symlink EXIT
3144
3145         # enable foreign_symlink behaviour
3146         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3147
3148         # foreign symlink LOV format is a partial path by default
3149
3150         # create foreign file (lfs + API)
3151         $LFS setstripe --foreign=symlink --flags 0xda05 \
3152                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3153                 error "$DIR/$tdir/${tfile}: create failed"
3154
3155         $LFS getstripe -v $DIR/$tdir/${tfile} |
3156                 grep "lfm_magic:.*0x0BD70BD0" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3158         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3160         $LFS getstripe -v $DIR/$tdir/${tfile} |
3161                 grep "lfm_flags:.*0x0000DA05" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3163         $LFS getstripe $DIR/$tdir/${tfile} |
3164                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3165                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3166
3167         # modify striping should fail
3168         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3169                 error "$DIR/$tdir/$tfile: setstripe should fail"
3170
3171         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3172         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3173         cat /etc/passwd > $DIR/$tdir/$tfile &&
3174                 error "$DIR/$tdir/$tfile: write should fail"
3175
3176         # rename should succeed
3177         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/$tfile: rename has failed"
3179
3180         #remove foreign_symlink file should fail
3181         rm $DIR/$tdir/${tfile}.new &&
3182                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3183
3184         #test fake symlink
3185         mkdir /tmp/${uuid1} ||
3186                 error "/tmp/${uuid1}: mkdir has failed"
3187         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3189         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3190         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3192         #read should succeed now
3193         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3194                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3195         #write should succeed now
3196         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3198         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3199                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3200         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3201                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3202
3203         #check that getstripe still works
3204         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3205                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3206
3207         # chmod should still succeed
3208         chmod 644 $DIR/$tdir/${tfile}.new ||
3209                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3210
3211         # chown should still succeed
3212         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3213                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3214
3215         # rename should still succeed
3216         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3217                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3218
3219         #remove foreign_symlink file should still fail
3220         rm $DIR/$tdir/${tfile} &&
3221                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3222
3223         #use special ioctl() to unlink foreign_symlink file
3224         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3225                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3226
3227 }
3228 run_test 27O "basic ops on foreign file of symlink type"
3229
3230 test_27P() {
3231         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3232                 skip "Need MDS version newer than 2.12.49"
3233
3234         test_mkdir $DIR/$tdir
3235         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3236         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3237
3238         trap clean_foreign_symlink EXIT
3239
3240         # enable foreign_symlink behaviour
3241         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3242
3243         # foreign symlink LMV format is a partial path by default
3244
3245         # create foreign dir (lfs + API)
3246         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3247                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3248                 error "$DIR/$tdir/${tdir}: create failed"
3249
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3251                 grep "lfm_magic:.*0x0CD50CD0" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3253         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3255         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3256                 grep "lfm_flags:.*0x0000DA05" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3258         $LFS getdirstripe $DIR/$tdir/${tdir} |
3259                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3260                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3261
3262         # file create in dir should fail
3263         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3264         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3265
3266         # rename should succeed
3267         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3268                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3269
3270         #remove foreign_symlink dir should fail
3271         rmdir $DIR/$tdir/${tdir}.new &&
3272                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3273
3274         #test fake symlink
3275         mkdir -p /tmp/${uuid1}/${uuid2} ||
3276                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3277         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3278                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3279         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3280         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3281                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3282         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3283                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3284
3285         #check that getstripe fails now that foreign_symlink enabled
3286         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3287                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3288
3289         # file create in dir should work now
3290         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3291                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3292         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3293                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3294         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3295                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3296
3297         # chmod should still succeed
3298         chmod 755 $DIR/$tdir/${tdir}.new ||
3299                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3300
3301         # chown should still succeed
3302         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3303                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3304
3305         # rename should still succeed
3306         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3307                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3308
3309         #remove foreign_symlink dir should still fail
3310         rmdir $DIR/$tdir/${tdir} &&
3311                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3312
3313         #use special ioctl() to unlink foreign_symlink file
3314         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3315                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3316
3317         #created file should still exist
3318         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3319                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3320         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3321                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3322 }
3323 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3324
3325 test_27Q() {
3326         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3327         stack_trap "rm -f $TMP/$tfile*"
3328
3329         test_mkdir $DIR/$tdir-1
3330         test_mkdir $DIR/$tdir-2
3331
3332         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3333         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3334
3335         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3336         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3337
3338         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3339         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3340
3341         # Create some bad symlinks and ensure that we don't loop
3342         # forever or something. These should return ELOOP (40) and
3343         # ENOENT (2) but I don't want to test for that because there's
3344         # always some weirdo architecture that needs to ruin
3345         # everything by defining these error numbers differently.
3346
3347         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3348         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3349
3350         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3351         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3352
3353         return 0
3354 }
3355 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3356
3357 # createtest also checks that device nodes are created and
3358 # then visible correctly (#2091)
3359 test_28() { # bug 2091
3360         test_mkdir $DIR/d28
3361         $CREATETEST $DIR/d28/ct || error "createtest failed"
3362 }
3363 run_test 28 "create/mknod/mkdir with bad file types ============"
3364
3365 test_29() {
3366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3367
3368         sync; sleep 1; sync # flush out any dirty pages from previous tests
3369         cancel_lru_locks
3370         test_mkdir $DIR/d29
3371         touch $DIR/d29/foo
3372         log 'first d29'
3373         ls -l $DIR/d29
3374
3375         declare -i LOCKCOUNTORIG=0
3376         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3377                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3378         done
3379         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3380
3381         declare -i LOCKUNUSEDCOUNTORIG=0
3382         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3383                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3384         done
3385
3386         log 'second d29'
3387         ls -l $DIR/d29
3388         log 'done'
3389
3390         declare -i LOCKCOUNTCURRENT=0
3391         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3392                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3393         done
3394
3395         declare -i LOCKUNUSEDCOUNTCURRENT=0
3396         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3397                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3398         done
3399
3400         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3401                 $LCTL set_param -n ldlm.dump_namespaces ""
3402                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3403                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3404                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3405                 return 2
3406         fi
3407         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3408                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3409                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3410                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3411                 return 3
3412         fi
3413 }
3414 run_test 29 "IT_GETATTR regression  ============================"
3415
3416 test_30a() { # was test_30
3417         cp $(which ls) $DIR || cp /bin/ls $DIR
3418         $DIR/ls / || error "Can't execute binary from lustre"
3419         rm $DIR/ls
3420 }
3421 run_test 30a "execute binary from Lustre (execve) =============="
3422
3423 test_30b() {
3424         cp `which ls` $DIR || cp /bin/ls $DIR
3425         chmod go+rx $DIR/ls
3426         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3427         rm $DIR/ls
3428 }
3429 run_test 30b "execute binary from Lustre as non-root ==========="
3430
3431 test_30c() { # b=22376
3432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3433
3434         cp $(which ls) $DIR || cp /bin/ls $DIR
3435         chmod a-rw $DIR/ls
3436         cancel_lru_locks mdc
3437         cancel_lru_locks osc
3438         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3439         rm -f $DIR/ls
3440 }
3441 run_test 30c "execute binary from Lustre without read perms ===="
3442
3443 test_30d() {
3444         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3445
3446         for i in {1..10}; do
3447                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3448                 local PID=$!
3449                 sleep 1
3450                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3451                 wait $PID || error "executing dd from Lustre failed"
3452                 rm -f $DIR/$tfile
3453         done
3454
3455         rm -f $DIR/dd
3456 }
3457 run_test 30d "execute binary from Lustre while clear locks"
3458
3459 test_31a() {
3460         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3461         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3462 }
3463 run_test 31a "open-unlink file =================================="
3464
3465 test_31b() {
3466         touch $DIR/f31 || error "touch $DIR/f31 failed"
3467         ln $DIR/f31 $DIR/f31b || error "ln failed"
3468         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3469         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3470 }
3471 run_test 31b "unlink file with multiple links while open ======="
3472
3473 test_31c() {
3474         touch $DIR/f31 || error "touch $DIR/f31 failed"
3475         ln $DIR/f31 $DIR/f31c || error "ln failed"
3476         multiop_bg_pause $DIR/f31 O_uc ||
3477                 error "multiop_bg_pause for $DIR/f31 failed"
3478         MULTIPID=$!
3479         $MULTIOP $DIR/f31c Ouc
3480         kill -USR1 $MULTIPID
3481         wait $MULTIPID
3482 }
3483 run_test 31c "open-unlink file with multiple links ============="
3484
3485 test_31d() {
3486         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3487         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3488 }
3489 run_test 31d "remove of open directory ========================="
3490
3491 test_31e() { # bug 2904
3492         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3493 }
3494 run_test 31e "remove of open non-empty directory ==============="
3495
3496 test_31f() { # bug 4554
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         set -vx
3500         test_mkdir $DIR/d31f
3501         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3502         cp /etc/hosts $DIR/d31f
3503         ls -l $DIR/d31f
3504         $LFS getstripe $DIR/d31f/hosts
3505         multiop_bg_pause $DIR/d31f D_c || return 1
3506         MULTIPID=$!
3507
3508         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3509         test_mkdir $DIR/d31f
3510         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3511         cp /etc/hosts $DIR/d31f
3512         ls -l $DIR/d31f
3513         $LFS getstripe $DIR/d31f/hosts
3514         multiop_bg_pause $DIR/d31f D_c || return 1
3515         MULTIPID2=$!
3516
3517         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3518         wait $MULTIPID || error "first opendir $MULTIPID failed"
3519
3520         sleep 6
3521
3522         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3523         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3524         set +vx
3525 }
3526 run_test 31f "remove of open directory with open-unlink file ==="
3527
3528 test_31g() {
3529         echo "-- cross directory link --"
3530         test_mkdir -c1 $DIR/${tdir}ga
3531         test_mkdir -c1 $DIR/${tdir}gb
3532         touch $DIR/${tdir}ga/f
3533         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3534         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3535         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3536         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3537         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3538 }
3539 run_test 31g "cross directory link==============="
3540
3541 test_31h() {
3542         echo "-- cross directory link --"
3543         test_mkdir -c1 $DIR/${tdir}
3544         test_mkdir -c1 $DIR/${tdir}/dir
3545         touch $DIR/${tdir}/f
3546         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3547         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3548         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3549         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3550         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3551 }
3552 run_test 31h "cross directory link under child==============="
3553
3554 test_31i() {
3555         echo "-- cross directory link --"
3556         test_mkdir -c1 $DIR/$tdir
3557         test_mkdir -c1 $DIR/$tdir/dir
3558         touch $DIR/$tdir/dir/f
3559         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3560         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3561         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3562         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3563         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3564 }
3565 run_test 31i "cross directory link under parent==============="
3566
3567 test_31j() {
3568         test_mkdir -c1 -p $DIR/$tdir
3569         test_mkdir -c1 -p $DIR/$tdir/dir1
3570         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3571         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3572         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3573         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3574         return 0
3575 }
3576 run_test 31j "link for directory==============="
3577
3578 test_31k() {
3579         test_mkdir -c1 -p $DIR/$tdir
3580         touch $DIR/$tdir/s
3581         touch $DIR/$tdir/exist
3582         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3583         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3584         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3585         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3586         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3587         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3588         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3589         return 0
3590 }
3591 run_test 31k "link to file: the same, non-existing, dir==============="
3592
3593 test_31m() {
3594         mkdir $DIR/d31m
3595         touch $DIR/d31m/s
3596         mkdir $DIR/d31m2
3597         touch $DIR/d31m2/exist
3598         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3599         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3600         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3601         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3602         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3603         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3604         return 0
3605 }
3606 run_test 31m "link to file: the same, non-existing, dir==============="
3607
3608 test_31n() {
3609         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3610         nlink=$(stat --format=%h $DIR/$tfile)
3611         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3612         local fd=$(free_fd)
3613         local cmd="exec $fd<$DIR/$tfile"
3614         eval $cmd
3615         cmd="exec $fd<&-"
3616         trap "eval $cmd" EXIT
3617         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3618         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3619         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3620         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3621         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3622         eval $cmd
3623 }
3624 run_test 31n "check link count of unlinked file"
3625
3626 link_one() {
3627         local tempfile=$(mktemp $1_XXXXXX)
3628         mlink $tempfile $1 2> /dev/null &&
3629                 echo "$BASHPID: link $tempfile to $1 succeeded"
3630         munlink $tempfile
3631 }
3632
3633 test_31o() { # LU-2901
3634         test_mkdir $DIR/$tdir
3635         for LOOP in $(seq 100); do
3636                 rm -f $DIR/$tdir/$tfile*
3637                 for THREAD in $(seq 8); do
3638                         link_one $DIR/$tdir/$tfile.$LOOP &
3639                 done
3640                 wait
3641                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3642                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3643                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3644                         break || true
3645         done
3646 }
3647 run_test 31o "duplicate hard links with same filename"
3648
3649 test_31p() {
3650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3651
3652         test_mkdir $DIR/$tdir
3653         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3654         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3655
3656         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3657                 error "open unlink test1 failed"
3658         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3659                 error "open unlink test2 failed"
3660
3661         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3662                 error "test1 still exists"
3663         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3664                 error "test2 still exists"
3665 }
3666 run_test 31p "remove of open striped directory"
3667
3668 test_31q() {
3669         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3670
3671         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3672         index=$($LFS getdirstripe -i $DIR/$tdir)
3673         [ $index -eq 3 ] || error "first stripe index $index != 3"
3674         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3675         [ $index -eq 1 ] || error "second stripe index $index != 1"
3676
3677         # when "-c <stripe_count>" is set, the number of MDTs specified after
3678         # "-i" should equal to the stripe count
3679         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3680 }
3681 run_test 31q "create striped directory on specific MDTs"
3682
3683 cleanup_test32_mount() {
3684         local rc=0
3685         trap 0
3686         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3687         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3688         losetup -d $loopdev || true
3689         rm -rf $DIR/$tdir
3690         return $rc
3691 }
3692
3693 test_32a() {
3694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3695
3696         echo "== more mountpoints and symlinks ================="
3697         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3698         trap cleanup_test32_mount EXIT
3699         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3700         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3701                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3702         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3703                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3704         cleanup_test32_mount
3705 }
3706 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3707
3708 test_32b() {
3709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3710
3711         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3712         trap cleanup_test32_mount EXIT
3713         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3714         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3715                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3716         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3717                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3718         cleanup_test32_mount
3719 }
3720 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3721
3722 test_32c() {
3723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3724
3725         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3726         trap cleanup_test32_mount EXIT
3727         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3728         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3729                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3730         test_mkdir -p $DIR/$tdir/d2/test_dir
3731         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3732                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3733         cleanup_test32_mount
3734 }
3735 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3736
3737 test_32d() {
3738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3739
3740         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3741         trap cleanup_test32_mount EXIT
3742         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3743         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3744                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3745         test_mkdir -p $DIR/$tdir/d2/test_dir
3746         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3747                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3748         cleanup_test32_mount
3749 }
3750 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3751
3752 test_32e() {
3753         rm -fr $DIR/$tdir
3754         test_mkdir -p $DIR/$tdir/tmp
3755         local tmp_dir=$DIR/$tdir/tmp
3756         ln -s $DIR/$tdir $tmp_dir/symlink11
3757         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3758         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3759         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3760 }
3761 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3762
3763 test_32f() {
3764         rm -fr $DIR/$tdir
3765         test_mkdir -p $DIR/$tdir/tmp
3766         local tmp_dir=$DIR/$tdir/tmp
3767         ln -s $DIR/$tdir $tmp_dir/symlink11
3768         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3769         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3770         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3771 }
3772 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3773
3774 test_32g() {
3775         local tmp_dir=$DIR/$tdir/tmp
3776         test_mkdir -p $tmp_dir
3777         test_mkdir $DIR/${tdir}2
3778         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3779         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3780         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3781         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3782         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3783         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3784 }
3785 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3786
3787 test_32h() {
3788         rm -fr $DIR/$tdir $DIR/${tdir}2
3789         tmp_dir=$DIR/$tdir/tmp
3790         test_mkdir -p $tmp_dir
3791         test_mkdir $DIR/${tdir}2
3792         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3793         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3794         ls $tmp_dir/symlink12 || error "listing symlink12"
3795         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3796 }
3797 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3798
3799 test_32i() {
3800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3801
3802         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3803         trap cleanup_test32_mount EXIT
3804         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3805         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3806                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3807         touch $DIR/$tdir/test_file
3808         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3809                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3810         cleanup_test32_mount
3811 }
3812 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3813
3814 test_32j() {
3815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3816
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         touch $DIR/$tdir/test_file
3823         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3824                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3825         cleanup_test32_mount
3826 }
3827 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3828
3829 test_32k() {
3830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3831
3832         rm -fr $DIR/$tdir
3833         trap cleanup_test32_mount EXIT
3834         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3835         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3836                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3837         test_mkdir -p $DIR/$tdir/d2
3838         touch $DIR/$tdir/d2/test_file || error "touch failed"
3839         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3840                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3841         cleanup_test32_mount
3842 }
3843 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3844
3845 test_32l() {
3846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3847
3848         rm -fr $DIR/$tdir
3849         trap cleanup_test32_mount EXIT
3850         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3851         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3852                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3853         test_mkdir -p $DIR/$tdir/d2
3854         touch $DIR/$tdir/d2/test_file || error "touch failed"
3855         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3856                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3857         cleanup_test32_mount
3858 }
3859 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3860
3861 test_32m() {
3862         rm -fr $DIR/d32m
3863         test_mkdir -p $DIR/d32m/tmp
3864         TMP_DIR=$DIR/d32m/tmp
3865         ln -s $DIR $TMP_DIR/symlink11
3866         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3867         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3868                 error "symlink11 not a link"
3869         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3870                 error "symlink01 not a link"
3871 }
3872 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3873
3874 test_32n() {
3875         rm -fr $DIR/d32n
3876         test_mkdir -p $DIR/d32n/tmp
3877         TMP_DIR=$DIR/d32n/tmp
3878         ln -s $DIR $TMP_DIR/symlink11
3879         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3880         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3881         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3882 }
3883 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3884
3885 test_32o() {
3886         touch $DIR/$tfile
3887         test_mkdir -p $DIR/d32o/tmp
3888         TMP_DIR=$DIR/d32o/tmp
3889         ln -s $DIR/$tfile $TMP_DIR/symlink12
3890         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3891         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3892                 error "symlink12 not a link"
3893         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3894         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3895                 error "$DIR/d32o/tmp/symlink12 not file type"
3896         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3897                 error "$DIR/d32o/symlink02 not file type"
3898 }
3899 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3900
3901 test_32p() {
3902         log 32p_1
3903         rm -fr $DIR/d32p
3904         log 32p_2
3905         rm -f $DIR/$tfile
3906         log 32p_3
3907         touch $DIR/$tfile
3908         log 32p_4
3909         test_mkdir -p $DIR/d32p/tmp
3910         log 32p_5
3911         TMP_DIR=$DIR/d32p/tmp
3912         log 32p_6
3913         ln -s $DIR/$tfile $TMP_DIR/symlink12
3914         log 32p_7
3915         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3916         log 32p_8
3917         cat $DIR/d32p/tmp/symlink12 ||
3918                 error "Can't open $DIR/d32p/tmp/symlink12"
3919         log 32p_9
3920         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3921         log 32p_10
3922 }
3923 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3924
3925 test_32q() {
3926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3927
3928         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3929         trap cleanup_test32_mount EXIT
3930         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3931         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3932         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3933                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3934         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3935         cleanup_test32_mount
3936 }
3937 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3938
3939 test_32r() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3943         trap cleanup_test32_mount EXIT
3944         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3945         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3946         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3947                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3948         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3949         cleanup_test32_mount
3950 }
3951 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3952
3953 test_33aa() {
3954         rm -f $DIR/$tfile
3955         touch $DIR/$tfile
3956         chmod 444 $DIR/$tfile
3957         chown $RUNAS_ID $DIR/$tfile
3958         log 33_1
3959         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3960         log 33_2
3961 }
3962 run_test 33aa "write file with mode 444 (should return error)"
3963
3964 test_33a() {
3965         rm -fr $DIR/$tdir
3966         test_mkdir $DIR/$tdir
3967         chown $RUNAS_ID $DIR/$tdir
3968         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3969                 error "$RUNAS create $tdir/$tfile failed"
3970         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3971                 error "open RDWR" || true
3972 }
3973 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3974
3975 test_33b() {
3976         rm -fr $DIR/$tdir
3977         test_mkdir $DIR/$tdir
3978         chown $RUNAS_ID $DIR/$tdir
3979         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3980 }
3981 run_test 33b "test open file with malformed flags (No panic)"
3982
3983 test_33c() {
3984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3985         remote_ost_nodsh && skip "remote OST with nodsh"
3986
3987         local ostnum
3988         local ostname
3989         local write_bytes
3990         local all_zeros
3991
3992         all_zeros=true
3993         test_mkdir $DIR/$tdir
3994         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3995
3996         sync
3997         for ostnum in $(seq $OSTCOUNT); do
3998                 # test-framework's OST numbering is one-based, while Lustre's
3999                 # is zero-based
4000                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4001                 # check if at least some write_bytes stats are counted
4002                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4003                               obdfilter.$ostname.stats |
4004                               awk '/^write_bytes/ {print $7}' )
4005                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4006                 if (( ${write_bytes:-0} > 0 )); then
4007                         all_zeros=false
4008                         break
4009                 fi
4010         done
4011
4012         $all_zeros || return 0
4013
4014         # Write four bytes
4015         echo foo > $DIR/$tdir/bar
4016         # Really write them
4017         sync
4018
4019         # Total up write_bytes after writing.  We'd better find non-zeros.
4020         for ostnum in $(seq $OSTCOUNT); do
4021                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4022                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4023                               obdfilter/$ostname/stats |
4024                               awk '/^write_bytes/ {print $7}' )
4025                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4026                 if (( ${write_bytes:-0} > 0 )); then
4027                         all_zeros=false
4028                         break
4029                 fi
4030         done
4031
4032         if $all_zeros; then
4033                 for ostnum in $(seq $OSTCOUNT); do
4034                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4035                         echo "Check write_bytes is in obdfilter.*.stats:"
4036                         do_facet ost$ostnum lctl get_param -n \
4037                                 obdfilter.$ostname.stats
4038                 done
4039                 error "OST not keeping write_bytes stats (b=22312)"
4040         fi
4041 }
4042 run_test 33c "test write_bytes stats"
4043
4044 test_33d() {
4045         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         local MDTIDX=1
4049         local remote_dir=$DIR/$tdir/remote_dir
4050
4051         test_mkdir $DIR/$tdir
4052         $LFS mkdir -i $MDTIDX $remote_dir ||
4053                 error "create remote directory failed"
4054
4055         touch $remote_dir/$tfile
4056         chmod 444 $remote_dir/$tfile
4057         chown $RUNAS_ID $remote_dir/$tfile
4058
4059         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4060
4061         chown $RUNAS_ID $remote_dir
4062         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4063                                         error "create" || true
4064         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4065                                     error "open RDWR" || true
4066         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4067 }
4068 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4069
4070 test_33e() {
4071         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4072
4073         mkdir $DIR/$tdir
4074
4075         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4076         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4077         mkdir $DIR/$tdir/local_dir
4078
4079         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4080         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4081         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4082
4083         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4084                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4085
4086         rmdir $DIR/$tdir/* || error "rmdir failed"
4087
4088         umask 777
4089         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4090         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4091         mkdir $DIR/$tdir/local_dir
4092
4093         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4094         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4095         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4096
4097         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4098                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4099
4100         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4101
4102         umask 000
4103         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4104         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4105         mkdir $DIR/$tdir/local_dir
4106
4107         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4108         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4109         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4110
4111         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4112                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4113 }
4114 run_test 33e "mkdir and striped directory should have same mode"
4115
4116 cleanup_33f() {
4117         trap 0
4118         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4119 }
4120
4121 test_33f() {
4122         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4123         remote_mds_nodsh && skip "remote MDS with nodsh"
4124
4125         mkdir $DIR/$tdir
4126         chmod go+rwx $DIR/$tdir
4127         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4128         trap cleanup_33f EXIT
4129
4130         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4131                 error "cannot create striped directory"
4132
4133         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4134                 error "cannot create files in striped directory"
4135
4136         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4137                 error "cannot remove files in striped directory"
4138
4139         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4140                 error "cannot remove striped directory"
4141
4142         cleanup_33f
4143 }
4144 run_test 33f "nonroot user can create, access, and remove a striped directory"
4145
4146 test_33g() {
4147         mkdir -p $DIR/$tdir/dir2
4148
4149         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4150         echo $err
4151         [[ $err =~ "exists" ]] || error "Not exists error"
4152 }
4153 run_test 33g "nonroot user create already existing root created file"
4154
4155 test_33h() {
4156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4157         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4158                 skip "Need MDS version at least 2.13.50"
4159
4160         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4161                 error "mkdir $tdir failed"
4162         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4163
4164         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4165         local index2
4166
4167         for fname in $DIR/$tdir/$tfile.bak \
4168                      $DIR/$tdir/$tfile.SAV \
4169                      $DIR/$tdir/$tfile.orig \
4170                      $DIR/$tdir/$tfile~; do
4171                 touch $fname  || error "touch $fname failed"
4172                 index2=$($LFS getstripe -m $fname)
4173                 [ $index -eq $index2 ] ||
4174                         error "$fname MDT index mismatch $index != $index2"
4175         done
4176
4177         local failed=0
4178         for i in {1..250}; do
4179                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4180                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4181                         touch $fname  || error "touch $fname failed"
4182                         index2=$($LFS getstripe -m $fname)
4183                         if [[ $index != $index2 ]]; then
4184                                 failed=$((failed + 1))
4185                                 echo "$fname MDT index mismatch $index != $index2"
4186                         fi
4187                 done
4188         done
4189         echo "$failed MDT index mismatches"
4190         (( failed < 20 )) || error "MDT index mismatch $failed times"
4191
4192 }
4193 run_test 33h "temp file is located on the same MDT as target"
4194
4195 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4196 test_34a() {
4197         rm -f $DIR/f34
4198         $MCREATE $DIR/f34 || error "mcreate failed"
4199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4200                 error "getstripe failed"
4201         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4202         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4203                 error "getstripe failed"
4204         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4205                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4206 }
4207 run_test 34a "truncate file that has not been opened ==========="
4208
4209 test_34b() {
4210         [ ! -f $DIR/f34 ] && test_34a
4211         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4212                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4213         $OPENFILE -f O_RDONLY $DIR/f34
4214         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4215                 error "getstripe failed"
4216         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4217                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4218 }
4219 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4220
4221 test_34c() {
4222         [ ! -f $DIR/f34 ] && test_34a
4223         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4224                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4225         $OPENFILE -f O_RDWR $DIR/f34
4226         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4227                 error "$LFS getstripe failed"
4228         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4229                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4230 }
4231 run_test 34c "O_RDWR opening file-with-size works =============="
4232
4233 test_34d() {
4234         [ ! -f $DIR/f34 ] && test_34a
4235         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4236                 error "dd failed"
4237         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4238                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4239         rm $DIR/f34
4240 }
4241 run_test 34d "write to sparse file ============================="
4242
4243 test_34e() {
4244         rm -f $DIR/f34e
4245         $MCREATE $DIR/f34e || error "mcreate failed"
4246         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4247         $CHECKSTAT -s 1000 $DIR/f34e ||
4248                 error "Size of $DIR/f34e not equal to 1000 bytes"
4249         $OPENFILE -f O_RDWR $DIR/f34e
4250         $CHECKSTAT -s 1000 $DIR/f34e ||
4251                 error "Size of $DIR/f34e not equal to 1000 bytes"
4252 }
4253 run_test 34e "create objects, some with size and some without =="
4254
4255 test_34f() { # bug 6242, 6243
4256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4257
4258         SIZE34F=48000
4259         rm -f $DIR/f34f
4260         $MCREATE $DIR/f34f || error "mcreate failed"
4261         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4262         dd if=$DIR/f34f of=$TMP/f34f
4263         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4264         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4265         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4266         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4267         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4268 }
4269 run_test 34f "read from a file with no objects until EOF ======="
4270
4271 test_34g() {
4272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4273
4274         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4275                 error "dd failed"
4276         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4277         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4278                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4279         cancel_lru_locks osc
4280         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4281                 error "wrong size after lock cancel"
4282
4283         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4284         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4285                 error "expanding truncate failed"
4286         cancel_lru_locks osc
4287         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4288                 error "wrong expanded size after lock cancel"
4289 }
4290 run_test 34g "truncate long file ==============================="
4291
4292 test_34h() {
4293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4294
4295         local gid=10
4296         local sz=1000
4297
4298         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4299         sync # Flush the cache so that multiop below does not block on cache
4300              # flush when getting the group lock
4301         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4302         MULTIPID=$!
4303
4304         # Since just timed wait is not good enough, let's do a sync write
4305         # that way we are sure enough time for a roundtrip + processing
4306         # passed + 2 seconds of extra margin.
4307         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4308         rm $DIR/${tfile}-1
4309         sleep 2
4310
4311         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4312                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4313                 kill -9 $MULTIPID
4314         fi
4315         wait $MULTIPID
4316         local nsz=`stat -c %s $DIR/$tfile`
4317         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4318 }
4319 run_test 34h "ftruncate file under grouplock should not block"
4320
4321 test_35a() {
4322         cp /bin/sh $DIR/f35a
4323         chmod 444 $DIR/f35a
4324         chown $RUNAS_ID $DIR/f35a
4325         $RUNAS $DIR/f35a && error || true
4326         rm $DIR/f35a
4327 }
4328 run_test 35a "exec file with mode 444 (should return and not leak)"
4329
4330 test_36a() {
4331         rm -f $DIR/f36
4332         utime $DIR/f36 || error "utime failed for MDS"
4333 }
4334 run_test 36a "MDS utime check (mknod, utime)"
4335
4336 test_36b() {
4337         echo "" > $DIR/f36
4338         utime $DIR/f36 || error "utime failed for OST"
4339 }
4340 run_test 36b "OST utime check (open, utime)"
4341
4342 test_36c() {
4343         rm -f $DIR/d36/f36
4344         test_mkdir $DIR/d36
4345         chown $RUNAS_ID $DIR/d36
4346         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4347 }
4348 run_test 36c "non-root MDS utime check (mknod, utime)"
4349
4350 test_36d() {
4351         [ ! -d $DIR/d36 ] && test_36c
4352         echo "" > $DIR/d36/f36
4353         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4354 }
4355 run_test 36d "non-root OST utime check (open, utime)"
4356
4357 test_36e() {
4358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4359
4360         test_mkdir $DIR/$tdir
4361         touch $DIR/$tdir/$tfile
4362         $RUNAS utime $DIR/$tdir/$tfile &&
4363                 error "utime worked, expected failure" || true
4364 }
4365 run_test 36e "utime on non-owned file (should return error)"
4366
4367 subr_36fh() {
4368         local fl="$1"
4369         local LANG_SAVE=$LANG
4370         local LC_LANG_SAVE=$LC_LANG
4371         export LANG=C LC_LANG=C # for date language
4372
4373         DATESTR="Dec 20  2000"
4374         test_mkdir $DIR/$tdir
4375         lctl set_param fail_loc=$fl
4376         date; date +%s
4377         cp /etc/hosts $DIR/$tdir/$tfile
4378         sync & # write RPC generated with "current" inode timestamp, but delayed
4379         sleep 1
4380         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4381         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4382         cancel_lru_locks $OSC
4383         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4384         date; date +%s
4385         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4386                 echo "BEFORE: $LS_BEFORE" && \
4387                 echo "AFTER : $LS_AFTER" && \
4388                 echo "WANT  : $DATESTR" && \
4389                 error "$DIR/$tdir/$tfile timestamps changed" || true
4390
4391         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4392 }
4393
4394 test_36f() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4398         subr_36fh "0x80000214"
4399 }
4400 run_test 36f "utime on file racing with OST BRW write =========="
4401
4402 test_36g() {
4403         remote_ost_nodsh && skip "remote OST with nodsh"
4404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4405         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4406                 skip "Need MDS version at least 2.12.51"
4407
4408         local fmd_max_age
4409         local fmd
4410         local facet="ost1"
4411         local tgt="obdfilter"
4412
4413         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4414
4415         test_mkdir $DIR/$tdir
4416         fmd_max_age=$(do_facet $facet \
4417                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4418                 head -n 1")
4419
4420         echo "FMD max age: ${fmd_max_age}s"
4421         touch $DIR/$tdir/$tfile
4422         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4423                 gawk '{cnt=cnt+$1}  END{print cnt}')
4424         echo "FMD before: $fmd"
4425         [[ $fmd == 0 ]] &&
4426                 error "FMD wasn't create by touch"
4427         sleep $((fmd_max_age + 12))
4428         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4429                 gawk '{cnt=cnt+$1}  END{print cnt}')
4430         echo "FMD after: $fmd"
4431         [[ $fmd == 0 ]] ||
4432                 error "FMD wasn't expired by ping"
4433 }
4434 run_test 36g "FMD cache expiry ====================="
4435
4436 test_36h() {
4437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4438
4439         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4440         subr_36fh "0x80000227"
4441 }
4442 run_test 36h "utime on file racing with OST BRW write =========="
4443
4444 test_36i() {
4445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4446
4447         test_mkdir $DIR/$tdir
4448         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4449
4450         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4451         local new_mtime=$((mtime + 200))
4452
4453         #change Modify time of striped dir
4454         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4455                         error "change mtime failed"
4456
4457         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4458
4459         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4460 }
4461 run_test 36i "change mtime on striped directory"
4462
4463 # test_37 - duplicate with tests 32q 32r
4464
4465 test_38() {
4466         local file=$DIR/$tfile
4467         touch $file
4468         openfile -f O_DIRECTORY $file
4469         local RC=$?
4470         local ENOTDIR=20
4471         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4472         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4473 }
4474 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4475
4476 test_39a() { # was test_39
4477         touch $DIR/$tfile
4478         touch $DIR/${tfile}2
4479 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4480 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4481 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4482         sleep 2
4483         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4484         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4485                 echo "mtime"
4486                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4487                 echo "atime"
4488                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4489                 echo "ctime"
4490                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4491                 error "O_TRUNC didn't change timestamps"
4492         fi
4493 }
4494 run_test 39a "mtime changed on create"
4495
4496 test_39b() {
4497         test_mkdir -c1 $DIR/$tdir
4498         cp -p /etc/passwd $DIR/$tdir/fopen
4499         cp -p /etc/passwd $DIR/$tdir/flink
4500         cp -p /etc/passwd $DIR/$tdir/funlink
4501         cp -p /etc/passwd $DIR/$tdir/frename
4502         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4503
4504         sleep 1
4505         echo "aaaaaa" >> $DIR/$tdir/fopen
4506         echo "aaaaaa" >> $DIR/$tdir/flink
4507         echo "aaaaaa" >> $DIR/$tdir/funlink
4508         echo "aaaaaa" >> $DIR/$tdir/frename
4509
4510         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4511         local link_new=`stat -c %Y $DIR/$tdir/flink`
4512         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4513         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4514
4515         cat $DIR/$tdir/fopen > /dev/null
4516         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4517         rm -f $DIR/$tdir/funlink2
4518         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4519
4520         for (( i=0; i < 2; i++ )) ; do
4521                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4522                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4523                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4524                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4525
4526                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4527                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4528                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4529                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4530
4531                 cancel_lru_locks $OSC
4532                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4533         done
4534 }
4535 run_test 39b "mtime change on open, link, unlink, rename  ======"
4536
4537 # this should be set to past
4538 TEST_39_MTIME=`date -d "1 year ago" +%s`
4539
4540 # bug 11063
4541 test_39c() {
4542         touch $DIR1/$tfile
4543         sleep 2
4544         local mtime0=`stat -c %Y $DIR1/$tfile`
4545
4546         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4547         local mtime1=`stat -c %Y $DIR1/$tfile`
4548         [ "$mtime1" = $TEST_39_MTIME ] || \
4549                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4550
4551         local d1=`date +%s`
4552         echo hello >> $DIR1/$tfile
4553         local d2=`date +%s`
4554         local mtime2=`stat -c %Y $DIR1/$tfile`
4555         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4556                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4557
4558         mv $DIR1/$tfile $DIR1/$tfile-1
4559
4560         for (( i=0; i < 2; i++ )) ; do
4561                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4562                 [ "$mtime2" = "$mtime3" ] || \
4563                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4564
4565                 cancel_lru_locks $OSC
4566                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4567         done
4568 }
4569 run_test 39c "mtime change on rename ==========================="
4570
4571 # bug 21114
4572 test_39d() {
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         touch $DIR1/$tfile
4576         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4577
4578         for (( i=0; i < 2; i++ )) ; do
4579                 local mtime=`stat -c %Y $DIR1/$tfile`
4580                 [ $mtime = $TEST_39_MTIME ] || \
4581                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4582
4583                 cancel_lru_locks $OSC
4584                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4585         done
4586 }
4587 run_test 39d "create, utime, stat =============================="
4588
4589 # bug 21114
4590 test_39e() {
4591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4592
4593         touch $DIR1/$tfile
4594         local mtime1=`stat -c %Y $DIR1/$tfile`
4595
4596         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4597
4598         for (( i=0; i < 2; i++ )) ; do
4599                 local mtime2=`stat -c %Y $DIR1/$tfile`
4600                 [ $mtime2 = $TEST_39_MTIME ] || \
4601                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4602
4603                 cancel_lru_locks $OSC
4604                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4605         done
4606 }
4607 run_test 39e "create, stat, utime, stat ========================"
4608
4609 # bug 21114
4610 test_39f() {
4611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4612
4613         touch $DIR1/$tfile
4614         mtime1=`stat -c %Y $DIR1/$tfile`
4615
4616         sleep 2
4617         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4618
4619         for (( i=0; i < 2; i++ )) ; do
4620                 local mtime2=`stat -c %Y $DIR1/$tfile`
4621                 [ $mtime2 = $TEST_39_MTIME ] || \
4622                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4623
4624                 cancel_lru_locks $OSC
4625                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4626         done
4627 }
4628 run_test 39f "create, stat, sleep, utime, stat ================="
4629
4630 # bug 11063
4631 test_39g() {
4632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4633
4634         echo hello >> $DIR1/$tfile
4635         local mtime1=`stat -c %Y $DIR1/$tfile`
4636
4637         sleep 2
4638         chmod o+r $DIR1/$tfile
4639
4640         for (( i=0; i < 2; i++ )) ; do
4641                 local mtime2=`stat -c %Y $DIR1/$tfile`
4642                 [ "$mtime1" = "$mtime2" ] || \
4643                         error "lost mtime: $mtime2, should be $mtime1"
4644
4645                 cancel_lru_locks $OSC
4646                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4647         done
4648 }
4649 run_test 39g "write, chmod, stat ==============================="
4650
4651 # bug 11063
4652 test_39h() {
4653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4654
4655         touch $DIR1/$tfile
4656         sleep 1
4657
4658         local d1=`date`
4659         echo hello >> $DIR1/$tfile
4660         local mtime1=`stat -c %Y $DIR1/$tfile`
4661
4662         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4663         local d2=`date`
4664         if [ "$d1" != "$d2" ]; then
4665                 echo "write and touch not within one second"
4666         else
4667                 for (( i=0; i < 2; i++ )) ; do
4668                         local mtime2=`stat -c %Y $DIR1/$tfile`
4669                         [ "$mtime2" = $TEST_39_MTIME ] || \
4670                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4671
4672                         cancel_lru_locks $OSC
4673                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4674                 done
4675         fi
4676 }
4677 run_test 39h "write, utime within one second, stat ============="
4678
4679 test_39i() {
4680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4681
4682         touch $DIR1/$tfile
4683         sleep 1
4684
4685         echo hello >> $DIR1/$tfile
4686         local mtime1=`stat -c %Y $DIR1/$tfile`
4687
4688         mv $DIR1/$tfile $DIR1/$tfile-1
4689
4690         for (( i=0; i < 2; i++ )) ; do
4691                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4692
4693                 [ "$mtime1" = "$mtime2" ] || \
4694                         error "lost mtime: $mtime2, should be $mtime1"
4695
4696                 cancel_lru_locks $OSC
4697                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4698         done
4699 }
4700 run_test 39i "write, rename, stat =============================="
4701
4702 test_39j() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         start_full_debug_logging
4706         touch $DIR1/$tfile
4707         sleep 1
4708
4709         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4710         lctl set_param fail_loc=0x80000412
4711         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4712                 error "multiop failed"
4713         local multipid=$!
4714         local mtime1=`stat -c %Y $DIR1/$tfile`
4715
4716         mv $DIR1/$tfile $DIR1/$tfile-1
4717
4718         kill -USR1 $multipid
4719         wait $multipid || error "multiop close failed"
4720
4721         for (( i=0; i < 2; i++ )) ; do
4722                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4723                 [ "$mtime1" = "$mtime2" ] ||
4724                         error "mtime is lost on close: $mtime2, " \
4725                               "should be $mtime1"
4726
4727                 cancel_lru_locks
4728                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4729         done
4730         lctl set_param fail_loc=0
4731         stop_full_debug_logging
4732 }
4733 run_test 39j "write, rename, close, stat ======================="
4734
4735 test_39k() {
4736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4737
4738         touch $DIR1/$tfile
4739         sleep 1
4740
4741         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4742         local multipid=$!
4743         local mtime1=`stat -c %Y $DIR1/$tfile`
4744
4745         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4746
4747         kill -USR1 $multipid
4748         wait $multipid || error "multiop close failed"
4749
4750         for (( i=0; i < 2; i++ )) ; do
4751                 local mtime2=`stat -c %Y $DIR1/$tfile`
4752
4753                 [ "$mtime2" = $TEST_39_MTIME ] || \
4754                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4755
4756                 cancel_lru_locks
4757                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4758         done
4759 }
4760 run_test 39k "write, utime, close, stat ========================"
4761
4762 # this should be set to future
4763 TEST_39_ATIME=`date -d "1 year" +%s`
4764
4765 test_39l() {
4766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4767         remote_mds_nodsh && skip "remote MDS with nodsh"
4768
4769         local atime_diff=$(do_facet $SINGLEMDS \
4770                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4771         rm -rf $DIR/$tdir
4772         mkdir_on_mdt0 $DIR/$tdir
4773
4774         # test setting directory atime to future
4775         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4776         local atime=$(stat -c %X $DIR/$tdir)
4777         [ "$atime" = $TEST_39_ATIME ] ||
4778                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4779
4780         # test setting directory atime from future to now
4781         local now=$(date +%s)
4782         touch -a -d @$now $DIR/$tdir
4783
4784         atime=$(stat -c %X $DIR/$tdir)
4785         [ "$atime" -eq "$now"  ] ||
4786                 error "atime is not updated from future: $atime, $now"
4787
4788         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4789         sleep 3
4790
4791         # test setting directory atime when now > dir atime + atime_diff
4792         local d1=$(date +%s)
4793         ls $DIR/$tdir
4794         local d2=$(date +%s)
4795         cancel_lru_locks mdc
4796         atime=$(stat -c %X $DIR/$tdir)
4797         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4798                 error "atime is not updated  : $atime, should be $d2"
4799
4800         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4801         sleep 3
4802
4803         # test not setting directory atime when now < dir atime + atime_diff
4804         ls $DIR/$tdir
4805         cancel_lru_locks mdc
4806         atime=$(stat -c %X $DIR/$tdir)
4807         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4808                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4809
4810         do_facet $SINGLEMDS \
4811                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4812 }
4813 run_test 39l "directory atime update ==========================="
4814
4815 test_39m() {
4816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4817
4818         touch $DIR1/$tfile
4819         sleep 2
4820         local far_past_mtime=$(date -d "May 29 1953" +%s)
4821         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4822
4823         touch -m -d @$far_past_mtime $DIR1/$tfile
4824         touch -a -d @$far_past_atime $DIR1/$tfile
4825
4826         for (( i=0; i < 2; i++ )) ; do
4827                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4828                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4829                         error "atime or mtime set incorrectly"
4830
4831                 cancel_lru_locks $OSC
4832                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4833         done
4834 }
4835 run_test 39m "test atime and mtime before 1970"
4836
4837 test_39n() { # LU-3832
4838         remote_mds_nodsh && skip "remote MDS with nodsh"
4839
4840         local atime_diff=$(do_facet $SINGLEMDS \
4841                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4842         local atime0
4843         local atime1
4844         local atime2
4845
4846         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4847
4848         rm -rf $DIR/$tfile
4849         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4850         atime0=$(stat -c %X $DIR/$tfile)
4851
4852         sleep 5
4853         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4854         atime1=$(stat -c %X $DIR/$tfile)
4855
4856         sleep 5
4857         cancel_lru_locks mdc
4858         cancel_lru_locks osc
4859         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4860         atime2=$(stat -c %X $DIR/$tfile)
4861
4862         do_facet $SINGLEMDS \
4863                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4864
4865         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4866         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4867 }
4868 run_test 39n "check that O_NOATIME is honored"
4869
4870 test_39o() {
4871         TESTDIR=$DIR/$tdir/$tfile
4872         [ -e $TESTDIR ] && rm -rf $TESTDIR
4873         mkdir -p $TESTDIR
4874         cd $TESTDIR
4875         links1=2
4876         ls
4877         mkdir a b
4878         ls
4879         links2=$(stat -c %h .)
4880         [ $(($links1 + 2)) != $links2 ] &&
4881                 error "wrong links count $(($links1 + 2)) != $links2"
4882         rmdir b
4883         links3=$(stat -c %h .)
4884         [ $(($links1 + 1)) != $links3 ] &&
4885                 error "wrong links count $links1 != $links3"
4886         return 0
4887 }
4888 run_test 39o "directory cached attributes updated after create"
4889
4890 test_39p() {
4891         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4892
4893         local MDTIDX=1
4894         TESTDIR=$DIR/$tdir/$tdir
4895         [ -e $TESTDIR ] && rm -rf $TESTDIR
4896         test_mkdir -p $TESTDIR
4897         cd $TESTDIR
4898         links1=2
4899         ls
4900         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4901         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4902         ls
4903         links2=$(stat -c %h .)
4904         [ $(($links1 + 2)) != $links2 ] &&
4905                 error "wrong links count $(($links1 + 2)) != $links2"
4906         rmdir remote_dir2
4907         links3=$(stat -c %h .)
4908         [ $(($links1 + 1)) != $links3 ] &&
4909                 error "wrong links count $links1 != $links3"
4910         return 0
4911 }
4912 run_test 39p "remote directory cached attributes updated after create ========"
4913
4914 test_39r() {
4915         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4916                 skip "no atime update on old OST"
4917         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4918                 skip_env "ldiskfs only test"
4919         fi
4920
4921         local saved_adiff
4922         saved_adiff=$(do_facet ost1 \
4923                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4924         stack_trap "do_facet ost1 \
4925                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4926
4927         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4928
4929         $LFS setstripe -i 0 $DIR/$tfile
4930         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4931                 error "can't write initial file"
4932         cancel_lru_locks osc
4933
4934         # exceed atime_diff and access file
4935         sleep 6
4936         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4937                 error "can't udpate atime"
4938
4939         local atime_cli=$(stat -c %X $DIR/$tfile)
4940         echo "client atime: $atime_cli"
4941         # allow atime update to be written to device
4942         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4943         sleep 5
4944
4945         local ostdev=$(ostdevname 1)
4946         local fid=($(lfs getstripe -y $DIR/$tfile |
4947                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4948         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4949         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4950
4951         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4952         local atime_ost=$(do_facet ost1 "$cmd" |&
4953                           awk -F'[: ]' '/atime:/ { print $4 }')
4954         (( atime_cli == atime_ost )) ||
4955                 error "atime on client $atime_cli != ost $atime_ost"
4956 }
4957 run_test 39r "lazy atime update on OST"
4958
4959 test_39q() { # LU-8041
4960         local testdir=$DIR/$tdir
4961         mkdir -p $testdir
4962         multiop_bg_pause $testdir D_c || error "multiop failed"
4963         local multipid=$!
4964         cancel_lru_locks mdc
4965         kill -USR1 $multipid
4966         local atime=$(stat -c %X $testdir)
4967         [ "$atime" -ne 0 ] || error "atime is zero"
4968 }
4969 run_test 39q "close won't zero out atime"
4970
4971 test_40() {
4972         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4973         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4974                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4975         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4976                 error "$tfile is not 4096 bytes in size"
4977 }
4978 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4979
4980 test_41() {
4981         # bug 1553
4982         small_write $DIR/f41 18
4983 }
4984 run_test 41 "test small file write + fstat ====================="
4985
4986 count_ost_writes() {
4987         lctl get_param -n ${OSC}.*.stats |
4988                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4989                         END { printf("%0.0f", writes) }'
4990 }
4991
4992 # decent default
4993 WRITEBACK_SAVE=500
4994 DIRTY_RATIO_SAVE=40
4995 MAX_DIRTY_RATIO=50
4996 BG_DIRTY_RATIO_SAVE=10
4997 MAX_BG_DIRTY_RATIO=25
4998
4999 start_writeback() {
5000         trap 0
5001         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5002         # dirty_ratio, dirty_background_ratio
5003         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5004                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5005                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5006                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5007         else
5008                 # if file not here, we are a 2.4 kernel
5009                 kill -CONT `pidof kupdated`
5010         fi
5011 }
5012
5013 stop_writeback() {
5014         # setup the trap first, so someone cannot exit the test at the
5015         # exact wrong time and mess up a machine
5016         trap start_writeback EXIT
5017         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5018         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5019                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5020                 sysctl -w vm.dirty_writeback_centisecs=0
5021                 sysctl -w vm.dirty_writeback_centisecs=0
5022                 # save and increase /proc/sys/vm/dirty_ratio
5023                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5024                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5025                 # save and increase /proc/sys/vm/dirty_background_ratio
5026                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5027                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5028         else
5029                 # if file not here, we are a 2.4 kernel
5030                 kill -STOP `pidof kupdated`
5031         fi
5032 }
5033
5034 # ensure that all stripes have some grant before we test client-side cache
5035 setup_test42() {
5036         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5037                 dd if=/dev/zero of=$i bs=4k count=1
5038                 rm $i
5039         done
5040 }
5041
5042 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5043 # file truncation, and file removal.
5044 test_42a() {
5045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5046
5047         setup_test42
5048         cancel_lru_locks $OSC
5049         stop_writeback
5050         sync; sleep 1; sync # just to be safe
5051         BEFOREWRITES=`count_ost_writes`
5052         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5053         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5054         AFTERWRITES=`count_ost_writes`
5055         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5056                 error "$BEFOREWRITES < $AFTERWRITES"
5057         start_writeback
5058 }
5059 run_test 42a "ensure that we don't flush on close"
5060
5061 test_42b() {
5062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5063
5064         setup_test42
5065         cancel_lru_locks $OSC
5066         stop_writeback
5067         sync
5068         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5069         BEFOREWRITES=$(count_ost_writes)
5070         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5071         AFTERWRITES=$(count_ost_writes)
5072         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5073                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5074         fi
5075         BEFOREWRITES=$(count_ost_writes)
5076         sync || error "sync: $?"
5077         AFTERWRITES=$(count_ost_writes)
5078         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5079                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5080         fi
5081         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5082         start_writeback
5083         return 0
5084 }
5085 run_test 42b "test destroy of file with cached dirty data ======"
5086
5087 # if these tests just want to test the effect of truncation,
5088 # they have to be very careful.  consider:
5089 # - the first open gets a {0,EOF}PR lock
5090 # - the first write conflicts and gets a {0, count-1}PW
5091 # - the rest of the writes are under {count,EOF}PW
5092 # - the open for truncate tries to match a {0,EOF}PR
5093 #   for the filesize and cancels the PWs.
5094 # any number of fixes (don't get {0,EOF} on open, match
5095 # composite locks, do smarter file size management) fix
5096 # this, but for now we want these tests to verify that
5097 # the cancellation with truncate intent works, so we
5098 # start the file with a full-file pw lock to match against
5099 # until the truncate.
5100 trunc_test() {
5101         test=$1
5102         file=$DIR/$test
5103         offset=$2
5104         cancel_lru_locks $OSC
5105         stop_writeback
5106         # prime the file with 0,EOF PW to match
5107         touch $file
5108         $TRUNCATE $file 0
5109         sync; sync
5110         # now the real test..
5111         dd if=/dev/zero of=$file bs=1024 count=100
5112         BEFOREWRITES=`count_ost_writes`
5113         $TRUNCATE $file $offset
5114         cancel_lru_locks $OSC
5115         AFTERWRITES=`count_ost_writes`
5116         start_writeback
5117 }
5118
5119 test_42c() {
5120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5121
5122         trunc_test 42c 1024
5123         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5124                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5125         rm $file
5126 }
5127 run_test 42c "test partial truncate of file with cached dirty data"
5128
5129 test_42d() {
5130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5131
5132         trunc_test 42d 0
5133         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5134                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5135         rm $file
5136 }
5137 run_test 42d "test complete truncate of file with cached dirty data"
5138
5139 test_42e() { # bug22074
5140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5141
5142         local TDIR=$DIR/${tdir}e
5143         local pages=16 # hardcoded 16 pages, don't change it.
5144         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5145         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5146         local max_dirty_mb
5147         local warmup_files
5148
5149         test_mkdir $DIR/${tdir}e
5150         $LFS setstripe -c 1 $TDIR
5151         createmany -o $TDIR/f $files
5152
5153         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5154
5155         # we assume that with $OSTCOUNT files, at least one of them will
5156         # be allocated on OST0.
5157         warmup_files=$((OSTCOUNT * max_dirty_mb))
5158         createmany -o $TDIR/w $warmup_files
5159
5160         # write a large amount of data into one file and sync, to get good
5161         # avail_grant number from OST.
5162         for ((i=0; i<$warmup_files; i++)); do
5163                 idx=$($LFS getstripe -i $TDIR/w$i)
5164                 [ $idx -ne 0 ] && continue
5165                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5166                 break
5167         done
5168         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5169         sync
5170         $LCTL get_param $proc_osc0/cur_dirty_bytes
5171         $LCTL get_param $proc_osc0/cur_grant_bytes
5172
5173         # create as much dirty pages as we can while not to trigger the actual
5174         # RPCs directly. but depends on the env, VFS may trigger flush during this
5175         # period, hopefully we are good.
5176         for ((i=0; i<$warmup_files; i++)); do
5177                 idx=$($LFS getstripe -i $TDIR/w$i)
5178                 [ $idx -ne 0 ] && continue
5179                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5180         done
5181         $LCTL get_param $proc_osc0/cur_dirty_bytes
5182         $LCTL get_param $proc_osc0/cur_grant_bytes
5183
5184         # perform the real test
5185         $LCTL set_param $proc_osc0/rpc_stats 0
5186         for ((;i<$files; i++)); do
5187                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5188                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5189         done
5190         sync
5191         $LCTL get_param $proc_osc0/rpc_stats
5192
5193         local percent=0
5194         local have_ppr=false
5195         $LCTL get_param $proc_osc0/rpc_stats |
5196                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5197                         # skip lines until we are at the RPC histogram data
5198                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5199                         $have_ppr || continue
5200
5201                         # we only want the percent stat for < 16 pages
5202                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5203
5204                         percent=$((percent + WPCT))
5205                         if [[ $percent -gt 15 ]]; then
5206                                 error "less than 16-pages write RPCs" \
5207                                       "$percent% > 15%"
5208                                 break
5209                         fi
5210                 done
5211         rm -rf $TDIR
5212 }
5213 run_test 42e "verify sub-RPC writes are not done synchronously"
5214
5215 test_43A() { # was test_43
5216         test_mkdir $DIR/$tdir
5217         cp -p /bin/ls $DIR/$tdir/$tfile
5218         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5219         pid=$!
5220         # give multiop a chance to open
5221         sleep 1
5222
5223         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5224         kill -USR1 $pid
5225         # Wait for multiop to exit
5226         wait $pid
5227 }
5228 run_test 43A "execution of file opened for write should return -ETXTBSY"
5229
5230 test_43a() {
5231         test_mkdir $DIR/$tdir
5232         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5233         $DIR/$tdir/sleep 60 &
5234         SLEEP_PID=$!
5235         # Make sure exec of $tdir/sleep wins race with truncate
5236         sleep 1
5237         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5238         kill $SLEEP_PID
5239 }
5240 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5241
5242 test_43b() {
5243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5244
5245         test_mkdir $DIR/$tdir
5246         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5247         $DIR/$tdir/sleep 60 &
5248         SLEEP_PID=$!
5249         # Make sure exec of $tdir/sleep wins race with truncate
5250         sleep 1
5251         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5252         kill $SLEEP_PID
5253 }
5254 run_test 43b "truncate of file being executed should return -ETXTBSY"
5255
5256 test_43c() {
5257         local testdir="$DIR/$tdir"
5258         test_mkdir $testdir
5259         cp $SHELL $testdir/
5260         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5261                 ( cd $testdir && md5sum -c )
5262 }
5263 run_test 43c "md5sum of copy into lustre"
5264
5265 test_44A() { # was test_44
5266         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5267
5268         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5269         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5270 }
5271 run_test 44A "zero length read from a sparse stripe"
5272
5273 test_44a() {
5274         local nstripe=$($LFS getstripe -c -d $DIR)
5275         [ -z "$nstripe" ] && skip "can't get stripe info"
5276         [[ $nstripe -gt $OSTCOUNT ]] &&
5277                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5278
5279         local stride=$($LFS getstripe -S -d $DIR)
5280         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5281                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5282         fi
5283
5284         OFFSETS="0 $((stride/2)) $((stride-1))"
5285         for offset in $OFFSETS; do
5286                 for i in $(seq 0 $((nstripe-1))); do
5287                         local GLOBALOFFSETS=""
5288                         # size in Bytes
5289                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5290                         local myfn=$DIR/d44a-$size
5291                         echo "--------writing $myfn at $size"
5292                         ll_sparseness_write $myfn $size ||
5293                                 error "ll_sparseness_write"
5294                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5295                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5296                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5297
5298                         for j in $(seq 0 $((nstripe-1))); do
5299                                 # size in Bytes
5300                                 size=$((((j + $nstripe )*$stride + $offset)))
5301                                 ll_sparseness_write $myfn $size ||
5302                                         error "ll_sparseness_write"
5303                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5304                         done
5305                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5306                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5307                         rm -f $myfn
5308                 done
5309         done
5310 }
5311 run_test 44a "test sparse pwrite ==============================="
5312
5313 dirty_osc_total() {
5314         tot=0
5315         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5316                 tot=$(($tot + $d))
5317         done
5318         echo $tot
5319 }
5320 do_dirty_record() {
5321         before=`dirty_osc_total`
5322         echo executing "\"$*\""
5323         eval $*
5324         after=`dirty_osc_total`
5325         echo before $before, after $after
5326 }
5327 test_45() {
5328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5329
5330         f="$DIR/f45"
5331         # Obtain grants from OST if it supports it
5332         echo blah > ${f}_grant
5333         stop_writeback
5334         sync
5335         do_dirty_record "echo blah > $f"
5336         [[ $before -eq $after ]] && error "write wasn't cached"
5337         do_dirty_record "> $f"
5338         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5339         do_dirty_record "echo blah > $f"
5340         [[ $before -eq $after ]] && error "write wasn't cached"
5341         do_dirty_record "sync"
5342         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5343         do_dirty_record "echo blah > $f"
5344         [[ $before -eq $after ]] && error "write wasn't cached"
5345         do_dirty_record "cancel_lru_locks osc"
5346         [[ $before -gt $after ]] ||
5347                 error "lock cancellation didn't lower dirty count"
5348         start_writeback
5349 }
5350 run_test 45 "osc io page accounting ============================"
5351
5352 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5353 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5354 # objects offset and an assert hit when an rpc was built with 1023's mapped
5355 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5356 test_46() {
5357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5358
5359         f="$DIR/f46"
5360         stop_writeback
5361         sync
5362         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5363         sync
5364         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5365         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5366         sync
5367         start_writeback
5368 }
5369 run_test 46 "dirtying a previously written page ================"
5370
5371 # test_47 is removed "Device nodes check" is moved to test_28
5372
5373 test_48a() { # bug 2399
5374         [ "$mds1_FSTYPE" = "zfs" ] &&
5375         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5376                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5377
5378         test_mkdir $DIR/$tdir
5379         cd $DIR/$tdir
5380         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5381         test_mkdir $DIR/$tdir
5382         touch foo || error "'touch foo' failed after recreating cwd"
5383         test_mkdir bar
5384         touch .foo || error "'touch .foo' failed after recreating cwd"
5385         test_mkdir .bar
5386         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5387         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5388         cd . || error "'cd .' failed after recreating cwd"
5389         mkdir . && error "'mkdir .' worked after recreating cwd"
5390         rmdir . && error "'rmdir .' worked after recreating cwd"
5391         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5392         cd .. || error "'cd ..' failed after recreating cwd"
5393 }
5394 run_test 48a "Access renamed working dir (should return errors)="
5395
5396 test_48b() { # bug 2399
5397         rm -rf $DIR/$tdir
5398         test_mkdir $DIR/$tdir
5399         cd $DIR/$tdir
5400         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5401         touch foo && error "'touch foo' worked after removing cwd"
5402         mkdir foo && error "'mkdir foo' worked after removing cwd"
5403         touch .foo && error "'touch .foo' worked after removing cwd"
5404         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5405         ls . > /dev/null && error "'ls .' worked after removing cwd"
5406         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5407         mkdir . && error "'mkdir .' worked after removing cwd"
5408         rmdir . && error "'rmdir .' worked after removing cwd"
5409         ln -s . foo && error "'ln -s .' worked after removing cwd"
5410         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5411 }
5412 run_test 48b "Access removed working dir (should return errors)="
5413
5414 test_48c() { # bug 2350
5415         #lctl set_param debug=-1
5416         #set -vx
5417         rm -rf $DIR/$tdir
5418         test_mkdir -p $DIR/$tdir/dir
5419         cd $DIR/$tdir/dir
5420         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5421         $TRACE touch foo && error "touch foo worked after removing cwd"
5422         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5423         touch .foo && error "touch .foo worked after removing cwd"
5424         mkdir .foo && error "mkdir .foo worked after removing cwd"
5425         $TRACE ls . && error "'ls .' worked after removing cwd"
5426         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5427         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5428         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5429         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5430         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5431 }
5432 run_test 48c "Access removed working subdir (should return errors)"
5433
5434 test_48d() { # bug 2350
5435         #lctl set_param debug=-1
5436         #set -vx
5437         rm -rf $DIR/$tdir
5438         test_mkdir -p $DIR/$tdir/dir
5439         cd $DIR/$tdir/dir
5440         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5441         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5442         $TRACE touch foo && error "'touch foo' worked after removing parent"
5443         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5444         touch .foo && error "'touch .foo' worked after removing parent"
5445         mkdir .foo && error "mkdir .foo worked after removing parent"
5446         $TRACE ls . && error "'ls .' worked after removing parent"
5447         $TRACE ls .. && error "'ls ..' worked after removing parent"
5448         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5449         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5450         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5451         true
5452 }
5453 run_test 48d "Access removed parent subdir (should return errors)"
5454
5455 test_48e() { # bug 4134
5456         #lctl set_param debug=-1
5457         #set -vx
5458         rm -rf $DIR/$tdir
5459         test_mkdir -p $DIR/$tdir/dir
5460         cd $DIR/$tdir/dir
5461         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5462         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5463         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5464         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5465         # On a buggy kernel addition of "touch foo" after cd .. will
5466         # produce kernel oops in lookup_hash_it
5467         touch ../foo && error "'cd ..' worked after recreate parent"
5468         cd $DIR
5469         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5470 }
5471 run_test 48e "Access to recreated parent subdir (should return errors)"
5472
5473 test_48f() {
5474         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5475                 skip "need MDS >= 2.13.55"
5476         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5477         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5478                 skip "needs different host for mdt1 mdt2"
5479         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5480
5481         $LFS mkdir -i0 $DIR/$tdir
5482         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5483
5484         for d in sub1 sub2 sub3; do
5485                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5486                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5487                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5488         done
5489
5490         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5491 }
5492 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5493
5494 test_49() { # LU-1030
5495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5496         remote_ost_nodsh && skip "remote OST with nodsh"
5497
5498         # get ost1 size - $FSNAME-OST0000
5499         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5500                 awk '{ print $4 }')
5501         # write 800M at maximum
5502         [[ $ost1_size -lt 2 ]] && ost1_size=2
5503         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5504
5505         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5506         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5507         local dd_pid=$!
5508
5509         # change max_pages_per_rpc while writing the file
5510         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5511         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5512         # loop until dd process exits
5513         while ps ax -opid | grep -wq $dd_pid; do
5514                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5515                 sleep $((RANDOM % 5 + 1))
5516         done
5517         # restore original max_pages_per_rpc
5518         $LCTL set_param $osc1_mppc=$orig_mppc
5519         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5520 }
5521 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5522
5523 test_50() {
5524         # bug 1485
5525         test_mkdir $DIR/$tdir
5526         cd $DIR/$tdir
5527         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5528 }
5529 run_test 50 "special situations: /proc symlinks  ==============="
5530
5531 test_51a() {    # was test_51
5532         # bug 1516 - create an empty entry right after ".." then split dir
5533         test_mkdir -c1 $DIR/$tdir
5534         touch $DIR/$tdir/foo
5535         $MCREATE $DIR/$tdir/bar
5536         rm $DIR/$tdir/foo
5537         createmany -m $DIR/$tdir/longfile 201
5538         FNUM=202
5539         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5540                 $MCREATE $DIR/$tdir/longfile$FNUM
5541                 FNUM=$(($FNUM + 1))
5542                 echo -n "+"
5543         done
5544         echo
5545         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5546 }
5547 run_test 51a "special situations: split htree with empty entry =="
5548
5549 cleanup_print_lfs_df () {
5550         trap 0
5551         $LFS df
5552         $LFS df -i
5553 }
5554
5555 test_51b() {
5556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5557
5558         local dir=$DIR/$tdir
5559         local nrdirs=$((65536 + 100))
5560
5561         # cleanup the directory
5562         rm -fr $dir
5563
5564         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5565
5566         $LFS df
5567         $LFS df -i
5568         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5569         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5570         [[ $numfree -lt $nrdirs ]] &&
5571                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5572
5573         # need to check free space for the directories as well
5574         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5575         numfree=$(( blkfree / $(fs_inode_ksize) ))
5576         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5577
5578         trap cleanup_print_lfs_df EXIT
5579
5580         # create files
5581         createmany -d $dir/d $nrdirs || {
5582                 unlinkmany $dir/d $nrdirs
5583                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5584         }
5585
5586         # really created :
5587         nrdirs=$(ls -U $dir | wc -l)
5588
5589         # unlink all but 100 subdirectories, then check it still works
5590         local left=100
5591         local delete=$((nrdirs - left))
5592
5593         $LFS df
5594         $LFS df -i
5595
5596         # for ldiskfs the nlink count should be 1, but this is OSD specific
5597         # and so this is listed for informational purposes only
5598         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5599         unlinkmany -d $dir/d $delete ||
5600                 error "unlink of first $delete subdirs failed"
5601
5602         echo "nlink between: $(stat -c %h $dir)"
5603         local found=$(ls -U $dir | wc -l)
5604         [ $found -ne $left ] &&
5605                 error "can't find subdirs: found only $found, expected $left"
5606
5607         unlinkmany -d $dir/d $delete $left ||
5608                 error "unlink of second $left subdirs failed"
5609         # regardless of whether the backing filesystem tracks nlink accurately
5610         # or not, the nlink count shouldn't be more than "." and ".." here
5611         local after=$(stat -c %h $dir)
5612         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5613                 echo "nlink after: $after"
5614
5615         cleanup_print_lfs_df
5616 }
5617 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5618
5619 test_51d() {
5620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5621         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5622
5623         test_mkdir $DIR/$tdir
5624         createmany -o $DIR/$tdir/t- 1000
5625         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5626         for N in $(seq 0 $((OSTCOUNT - 1))); do
5627                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5628                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5629                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5630                         '($1 == '$N') { objs += 1 } \
5631                         END { printf("%0.0f", objs) }')
5632                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5633         done
5634         unlinkmany $DIR/$tdir/t- 1000
5635
5636         NLAST=0
5637         for N in $(seq 1 $((OSTCOUNT - 1))); do
5638                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5639                         error "OST $N has less objects vs OST $NLAST" \
5640                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5641                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5642                         error "OST $N has less objects vs OST $NLAST" \
5643                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5644
5645                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5646                         error "OST $N has less #0 objects vs OST $NLAST" \
5647                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5648                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5649                         error "OST $N has less #0 objects vs OST $NLAST" \
5650                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5651                 NLAST=$N
5652         done
5653         rm -f $TMP/$tfile
5654 }
5655 run_test 51d "check object distribution"
5656
5657 test_51e() {
5658         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5659                 skip_env "ldiskfs only test"
5660         fi
5661
5662         test_mkdir -c1 $DIR/$tdir
5663         test_mkdir -c1 $DIR/$tdir/d0
5664
5665         touch $DIR/$tdir/d0/foo
5666         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5667                 error "file exceed 65000 nlink limit!"
5668         unlinkmany $DIR/$tdir/d0/f- 65001
5669         return 0
5670 }
5671 run_test 51e "check file nlink limit"
5672
5673 test_51f() {
5674         test_mkdir $DIR/$tdir
5675
5676         local max=100000
5677         local ulimit_old=$(ulimit -n)
5678         local spare=20 # number of spare fd's for scripts/libraries, etc.
5679         local mdt=$($LFS getstripe -m $DIR/$tdir)
5680         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5681
5682         echo "MDT$mdt numfree=$numfree, max=$max"
5683         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5684         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5685                 while ! ulimit -n $((numfree + spare)); do
5686                         numfree=$((numfree * 3 / 4))
5687                 done
5688                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5689         else
5690                 echo "left ulimit at $ulimit_old"
5691         fi
5692
5693         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5694                 unlinkmany $DIR/$tdir/f $numfree
5695                 error "create+open $numfree files in $DIR/$tdir failed"
5696         }
5697         ulimit -n $ulimit_old
5698
5699         # if createmany exits at 120s there will be fewer than $numfree files
5700         unlinkmany $DIR/$tdir/f $numfree || true
5701 }
5702 run_test 51f "check many open files limit"
5703
5704 test_52a() {
5705         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5706         test_mkdir $DIR/$tdir
5707         touch $DIR/$tdir/foo
5708         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5709         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5710         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5711         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5712         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5713                                         error "link worked"
5714         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5715         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5716         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5717                                                      error "lsattr"
5718         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5719         cp -r $DIR/$tdir $TMP/
5720         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5721 }
5722 run_test 52a "append-only flag test (should return errors)"
5723
5724 test_52b() {
5725         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5726         test_mkdir $DIR/$tdir
5727         touch $DIR/$tdir/foo
5728         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5729         cat test > $DIR/$tdir/foo && error "cat test worked"
5730         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5731         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5732         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5733                                         error "link worked"
5734         echo foo >> $DIR/$tdir/foo && error "echo worked"
5735         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5736         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5737         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5738         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5739                                                         error "lsattr"
5740         chattr -i $DIR/$tdir/foo || error "chattr failed"
5741
5742         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5743 }
5744 run_test 52b "immutable flag test (should return errors) ======="
5745
5746 test_53() {
5747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5748         remote_mds_nodsh && skip "remote MDS with nodsh"
5749         remote_ost_nodsh && skip "remote OST with nodsh"
5750
5751         local param
5752         local param_seq
5753         local ostname
5754         local mds_last
5755         local mds_last_seq
5756         local ost_last
5757         local ost_last_seq
5758         local ost_last_id
5759         local ostnum
5760         local node
5761         local found=false
5762         local support_last_seq=true
5763
5764         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5765                 support_last_seq=false
5766
5767         # only test MDT0000
5768         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5769         local value
5770         for value in $(do_facet $SINGLEMDS \
5771                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5772                 param=$(echo ${value[0]} | cut -d "=" -f1)
5773                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5774
5775                 if $support_last_seq; then
5776                         param_seq=$(echo $param |
5777                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5778                         mds_last_seq=$(do_facet $SINGLEMDS \
5779                                        $LCTL get_param -n $param_seq)
5780                 fi
5781                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5782
5783                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5784                 node=$(facet_active_host ost$((ostnum+1)))
5785                 param="obdfilter.$ostname.last_id"
5786                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5787                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5788                         ost_last_id=$ost_last
5789
5790                         if $support_last_seq; then
5791                                 ost_last_id=$(echo $ost_last |
5792                                               awk -F':' '{print $2}' |
5793                                               sed -e "s/^0x//g")
5794                                 ost_last_seq=$(echo $ost_last |
5795                                                awk -F':' '{print $1}')
5796                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5797                         fi
5798
5799                         if [[ $ost_last_id != $mds_last ]]; then
5800                                 error "$ost_last_id != $mds_last"
5801                         else
5802                                 found=true
5803                                 break
5804                         fi
5805                 done
5806         done
5807         $found || error "can not match last_seq/last_id for $mdtosc"
5808         return 0
5809 }
5810 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5811
5812 test_54a() {
5813         perl -MSocket -e ';' || skip "no Socket perl module installed"
5814
5815         $SOCKETSERVER $DIR/socket ||
5816                 error "$SOCKETSERVER $DIR/socket failed: $?"
5817         $SOCKETCLIENT $DIR/socket ||
5818                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5819         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5820 }
5821 run_test 54a "unix domain socket test =========================="
5822
5823 test_54b() {
5824         f="$DIR/f54b"
5825         mknod $f c 1 3
5826         chmod 0666 $f
5827         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5828 }
5829 run_test 54b "char device works in lustre ======================"
5830
5831 find_loop_dev() {
5832         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5833         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5834         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5835
5836         for i in $(seq 3 7); do
5837                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5838                 LOOPDEV=$LOOPBASE$i
5839                 LOOPNUM=$i
5840                 break
5841         done
5842 }
5843
5844 cleanup_54c() {
5845         local rc=0
5846         loopdev="$DIR/loop54c"
5847
5848         trap 0
5849         $UMOUNT $DIR/$tdir || rc=$?
5850         losetup -d $loopdev || true
5851         losetup -d $LOOPDEV || true
5852         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5853         return $rc
5854 }
5855
5856 test_54c() {
5857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5858
5859         loopdev="$DIR/loop54c"
5860
5861         find_loop_dev
5862         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5863         trap cleanup_54c EXIT
5864         mknod $loopdev b 7 $LOOPNUM
5865         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5866         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5867         losetup $loopdev $DIR/$tfile ||
5868                 error "can't set up $loopdev for $DIR/$tfile"
5869         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5870         test_mkdir $DIR/$tdir
5871         mount -t ext2 $loopdev $DIR/$tdir ||
5872                 error "error mounting $loopdev on $DIR/$tdir"
5873         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5874                 error "dd write"
5875         df $DIR/$tdir
5876         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5877                 error "dd read"
5878         cleanup_54c
5879 }
5880 run_test 54c "block device works in lustre ====================="
5881
5882 test_54d() {
5883         f="$DIR/f54d"
5884         string="aaaaaa"
5885         mknod $f p
5886         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5887 }
5888 run_test 54d "fifo device works in lustre ======================"
5889
5890 test_54e() {
5891         f="$DIR/f54e"
5892         string="aaaaaa"
5893         cp -aL /dev/console $f
5894         echo $string > $f || error "echo $string to $f failed"
5895 }
5896 run_test 54e "console/tty device works in lustre ======================"
5897
5898 test_56a() {
5899         local numfiles=3
5900         local numdirs=2
5901         local dir=$DIR/$tdir
5902
5903         rm -rf $dir
5904         test_mkdir -p $dir/dir
5905         for i in $(seq $numfiles); do
5906                 touch $dir/file$i
5907                 touch $dir/dir/file$i
5908         done
5909
5910         local numcomp=$($LFS getstripe --component-count $dir)
5911
5912         [[ $numcomp == 0 ]] && numcomp=1
5913
5914         # test lfs getstripe with --recursive
5915         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5916
5917         [[ $filenum -eq $((numfiles * 2)) ]] ||
5918                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5919         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5920         [[ $filenum -eq $numfiles ]] ||
5921                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5922         echo "$LFS getstripe showed obdidx or l_ost_idx"
5923
5924         # test lfs getstripe with file instead of dir
5925         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5926         [[ $filenum -eq 1 ]] ||
5927                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5928         echo "$LFS getstripe file1 passed"
5929
5930         #test lfs getstripe with --verbose
5931         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5932         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5933                 error "$LFS getstripe --verbose $dir: "\
5934                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5935         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5936                 error "$LFS getstripe $dir: showed lmm_magic"
5937
5938         #test lfs getstripe with -v prints lmm_fid
5939         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5940         local countfids=$((numdirs + numfiles * numcomp))
5941         [[ $filenum -eq $countfids ]] ||
5942                 error "$LFS getstripe -v $dir: "\
5943                       "got $filenum want $countfids lmm_fid"
5944         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5945                 error "$LFS getstripe $dir: showed lmm_fid by default"
5946         echo "$LFS getstripe --verbose passed"
5947
5948         #check for FID information
5949         local fid1=$($LFS getstripe --fid $dir/file1)
5950         local fid2=$($LFS getstripe --verbose $dir/file1 |
5951                      awk '/lmm_fid: / { print $2; exit; }')
5952         local fid3=$($LFS path2fid $dir/file1)
5953
5954         [ "$fid1" != "$fid2" ] &&
5955                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5956         [ "$fid1" != "$fid3" ] &&
5957                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5958         echo "$LFS getstripe --fid passed"
5959
5960         #test lfs getstripe with --obd
5961         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5962                 error "$LFS getstripe --obd wrong_uuid: should return error"
5963
5964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5965
5966         local ostidx=1
5967         local obduuid=$(ostuuid_from_index $ostidx)
5968         local found=$($LFS getstripe -r --obd $obduuid $dir |
5969                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5970
5971         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5972         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5973                 ((filenum--))
5974         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5975                 ((filenum--))
5976
5977         [[ $found -eq $filenum ]] ||
5978                 error "$LFS getstripe --obd: found $found expect $filenum"
5979         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5980                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5981                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5982                 error "$LFS getstripe --obd: should not show file on other obd"
5983         echo "$LFS getstripe --obd passed"
5984 }
5985 run_test 56a "check $LFS getstripe"
5986
5987 test_56b() {
5988         local dir=$DIR/$tdir
5989         local numdirs=3
5990
5991         test_mkdir $dir
5992         for i in $(seq $numdirs); do
5993                 test_mkdir $dir/dir$i
5994         done
5995
5996         # test lfs getdirstripe default mode is non-recursion, which is
5997         # different from lfs getstripe
5998         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5999
6000         [[ $dircnt -eq 1 ]] ||
6001                 error "$LFS getdirstripe: found $dircnt, not 1"
6002         dircnt=$($LFS getdirstripe --recursive $dir |
6003                 grep -c lmv_stripe_count)
6004         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6005                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6006 }
6007 run_test 56b "check $LFS getdirstripe"
6008
6009 test_56c() {
6010         remote_ost_nodsh && skip "remote OST with nodsh"
6011
6012         local ost_idx=0
6013         local ost_name=$(ostname_from_index $ost_idx)
6014         local old_status=$(ost_dev_status $ost_idx)
6015         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6016
6017         [[ -z "$old_status" ]] ||
6018                 skip_env "OST $ost_name is in $old_status status"
6019
6020         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6021         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6022                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6023         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6024                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6025                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6026         fi
6027
6028         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6029                 error "$LFS df -v showing inactive devices"
6030         sleep_maxage
6031
6032         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6033
6034         [[ "$new_status" =~ "D" ]] ||
6035                 error "$ost_name status is '$new_status', missing 'D'"
6036         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6037                 [[ "$new_status" =~ "N" ]] ||
6038                         error "$ost_name status is '$new_status', missing 'N'"
6039         fi
6040         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6041                 [[ "$new_status" =~ "f" ]] ||
6042                         error "$ost_name status is '$new_status', missing 'f'"
6043         fi
6044
6045         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6046         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6047                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6048         [[ -z "$p" ]] && restore_lustre_params < $p || true
6049         sleep_maxage
6050
6051         new_status=$(ost_dev_status $ost_idx)
6052         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6053                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6054         # can't check 'f' as devices may actually be on flash
6055 }
6056 run_test 56c "check 'lfs df' showing device status"
6057
6058 test_56d() {
6059         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6060         local osts=$($LFS df -v $MOUNT | grep -c OST)
6061
6062         $LFS df $MOUNT
6063
6064         (( mdts == MDSCOUNT )) ||
6065                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6066         (( osts == OSTCOUNT )) ||
6067                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6068 }
6069 run_test 56d "'lfs df -v' prints only configured devices"
6070
6071 NUMFILES=3
6072 NUMDIRS=3
6073 setup_56() {
6074         local local_tdir="$1"
6075         local local_numfiles="$2"
6076         local local_numdirs="$3"
6077         local dir_params="$4"
6078         local dir_stripe_params="$5"
6079
6080         if [ ! -d "$local_tdir" ] ; then
6081                 test_mkdir -p $dir_stripe_params $local_tdir
6082                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6083                 for i in $(seq $local_numfiles) ; do
6084                         touch $local_tdir/file$i
6085                 done
6086                 for i in $(seq $local_numdirs) ; do
6087                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6088                         for j in $(seq $local_numfiles) ; do
6089                                 touch $local_tdir/dir$i/file$j
6090                         done
6091                 done
6092         fi
6093 }
6094
6095 setup_56_special() {
6096         local local_tdir=$1
6097         local local_numfiles=$2
6098         local local_numdirs=$3
6099
6100         setup_56 $local_tdir $local_numfiles $local_numdirs
6101
6102         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6103                 for i in $(seq $local_numfiles) ; do
6104                         mknod $local_tdir/loop${i}b b 7 $i
6105                         mknod $local_tdir/null${i}c c 1 3
6106                         ln -s $local_tdir/file1 $local_tdir/link${i}
6107                 done
6108                 for i in $(seq $local_numdirs) ; do
6109                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6110                         mknod $local_tdir/dir$i/null${i}c c 1 3
6111                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6112                 done
6113         fi
6114 }
6115
6116 test_56g() {
6117         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6118         local expected=$(($NUMDIRS + 2))
6119
6120         setup_56 $dir $NUMFILES $NUMDIRS
6121
6122         # test lfs find with -name
6123         for i in $(seq $NUMFILES) ; do
6124                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6125
6126                 [ $nums -eq $expected ] ||
6127                         error "lfs find -name '*$i' $dir wrong: "\
6128                               "found $nums, expected $expected"
6129         done
6130 }
6131 run_test 56g "check lfs find -name"
6132
6133 test_56h() {
6134         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6135         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6136
6137         setup_56 $dir $NUMFILES $NUMDIRS
6138
6139         # test lfs find with ! -name
6140         for i in $(seq $NUMFILES) ; do
6141                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6142
6143                 [ $nums -eq $expected ] ||
6144                         error "lfs find ! -name '*$i' $dir wrong: "\
6145                               "found $nums, expected $expected"
6146         done
6147 }
6148 run_test 56h "check lfs find ! -name"
6149
6150 test_56i() {
6151         local dir=$DIR/$tdir
6152
6153         test_mkdir $dir
6154
6155         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6156         local out=$($cmd)
6157
6158         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6159 }
6160 run_test 56i "check 'lfs find -ost UUID' skips directories"
6161
6162 test_56j() {
6163         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6164
6165         setup_56_special $dir $NUMFILES $NUMDIRS
6166
6167         local expected=$((NUMDIRS + 1))
6168         local cmd="$LFS find -type d $dir"
6169         local nums=$($cmd | wc -l)
6170
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173 }
6174 run_test 56j "check lfs find -type d"
6175
6176 test_56k() {
6177         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6178
6179         setup_56_special $dir $NUMFILES $NUMDIRS
6180
6181         local expected=$(((NUMDIRS + 1) * NUMFILES))
6182         local cmd="$LFS find -type f $dir"
6183         local nums=$($cmd | wc -l)
6184
6185         [ $nums -eq $expected ] ||
6186                 error "'$cmd' wrong: found $nums, expected $expected"
6187 }
6188 run_test 56k "check lfs find -type f"
6189
6190 test_56l() {
6191         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6192
6193         setup_56_special $dir $NUMFILES $NUMDIRS
6194
6195         local expected=$((NUMDIRS + NUMFILES))
6196         local cmd="$LFS find -type b $dir"
6197         local nums=$($cmd | wc -l)
6198
6199         [ $nums -eq $expected ] ||
6200                 error "'$cmd' wrong: found $nums, expected $expected"
6201 }
6202 run_test 56l "check lfs find -type b"
6203
6204 test_56m() {
6205         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6206
6207         setup_56_special $dir $NUMFILES $NUMDIRS
6208
6209         local expected=$((NUMDIRS + NUMFILES))
6210         local cmd="$LFS find -type c $dir"
6211         local nums=$($cmd | wc -l)
6212         [ $nums -eq $expected ] ||
6213                 error "'$cmd' wrong: found $nums, expected $expected"
6214 }
6215 run_test 56m "check lfs find -type c"
6216
6217 test_56n() {
6218         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6219         setup_56_special $dir $NUMFILES $NUMDIRS
6220
6221         local expected=$((NUMDIRS + NUMFILES))
6222         local cmd="$LFS find -type l $dir"
6223         local nums=$($cmd | wc -l)
6224
6225         [ $nums -eq $expected ] ||
6226                 error "'$cmd' wrong: found $nums, expected $expected"
6227 }
6228 run_test 56n "check lfs find -type l"
6229
6230 test_56o() {
6231         local dir=$DIR/$tdir
6232
6233         setup_56 $dir $NUMFILES $NUMDIRS
6234         utime $dir/file1 > /dev/null || error "utime (1)"
6235         utime $dir/file2 > /dev/null || error "utime (2)"
6236         utime $dir/dir1 > /dev/null || error "utime (3)"
6237         utime $dir/dir2 > /dev/null || error "utime (4)"
6238         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6239         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6240
6241         local expected=4
6242         local nums=$($LFS find -mtime +0 $dir | wc -l)
6243
6244         [ $nums -eq $expected ] ||
6245                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6246
6247         expected=12
6248         cmd="$LFS find -mtime 0 $dir"
6249         nums=$($cmd | wc -l)
6250         [ $nums -eq $expected ] ||
6251                 error "'$cmd' wrong: found $nums, expected $expected"
6252 }
6253 run_test 56o "check lfs find -mtime for old files"
6254
6255 test_56ob() {
6256         local dir=$DIR/$tdir
6257         local expected=1
6258         local count=0
6259
6260         # just to make sure there is something that won't be found
6261         test_mkdir $dir
6262         touch $dir/$tfile.now
6263
6264         for age in year week day hour min; do
6265                 count=$((count + 1))
6266
6267                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6268                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6269                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6270
6271                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6272                 local nums=$($cmd | wc -l)
6273                 [ $nums -eq $expected ] ||
6274                         error "'$cmd' wrong: found $nums, expected $expected"
6275
6276                 cmd="$LFS find $dir -atime $count${age:0:1}"
6277                 nums=$($cmd | wc -l)
6278                 [ $nums -eq $expected ] ||
6279                         error "'$cmd' wrong: found $nums, expected $expected"
6280         done
6281
6282         sleep 2
6283         cmd="$LFS find $dir -ctime +1s -type f"
6284         nums=$($cmd | wc -l)
6285         (( $nums == $count * 2 + 1)) ||
6286                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6287 }
6288 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6289
6290 test_newerXY_base() {
6291         local x=$1
6292         local y=$2
6293         local dir=$DIR/$tdir
6294         local ref
6295         local negref
6296
6297         if [ $y == "t" ]; then
6298                 if [ $x == "b" ]; then
6299                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6300                 else
6301                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6302                 fi
6303         else
6304                 ref=$DIR/$tfile.newer.$x$y
6305                 touch $ref || error "touch $ref failed"
6306         fi
6307
6308         echo "before = $ref"
6309         sleep 2
6310         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6311         sleep 2
6312         if [ $y == "t" ]; then
6313                 if [ $x == "b" ]; then
6314                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6315                 else
6316                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6317                 fi
6318         else
6319                 negref=$DIR/$tfile.negnewer.$x$y
6320                 touch $negref || error "touch $negref failed"
6321         fi
6322
6323         echo "after = $negref"
6324         local cmd="$LFS find $dir -newer$x$y $ref"
6325         local nums=$(eval $cmd | wc -l)
6326         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6327
6328         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6329                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6330
6331         cmd="$LFS find $dir ! -newer$x$y $negref"
6332         nums=$(eval $cmd | wc -l)
6333         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6334                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6335
6336         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6337         nums=$(eval $cmd | wc -l)
6338         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6339                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6340
6341         rm -rf $DIR/*
6342 }
6343
6344 test_56oc() {
6345         test_newerXY_base "a" "a"
6346         test_newerXY_base "a" "m"
6347         test_newerXY_base "a" "c"
6348         test_newerXY_base "m" "a"
6349         test_newerXY_base "m" "m"
6350         test_newerXY_base "m" "c"
6351         test_newerXY_base "c" "a"
6352         test_newerXY_base "c" "m"
6353         test_newerXY_base "c" "c"
6354
6355         [[ -n "$sles_version" ]] &&
6356                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6357
6358         test_newerXY_base "a" "t"
6359         test_newerXY_base "m" "t"
6360         test_newerXY_base "c" "t"
6361
6362         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6363            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6364                 ! btime_supported && echo "btime unsupported" && return 0
6365
6366         test_newerXY_base "b" "b"
6367         test_newerXY_base "b" "t"
6368 }
6369 run_test 56oc "check lfs find -newerXY work"
6370
6371 btime_supported() {
6372         local dir=$DIR/$tdir
6373         local rc
6374
6375         mkdir -p $dir
6376         touch $dir/$tfile
6377         $LFS find $dir -btime -1d -type f
6378         rc=$?
6379         rm -rf $dir
6380         return $rc
6381 }
6382
6383 test_56od() {
6384         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6385                 ! btime_supported && skip "btime unsupported on MDS"
6386
6387         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6388                 ! btime_supported && skip "btime unsupported on clients"
6389
6390         local dir=$DIR/$tdir
6391         local ref=$DIR/$tfile.ref
6392         local negref=$DIR/$tfile.negref
6393
6394         mkdir $dir || error "mkdir $dir failed"
6395         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6396         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6397         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6398         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6399         touch $ref || error "touch $ref failed"
6400         # sleep 3 seconds at least
6401         sleep 3
6402
6403         local before=$(do_facet mds1 date +%s)
6404         local skew=$(($(date +%s) - before + 1))
6405
6406         if (( skew < 0 && skew > -5 )); then
6407                 sleep $((0 - skew + 1))
6408                 skew=0
6409         fi
6410
6411         # Set the dir stripe params to limit files all on MDT0,
6412         # otherwise we need to calc the max clock skew between
6413         # the client and MDTs.
6414         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6415         sleep 2
6416         touch $negref || error "touch $negref failed"
6417
6418         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6419         local nums=$($cmd | wc -l)
6420         local expected=$(((NUMFILES + 1) * NUMDIRS))
6421
6422         [ $nums -eq $expected ] ||
6423                 error "'$cmd' wrong: found $nums, expected $expected"
6424
6425         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6426         nums=$($cmd | wc -l)
6427         expected=$((NUMFILES + 1))
6428         [ $nums -eq $expected ] ||
6429                 error "'$cmd' wrong: found $nums, expected $expected"
6430
6431         [ $skew -lt 0 ] && return
6432
6433         local after=$(do_facet mds1 date +%s)
6434         local age=$((after - before + 1 + skew))
6435
6436         cmd="$LFS find $dir -btime -${age}s -type f"
6437         nums=$($cmd | wc -l)
6438         expected=$(((NUMFILES + 1) * NUMDIRS))
6439
6440         echo "Clock skew between client and server: $skew, age:$age"
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443
6444         expected=$(($NUMDIRS + 1))
6445         cmd="$LFS find $dir -btime -${age}s -type d"
6446         nums=$($cmd | wc -l)
6447         [ $nums -eq $expected ] ||
6448                 error "'$cmd' wrong: found $nums, expected $expected"
6449         rm -f $ref $negref || error "Failed to remove $ref $negref"
6450 }
6451 run_test 56od "check lfs find -btime with units"
6452
6453 test_56p() {
6454         [ $RUNAS_ID -eq $UID ] &&
6455                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6456
6457         local dir=$DIR/$tdir
6458
6459         setup_56 $dir $NUMFILES $NUMDIRS
6460         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6461
6462         local expected=$NUMFILES
6463         local cmd="$LFS find -uid $RUNAS_ID $dir"
6464         local nums=$($cmd | wc -l)
6465
6466         [ $nums -eq $expected ] ||
6467                 error "'$cmd' wrong: found $nums, expected $expected"
6468
6469         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6470         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6471         nums=$($cmd | wc -l)
6472         [ $nums -eq $expected ] ||
6473                 error "'$cmd' wrong: found $nums, expected $expected"
6474 }
6475 run_test 56p "check lfs find -uid and ! -uid"
6476
6477 test_56q() {
6478         [ $RUNAS_ID -eq $UID ] &&
6479                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6480
6481         local dir=$DIR/$tdir
6482
6483         setup_56 $dir $NUMFILES $NUMDIRS
6484         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6485
6486         local expected=$NUMFILES
6487         local cmd="$LFS find -gid $RUNAS_GID $dir"
6488         local nums=$($cmd | wc -l)
6489
6490         [ $nums -eq $expected ] ||
6491                 error "'$cmd' wrong: found $nums, expected $expected"
6492
6493         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6494         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6495         nums=$($cmd | wc -l)
6496         [ $nums -eq $expected ] ||
6497                 error "'$cmd' wrong: found $nums, expected $expected"
6498 }
6499 run_test 56q "check lfs find -gid and ! -gid"
6500
6501 test_56r() {
6502         local dir=$DIR/$tdir
6503
6504         setup_56 $dir $NUMFILES $NUMDIRS
6505
6506         local expected=12
6507         local cmd="$LFS find -size 0 -type f -lazy $dir"
6508         local nums=$($cmd | wc -l)
6509
6510         [ $nums -eq $expected ] ||
6511                 error "'$cmd' wrong: found $nums, expected $expected"
6512         cmd="$LFS find -size 0 -type f $dir"
6513         nums=$($cmd | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516
6517         expected=0
6518         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6519         nums=$($cmd | wc -l)
6520         [ $nums -eq $expected ] ||
6521                 error "'$cmd' wrong: found $nums, expected $expected"
6522         cmd="$LFS find ! -size 0 -type f $dir"
6523         nums=$($cmd | wc -l)
6524         [ $nums -eq $expected ] ||
6525                 error "'$cmd' wrong: found $nums, expected $expected"
6526
6527         echo "test" > $dir/$tfile
6528         echo "test2" > $dir/$tfile.2 && sync
6529         expected=1
6530         cmd="$LFS find -size 5 -type f -lazy $dir"
6531         nums=$($cmd | wc -l)
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534         cmd="$LFS find -size 5 -type f $dir"
6535         nums=$($cmd | wc -l)
6536         [ $nums -eq $expected ] ||
6537                 error "'$cmd' wrong: found $nums, expected $expected"
6538
6539         expected=1
6540         cmd="$LFS find -size +5 -type f -lazy $dir"
6541         nums=$($cmd | wc -l)
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544         cmd="$LFS find -size +5 -type f $dir"
6545         nums=$($cmd | wc -l)
6546         [ $nums -eq $expected ] ||
6547                 error "'$cmd' wrong: found $nums, expected $expected"
6548
6549         expected=2
6550         cmd="$LFS find -size +0 -type f -lazy $dir"
6551         nums=$($cmd | wc -l)
6552         [ $nums -eq $expected ] ||
6553                 error "'$cmd' wrong: found $nums, expected $expected"
6554         cmd="$LFS find -size +0 -type f $dir"
6555         nums=$($cmd | wc -l)
6556         [ $nums -eq $expected ] ||
6557                 error "'$cmd' wrong: found $nums, expected $expected"
6558
6559         expected=2
6560         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6561         nums=$($cmd | wc -l)
6562         [ $nums -eq $expected ] ||
6563                 error "'$cmd' wrong: found $nums, expected $expected"
6564         cmd="$LFS find ! -size -5 -type f $dir"
6565         nums=$($cmd | wc -l)
6566         [ $nums -eq $expected ] ||
6567                 error "'$cmd' wrong: found $nums, expected $expected"
6568
6569         expected=12
6570         cmd="$LFS find -size -5 -type f -lazy $dir"
6571         nums=$($cmd | wc -l)
6572         [ $nums -eq $expected ] ||
6573                 error "'$cmd' wrong: found $nums, expected $expected"
6574         cmd="$LFS find -size -5 -type f $dir"
6575         nums=$($cmd | wc -l)
6576         [ $nums -eq $expected ] ||
6577                 error "'$cmd' wrong: found $nums, expected $expected"
6578 }
6579 run_test 56r "check lfs find -size works"
6580
6581 test_56ra_sub() {
6582         local expected=$1
6583         local glimpses=$2
6584         local cmd="$3"
6585
6586         cancel_lru_locks $OSC
6587
6588         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6589         local nums=$($cmd | wc -l)
6590
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593
6594         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6595
6596         if (( rpcs_before + glimpses != rpcs_after )); then
6597                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6598                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6599
6600                 if [[ $glimpses == 0 ]]; then
6601                         error "'$cmd' should not send glimpse RPCs to OST"
6602                 else
6603                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6604                 fi
6605         fi
6606 }
6607
6608 test_56ra() {
6609         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6610                 skip "MDS < 2.12.58 doesn't return LSOM data"
6611         local dir=$DIR/$tdir
6612         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6613
6614         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6615
6616         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6617         $LCTL set_param -n llite.*.statahead_agl=0
6618         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6619
6620         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6621         # open and close all files to ensure LSOM is updated
6622         cancel_lru_locks $OSC
6623         find $dir -type f | xargs cat > /dev/null
6624
6625         #   expect_found  glimpse_rpcs  command_to_run
6626         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6627         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6628         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6629         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6630
6631         echo "test" > $dir/$tfile
6632         echo "test2" > $dir/$tfile.2 && sync
6633         cancel_lru_locks $OSC
6634         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6635
6636         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6637         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6638         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6639         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6640
6641         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6642         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6643         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6644         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6645         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6646         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6647 }
6648 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6649
6650 test_56rb() {
6651         local dir=$DIR/$tdir
6652         local tmp=$TMP/$tfile.log
6653         local mdt_idx;
6654
6655         test_mkdir -p $dir || error "failed to mkdir $dir"
6656         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6657                 error "failed to setstripe $dir/$tfile"
6658         mdt_idx=$($LFS getdirstripe -i $dir)
6659         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6660
6661         stack_trap "rm -f $tmp" EXIT
6662         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6663         ! grep -q obd_uuid $tmp ||
6664                 error "failed to find --size +100K --ost 0 $dir"
6665         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6666         ! grep -q obd_uuid $tmp ||
6667                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6668 }
6669 run_test 56rb "check lfs find --size --ost/--mdt works"
6670
6671 test_56rc() {
6672         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6673         local dir=$DIR/$tdir
6674         local found
6675
6676         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6677         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6678         (( $MDSCOUNT > 2 )) &&
6679                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6680         mkdir $dir/$tdir-{1..10}
6681         touch $dir/$tfile-{1..10}
6682
6683         found=$($LFS find $dir --mdt-count 2 | wc -l)
6684         expect=11
6685         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6686
6687         found=$($LFS find $dir -T +1 | wc -l)
6688         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6689         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6690
6691         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6692         expect=11
6693         (( $found == $expect )) || error "found $found all_char, expect $expect"
6694
6695         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6696         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6697         (( $found == $expect )) || error "found $found all_char, expect $expect"
6698 }
6699 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6700
6701 test_56s() { # LU-611 #LU-9369
6702         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6703
6704         local dir=$DIR/$tdir
6705         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6706
6707         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6708         for i in $(seq $NUMDIRS); do
6709                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6710         done
6711
6712         local expected=$NUMDIRS
6713         local cmd="$LFS find -c $OSTCOUNT $dir"
6714         local nums=$($cmd | wc -l)
6715
6716         [ $nums -eq $expected ] || {
6717                 $LFS getstripe -R $dir
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719         }
6720
6721         expected=$((NUMDIRS + onestripe))
6722         cmd="$LFS find -stripe-count +0 -type f $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] || {
6725                 $LFS getstripe -R $dir
6726                 error "'$cmd' wrong: found $nums, expected $expected"
6727         }
6728
6729         expected=$onestripe
6730         cmd="$LFS find -stripe-count 1 -type f $dir"
6731         nums=$($cmd | wc -l)
6732         [ $nums -eq $expected ] || {
6733                 $LFS getstripe -R $dir
6734                 error "'$cmd' wrong: found $nums, expected $expected"
6735         }
6736
6737         cmd="$LFS find -stripe-count -2 -type f $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] || {
6740                 $LFS getstripe -R $dir
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742         }
6743
6744         expected=0
6745         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6746         nums=$($cmd | wc -l)
6747         [ $nums -eq $expected ] || {
6748                 $LFS getstripe -R $dir
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750         }
6751 }
6752 run_test 56s "check lfs find -stripe-count works"
6753
6754 test_56t() { # LU-611 #LU-9369
6755         local dir=$DIR/$tdir
6756
6757         setup_56 $dir 0 $NUMDIRS
6758         for i in $(seq $NUMDIRS); do
6759                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6760         done
6761
6762         local expected=$NUMDIRS
6763         local cmd="$LFS find -S 8M $dir"
6764         local nums=$($cmd | wc -l)
6765
6766         [ $nums -eq $expected ] || {
6767                 $LFS getstripe -R $dir
6768                 error "'$cmd' wrong: found $nums, expected $expected"
6769         }
6770         rm -rf $dir
6771
6772         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6773
6774         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6775
6776         expected=$(((NUMDIRS + 1) * NUMFILES))
6777         cmd="$LFS find -stripe-size 512k -type f $dir"
6778         nums=$($cmd | wc -l)
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781
6782         cmd="$LFS find -stripe-size +320k -type f $dir"
6783         nums=$($cmd | wc -l)
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786
6787         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6788         cmd="$LFS find -stripe-size +200k -type f $dir"
6789         nums=$($cmd | wc -l)
6790         [ $nums -eq $expected ] ||
6791                 error "'$cmd' wrong: found $nums, expected $expected"
6792
6793         cmd="$LFS find -stripe-size -640k -type f $dir"
6794         nums=$($cmd | wc -l)
6795         [ $nums -eq $expected ] ||
6796                 error "'$cmd' wrong: found $nums, expected $expected"
6797
6798         expected=4
6799         cmd="$LFS find -stripe-size 256k -type f $dir"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803
6804         cmd="$LFS find -stripe-size -320k -type f $dir"
6805         nums=$($cmd | wc -l)
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808
6809         expected=0
6810         cmd="$LFS find -stripe-size 1024k -type f $dir"
6811         nums=$($cmd | wc -l)
6812         [ $nums -eq $expected ] ||
6813                 error "'$cmd' wrong: found $nums, expected $expected"
6814 }
6815 run_test 56t "check lfs find -stripe-size works"
6816
6817 test_56u() { # LU-611
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6821
6822         if [[ $OSTCOUNT -gt 1 ]]; then
6823                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6824                 onestripe=4
6825         else
6826                 onestripe=0
6827         fi
6828
6829         local expected=$(((NUMDIRS + 1) * NUMFILES))
6830         local cmd="$LFS find -stripe-index 0 -type f $dir"
6831         local nums=$($cmd | wc -l)
6832
6833         [ $nums -eq $expected ] ||
6834                 error "'$cmd' wrong: found $nums, expected $expected"
6835
6836         expected=$onestripe
6837         cmd="$LFS find -stripe-index 1 -type f $dir"
6838         nums=$($cmd | wc -l)
6839         [ $nums -eq $expected ] ||
6840                 error "'$cmd' wrong: found $nums, expected $expected"
6841
6842         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6843         nums=$($cmd | wc -l)
6844         [ $nums -eq $expected ] ||
6845                 error "'$cmd' wrong: found $nums, expected $expected"
6846
6847         expected=0
6848         # This should produce an error and not return any files
6849         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6850         nums=$($cmd 2>/dev/null | wc -l)
6851         [ $nums -eq $expected ] ||
6852                 error "'$cmd' wrong: found $nums, expected $expected"
6853
6854         if [[ $OSTCOUNT -gt 1 ]]; then
6855                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6856                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6857                 nums=$($cmd | wc -l)
6858                 [ $nums -eq $expected ] ||
6859                         error "'$cmd' wrong: found $nums, expected $expected"
6860         fi
6861 }
6862 run_test 56u "check lfs find -stripe-index works"
6863
6864 test_56v() {
6865         local mdt_idx=0
6866         local dir=$DIR/$tdir
6867
6868         setup_56 $dir $NUMFILES $NUMDIRS
6869
6870         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6871         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6872
6873         for file in $($LFS find -m $UUID $dir); do
6874                 file_midx=$($LFS getstripe -m $file)
6875                 [ $file_midx -eq $mdt_idx ] ||
6876                         error "lfs find -m $UUID != getstripe -m $file_midx"
6877         done
6878 }
6879 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6880
6881 test_56w() {
6882         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6884
6885         local dir=$DIR/$tdir
6886
6887         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6888
6889         local stripe_size=$($LFS getstripe -S -d $dir) ||
6890                 error "$LFS getstripe -S -d $dir failed"
6891         stripe_size=${stripe_size%% *}
6892
6893         local file_size=$((stripe_size * OSTCOUNT))
6894         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6895         local required_space=$((file_num * file_size))
6896         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6897                            head -n1)
6898         [[ $free_space -le $((required_space / 1024)) ]] &&
6899                 skip_env "need $required_space, have $free_space kbytes"
6900
6901         local dd_bs=65536
6902         local dd_count=$((file_size / dd_bs))
6903
6904         # write data into the files
6905         local i
6906         local j
6907         local file
6908
6909         for i in $(seq $NUMFILES); do
6910                 file=$dir/file$i
6911                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6912                         error "write data into $file failed"
6913         done
6914         for i in $(seq $NUMDIRS); do
6915                 for j in $(seq $NUMFILES); do
6916                         file=$dir/dir$i/file$j
6917                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6918                                 error "write data into $file failed"
6919                 done
6920         done
6921
6922         # $LFS_MIGRATE will fail if hard link migration is unsupported
6923         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6924                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6925                         error "creating links to $dir/dir1/file1 failed"
6926         fi
6927
6928         local expected=-1
6929
6930         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6931
6932         # lfs_migrate file
6933         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6934
6935         echo "$cmd"
6936         eval $cmd || error "$cmd failed"
6937
6938         check_stripe_count $dir/file1 $expected
6939
6940         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6941         then
6942                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6943                 # OST 1 if it is on OST 0. This file is small enough to
6944                 # be on only one stripe.
6945                 file=$dir/migr_1_ost
6946                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6947                         error "write data into $file failed"
6948                 local obdidx=$($LFS getstripe -i $file)
6949                 local oldmd5=$(md5sum $file)
6950                 local newobdidx=0
6951
6952                 [[ $obdidx -eq 0 ]] && newobdidx=1
6953                 cmd="$LFS migrate -i $newobdidx $file"
6954                 echo $cmd
6955                 eval $cmd || error "$cmd failed"
6956
6957                 local realobdix=$($LFS getstripe -i $file)
6958                 local newmd5=$(md5sum $file)
6959
6960                 [[ $newobdidx -ne $realobdix ]] &&
6961                         error "new OST is different (was=$obdidx, "\
6962                               "wanted=$newobdidx, got=$realobdix)"
6963                 [[ "$oldmd5" != "$newmd5" ]] &&
6964                         error "md5sum differ: $oldmd5, $newmd5"
6965         fi
6966
6967         # lfs_migrate dir
6968         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6969         echo "$cmd"
6970         eval $cmd || error "$cmd failed"
6971
6972         for j in $(seq $NUMFILES); do
6973                 check_stripe_count $dir/dir1/file$j $expected
6974         done
6975
6976         # lfs_migrate works with lfs find
6977         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6978              $LFS_MIGRATE -y -c $expected"
6979         echo "$cmd"
6980         eval $cmd || error "$cmd failed"
6981
6982         for i in $(seq 2 $NUMFILES); do
6983                 check_stripe_count $dir/file$i $expected
6984         done
6985         for i in $(seq 2 $NUMDIRS); do
6986                 for j in $(seq $NUMFILES); do
6987                 check_stripe_count $dir/dir$i/file$j $expected
6988                 done
6989         done
6990 }
6991 run_test 56w "check lfs_migrate -c stripe_count works"
6992
6993 test_56wb() {
6994         local file1=$DIR/$tdir/file1
6995         local create_pool=false
6996         local initial_pool=$($LFS getstripe -p $DIR)
6997         local pool_list=()
6998         local pool=""
6999
7000         echo -n "Creating test dir..."
7001         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7002         echo "done."
7003
7004         echo -n "Creating test file..."
7005         touch $file1 || error "cannot create file"
7006         echo "done."
7007
7008         echo -n "Detecting existing pools..."
7009         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7010
7011         if [ ${#pool_list[@]} -gt 0 ]; then
7012                 echo "${pool_list[@]}"
7013                 for thispool in "${pool_list[@]}"; do
7014                         if [[ -z "$initial_pool" ||
7015                               "$initial_pool" != "$thispool" ]]; then
7016                                 pool="$thispool"
7017                                 echo "Using existing pool '$pool'"
7018                                 break
7019                         fi
7020                 done
7021         else
7022                 echo "none detected."
7023         fi
7024         if [ -z "$pool" ]; then
7025                 pool=${POOL:-testpool}
7026                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7027                 echo -n "Creating pool '$pool'..."
7028                 create_pool=true
7029                 pool_add $pool &> /dev/null ||
7030                         error "pool_add failed"
7031                 echo "done."
7032
7033                 echo -n "Adding target to pool..."
7034                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7035                         error "pool_add_targets failed"
7036                 echo "done."
7037         fi
7038
7039         echo -n "Setting pool using -p option..."
7040         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7041                 error "migrate failed rc = $?"
7042         echo "done."
7043
7044         echo -n "Verifying test file is in pool after migrating..."
7045         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7046                 error "file was not migrated to pool $pool"
7047         echo "done."
7048
7049         echo -n "Removing test file from pool '$pool'..."
7050         # "lfs migrate $file" won't remove the file from the pool
7051         # until some striping information is changed.
7052         $LFS migrate -c 1 $file1 &> /dev/null ||
7053                 error "cannot remove from pool"
7054         [ "$($LFS getstripe -p $file1)" ] &&
7055                 error "pool still set"
7056         echo "done."
7057
7058         echo -n "Setting pool using --pool option..."
7059         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7060                 error "migrate failed rc = $?"
7061         echo "done."
7062
7063         # Clean up
7064         rm -f $file1
7065         if $create_pool; then
7066                 destroy_test_pools 2> /dev/null ||
7067                         error "destroy test pools failed"
7068         fi
7069 }
7070 run_test 56wb "check lfs_migrate pool support"
7071
7072 test_56wc() {
7073         local file1="$DIR/$tdir/file1"
7074         local parent_ssize
7075         local parent_scount
7076         local cur_ssize
7077         local cur_scount
7078         local orig_ssize
7079
7080         echo -n "Creating test dir..."
7081         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7082         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7083                 error "cannot set stripe by '-S 1M -c 1'"
7084         echo "done"
7085
7086         echo -n "Setting initial stripe for test file..."
7087         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7088                 error "cannot set stripe"
7089         cur_ssize=$($LFS getstripe -S "$file1")
7090         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7091         echo "done."
7092
7093         # File currently set to -S 512K -c 1
7094
7095         # Ensure -c and -S options are rejected when -R is set
7096         echo -n "Verifying incompatible options are detected..."
7097         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7098                 error "incompatible -c and -R options not detected"
7099         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7100                 error "incompatible -S and -R options not detected"
7101         echo "done."
7102
7103         # Ensure unrecognized options are passed through to 'lfs migrate'
7104         echo -n "Verifying -S option is passed through to lfs migrate..."
7105         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7106                 error "migration failed"
7107         cur_ssize=$($LFS getstripe -S "$file1")
7108         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7109         echo "done."
7110
7111         # File currently set to -S 1M -c 1
7112
7113         # Ensure long options are supported
7114         echo -n "Verifying long options supported..."
7115         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7116                 error "long option without argument not supported"
7117         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7118                 error "long option with argument not supported"
7119         cur_ssize=$($LFS getstripe -S "$file1")
7120         [ $cur_ssize -eq 524288 ] ||
7121                 error "migrate --stripe-size $cur_ssize != 524288"
7122         echo "done."
7123
7124         # File currently set to -S 512K -c 1
7125
7126         if [ "$OSTCOUNT" -gt 1 ]; then
7127                 echo -n "Verifying explicit stripe count can be set..."
7128                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7129                         error "migrate failed"
7130                 cur_scount=$($LFS getstripe -c "$file1")
7131                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7132                 echo "done."
7133         fi
7134
7135         # File currently set to -S 512K -c 1 or -S 512K -c 2
7136
7137         # Ensure parent striping is used if -R is set, and no stripe
7138         # count or size is specified
7139         echo -n "Setting stripe for parent directory..."
7140         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7141                 error "cannot set stripe '-S 2M -c 1'"
7142         echo "done."
7143
7144         echo -n "Verifying restripe option uses parent stripe settings..."
7145         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7146         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7147         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7148                 error "migrate failed"
7149         cur_ssize=$($LFS getstripe -S "$file1")
7150         [ $cur_ssize -eq $parent_ssize ] ||
7151                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7152         cur_scount=$($LFS getstripe -c "$file1")
7153         [ $cur_scount -eq $parent_scount ] ||
7154                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7155         echo "done."
7156
7157         # File currently set to -S 1M -c 1
7158
7159         # Ensure striping is preserved if -R is not set, and no stripe
7160         # count or size is specified
7161         echo -n "Verifying striping size preserved when not specified..."
7162         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7163         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7164                 error "cannot set stripe on parent directory"
7165         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7166                 error "migrate failed"
7167         cur_ssize=$($LFS getstripe -S "$file1")
7168         [ $cur_ssize -eq $orig_ssize ] ||
7169                 error "migrate by default $cur_ssize != $orig_ssize"
7170         echo "done."
7171
7172         # Ensure file name properly detected when final option has no argument
7173         echo -n "Verifying file name properly detected..."
7174         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7175                 error "file name interpreted as option argument"
7176         echo "done."
7177
7178         # Clean up
7179         rm -f "$file1"
7180 }
7181 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7182
7183 test_56wd() {
7184         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7185
7186         local file1=$DIR/$tdir/file1
7187
7188         echo -n "Creating test dir..."
7189         test_mkdir $DIR/$tdir || error "cannot create dir"
7190         echo "done."
7191
7192         echo -n "Creating test file..."
7193         touch $file1
7194         echo "done."
7195
7196         # Ensure 'lfs migrate' will fail by using a non-existent option,
7197         # and make sure rsync is not called to recover
7198         echo -n "Make sure --no-rsync option works..."
7199         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7200                 grep -q 'refusing to fall back to rsync' ||
7201                 error "rsync was called with --no-rsync set"
7202         echo "done."
7203
7204         # Ensure rsync is called without trying 'lfs migrate' first
7205         echo -n "Make sure --rsync option works..."
7206         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7207                 grep -q 'falling back to rsync' &&
7208                 error "lfs migrate was called with --rsync set"
7209         echo "done."
7210
7211         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7212         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7213                 grep -q 'at the same time' ||
7214                 error "--rsync and --no-rsync accepted concurrently"
7215         echo "done."
7216
7217         # Clean up
7218         rm -f $file1
7219 }
7220 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7221
7222 test_56we() {
7223         local td=$DIR/$tdir
7224         local tf=$td/$tfile
7225
7226         test_mkdir $td || error "cannot create $td"
7227         touch $tf || error "cannot touch $tf"
7228
7229         echo -n "Make sure --non-direct|-D works..."
7230         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7231                 grep -q "lfs migrate --non-direct" ||
7232                 error "--non-direct option cannot work correctly"
7233         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7234                 grep -q "lfs migrate -D" ||
7235                 error "-D option cannot work correctly"
7236         echo "done."
7237 }
7238 run_test 56we "check lfs_migrate --non-direct|-D support"
7239
7240 test_56x() {
7241         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7242         check_swap_layouts_support
7243
7244         local dir=$DIR/$tdir
7245         local ref1=/etc/passwd
7246         local file1=$dir/file1
7247
7248         test_mkdir $dir || error "creating dir $dir"
7249         $LFS setstripe -c 2 $file1
7250         cp $ref1 $file1
7251         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7252         stripe=$($LFS getstripe -c $file1)
7253         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7254         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7255
7256         # clean up
7257         rm -f $file1
7258 }
7259 run_test 56x "lfs migration support"
7260
7261 test_56xa() {
7262         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7263         check_swap_layouts_support
7264
7265         local dir=$DIR/$tdir/$testnum
7266
7267         test_mkdir -p $dir
7268
7269         local ref1=/etc/passwd
7270         local file1=$dir/file1
7271
7272         $LFS setstripe -c 2 $file1
7273         cp $ref1 $file1
7274         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7275
7276         local stripe=$($LFS getstripe -c $file1)
7277
7278         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7279         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7280
7281         # clean up
7282         rm -f $file1
7283 }
7284 run_test 56xa "lfs migration --block support"
7285
7286 check_migrate_links() {
7287         local dir="$1"
7288         local file1="$dir/file1"
7289         local begin="$2"
7290         local count="$3"
7291         local runas="$4"
7292         local total_count=$(($begin + $count - 1))
7293         local symlink_count=10
7294         local uniq_count=10
7295
7296         if [ ! -f "$file1" ]; then
7297                 echo -n "creating initial file..."
7298                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7299                         error "cannot setstripe initial file"
7300                 echo "done"
7301
7302                 echo -n "creating symlinks..."
7303                 for s in $(seq 1 $symlink_count); do
7304                         ln -s "$file1" "$dir/slink$s" ||
7305                                 error "cannot create symlinks"
7306                 done
7307                 echo "done"
7308
7309                 echo -n "creating nonlinked files..."
7310                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7311                         error "cannot create nonlinked files"
7312                 echo "done"
7313         fi
7314
7315         # create hard links
7316         if [ ! -f "$dir/file$total_count" ]; then
7317                 echo -n "creating hard links $begin:$total_count..."
7318                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7319                         /dev/null || error "cannot create hard links"
7320                 echo "done"
7321         fi
7322
7323         echo -n "checking number of hard links listed in xattrs..."
7324         local fid=$($LFS getstripe -F "$file1")
7325         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7326
7327         echo "${#paths[*]}"
7328         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7329                         skip "hard link list has unexpected size, skipping test"
7330         fi
7331         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7332                         error "link names should exceed xattrs size"
7333         fi
7334
7335         echo -n "migrating files..."
7336         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7337         local rc=$?
7338         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7339         echo "done"
7340
7341         # make sure all links have been properly migrated
7342         echo -n "verifying files..."
7343         fid=$($LFS getstripe -F "$file1") ||
7344                 error "cannot get fid for file $file1"
7345         for i in $(seq 2 $total_count); do
7346                 local fid2=$($LFS getstripe -F $dir/file$i)
7347
7348                 [ "$fid2" == "$fid" ] ||
7349                         error "migrated hard link has mismatched FID"
7350         done
7351
7352         # make sure hard links were properly detected, and migration was
7353         # performed only once for the entire link set; nonlinked files should
7354         # also be migrated
7355         local actual=$(grep -c 'done' <<< "$migrate_out")
7356         local expected=$(($uniq_count + 1))
7357
7358         [ "$actual" -eq  "$expected" ] ||
7359                 error "hard links individually migrated ($actual != $expected)"
7360
7361         # make sure the correct number of hard links are present
7362         local hardlinks=$(stat -c '%h' "$file1")
7363
7364         [ $hardlinks -eq $total_count ] ||
7365                 error "num hard links $hardlinks != $total_count"
7366         echo "done"
7367
7368         return 0
7369 }
7370
7371 test_56xb() {
7372         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7373                 skip "Need MDS version at least 2.10.55"
7374
7375         local dir="$DIR/$tdir"
7376
7377         test_mkdir "$dir" || error "cannot create dir $dir"
7378
7379         echo "testing lfs migrate mode when all links fit within xattrs"
7380         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7381
7382         echo "testing rsync mode when all links fit within xattrs"
7383         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7384
7385         echo "testing lfs migrate mode when all links do not fit within xattrs"
7386         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7387
7388         echo "testing rsync mode when all links do not fit within xattrs"
7389         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7390
7391         chown -R $RUNAS_ID $dir
7392         echo "testing non-root lfs migrate mode when not all links are in xattr"
7393         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7394
7395         # clean up
7396         rm -rf $dir
7397 }
7398 run_test 56xb "lfs migration hard link support"
7399
7400 test_56xc() {
7401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7402
7403         local dir="$DIR/$tdir"
7404
7405         test_mkdir "$dir" || error "cannot create dir $dir"
7406
7407         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7408         echo -n "Setting initial stripe for 20MB test file..."
7409         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7410                 error "cannot setstripe 20MB file"
7411         echo "done"
7412         echo -n "Sizing 20MB test file..."
7413         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7414         echo "done"
7415         echo -n "Verifying small file autostripe count is 1..."
7416         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7417                 error "cannot migrate 20MB file"
7418         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7419                 error "cannot get stripe for $dir/20mb"
7420         [ $stripe_count -eq 1 ] ||
7421                 error "unexpected stripe count $stripe_count for 20MB file"
7422         rm -f "$dir/20mb"
7423         echo "done"
7424
7425         # Test 2: File is small enough to fit within the available space on
7426         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7427         # have at least an additional 1KB for each desired stripe for test 3
7428         echo -n "Setting stripe for 1GB test file..."
7429         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7430         echo "done"
7431         echo -n "Sizing 1GB test file..."
7432         # File size is 1GB + 3KB
7433         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7434         echo "done"
7435
7436         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7437         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7438         if (( avail > 524288 * OSTCOUNT )); then
7439                 echo -n "Migrating 1GB file..."
7440                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7441                         error "cannot migrate 1GB file"
7442                 echo "done"
7443                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7444                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7445                         error "cannot getstripe for 1GB file"
7446                 [ $stripe_count -eq 2 ] ||
7447                         error "unexpected stripe count $stripe_count != 2"
7448                 echo "done"
7449         fi
7450
7451         # Test 3: File is too large to fit within the available space on
7452         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7453         if [ $OSTCOUNT -ge 3 ]; then
7454                 # The required available space is calculated as
7455                 # file size (1GB + 3KB) / OST count (3).
7456                 local kb_per_ost=349526
7457
7458                 echo -n "Migrating 1GB file with limit..."
7459                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7460                         error "cannot migrate 1GB file with limit"
7461                 echo "done"
7462
7463                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7464                 echo -n "Verifying 1GB autostripe count with limited space..."
7465                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7466                         error "unexpected stripe count $stripe_count (min 3)"
7467                 echo "done"
7468         fi
7469
7470         # clean up
7471         rm -rf $dir
7472 }
7473 run_test 56xc "lfs migration autostripe"
7474
7475 test_56xd() {
7476         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7477
7478         local dir=$DIR/$tdir
7479         local f_mgrt=$dir/$tfile.mgrt
7480         local f_yaml=$dir/$tfile.yaml
7481         local f_copy=$dir/$tfile.copy
7482         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7483         local layout_copy="-c 2 -S 2M -i 1"
7484         local yamlfile=$dir/yamlfile
7485         local layout_before;
7486         local layout_after;
7487
7488         test_mkdir "$dir" || error "cannot create dir $dir"
7489         $LFS setstripe $layout_yaml $f_yaml ||
7490                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7491         $LFS getstripe --yaml $f_yaml > $yamlfile
7492         $LFS setstripe $layout_copy $f_copy ||
7493                 error "cannot setstripe $f_copy with layout $layout_copy"
7494         touch $f_mgrt
7495         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7496
7497         # 1. test option --yaml
7498         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7499                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7500         layout_before=$(get_layout_param $f_yaml)
7501         layout_after=$(get_layout_param $f_mgrt)
7502         [ "$layout_after" == "$layout_before" ] ||
7503                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7504
7505         # 2. test option --copy
7506         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7507                 error "cannot migrate $f_mgrt with --copy $f_copy"
7508         layout_before=$(get_layout_param $f_copy)
7509         layout_after=$(get_layout_param $f_mgrt)
7510         [ "$layout_after" == "$layout_before" ] ||
7511                 error "lfs_migrate --copy: $layout_after != $layout_before"
7512 }
7513 run_test 56xd "check lfs_migrate --yaml and --copy support"
7514
7515 test_56xe() {
7516         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7517
7518         local dir=$DIR/$tdir
7519         local f_comp=$dir/$tfile
7520         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7521         local layout_before=""
7522         local layout_after=""
7523
7524         test_mkdir "$dir" || error "cannot create dir $dir"
7525         $LFS setstripe $layout $f_comp ||
7526                 error "cannot setstripe $f_comp with layout $layout"
7527         layout_before=$(get_layout_param $f_comp)
7528         dd if=/dev/zero of=$f_comp bs=1M count=4
7529
7530         # 1. migrate a comp layout file by lfs_migrate
7531         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7532         layout_after=$(get_layout_param $f_comp)
7533         [ "$layout_before" == "$layout_after" ] ||
7534                 error "lfs_migrate: $layout_before != $layout_after"
7535
7536         # 2. migrate a comp layout file by lfs migrate
7537         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7538         layout_after=$(get_layout_param $f_comp)
7539         [ "$layout_before" == "$layout_after" ] ||
7540                 error "lfs migrate: $layout_before != $layout_after"
7541 }
7542 run_test 56xe "migrate a composite layout file"
7543
7544 test_56xf() {
7545         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7546
7547         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7548                 skip "Need server version at least 2.13.53"
7549
7550         local dir=$DIR/$tdir
7551         local f_comp=$dir/$tfile
7552         local layout="-E 1M -c1 -E -1 -c2"
7553         local fid_before=""
7554         local fid_after=""
7555
7556         test_mkdir "$dir" || error "cannot create dir $dir"
7557         $LFS setstripe $layout $f_comp ||
7558                 error "cannot setstripe $f_comp with layout $layout"
7559         fid_before=$($LFS getstripe --fid $f_comp)
7560         dd if=/dev/zero of=$f_comp bs=1M count=4
7561
7562         # 1. migrate a comp layout file to a comp layout
7563         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7564         fid_after=$($LFS getstripe --fid $f_comp)
7565         [ "$fid_before" == "$fid_after" ] ||
7566                 error "comp-to-comp migrate: $fid_before != $fid_after"
7567
7568         # 2. migrate a comp layout file to a plain layout
7569         $LFS migrate -c2 $f_comp ||
7570                 error "cannot migrate $f_comp by lfs migrate"
7571         fid_after=$($LFS getstripe --fid $f_comp)
7572         [ "$fid_before" == "$fid_after" ] ||
7573                 error "comp-to-plain migrate: $fid_before != $fid_after"
7574
7575         # 3. migrate a plain layout file to a comp layout
7576         $LFS migrate $layout $f_comp ||
7577                 error "cannot migrate $f_comp by lfs migrate"
7578         fid_after=$($LFS getstripe --fid $f_comp)
7579         [ "$fid_before" == "$fid_after" ] ||
7580                 error "plain-to-comp migrate: $fid_before != $fid_after"
7581 }
7582 run_test 56xf "FID is not lost during migration of a composite layout file"
7583
7584 test_56y() {
7585         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7586                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7587
7588         local res=""
7589         local dir=$DIR/$tdir
7590         local f1=$dir/file1
7591         local f2=$dir/file2
7592
7593         test_mkdir -p $dir || error "creating dir $dir"
7594         touch $f1 || error "creating std file $f1"
7595         $MULTIOP $f2 H2c || error "creating released file $f2"
7596
7597         # a directory can be raid0, so ask only for files
7598         res=$($LFS find $dir -L raid0 -type f | wc -l)
7599         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7600
7601         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7602         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7603
7604         # only files can be released, so no need to force file search
7605         res=$($LFS find $dir -L released)
7606         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7607
7608         res=$($LFS find $dir -type f \! -L released)
7609         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7610 }
7611 run_test 56y "lfs find -L raid0|released"
7612
7613 test_56z() { # LU-4824
7614         # This checks to make sure 'lfs find' continues after errors
7615         # There are two classes of errors that should be caught:
7616         # - If multiple paths are provided, all should be searched even if one
7617         #   errors out
7618         # - If errors are encountered during the search, it should not terminate
7619         #   early
7620         local dir=$DIR/$tdir
7621         local i
7622
7623         test_mkdir $dir
7624         for i in d{0..9}; do
7625                 test_mkdir $dir/$i
7626                 touch $dir/$i/$tfile
7627         done
7628         $LFS find $DIR/non_existent_dir $dir &&
7629                 error "$LFS find did not return an error"
7630         # Make a directory unsearchable. This should NOT be the last entry in
7631         # directory order.  Arbitrarily pick the 6th entry
7632         chmod 700 $($LFS find $dir -type d | sed '6!d')
7633
7634         $RUNAS $LFS find $DIR/non_existent $dir
7635         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7636
7637         # The user should be able to see 10 directories and 9 files
7638         (( count == 19 )) ||
7639                 error "$LFS find found $count != 19 entries after error"
7640 }
7641 run_test 56z "lfs find should continue after an error"
7642
7643 test_56aa() { # LU-5937
7644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7645
7646         local dir=$DIR/$tdir
7647
7648         mkdir $dir
7649         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7650
7651         createmany -o $dir/striped_dir/${tfile}- 1024
7652         local dirs=$($LFS find --size +8k $dir/)
7653
7654         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7655 }
7656 run_test 56aa "lfs find --size under striped dir"
7657
7658 test_56ab() { # LU-10705
7659         test_mkdir $DIR/$tdir
7660         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7661         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7662         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7663         # Flush writes to ensure valid blocks.  Need to be more thorough for
7664         # ZFS, since blocks are not allocated/returned to client immediately.
7665         sync_all_data
7666         wait_zfs_commit ost1 2
7667         cancel_lru_locks osc
7668         ls -ls $DIR/$tdir
7669
7670         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7671
7672         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7673
7674         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7675         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7676
7677         rm -f $DIR/$tdir/$tfile.[123]
7678 }
7679 run_test 56ab "lfs find --blocks"
7680
7681 # LU-11188
7682 test_56aca() {
7683         local dir="$DIR/$tdir"
7684         local perms=(001 002 003 004 005 006 007
7685                      010 020 030 040 050 060 070
7686                      100 200 300 400 500 600 700
7687                      111 222 333 444 555 666 777)
7688         local perm_minus=(8 8 4 8 4 4 2
7689                           8 8 4 8 4 4 2
7690                           8 8 4 8 4 4 2
7691                           4 4 2 4 2 2 1)
7692         local perm_slash=(8  8 12  8 12 12 14
7693                           8  8 12  8 12 12 14
7694                           8  8 12  8 12 12 14
7695                          16 16 24 16 24 24 28)
7696
7697         test_mkdir "$dir"
7698         for perm in ${perms[*]}; do
7699                 touch "$dir/$tfile.$perm"
7700                 chmod $perm "$dir/$tfile.$perm"
7701         done
7702
7703         for ((i = 0; i < ${#perms[*]}; i++)); do
7704                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7705                 (( $num == 1 )) ||
7706                         error "lfs find -perm ${perms[i]}:"\
7707                               "$num != 1"
7708
7709                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7710                 (( $num == ${perm_minus[i]} )) ||
7711                         error "lfs find -perm -${perms[i]}:"\
7712                               "$num != ${perm_minus[i]}"
7713
7714                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7715                 (( $num == ${perm_slash[i]} )) ||
7716                         error "lfs find -perm /${perms[i]}:"\
7717                               "$num != ${perm_slash[i]}"
7718         done
7719 }
7720 run_test 56aca "check lfs find -perm with octal representation"
7721
7722 test_56acb() {
7723         local dir=$DIR/$tdir
7724         # p is the permission of write and execute for user, group and other
7725         # without the umask. It is used to test +wx.
7726         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7727         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7728         local symbolic=(+t  a+t u+t g+t o+t
7729                         g+s u+s o+s +s o+sr
7730                         o=r,ug+o,u+w
7731                         u+ g+ o+ a+ ugo+
7732                         u- g- o- a- ugo-
7733                         u= g= o= a= ugo=
7734                         o=r,ug+o,u+w u=r,a+u,u+w
7735                         g=r,ugo=g,u+w u+x,+X +X
7736                         u+x,u+X u+X u+x,g+X o+r,+X
7737                         u+x,go+X +wx +rwx)
7738
7739         test_mkdir $dir
7740         for perm in ${perms[*]}; do
7741                 touch "$dir/$tfile.$perm"
7742                 chmod $perm "$dir/$tfile.$perm"
7743         done
7744
7745         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7746                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7747
7748                 (( $num == 1 )) ||
7749                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7750         done
7751 }
7752 run_test 56acb "check lfs find -perm with symbolic representation"
7753
7754 test_56acc() {
7755         local dir=$DIR/$tdir
7756         local tests="17777 787 789 abcd
7757                 ug=uu ug=a ug=gu uo=ou urw
7758                 u+xg+x a=r,u+x,"
7759
7760         test_mkdir $dir
7761         for err in $tests; do
7762                 if $LFS find $dir -perm $err 2>/dev/null; then
7763                         error "lfs find -perm $err: parsing should have failed"
7764                 fi
7765         done
7766 }
7767 run_test 56acc "check parsing error for lfs find -perm"
7768
7769 test_56ba() {
7770         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7771                 skip "Need MDS version at least 2.10.50"
7772
7773         # Create composite files with one component
7774         local dir=$DIR/$tdir
7775
7776         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7777         # Create composite files with three components
7778         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7779         # Create non-composite files
7780         createmany -o $dir/${tfile}- 10
7781
7782         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7783
7784         [[ $nfiles == 10 ]] ||
7785                 error "lfs find -E 1M found $nfiles != 10 files"
7786
7787         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7788         [[ $nfiles == 25 ]] ||
7789                 error "lfs find ! -E 1M found $nfiles != 25 files"
7790
7791         # All files have a component that starts at 0
7792         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7793         [[ $nfiles == 35 ]] ||
7794                 error "lfs find --component-start 0 - $nfiles != 35 files"
7795
7796         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7797         [[ $nfiles == 15 ]] ||
7798                 error "lfs find --component-start 2M - $nfiles != 15 files"
7799
7800         # All files created here have a componenet that does not starts at 2M
7801         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7802         [[ $nfiles == 35 ]] ||
7803                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7804
7805         # Find files with a specified number of components
7806         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7807         [[ $nfiles == 15 ]] ||
7808                 error "lfs find --component-count 3 - $nfiles != 15 files"
7809
7810         # Remember non-composite files have a component count of zero
7811         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7812         [[ $nfiles == 10 ]] ||
7813                 error "lfs find --component-count 0 - $nfiles != 10 files"
7814
7815         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7816         [[ $nfiles == 20 ]] ||
7817                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7818
7819         # All files have a flag called "init"
7820         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7821         [[ $nfiles == 35 ]] ||
7822                 error "lfs find --component-flags init - $nfiles != 35 files"
7823
7824         # Multi-component files will have a component not initialized
7825         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7826         [[ $nfiles == 15 ]] ||
7827                 error "lfs find !--component-flags init - $nfiles != 15 files"
7828
7829         rm -rf $dir
7830
7831 }
7832 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7833
7834 test_56ca() {
7835         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7836                 skip "Need MDS version at least 2.10.57"
7837
7838         local td=$DIR/$tdir
7839         local tf=$td/$tfile
7840         local dir
7841         local nfiles
7842         local cmd
7843         local i
7844         local j
7845
7846         # create mirrored directories and mirrored files
7847         mkdir $td || error "mkdir $td failed"
7848         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7849         createmany -o $tf- 10 || error "create $tf- failed"
7850
7851         for i in $(seq 2); do
7852                 dir=$td/dir$i
7853                 mkdir $dir || error "mkdir $dir failed"
7854                 $LFS mirror create -N$((3 + i)) $dir ||
7855                         error "create mirrored dir $dir failed"
7856                 createmany -o $dir/$tfile- 10 ||
7857                         error "create $dir/$tfile- failed"
7858         done
7859
7860         # change the states of some mirrored files
7861         echo foo > $tf-6
7862         for i in $(seq 2); do
7863                 dir=$td/dir$i
7864                 for j in $(seq 4 9); do
7865                         echo foo > $dir/$tfile-$j
7866                 done
7867         done
7868
7869         # find mirrored files with specific mirror count
7870         cmd="$LFS find --mirror-count 3 --type f $td"
7871         nfiles=$($cmd | wc -l)
7872         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7873
7874         cmd="$LFS find ! --mirror-count 3 --type f $td"
7875         nfiles=$($cmd | wc -l)
7876         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7877
7878         cmd="$LFS find --mirror-count +2 --type f $td"
7879         nfiles=$($cmd | wc -l)
7880         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7881
7882         cmd="$LFS find --mirror-count -6 --type f $td"
7883         nfiles=$($cmd | wc -l)
7884         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7885
7886         # find mirrored files with specific file state
7887         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7888         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7889
7890         cmd="$LFS find --mirror-state=ro --type f $td"
7891         nfiles=$($cmd | wc -l)
7892         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7893
7894         cmd="$LFS find ! --mirror-state=ro --type f $td"
7895         nfiles=$($cmd | wc -l)
7896         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7897
7898         cmd="$LFS find --mirror-state=wp --type f $td"
7899         nfiles=$($cmd | wc -l)
7900         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7901
7902         cmd="$LFS find ! --mirror-state=sp --type f $td"
7903         nfiles=$($cmd | wc -l)
7904         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7905 }
7906 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7907
7908 test_56da() { # LU-14179
7909         local path=$DIR/$tdir
7910
7911         test_mkdir $path
7912         cd $path
7913
7914         local longdir=$(str_repeat 'a' 255)
7915
7916         for i in {1..15}; do
7917                 path=$path/$longdir
7918                 test_mkdir $longdir
7919                 cd $longdir
7920         done
7921
7922         local len=${#path}
7923         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7924
7925         test_mkdir $lastdir
7926         cd $lastdir
7927         # PATH_MAX-1
7928         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7929
7930         # NAME_MAX
7931         touch $(str_repeat 'f' 255)
7932
7933         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7934                 error "lfs find reported an error"
7935
7936         rm -rf $DIR/$tdir
7937 }
7938 run_test 56da "test lfs find with long paths"
7939
7940 test_57a() {
7941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7942         # note test will not do anything if MDS is not local
7943         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7944                 skip_env "ldiskfs only test"
7945         fi
7946         remote_mds_nodsh && skip "remote MDS with nodsh"
7947
7948         local MNTDEV="osd*.*MDT*.mntdev"
7949         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7950         [ -z "$DEV" ] && error "can't access $MNTDEV"
7951         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7952                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7953                         error "can't access $DEV"
7954                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7955                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7956                 rm $TMP/t57a.dump
7957         done
7958 }
7959 run_test 57a "verify MDS filesystem created with large inodes =="
7960
7961 test_57b() {
7962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7963         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7964                 skip_env "ldiskfs only test"
7965         fi
7966         remote_mds_nodsh && skip "remote MDS with nodsh"
7967
7968         local dir=$DIR/$tdir
7969         local filecount=100
7970         local file1=$dir/f1
7971         local fileN=$dir/f$filecount
7972
7973         rm -rf $dir || error "removing $dir"
7974         test_mkdir -c1 $dir
7975         local mdtidx=$($LFS getstripe -m $dir)
7976         local mdtname=MDT$(printf %04x $mdtidx)
7977         local facet=mds$((mdtidx + 1))
7978
7979         echo "mcreating $filecount files"
7980         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7981
7982         # verify that files do not have EAs yet
7983         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7984                 error "$file1 has an EA"
7985         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7986                 error "$fileN has an EA"
7987
7988         sync
7989         sleep 1
7990         df $dir  #make sure we get new statfs data
7991         local mdsfree=$(do_facet $facet \
7992                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7993         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7994         local file
7995
7996         echo "opening files to create objects/EAs"
7997         for file in $(seq -f $dir/f%g 1 $filecount); do
7998                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7999                         error "opening $file"
8000         done
8001
8002         # verify that files have EAs now
8003         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8004         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8005
8006         sleep 1  #make sure we get new statfs data
8007         df $dir
8008         local mdsfree2=$(do_facet $facet \
8009                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8010         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8011
8012         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8013                 if [ "$mdsfree" != "$mdsfree2" ]; then
8014                         error "MDC before $mdcfree != after $mdcfree2"
8015                 else
8016                         echo "MDC before $mdcfree != after $mdcfree2"
8017                         echo "unable to confirm if MDS has large inodes"
8018                 fi
8019         fi
8020         rm -rf $dir
8021 }
8022 run_test 57b "default LOV EAs are stored inside large inodes ==="
8023
8024 test_58() {
8025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8026         [ -z "$(which wiretest 2>/dev/null)" ] &&
8027                         skip_env "could not find wiretest"
8028
8029         wiretest
8030 }
8031 run_test 58 "verify cross-platform wire constants =============="
8032
8033 test_59() {
8034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8035
8036         echo "touch 130 files"
8037         createmany -o $DIR/f59- 130
8038         echo "rm 130 files"
8039         unlinkmany $DIR/f59- 130
8040         sync
8041         # wait for commitment of removal
8042         wait_delete_completed
8043 }
8044 run_test 59 "verify cancellation of llog records async ========="
8045
8046 TEST60_HEAD="test_60 run $RANDOM"
8047 test_60a() {
8048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8049         remote_mgs_nodsh && skip "remote MGS with nodsh"
8050         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8051                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8052                         skip_env "missing subtest run-llog.sh"
8053
8054         log "$TEST60_HEAD - from kernel mode"
8055         do_facet mgs "$LCTL dk > /dev/null"
8056         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8057         do_facet mgs $LCTL dk > $TMP/$tfile
8058
8059         # LU-6388: test llog_reader
8060         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8061         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8062         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8063                         skip_env "missing llog_reader"
8064         local fstype=$(facet_fstype mgs)
8065         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8066                 skip_env "Only for ldiskfs or zfs type mgs"
8067
8068         local mntpt=$(facet_mntpt mgs)
8069         local mgsdev=$(mgsdevname 1)
8070         local fid_list
8071         local fid
8072         local rec_list
8073         local rec
8074         local rec_type
8075         local obj_file
8076         local path
8077         local seq
8078         local oid
8079         local pass=true
8080
8081         #get fid and record list
8082         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8083                 tail -n 4))
8084         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8085                 tail -n 4))
8086         #remount mgs as ldiskfs or zfs type
8087         stop mgs || error "stop mgs failed"
8088         mount_fstype mgs || error "remount mgs failed"
8089         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8090                 fid=${fid_list[i]}
8091                 rec=${rec_list[i]}
8092                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8093                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8094                 oid=$((16#$oid))
8095
8096                 case $fstype in
8097                         ldiskfs )
8098                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8099                         zfs )
8100                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8101                 esac
8102                 echo "obj_file is $obj_file"
8103                 do_facet mgs $llog_reader $obj_file
8104
8105                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8106                         awk '{ print $3 }' | sed -e "s/^type=//g")
8107                 if [ $rec_type != $rec ]; then
8108                         echo "FAILED test_60a wrong record type $rec_type," \
8109                               "should be $rec"
8110                         pass=false
8111                         break
8112                 fi
8113
8114                 #check obj path if record type is LLOG_LOGID_MAGIC
8115                 if [ "$rec" == "1064553b" ]; then
8116                         path=$(do_facet mgs $llog_reader $obj_file |
8117                                 grep "path=" | awk '{ print $NF }' |
8118                                 sed -e "s/^path=//g")
8119                         if [ $obj_file != $mntpt/$path ]; then
8120                                 echo "FAILED test_60a wrong obj path" \
8121                                       "$montpt/$path, should be $obj_file"
8122                                 pass=false
8123                                 break
8124                         fi
8125                 fi
8126         done
8127         rm -f $TMP/$tfile
8128         #restart mgs before "error", otherwise it will block the next test
8129         stop mgs || error "stop mgs failed"
8130         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8131         $pass || error "test failed, see FAILED test_60a messages for specifics"
8132 }
8133 run_test 60a "llog_test run from kernel module and test llog_reader"
8134
8135 test_60b() { # bug 6411
8136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8137
8138         dmesg > $DIR/$tfile
8139         LLOG_COUNT=$(do_facet mgs dmesg |
8140                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8141                           /llog_[a-z]*.c:[0-9]/ {
8142                                 if (marker)
8143                                         from_marker++
8144                                 from_begin++
8145                           }
8146                           END {
8147                                 if (marker)
8148                                         print from_marker
8149                                 else
8150                                         print from_begin
8151                           }")
8152
8153         [[ $LLOG_COUNT -gt 120 ]] &&
8154                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8155 }
8156 run_test 60b "limit repeated messages from CERROR/CWARN"
8157
8158 test_60c() {
8159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8160
8161         echo "create 5000 files"
8162         createmany -o $DIR/f60c- 5000
8163 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8164         lctl set_param fail_loc=0x80000137
8165         unlinkmany $DIR/f60c- 5000
8166         lctl set_param fail_loc=0
8167 }
8168 run_test 60c "unlink file when mds full"
8169
8170 test_60d() {
8171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8172
8173         SAVEPRINTK=$(lctl get_param -n printk)
8174         # verify "lctl mark" is even working"
8175         MESSAGE="test message ID $RANDOM $$"
8176         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8177         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8178
8179         lctl set_param printk=0 || error "set lnet.printk failed"
8180         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8181         MESSAGE="new test message ID $RANDOM $$"
8182         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8183         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8184         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8185
8186         lctl set_param -n printk="$SAVEPRINTK"
8187 }
8188 run_test 60d "test printk console message masking"
8189
8190 test_60e() {
8191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8192         remote_mds_nodsh && skip "remote MDS with nodsh"
8193
8194         touch $DIR/$tfile
8195 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8196         do_facet mds1 lctl set_param fail_loc=0x15b
8197         rm $DIR/$tfile
8198 }
8199 run_test 60e "no space while new llog is being created"
8200
8201 test_60f() {
8202         local old_path=$($LCTL get_param -n debug_path)
8203
8204         stack_trap "$LCTL set_param debug_path=$old_path"
8205         stack_trap "rm -f $TMP/$tfile*"
8206         rm -f $TMP/$tfile* 2> /dev/null
8207         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8208         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8209         test_mkdir $DIR/$tdir
8210         # retry in case the open is cached and not released
8211         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8212                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8213                 sleep 0.1
8214         done
8215         ls $TMP/$tfile*
8216         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8217 }
8218 run_test 60f "change debug_path works"
8219
8220 test_60g() {
8221         local pid
8222         local i
8223
8224         test_mkdir -c $MDSCOUNT $DIR/$tdir
8225
8226         (
8227                 local index=0
8228                 while true; do
8229                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8230                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8231                                 2>/dev/null
8232                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8233                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8234                         index=$((index + 1))
8235                 done
8236         ) &
8237
8238         pid=$!
8239
8240         for i in {0..100}; do
8241                 # define OBD_FAIL_OSD_TXN_START    0x19a
8242                 local index=$((i % MDSCOUNT + 1))
8243
8244                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8245                         > /dev/null
8246                 sleep 0.01
8247         done
8248
8249         kill -9 $pid
8250
8251         for i in $(seq $MDSCOUNT); do
8252                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8253         done
8254
8255         mkdir $DIR/$tdir/new || error "mkdir failed"
8256         rmdir $DIR/$tdir/new || error "rmdir failed"
8257
8258         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8259                 -t namespace
8260         for i in $(seq $MDSCOUNT); do
8261                 wait_update_facet mds$i "$LCTL get_param -n \
8262                         mdd.$(facet_svc mds$i).lfsck_namespace |
8263                         awk '/^status/ { print \\\$2 }'" "completed"
8264         done
8265
8266         ls -R $DIR/$tdir || error "ls failed"
8267         rm -rf $DIR/$tdir || error "rmdir failed"
8268 }
8269 run_test 60g "transaction abort won't cause MDT hung"
8270
8271 test_60h() {
8272         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8273                 skip "Need MDS version at least 2.12.52"
8274         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8275
8276         local f
8277
8278         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8279         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8280         for fail_loc in 0x80000188 0x80000189; do
8281                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8282                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8283                         error "mkdir $dir-$fail_loc failed"
8284                 for i in {0..10}; do
8285                         # create may fail on missing stripe
8286                         echo $i > $DIR/$tdir-$fail_loc/$i
8287                 done
8288                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8289                         error "getdirstripe $tdir-$fail_loc failed"
8290                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8291                         error "migrate $tdir-$fail_loc failed"
8292                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8293                         error "getdirstripe $tdir-$fail_loc failed"
8294                 pushd $DIR/$tdir-$fail_loc
8295                 for f in *; do
8296                         echo $f | cmp $f - || error "$f data mismatch"
8297                 done
8298                 popd
8299                 rm -rf $DIR/$tdir-$fail_loc
8300         done
8301 }
8302 run_test 60h "striped directory with missing stripes can be accessed"
8303
8304 function t60i_load() {
8305         mkdir $DIR/$tdir
8306         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8307         $LCTL set_param fail_loc=0x131c fail_val=1
8308         for ((i=0; i<5000; i++)); do
8309                 touch $DIR/$tdir/f$i
8310         done
8311 }
8312
8313 test_60i() {
8314         changelog_register || error "changelog_register failed"
8315         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8316         changelog_users $SINGLEMDS | grep -q $cl_user ||
8317                 error "User $cl_user not found in changelog_users"
8318         changelog_chmask "ALL"
8319         t60i_load &
8320         local PID=$!
8321         for((i=0; i<100; i++)); do
8322                 changelog_dump >/dev/null ||
8323                         error "can't read changelog"
8324         done
8325         kill $PID
8326         wait $PID
8327         changelog_deregister || error "changelog_deregister failed"
8328         $LCTL set_param fail_loc=0
8329 }
8330 run_test 60i "llog: new record vs reader race"
8331
8332 test_61a() {
8333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8334
8335         f="$DIR/f61"
8336         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8337         cancel_lru_locks osc
8338         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8339         sync
8340 }
8341 run_test 61a "mmap() writes don't make sync hang ================"
8342
8343 test_61b() {
8344         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8345 }
8346 run_test 61b "mmap() of unstriped file is successful"
8347
8348 # bug 2330 - insufficient obd_match error checking causes LBUG
8349 test_62() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351
8352         f="$DIR/f62"
8353         echo foo > $f
8354         cancel_lru_locks osc
8355         lctl set_param fail_loc=0x405
8356         cat $f && error "cat succeeded, expect -EIO"
8357         lctl set_param fail_loc=0
8358 }
8359 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8360 # match every page all of the time.
8361 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8362
8363 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8364 # Though this test is irrelevant anymore, it helped to reveal some
8365 # other grant bugs (LU-4482), let's keep it.
8366 test_63a() {   # was test_63
8367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8368
8369         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8370
8371         for i in `seq 10` ; do
8372                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8373                 sleep 5
8374                 kill $!
8375                 sleep 1
8376         done
8377
8378         rm -f $DIR/f63 || true
8379 }
8380 run_test 63a "Verify oig_wait interruption does not crash ======="
8381
8382 # bug 2248 - async write errors didn't return to application on sync
8383 # bug 3677 - async write errors left page locked
8384 test_63b() {
8385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8386
8387         debugsave
8388         lctl set_param debug=-1
8389
8390         # ensure we have a grant to do async writes
8391         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8392         rm $DIR/$tfile
8393
8394         sync    # sync lest earlier test intercept the fail_loc
8395
8396         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8397         lctl set_param fail_loc=0x80000406
8398         $MULTIOP $DIR/$tfile Owy && \
8399                 error "sync didn't return ENOMEM"
8400         sync; sleep 2; sync     # do a real sync this time to flush page
8401         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8402                 error "locked page left in cache after async error" || true
8403         debugrestore
8404 }
8405 run_test 63b "async write errors should be returned to fsync ==="
8406
8407 test_64a () {
8408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8409
8410         lfs df $DIR
8411         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8412 }
8413 run_test 64a "verify filter grant calculations (in kernel) ====="
8414
8415 test_64b () {
8416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8417
8418         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8419 }
8420 run_test 64b "check out-of-space detection on client"
8421
8422 test_64c() {
8423         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8424 }
8425 run_test 64c "verify grant shrink"
8426
8427 import_param() {
8428         local tgt=$1
8429         local param=$2
8430
8431         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8432 }
8433
8434 # this does exactly what osc_request.c:osc_announce_cached() does in
8435 # order to calculate max amount of grants to ask from server
8436 want_grant() {
8437         local tgt=$1
8438
8439         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8440         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8441
8442         ((rpc_in_flight++));
8443         nrpages=$((nrpages * rpc_in_flight))
8444
8445         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8446
8447         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8448
8449         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8450         local undirty=$((nrpages * PAGE_SIZE))
8451
8452         local max_extent_pages
8453         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8454         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8455         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8456         local grant_extent_tax
8457         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8458
8459         undirty=$((undirty + nrextents * grant_extent_tax))
8460
8461         echo $undirty
8462 }
8463
8464 # this is size of unit for grant allocation. It should be equal to
8465 # what tgt_grant.c:tgt_grant_chunk() calculates
8466 grant_chunk() {
8467         local tgt=$1
8468         local max_brw_size
8469         local grant_extent_tax
8470
8471         max_brw_size=$(import_param $tgt max_brw_size)
8472
8473         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8474
8475         echo $(((max_brw_size + grant_extent_tax) * 2))
8476 }
8477
8478 test_64d() {
8479         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8480                 skip "OST < 2.10.55 doesn't limit grants enough"
8481
8482         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8483
8484         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8485                 skip "no grant_param connect flag"
8486
8487         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8488
8489         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8490         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8491
8492
8493         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8494         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8495
8496         $LFS setstripe $DIR/$tfile -i 0 -c 1
8497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8498         ddpid=$!
8499
8500         while kill -0 $ddpid; do
8501                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8502
8503                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8504                         kill $ddpid
8505                         error "cur_grant $cur_grant > $max_cur_granted"
8506                 fi
8507
8508                 sleep 1
8509         done
8510 }
8511 run_test 64d "check grant limit exceed"
8512
8513 check_grants() {
8514         local tgt=$1
8515         local expected=$2
8516         local msg=$3
8517         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8518
8519         ((cur_grants == expected)) ||
8520                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8521 }
8522
8523 round_up_p2() {
8524         echo $((($1 + $2 - 1) & ~($2 - 1)))
8525 }
8526
8527 test_64e() {
8528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8529         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8530                 skip "Need OSS version at least 2.11.56"
8531
8532         # Remount client to reset grant
8533         remount_client $MOUNT || error "failed to remount client"
8534         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8535
8536         local init_grants=$(import_param $osc_tgt initial_grant)
8537
8538         check_grants $osc_tgt $init_grants "init grants"
8539
8540         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8541         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8542         local gbs=$(import_param $osc_tgt grant_block_size)
8543
8544         # write random number of bytes from max_brw_size / 4 to max_brw_size
8545         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8546         # align for direct io
8547         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8548         # round to grant consumption unit
8549         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8550
8551         local grants=$((wb_round_up + extent_tax))
8552
8553         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8554
8555         # define OBD_FAIL_TGT_NO_GRANT 0x725
8556         # make the server not grant more back
8557         do_facet ost1 $LCTL set_param fail_loc=0x725
8558         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8559
8560         do_facet ost1 $LCTL set_param fail_loc=0
8561
8562         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8563
8564         rm -f $DIR/$tfile || error "rm failed"
8565
8566         # Remount client to reset grant
8567         remount_client $MOUNT || error "failed to remount client"
8568         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8569
8570         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8571
8572         # define OBD_FAIL_TGT_NO_GRANT 0x725
8573         # make the server not grant more back
8574         do_facet ost1 $LCTL set_param fail_loc=0x725
8575         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8576         do_facet ost1 $LCTL set_param fail_loc=0
8577
8578         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8579 }
8580 run_test 64e "check grant consumption (no grant allocation)"
8581
8582 test_64f() {
8583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8584
8585         # Remount client to reset grant
8586         remount_client $MOUNT || error "failed to remount client"
8587         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8588
8589         local init_grants=$(import_param $osc_tgt initial_grant)
8590         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8591         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8592         local gbs=$(import_param $osc_tgt grant_block_size)
8593         local chunk=$(grant_chunk $osc_tgt)
8594
8595         # write random number of bytes from max_brw_size / 4 to max_brw_size
8596         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8597         # align for direct io
8598         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8599         # round to grant consumption unit
8600         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8601
8602         local grants=$((wb_round_up + extent_tax))
8603
8604         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8605         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8606                 error "error writing to $DIR/$tfile"
8607
8608         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8609                 "direct io with grant allocation"
8610
8611         rm -f $DIR/$tfile || error "rm failed"
8612
8613         # Remount client to reset grant
8614         remount_client $MOUNT || error "failed to remount client"
8615         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8616
8617         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8618
8619         local cmd="oO_WRONLY:w${write_bytes}_yc"
8620
8621         $MULTIOP $DIR/$tfile $cmd &
8622         MULTIPID=$!
8623         sleep 1
8624
8625         check_grants $osc_tgt $((init_grants - grants)) \
8626                 "buffered io, not write rpc"
8627
8628         kill -USR1 $MULTIPID
8629         wait
8630
8631         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8632                 "buffered io, one RPC"
8633 }
8634 run_test 64f "check grant consumption (with grant allocation)"
8635
8636 # bug 1414 - set/get directories' stripe info
8637 test_65a() {
8638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8639
8640         test_mkdir $DIR/$tdir
8641         touch $DIR/$tdir/f1
8642         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8643 }
8644 run_test 65a "directory with no stripe info"
8645
8646 test_65b() {
8647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8648
8649         test_mkdir $DIR/$tdir
8650         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8651
8652         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8653                                                 error "setstripe"
8654         touch $DIR/$tdir/f2
8655         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8656 }
8657 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8658
8659 test_65c() {
8660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8661         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8662
8663         test_mkdir $DIR/$tdir
8664         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8665
8666         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8667                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8668         touch $DIR/$tdir/f3
8669         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8670 }
8671 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8672
8673 test_65d() {
8674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8675
8676         test_mkdir $DIR/$tdir
8677         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8678         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8679
8680         if [[ $STRIPECOUNT -le 0 ]]; then
8681                 sc=1
8682         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8683                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8684                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8685         else
8686                 sc=$(($STRIPECOUNT - 1))
8687         fi
8688         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8689         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8690         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8691                 error "lverify failed"
8692 }
8693 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8694
8695 test_65e() {
8696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8697
8698         test_mkdir $DIR/$tdir
8699
8700         $LFS setstripe $DIR/$tdir || error "setstripe"
8701         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8702                                         error "no stripe info failed"
8703         touch $DIR/$tdir/f6
8704         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8705 }
8706 run_test 65e "directory setstripe defaults"
8707
8708 test_65f() {
8709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8710
8711         test_mkdir $DIR/${tdir}f
8712         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8713                 error "setstripe succeeded" || true
8714 }
8715 run_test 65f "dir setstripe permission (should return error) ==="
8716
8717 test_65g() {
8718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8719
8720         test_mkdir $DIR/$tdir
8721         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8722
8723         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8724                 error "setstripe -S failed"
8725         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8726         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8727                 error "delete default stripe failed"
8728 }
8729 run_test 65g "directory setstripe -d"
8730
8731 test_65h() {
8732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8733
8734         test_mkdir $DIR/$tdir
8735         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8736
8737         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8738                 error "setstripe -S failed"
8739         test_mkdir $DIR/$tdir/dd1
8740         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8741                 error "stripe info inherit failed"
8742 }
8743 run_test 65h "directory stripe info inherit ===================="
8744
8745 test_65i() {
8746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8747
8748         save_layout_restore_at_exit $MOUNT
8749
8750         # bug6367: set non-default striping on root directory
8751         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8752
8753         # bug12836: getstripe on -1 default directory striping
8754         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8755
8756         # bug12836: getstripe -v on -1 default directory striping
8757         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8758
8759         # bug12836: new find on -1 default directory striping
8760         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8761 }
8762 run_test 65i "various tests to set root directory striping"
8763
8764 test_65j() { # bug6367
8765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8766
8767         sync; sleep 1
8768
8769         # if we aren't already remounting for each test, do so for this test
8770         if [ "$I_MOUNTED" = "yes" ]; then
8771                 cleanup || error "failed to unmount"
8772                 setup
8773         fi
8774
8775         save_layout_restore_at_exit $MOUNT
8776
8777         $LFS setstripe -d $MOUNT || error "setstripe failed"
8778 }
8779 run_test 65j "set default striping on root directory (bug 6367)="
8780
8781 cleanup_65k() {
8782         rm -rf $DIR/$tdir
8783         wait_delete_completed
8784         do_facet $SINGLEMDS "lctl set_param -n \
8785                 osp.$ost*MDT0000.max_create_count=$max_count"
8786         do_facet $SINGLEMDS "lctl set_param -n \
8787                 osp.$ost*MDT0000.create_count=$count"
8788         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8789         echo $INACTIVE_OSC "is Activate"
8790
8791         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8792 }
8793
8794 test_65k() { # bug11679
8795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8796         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8797         remote_mds_nodsh && skip "remote MDS with nodsh"
8798
8799         local disable_precreate=true
8800         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8801                 disable_precreate=false
8802
8803         echo "Check OST status: "
8804         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8805                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8806
8807         for OSC in $MDS_OSCS; do
8808                 echo $OSC "is active"
8809                 do_facet $SINGLEMDS lctl --device %$OSC activate
8810         done
8811
8812         for INACTIVE_OSC in $MDS_OSCS; do
8813                 local ost=$(osc_to_ost $INACTIVE_OSC)
8814                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8815                                lov.*md*.target_obd |
8816                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8817
8818                 mkdir -p $DIR/$tdir
8819                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8820                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8821
8822                 echo "Deactivate: " $INACTIVE_OSC
8823                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8824
8825                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8826                               osp.$ost*MDT0000.create_count")
8827                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8828                                   osp.$ost*MDT0000.max_create_count")
8829                 $disable_precreate &&
8830                         do_facet $SINGLEMDS "lctl set_param -n \
8831                                 osp.$ost*MDT0000.max_create_count=0"
8832
8833                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8834                         [ -f $DIR/$tdir/$idx ] && continue
8835                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8836                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8837                                 { cleanup_65k;
8838                                   error "setstripe $idx should succeed"; }
8839                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8840                 done
8841                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8842                 rmdir $DIR/$tdir
8843
8844                 do_facet $SINGLEMDS "lctl set_param -n \
8845                         osp.$ost*MDT0000.max_create_count=$max_count"
8846                 do_facet $SINGLEMDS "lctl set_param -n \
8847                         osp.$ost*MDT0000.create_count=$count"
8848                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8849                 echo $INACTIVE_OSC "is Activate"
8850
8851                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8852         done
8853 }
8854 run_test 65k "validate manual striping works properly with deactivated OSCs"
8855
8856 test_65l() { # bug 12836
8857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8858
8859         test_mkdir -p $DIR/$tdir/test_dir
8860         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8861         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8862 }
8863 run_test 65l "lfs find on -1 stripe dir ========================"
8864
8865 test_65m() {
8866         local layout=$(save_layout $MOUNT)
8867         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8868                 restore_layout $MOUNT $layout
8869                 error "setstripe should fail by non-root users"
8870         }
8871         true
8872 }
8873 run_test 65m "normal user can't set filesystem default stripe"
8874
8875 test_65n() {
8876         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8877         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8878                 skip "Need MDS version at least 2.12.50"
8879         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8880
8881         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8882         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8883         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8884
8885         save_layout_restore_at_exit $MOUNT
8886
8887         # new subdirectory under root directory should not inherit
8888         # the default layout from root
8889         local dir1=$MOUNT/$tdir-1
8890         mkdir $dir1 || error "mkdir $dir1 failed"
8891         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8892                 error "$dir1 shouldn't have LOV EA"
8893
8894         # delete the default layout on root directory
8895         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8896
8897         local dir2=$MOUNT/$tdir-2
8898         mkdir $dir2 || error "mkdir $dir2 failed"
8899         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8900                 error "$dir2 shouldn't have LOV EA"
8901
8902         # set a new striping pattern on root directory
8903         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8904         local new_def_stripe_size=$((def_stripe_size * 2))
8905         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8906                 error "set stripe size on $MOUNT failed"
8907
8908         # new file created in $dir2 should inherit the new stripe size from
8909         # the filesystem default
8910         local file2=$dir2/$tfile-2
8911         touch $file2 || error "touch $file2 failed"
8912
8913         local file2_stripe_size=$($LFS getstripe -S $file2)
8914         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8915         {
8916                 echo "file2_stripe_size: '$file2_stripe_size'"
8917                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8918                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8919         }
8920
8921         local dir3=$MOUNT/$tdir-3
8922         mkdir $dir3 || error "mkdir $dir3 failed"
8923         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8924         # the root layout, which is the actual default layout that will be used
8925         # when new files are created in $dir3.
8926         local dir3_layout=$(get_layout_param $dir3)
8927         local root_dir_layout=$(get_layout_param $MOUNT)
8928         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8929         {
8930                 echo "dir3_layout: '$dir3_layout'"
8931                 echo "root_dir_layout: '$root_dir_layout'"
8932                 error "$dir3 should show the default layout from $MOUNT"
8933         }
8934
8935         # set OST pool on root directory
8936         local pool=$TESTNAME
8937         pool_add $pool || error "add $pool failed"
8938         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8939                 error "add targets to $pool failed"
8940
8941         $LFS setstripe -p $pool $MOUNT ||
8942                 error "set OST pool on $MOUNT failed"
8943
8944         # new file created in $dir3 should inherit the pool from
8945         # the filesystem default
8946         local file3=$dir3/$tfile-3
8947         touch $file3 || error "touch $file3 failed"
8948
8949         local file3_pool=$($LFS getstripe -p $file3)
8950         [[ "$file3_pool" = "$pool" ]] ||
8951                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8952
8953         local dir4=$MOUNT/$tdir-4
8954         mkdir $dir4 || error "mkdir $dir4 failed"
8955         local dir4_layout=$(get_layout_param $dir4)
8956         root_dir_layout=$(get_layout_param $MOUNT)
8957         echo "$LFS getstripe -d $dir4"
8958         $LFS getstripe -d $dir4
8959         echo "$LFS getstripe -d $MOUNT"
8960         $LFS getstripe -d $MOUNT
8961         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8962         {
8963                 echo "dir4_layout: '$dir4_layout'"
8964                 echo "root_dir_layout: '$root_dir_layout'"
8965                 error "$dir4 should show the default layout from $MOUNT"
8966         }
8967
8968         # new file created in $dir4 should inherit the pool from
8969         # the filesystem default
8970         local file4=$dir4/$tfile-4
8971         touch $file4 || error "touch $file4 failed"
8972
8973         local file4_pool=$($LFS getstripe -p $file4)
8974         [[ "$file4_pool" = "$pool" ]] ||
8975                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8976
8977         # new subdirectory under non-root directory should inherit
8978         # the default layout from its parent directory
8979         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8980                 error "set directory layout on $dir4 failed"
8981
8982         local dir5=$dir4/$tdir-5
8983         mkdir $dir5 || error "mkdir $dir5 failed"
8984
8985         dir4_layout=$(get_layout_param $dir4)
8986         local dir5_layout=$(get_layout_param $dir5)
8987         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8988         {
8989                 echo "dir4_layout: '$dir4_layout'"
8990                 echo "dir5_layout: '$dir5_layout'"
8991                 error "$dir5 should inherit the default layout from $dir4"
8992         }
8993
8994         # though subdir under ROOT doesn't inherit default layout, but
8995         # its sub dir/file should be created with default layout.
8996         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8997         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8998                 skip "Need MDS version at least 2.12.59"
8999
9000         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9001         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9002         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9003
9004         if [ $default_lmv_hash == "none" ]; then
9005                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9006         else
9007                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9008                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9009         fi
9010
9011         $LFS setdirstripe -D -c 2 $MOUNT ||
9012                 error "setdirstripe -D -c 2 failed"
9013         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9014         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9015         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9016 }
9017 run_test 65n "don't inherit default layout from root for new subdirectories"
9018
9019 # bug 2543 - update blocks count on client
9020 test_66() {
9021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9022
9023         COUNT=${COUNT:-8}
9024         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9025         sync; sync_all_data; sync; sync_all_data
9026         cancel_lru_locks osc
9027         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9028         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9029 }
9030 run_test 66 "update inode blocks count on client ==============="
9031
9032 meminfo() {
9033         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9034 }
9035
9036 swap_used() {
9037         swapon -s | awk '($1 == "'$1'") { print $4 }'
9038 }
9039
9040 # bug5265, obdfilter oa2dentry return -ENOENT
9041 # #define OBD_FAIL_SRV_ENOENT 0x217
9042 test_69() {
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044         remote_ost_nodsh && skip "remote OST with nodsh"
9045
9046         f="$DIR/$tfile"
9047         $LFS setstripe -c 1 -i 0 $f
9048
9049         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9050
9051         do_facet ost1 lctl set_param fail_loc=0x217
9052         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9053         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9054
9055         do_facet ost1 lctl set_param fail_loc=0
9056         $DIRECTIO write $f 0 2 || error "write error"
9057
9058         cancel_lru_locks osc
9059         $DIRECTIO read $f 0 1 || error "read error"
9060
9061         do_facet ost1 lctl set_param fail_loc=0x217
9062         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9063
9064         do_facet ost1 lctl set_param fail_loc=0
9065         rm -f $f
9066 }
9067 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9068
9069 test_71() {
9070         test_mkdir $DIR/$tdir
9071         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9072         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9073 }
9074 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9075
9076 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9078         [ "$RUNAS_ID" = "$UID" ] &&
9079                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9080         # Check that testing environment is properly set up. Skip if not
9081         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9082                 skip_env "User $RUNAS_ID does not exist - skipping"
9083
9084         touch $DIR/$tfile
9085         chmod 777 $DIR/$tfile
9086         chmod ug+s $DIR/$tfile
9087         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9088                 error "$RUNAS dd $DIR/$tfile failed"
9089         # See if we are still setuid/sgid
9090         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9091                 error "S/gid is not dropped on write"
9092         # Now test that MDS is updated too
9093         cancel_lru_locks mdc
9094         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9095                 error "S/gid is not dropped on MDS"
9096         rm -f $DIR/$tfile
9097 }
9098 run_test 72a "Test that remove suid works properly (bug5695) ===="
9099
9100 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9101         local perm
9102
9103         [ "$RUNAS_ID" = "$UID" ] &&
9104                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9105         [ "$RUNAS_ID" -eq 0 ] &&
9106                 skip_env "RUNAS_ID = 0 -- skipping"
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108         # Check that testing environment is properly set up. Skip if not
9109         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9110                 skip_env "User $RUNAS_ID does not exist - skipping"
9111
9112         touch $DIR/${tfile}-f{g,u}
9113         test_mkdir $DIR/${tfile}-dg
9114         test_mkdir $DIR/${tfile}-du
9115         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9116         chmod g+s $DIR/${tfile}-{f,d}g
9117         chmod u+s $DIR/${tfile}-{f,d}u
9118         for perm in 777 2777 4777; do
9119                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9120                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9121                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9122                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9123         done
9124         true
9125 }
9126 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9127
9128 # bug 3462 - multiple simultaneous MDC requests
9129 test_73() {
9130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9131
9132         test_mkdir $DIR/d73-1
9133         test_mkdir $DIR/d73-2
9134         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9135         pid1=$!
9136
9137         lctl set_param fail_loc=0x80000129
9138         $MULTIOP $DIR/d73-1/f73-2 Oc &
9139         sleep 1
9140         lctl set_param fail_loc=0
9141
9142         $MULTIOP $DIR/d73-2/f73-3 Oc &
9143         pid3=$!
9144
9145         kill -USR1 $pid1
9146         wait $pid1 || return 1
9147
9148         sleep 25
9149
9150         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9151         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9152         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9153
9154         rm -rf $DIR/d73-*
9155 }
9156 run_test 73 "multiple MDC requests (should not deadlock)"
9157
9158 test_74a() { # bug 6149, 6184
9159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9160
9161         touch $DIR/f74a
9162         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9163         #
9164         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9165         # will spin in a tight reconnection loop
9166         $LCTL set_param fail_loc=0x8000030e
9167         # get any lock that won't be difficult - lookup works.
9168         ls $DIR/f74a
9169         $LCTL set_param fail_loc=0
9170         rm -f $DIR/f74a
9171         true
9172 }
9173 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9174
9175 test_74b() { # bug 13310
9176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9177
9178         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9179         #
9180         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9181         # will spin in a tight reconnection loop
9182         $LCTL set_param fail_loc=0x8000030e
9183         # get a "difficult" lock
9184         touch $DIR/f74b
9185         $LCTL set_param fail_loc=0
9186         rm -f $DIR/f74b
9187         true
9188 }
9189 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9190
9191 test_74c() {
9192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9193
9194         #define OBD_FAIL_LDLM_NEW_LOCK
9195         $LCTL set_param fail_loc=0x319
9196         touch $DIR/$tfile && error "touch successful"
9197         $LCTL set_param fail_loc=0
9198         true
9199 }
9200 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9201
9202 slab_lic=/sys/kernel/slab/lustre_inode_cache
9203 num_objects() {
9204         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9205         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9206                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9207 }
9208
9209 test_76a() { # Now for b=20433, added originally in b=1443
9210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9211
9212         cancel_lru_locks osc
9213         # there may be some slab objects cached per core
9214         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9215         local before=$(num_objects)
9216         local count=$((512 * cpus))
9217         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9218         local margin=$((count / 10))
9219         if [[ -f $slab_lic/aliases ]]; then
9220                 local aliases=$(cat $slab_lic/aliases)
9221                 (( aliases > 0 )) && margin=$((margin * aliases))
9222         fi
9223
9224         echo "before slab objects: $before"
9225         for i in $(seq $count); do
9226                 touch $DIR/$tfile
9227                 rm -f $DIR/$tfile
9228         done
9229         cancel_lru_locks osc
9230         local after=$(num_objects)
9231         echo "created: $count, after slab objects: $after"
9232         # shared slab counts are not very accurate, allow significant margin
9233         # the main goal is that the cache growth is not permanently > $count
9234         while (( after > before + margin )); do
9235                 sleep 1
9236                 after=$(num_objects)
9237                 wait=$((wait + 1))
9238                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9239                 if (( wait > 60 )); then
9240                         error "inode slab grew from $before+$margin to $after"
9241                 fi
9242         done
9243 }
9244 run_test 76a "confirm clients recycle inodes properly ===="
9245
9246 test_76b() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9249
9250         local count=512
9251         local before=$(num_objects)
9252
9253         for i in $(seq $count); do
9254                 mkdir $DIR/$tdir
9255                 rmdir $DIR/$tdir
9256         done
9257
9258         local after=$(num_objects)
9259         local wait=0
9260
9261         while (( after > before )); do
9262                 sleep 1
9263                 after=$(num_objects)
9264                 wait=$((wait + 1))
9265                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9266                 if (( wait > 60 )); then
9267                         error "inode slab grew from $before to $after"
9268                 fi
9269         done
9270
9271         echo "slab objects before: $before, after: $after"
9272 }
9273 run_test 76b "confirm clients recycle directory inodes properly ===="
9274
9275 export ORIG_CSUM=""
9276 set_checksums()
9277 {
9278         # Note: in sptlrpc modes which enable its own bulk checksum, the
9279         # original crc32_le bulk checksum will be automatically disabled,
9280         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9281         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9282         # In this case set_checksums() will not be no-op, because sptlrpc
9283         # bulk checksum will be enabled all through the test.
9284
9285         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9286         lctl set_param -n osc.*.checksums $1
9287         return 0
9288 }
9289
9290 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9291                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9292 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9293                              tr -d [] | head -n1)}
9294 set_checksum_type()
9295 {
9296         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9297         rc=$?
9298         log "set checksum type to $1, rc = $rc"
9299         return $rc
9300 }
9301
9302 get_osc_checksum_type()
9303 {
9304         # arugment 1: OST name, like OST0000
9305         ost=$1
9306         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9307                         sed 's/.*\[\(.*\)\].*/\1/g')
9308         rc=$?
9309         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9310         echo $checksum_type
9311 }
9312
9313 F77_TMP=$TMP/f77-temp
9314 F77SZ=8
9315 setup_f77() {
9316         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9317                 error "error writing to $F77_TMP"
9318 }
9319
9320 test_77a() { # bug 10889
9321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9322         $GSS && skip_env "could not run with gss"
9323
9324         [ ! -f $F77_TMP ] && setup_f77
9325         set_checksums 1
9326         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9327         set_checksums 0
9328         rm -f $DIR/$tfile
9329 }
9330 run_test 77a "normal checksum read/write operation"
9331
9332 test_77b() { # bug 10889
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334         $GSS && skip_env "could not run with gss"
9335
9336         [ ! -f $F77_TMP ] && setup_f77
9337         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9338         $LCTL set_param fail_loc=0x80000409
9339         set_checksums 1
9340
9341         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9342                 error "dd error: $?"
9343         $LCTL set_param fail_loc=0
9344
9345         for algo in $CKSUM_TYPES; do
9346                 cancel_lru_locks osc
9347                 set_checksum_type $algo
9348                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9349                 $LCTL set_param fail_loc=0x80000408
9350                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9351                 $LCTL set_param fail_loc=0
9352         done
9353         set_checksums 0
9354         set_checksum_type $ORIG_CSUM_TYPE
9355         rm -f $DIR/$tfile
9356 }
9357 run_test 77b "checksum error on client write, read"
9358
9359 cleanup_77c() {
9360         trap 0
9361         set_checksums 0
9362         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9363         $check_ost &&
9364                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9365         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9366         $check_ost && [ -n "$ost_file_prefix" ] &&
9367                 do_facet ost1 rm -f ${ost_file_prefix}\*
9368 }
9369
9370 test_77c() {
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372         $GSS && skip_env "could not run with gss"
9373         remote_ost_nodsh && skip "remote OST with nodsh"
9374
9375         local bad1
9376         local osc_file_prefix
9377         local osc_file
9378         local check_ost=false
9379         local ost_file_prefix
9380         local ost_file
9381         local orig_cksum
9382         local dump_cksum
9383         local fid
9384
9385         # ensure corruption will occur on first OSS/OST
9386         $LFS setstripe -i 0 $DIR/$tfile
9387
9388         [ ! -f $F77_TMP ] && setup_f77
9389         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9390                 error "dd write error: $?"
9391         fid=$($LFS path2fid $DIR/$tfile)
9392
9393         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9394         then
9395                 check_ost=true
9396                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9397                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9398         else
9399                 echo "OSS do not support bulk pages dump upon error"
9400         fi
9401
9402         osc_file_prefix=$($LCTL get_param -n debug_path)
9403         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9404
9405         trap cleanup_77c EXIT
9406
9407         set_checksums 1
9408         # enable bulk pages dump upon error on Client
9409         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9410         # enable bulk pages dump upon error on OSS
9411         $check_ost &&
9412                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9413
9414         # flush Client cache to allow next read to reach OSS
9415         cancel_lru_locks osc
9416
9417         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9418         $LCTL set_param fail_loc=0x80000408
9419         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9420         $LCTL set_param fail_loc=0
9421
9422         rm -f $DIR/$tfile
9423
9424         # check cksum dump on Client
9425         osc_file=$(ls ${osc_file_prefix}*)
9426         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9427         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9428         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9429         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9430         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9431                      cksum)
9432         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9433         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9434                 error "dump content does not match on Client"
9435
9436         $check_ost || skip "No need to check cksum dump on OSS"
9437
9438         # check cksum dump on OSS
9439         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9440         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9441         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9442         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9443         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9444                 error "dump content does not match on OSS"
9445
9446         cleanup_77c
9447 }
9448 run_test 77c "checksum error on client read with debug"
9449
9450 test_77d() { # bug 10889
9451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9452         $GSS && skip_env "could not run with gss"
9453
9454         stack_trap "rm -f $DIR/$tfile"
9455         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9456         $LCTL set_param fail_loc=0x80000409
9457         set_checksums 1
9458         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9459                 error "direct write: rc=$?"
9460         $LCTL set_param fail_loc=0
9461         set_checksums 0
9462
9463         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9464         $LCTL set_param fail_loc=0x80000408
9465         set_checksums 1
9466         cancel_lru_locks osc
9467         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9468                 error "direct read: rc=$?"
9469         $LCTL set_param fail_loc=0
9470         set_checksums 0
9471 }
9472 run_test 77d "checksum error on OST direct write, read"
9473
9474 test_77f() { # bug 10889
9475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9476         $GSS && skip_env "could not run with gss"
9477
9478         set_checksums 1
9479         stack_trap "rm -f $DIR/$tfile"
9480         for algo in $CKSUM_TYPES; do
9481                 cancel_lru_locks osc
9482                 set_checksum_type $algo
9483                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9484                 $LCTL set_param fail_loc=0x409
9485                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9486                         error "direct write succeeded"
9487                 $LCTL set_param fail_loc=0
9488         done
9489         set_checksum_type $ORIG_CSUM_TYPE
9490         set_checksums 0
9491 }
9492 run_test 77f "repeat checksum error on write (expect error)"
9493
9494 test_77g() { # bug 10889
9495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9496         $GSS && skip_env "could not run with gss"
9497         remote_ost_nodsh && skip "remote OST with nodsh"
9498
9499         [ ! -f $F77_TMP ] && setup_f77
9500
9501         local file=$DIR/$tfile
9502         stack_trap "rm -f $file" EXIT
9503
9504         $LFS setstripe -c 1 -i 0 $file
9505         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9506         do_facet ost1 lctl set_param fail_loc=0x8000021a
9507         set_checksums 1
9508         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9509                 error "write error: rc=$?"
9510         do_facet ost1 lctl set_param fail_loc=0
9511         set_checksums 0
9512
9513         cancel_lru_locks osc
9514         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9515         do_facet ost1 lctl set_param fail_loc=0x8000021b
9516         set_checksums 1
9517         cmp $F77_TMP $file || error "file compare failed"
9518         do_facet ost1 lctl set_param fail_loc=0
9519         set_checksums 0
9520 }
9521 run_test 77g "checksum error on OST write, read"
9522
9523 test_77k() { # LU-10906
9524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9525         $GSS && skip_env "could not run with gss"
9526
9527         local cksum_param="osc.$FSNAME*.checksums"
9528         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9529         local checksum
9530         local i
9531
9532         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9533         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9534         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9535
9536         for i in 0 1; do
9537                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9538                         error "failed to set checksum=$i on MGS"
9539                 wait_update $HOSTNAME "$get_checksum" $i
9540                 #remount
9541                 echo "remount client, checksum should be $i"
9542                 remount_client $MOUNT || error "failed to remount client"
9543                 checksum=$(eval $get_checksum)
9544                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9545         done
9546         # remove persistent param to avoid races with checksum mountopt below
9547         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9548                 error "failed to delete checksum on MGS"
9549
9550         for opt in "checksum" "nochecksum"; do
9551                 #remount with mount option
9552                 echo "remount client with option $opt, checksum should be $i"
9553                 umount_client $MOUNT || error "failed to umount client"
9554                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9555                         error "failed to mount client with option '$opt'"
9556                 checksum=$(eval $get_checksum)
9557                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9558                 i=$((i - 1))
9559         done
9560
9561         remount_client $MOUNT || error "failed to remount client"
9562 }
9563 run_test 77k "enable/disable checksum correctly"
9564
9565 test_77l() {
9566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9567         $GSS && skip_env "could not run with gss"
9568
9569         set_checksums 1
9570         stack_trap "set_checksums $ORIG_CSUM" EXIT
9571         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9572
9573         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9574
9575         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9576         for algo in $CKSUM_TYPES; do
9577                 set_checksum_type $algo || error "fail to set checksum type $algo"
9578                 osc_algo=$(get_osc_checksum_type OST0000)
9579                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9580
9581                 # no locks, no reqs to let the connection idle
9582                 cancel_lru_locks osc
9583                 lru_resize_disable osc
9584                 wait_osc_import_state client ost1 IDLE
9585
9586                 # ensure ost1 is connected
9587                 stat $DIR/$tfile >/dev/null || error "can't stat"
9588                 wait_osc_import_state client ost1 FULL
9589
9590                 osc_algo=$(get_osc_checksum_type OST0000)
9591                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9592         done
9593         return 0
9594 }
9595 run_test 77l "preferred checksum type is remembered after reconnected"
9596
9597 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9598 rm -f $F77_TMP
9599 unset F77_TMP
9600
9601 test_77m() {
9602         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9603                 skip "Need at least version 2.14.52"
9604         local param=checksum_speed
9605
9606         $LCTL get_param $param || error "reading $param failed"
9607
9608         csum_speeds=$($LCTL get_param -n $param)
9609
9610         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9611                 error "known checksum types are missing"
9612 }
9613 run_test 77m "Verify checksum_speed is correctly read"
9614
9615 cleanup_test_78() {
9616         trap 0
9617         rm -f $DIR/$tfile
9618 }
9619
9620 test_78() { # bug 10901
9621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9622         remote_ost || skip_env "local OST"
9623
9624         NSEQ=5
9625         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9626         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9627         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9628         echo "MemTotal: $MEMTOTAL"
9629
9630         # reserve 256MB of memory for the kernel and other running processes,
9631         # and then take 1/2 of the remaining memory for the read/write buffers.
9632         if [ $MEMTOTAL -gt 512 ] ;then
9633                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9634         else
9635                 # for those poor memory-starved high-end clusters...
9636                 MEMTOTAL=$((MEMTOTAL / 2))
9637         fi
9638         echo "Mem to use for directio: $MEMTOTAL"
9639
9640         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9641         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9642         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9643         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9644                 head -n1)
9645         echo "Smallest OST: $SMALLESTOST"
9646         [[ $SMALLESTOST -lt 10240 ]] &&
9647                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9648
9649         trap cleanup_test_78 EXIT
9650
9651         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9652                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9653
9654         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9655         echo "File size: $F78SIZE"
9656         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9657         for i in $(seq 1 $NSEQ); do
9658                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9659                 echo directIO rdwr round $i of $NSEQ
9660                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9661         done
9662
9663         cleanup_test_78
9664 }
9665 run_test 78 "handle large O_DIRECT writes correctly ============"
9666
9667 test_79() { # bug 12743
9668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9669
9670         wait_delete_completed
9671
9672         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9673         BKFREE=$(calc_osc_kbytes kbytesfree)
9674         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9675
9676         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9677         DFTOTAL=`echo $STRING | cut -d, -f1`
9678         DFUSED=`echo $STRING  | cut -d, -f2`
9679         DFAVAIL=`echo $STRING | cut -d, -f3`
9680         DFFREE=$(($DFTOTAL - $DFUSED))
9681
9682         ALLOWANCE=$((64 * $OSTCOUNT))
9683
9684         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9685            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9686                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9687         fi
9688         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9689            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9690                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9691         fi
9692         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9693            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9694                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9695         fi
9696 }
9697 run_test 79 "df report consistency check ======================="
9698
9699 test_80() { # bug 10718
9700         remote_ost_nodsh && skip "remote OST with nodsh"
9701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9702
9703         # relax strong synchronous semantics for slow backends like ZFS
9704         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9705                 local soc="obdfilter.*.sync_lock_cancel"
9706                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9707
9708                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9709                 if [ -z "$save" ]; then
9710                         soc="obdfilter.*.sync_on_lock_cancel"
9711                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9712                 fi
9713
9714                 if [ "$save" != "never" ]; then
9715                         local hosts=$(comma_list $(osts_nodes))
9716
9717                         do_nodes $hosts $LCTL set_param $soc=never
9718                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9719                 fi
9720         fi
9721
9722         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9723         sync; sleep 1; sync
9724         local before=$(date +%s)
9725         cancel_lru_locks osc
9726         local after=$(date +%s)
9727         local diff=$((after - before))
9728         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9729
9730         rm -f $DIR/$tfile
9731 }
9732 run_test 80 "Page eviction is equally fast at high offsets too"
9733
9734 test_81a() { # LU-456
9735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9736         remote_ost_nodsh && skip "remote OST with nodsh"
9737
9738         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9739         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9740         do_facet ost1 lctl set_param fail_loc=0x80000228
9741
9742         # write should trigger a retry and success
9743         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9744         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9745         RC=$?
9746         if [ $RC -ne 0 ] ; then
9747                 error "write should success, but failed for $RC"
9748         fi
9749 }
9750 run_test 81a "OST should retry write when get -ENOSPC ==============="
9751
9752 test_81b() { # LU-456
9753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9754         remote_ost_nodsh && skip "remote OST with nodsh"
9755
9756         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9757         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9758         do_facet ost1 lctl set_param fail_loc=0x228
9759
9760         # write should retry several times and return -ENOSPC finally
9761         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9762         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9763         RC=$?
9764         ENOSPC=28
9765         if [ $RC -ne $ENOSPC ] ; then
9766                 error "dd should fail for -ENOSPC, but succeed."
9767         fi
9768 }
9769 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9770
9771 test_99() {
9772         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9773
9774         test_mkdir $DIR/$tdir.cvsroot
9775         chown $RUNAS_ID $DIR/$tdir.cvsroot
9776
9777         cd $TMP
9778         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9779
9780         cd /etc/init.d
9781         # some versions of cvs import exit(1) when asked to import links or
9782         # files they can't read.  ignore those files.
9783         local toignore=$(find . -type l -printf '-I %f\n' -o \
9784                          ! -perm /4 -printf '-I %f\n')
9785         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9786                 $tdir.reposname vtag rtag
9787
9788         cd $DIR
9789         test_mkdir $DIR/$tdir.reposname
9790         chown $RUNAS_ID $DIR/$tdir.reposname
9791         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9792
9793         cd $DIR/$tdir.reposname
9794         $RUNAS touch foo99
9795         $RUNAS cvs add -m 'addmsg' foo99
9796         $RUNAS cvs update
9797         $RUNAS cvs commit -m 'nomsg' foo99
9798         rm -fr $DIR/$tdir.cvsroot
9799 }
9800 run_test 99 "cvs strange file/directory operations"
9801
9802 test_100() {
9803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9804         [[ "$NETTYPE" =~ tcp ]] ||
9805                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9806         remote_ost_nodsh && skip "remote OST with nodsh"
9807         remote_mds_nodsh && skip "remote MDS with nodsh"
9808         remote_servers ||
9809                 skip "useless for local single node setup"
9810
9811         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9812                 [ "$PROT" != "tcp" ] && continue
9813                 RPORT=$(echo $REMOTE | cut -d: -f2)
9814                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9815
9816                 rc=0
9817                 LPORT=`echo $LOCAL | cut -d: -f2`
9818                 if [ $LPORT -ge 1024 ]; then
9819                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9820                         netstat -tna
9821                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9822                 fi
9823         done
9824         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9825 }
9826 run_test 100 "check local port using privileged port ==========="
9827
9828 function get_named_value()
9829 {
9830     local tag=$1
9831
9832     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9833 }
9834
9835 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9836                    awk '/^max_cached_mb/ { print $2 }')
9837
9838 cleanup_101a() {
9839         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9840         trap 0
9841 }
9842
9843 test_101a() {
9844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9845
9846         local s
9847         local discard
9848         local nreads=10000
9849         local cache_limit=32
9850
9851         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9852         trap cleanup_101a EXIT
9853         $LCTL set_param -n llite.*.read_ahead_stats=0
9854         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9855
9856         #
9857         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9858         #
9859         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9860         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9861
9862         discard=0
9863         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9864                    get_named_value 'read.but.discarded'); do
9865                         discard=$(($discard + $s))
9866         done
9867         cleanup_101a
9868
9869         $LCTL get_param osc.*-osc*.rpc_stats
9870         $LCTL get_param llite.*.read_ahead_stats
9871
9872         # Discard is generally zero, but sometimes a few random reads line up
9873         # and trigger larger readahead, which is wasted & leads to discards.
9874         if [[ $(($discard)) -gt $nreads ]]; then
9875                 error "too many ($discard) discarded pages"
9876         fi
9877         rm -f $DIR/$tfile || true
9878 }
9879 run_test 101a "check read-ahead for random reads"
9880
9881 setup_test101bc() {
9882         test_mkdir $DIR/$tdir
9883         local ssize=$1
9884         local FILE_LENGTH=$2
9885         STRIPE_OFFSET=0
9886
9887         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9888
9889         local list=$(comma_list $(osts_nodes))
9890         set_osd_param $list '' read_cache_enable 0
9891         set_osd_param $list '' writethrough_cache_enable 0
9892
9893         trap cleanup_test101bc EXIT
9894         # prepare the read-ahead file
9895         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9896
9897         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9898                                 count=$FILE_SIZE_MB 2> /dev/null
9899
9900 }
9901
9902 cleanup_test101bc() {
9903         trap 0
9904         rm -rf $DIR/$tdir
9905         rm -f $DIR/$tfile
9906
9907         local list=$(comma_list $(osts_nodes))
9908         set_osd_param $list '' read_cache_enable 1
9909         set_osd_param $list '' writethrough_cache_enable 1
9910 }
9911
9912 calc_total() {
9913         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9914 }
9915
9916 ra_check_101() {
9917         local READ_SIZE=$1
9918         local STRIPE_SIZE=$2
9919         local FILE_LENGTH=$3
9920         local RA_INC=1048576
9921         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9922         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9923                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9924         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9925                   get_named_value 'read.but.discarded' | calc_total)
9926         if [[ $DISCARD -gt $discard_limit ]]; then
9927                 $LCTL get_param llite.*.read_ahead_stats
9928                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9929         else
9930                 echo "Read-ahead success for size ${READ_SIZE}"
9931         fi
9932 }
9933
9934 test_101b() {
9935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9937
9938         local STRIPE_SIZE=1048576
9939         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9940
9941         if [ $SLOW == "yes" ]; then
9942                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9943         else
9944                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9945         fi
9946
9947         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9948
9949         # prepare the read-ahead file
9950         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9951         cancel_lru_locks osc
9952         for BIDX in 2 4 8 16 32 64 128 256
9953         do
9954                 local BSIZE=$((BIDX*4096))
9955                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9956                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9957                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9958                 $LCTL set_param -n llite.*.read_ahead_stats=0
9959                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9960                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9961                 cancel_lru_locks osc
9962                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9963         done
9964         cleanup_test101bc
9965         true
9966 }
9967 run_test 101b "check stride-io mode read-ahead ================="
9968
9969 test_101c() {
9970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9971
9972         local STRIPE_SIZE=1048576
9973         local FILE_LENGTH=$((STRIPE_SIZE*100))
9974         local nreads=10000
9975         local rsize=65536
9976         local osc_rpc_stats
9977
9978         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9979
9980         cancel_lru_locks osc
9981         $LCTL set_param osc.*.rpc_stats=0
9982         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9983         $LCTL get_param osc.*.rpc_stats
9984         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9985                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9986                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9987                 local size
9988
9989                 if [ $lines -le 20 ]; then
9990                         echo "continue debug"
9991                         continue
9992                 fi
9993                 for size in 1 2 4 8; do
9994                         local rpc=$(echo "$stats" |
9995                                     awk '($1 == "'$size':") {print $2; exit; }')
9996                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9997                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9998                 done
9999                 echo "$osc_rpc_stats check passed!"
10000         done
10001         cleanup_test101bc
10002         true
10003 }
10004 run_test 101c "check stripe_size aligned read-ahead"
10005
10006 test_101d() {
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008
10009         local file=$DIR/$tfile
10010         local sz_MB=${FILESIZE_101d:-80}
10011         local ra_MB=${READAHEAD_MB:-40}
10012
10013         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10014         [ $free_MB -lt $sz_MB ] &&
10015                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10016
10017         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10018         $LFS setstripe -c -1 $file || error "setstripe failed"
10019
10020         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10021         echo Cancel LRU locks on lustre client to flush the client cache
10022         cancel_lru_locks osc
10023
10024         echo Disable read-ahead
10025         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10026         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10027         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10028         $LCTL get_param -n llite.*.max_read_ahead_mb
10029
10030         echo "Reading the test file $file with read-ahead disabled"
10031         local sz_KB=$((sz_MB * 1024 / 4))
10032         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10033         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10034         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10035                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10036
10037         echo "Cancel LRU locks on lustre client to flush the client cache"
10038         cancel_lru_locks osc
10039         echo Enable read-ahead with ${ra_MB}MB
10040         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10041
10042         echo "Reading the test file $file with read-ahead enabled"
10043         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10044                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10045
10046         echo "read-ahead disabled time read $raOFF"
10047         echo "read-ahead enabled time read $raON"
10048
10049         rm -f $file
10050         wait_delete_completed
10051
10052         # use awk for this check instead of bash because it handles decimals
10053         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10054                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10055 }
10056 run_test 101d "file read with and without read-ahead enabled"
10057
10058 test_101e() {
10059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10060
10061         local file=$DIR/$tfile
10062         local size_KB=500  #KB
10063         local count=100
10064         local bsize=1024
10065
10066         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10067         local need_KB=$((count * size_KB))
10068         [[ $free_KB -le $need_KB ]] &&
10069                 skip_env "Need free space $need_KB, have $free_KB"
10070
10071         echo "Creating $count ${size_KB}K test files"
10072         for ((i = 0; i < $count; i++)); do
10073                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10074         done
10075
10076         echo "Cancel LRU locks on lustre client to flush the client cache"
10077         cancel_lru_locks $OSC
10078
10079         echo "Reset readahead stats"
10080         $LCTL set_param -n llite.*.read_ahead_stats=0
10081
10082         for ((i = 0; i < $count; i++)); do
10083                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10084         done
10085
10086         $LCTL get_param llite.*.max_cached_mb
10087         $LCTL get_param llite.*.read_ahead_stats
10088         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10089                      get_named_value 'misses' | calc_total)
10090
10091         for ((i = 0; i < $count; i++)); do
10092                 rm -rf $file.$i 2>/dev/null
10093         done
10094
10095         #10000 means 20% reads are missing in readahead
10096         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10097 }
10098 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10099
10100 test_101f() {
10101         which iozone || skip_env "no iozone installed"
10102
10103         local old_debug=$($LCTL get_param debug)
10104         old_debug=${old_debug#*=}
10105         $LCTL set_param debug="reada mmap"
10106
10107         # create a test file
10108         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10109
10110         echo Cancel LRU locks on lustre client to flush the client cache
10111         cancel_lru_locks osc
10112
10113         echo Reset readahead stats
10114         $LCTL set_param -n llite.*.read_ahead_stats=0
10115
10116         echo mmap read the file with small block size
10117         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10118                 > /dev/null 2>&1
10119
10120         echo checking missing pages
10121         $LCTL get_param llite.*.read_ahead_stats
10122         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10123                         get_named_value 'misses' | calc_total)
10124
10125         $LCTL set_param debug="$old_debug"
10126         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10127         rm -f $DIR/$tfile
10128 }
10129 run_test 101f "check mmap read performance"
10130
10131 test_101g_brw_size_test() {
10132         local mb=$1
10133         local pages=$((mb * 1048576 / PAGE_SIZE))
10134         local file=$DIR/$tfile
10135
10136         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10137                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10138         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10139                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10140                         return 2
10141         done
10142
10143         stack_trap "rm -f $file" EXIT
10144         $LCTL set_param -n osc.*.rpc_stats=0
10145
10146         # 10 RPCs should be enough for the test
10147         local count=10
10148         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10149                 { error "dd write ${mb} MB blocks failed"; return 3; }
10150         cancel_lru_locks osc
10151         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10152                 { error "dd write ${mb} MB blocks failed"; return 4; }
10153
10154         # calculate number of full-sized read and write RPCs
10155         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10156                 sed -n '/pages per rpc/,/^$/p' |
10157                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10158                 END { print reads,writes }'))
10159         # allow one extra full-sized read RPC for async readahead
10160         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10161                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10162         [[ ${rpcs[1]} == $count ]] ||
10163                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10164 }
10165
10166 test_101g() {
10167         remote_ost_nodsh && skip "remote OST with nodsh"
10168
10169         local rpcs
10170         local osts=$(get_facets OST)
10171         local list=$(comma_list $(osts_nodes))
10172         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10173         local brw_size="obdfilter.*.brw_size"
10174
10175         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10176
10177         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10178
10179         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10180                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10181                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10182            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10183                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10184                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10185
10186                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10187                         suffix="M"
10188
10189                 if [[ $orig_mb -lt 16 ]]; then
10190                         save_lustre_params $osts "$brw_size" > $p
10191                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10192                                 error "set 16MB RPC size failed"
10193
10194                         echo "remount client to enable new RPC size"
10195                         remount_client $MOUNT || error "remount_client failed"
10196                 fi
10197
10198                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10199                 # should be able to set brw_size=12, but no rpc_stats for that
10200                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10201         fi
10202
10203         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10204
10205         if [[ $orig_mb -lt 16 ]]; then
10206                 restore_lustre_params < $p
10207                 remount_client $MOUNT || error "remount_client restore failed"
10208         fi
10209
10210         rm -f $p $DIR/$tfile
10211 }
10212 run_test 101g "Big bulk(4/16 MiB) readahead"
10213
10214 test_101h() {
10215         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10216
10217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10218                 error "dd 70M file failed"
10219         echo Cancel LRU locks on lustre client to flush the client cache
10220         cancel_lru_locks osc
10221
10222         echo "Reset readahead stats"
10223         $LCTL set_param -n llite.*.read_ahead_stats 0
10224
10225         echo "Read 10M of data but cross 64M bundary"
10226         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10227         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10228                      get_named_value 'misses' | calc_total)
10229         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10230         rm -f $p $DIR/$tfile
10231 }
10232 run_test 101h "Readahead should cover current read window"
10233
10234 test_101i() {
10235         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10236                 error "dd 10M file failed"
10237
10238         local max_per_file_mb=$($LCTL get_param -n \
10239                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10240         cancel_lru_locks osc
10241         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10242         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10243                 error "set max_read_ahead_per_file_mb to 1 failed"
10244
10245         echo "Reset readahead stats"
10246         $LCTL set_param llite.*.read_ahead_stats=0
10247
10248         dd if=$DIR/$tfile of=/dev/null bs=2M
10249
10250         $LCTL get_param llite.*.read_ahead_stats
10251         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10252                      awk '/misses/ { print $2 }')
10253         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10254         rm -f $DIR/$tfile
10255 }
10256 run_test 101i "allow current readahead to exceed reservation"
10257
10258 test_101j() {
10259         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10260                 error "setstripe $DIR/$tfile failed"
10261         local file_size=$((1048576 * 16))
10262         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10263         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10264
10265         echo Disable read-ahead
10266         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10267
10268         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10269         for blk in $PAGE_SIZE 1048576 $file_size; do
10270                 cancel_lru_locks osc
10271                 echo "Reset readahead stats"
10272                 $LCTL set_param -n llite.*.read_ahead_stats=0
10273                 local count=$(($file_size / $blk))
10274                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10275                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10276                              get_named_value 'failed.to.fast.read' | calc_total)
10277                 $LCTL get_param -n llite.*.read_ahead_stats
10278                 [ $miss -eq $count ] || error "expected $count got $miss"
10279         done
10280
10281         rm -f $p $DIR/$tfile
10282 }
10283 run_test 101j "A complete read block should be submitted when no RA"
10284
10285 setup_test102() {
10286         test_mkdir $DIR/$tdir
10287         chown $RUNAS_ID $DIR/$tdir
10288         STRIPE_SIZE=65536
10289         STRIPE_OFFSET=1
10290         STRIPE_COUNT=$OSTCOUNT
10291         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10292
10293         trap cleanup_test102 EXIT
10294         cd $DIR
10295         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10296         cd $DIR/$tdir
10297         for num in 1 2 3 4; do
10298                 for count in $(seq 1 $STRIPE_COUNT); do
10299                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10300                                 local size=`expr $STRIPE_SIZE \* $num`
10301                                 local file=file"$num-$idx-$count"
10302                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10303                         done
10304                 done
10305         done
10306
10307         cd $DIR
10308         $1 tar cf $TMP/f102.tar $tdir --xattrs
10309 }
10310
10311 cleanup_test102() {
10312         trap 0
10313         rm -f $TMP/f102.tar
10314         rm -rf $DIR/d0.sanity/d102
10315 }
10316
10317 test_102a() {
10318         [ "$UID" != 0 ] && skip "must run as root"
10319         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10320                 skip_env "must have user_xattr"
10321
10322         [ -z "$(which setfattr 2>/dev/null)" ] &&
10323                 skip_env "could not find setfattr"
10324
10325         local testfile=$DIR/$tfile
10326
10327         touch $testfile
10328         echo "set/get xattr..."
10329         setfattr -n trusted.name1 -v value1 $testfile ||
10330                 error "setfattr -n trusted.name1=value1 $testfile failed"
10331         getfattr -n trusted.name1 $testfile 2> /dev/null |
10332           grep "trusted.name1=.value1" ||
10333                 error "$testfile missing trusted.name1=value1"
10334
10335         setfattr -n user.author1 -v author1 $testfile ||
10336                 error "setfattr -n user.author1=author1 $testfile failed"
10337         getfattr -n user.author1 $testfile 2> /dev/null |
10338           grep "user.author1=.author1" ||
10339                 error "$testfile missing trusted.author1=author1"
10340
10341         echo "listxattr..."
10342         setfattr -n trusted.name2 -v value2 $testfile ||
10343                 error "$testfile unable to set trusted.name2"
10344         setfattr -n trusted.name3 -v value3 $testfile ||
10345                 error "$testfile unable to set trusted.name3"
10346         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10347             grep "trusted.name" | wc -l) -eq 3 ] ||
10348                 error "$testfile missing 3 trusted.name xattrs"
10349
10350         setfattr -n user.author2 -v author2 $testfile ||
10351                 error "$testfile unable to set user.author2"
10352         setfattr -n user.author3 -v author3 $testfile ||
10353                 error "$testfile unable to set user.author3"
10354         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10355             grep "user.author" | wc -l) -eq 3 ] ||
10356                 error "$testfile missing 3 user.author xattrs"
10357
10358         echo "remove xattr..."
10359         setfattr -x trusted.name1 $testfile ||
10360                 error "$testfile error deleting trusted.name1"
10361         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10362                 error "$testfile did not delete trusted.name1 xattr"
10363
10364         setfattr -x user.author1 $testfile ||
10365                 error "$testfile error deleting user.author1"
10366         echo "set lustre special xattr ..."
10367         $LFS setstripe -c1 $testfile
10368         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10369                 awk -F "=" '/trusted.lov/ { print $2 }' )
10370         setfattr -n "trusted.lov" -v $lovea $testfile ||
10371                 error "$testfile doesn't ignore setting trusted.lov again"
10372         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10373                 error "$testfile allow setting invalid trusted.lov"
10374         rm -f $testfile
10375 }
10376 run_test 102a "user xattr test =================================="
10377
10378 check_102b_layout() {
10379         local layout="$*"
10380         local testfile=$DIR/$tfile
10381
10382         echo "test layout '$layout'"
10383         $LFS setstripe $layout $testfile || error "setstripe failed"
10384         $LFS getstripe -y $testfile
10385
10386         echo "get/set/list trusted.lov xattr ..." # b=10930
10387         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10388         [[ "$value" =~ "trusted.lov" ]] ||
10389                 error "can't get trusted.lov from $testfile"
10390         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10391                 error "getstripe failed"
10392
10393         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10394
10395         value=$(cut -d= -f2 <<<$value)
10396         # LU-13168: truncated xattr should fail if short lov_user_md header
10397         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10398                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10399         for len in $lens; do
10400                 echo "setfattr $len $testfile.2"
10401                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10402                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10403         done
10404         local stripe_size=$($LFS getstripe -S $testfile.2)
10405         local stripe_count=$($LFS getstripe -c $testfile.2)
10406         [[ $stripe_size -eq 65536 ]] ||
10407                 error "stripe size $stripe_size != 65536"
10408         [[ $stripe_count -eq $stripe_count_orig ]] ||
10409                 error "stripe count $stripe_count != $stripe_count_orig"
10410         rm $testfile $testfile.2
10411 }
10412
10413 test_102b() {
10414         [ -z "$(which setfattr 2>/dev/null)" ] &&
10415                 skip_env "could not find setfattr"
10416         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10417
10418         # check plain layout
10419         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10420
10421         # and also check composite layout
10422         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10423
10424 }
10425 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10426
10427 test_102c() {
10428         [ -z "$(which setfattr 2>/dev/null)" ] &&
10429                 skip_env "could not find setfattr"
10430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10431
10432         # b10930: get/set/list lustre.lov xattr
10433         echo "get/set/list lustre.lov xattr ..."
10434         test_mkdir $DIR/$tdir
10435         chown $RUNAS_ID $DIR/$tdir
10436         local testfile=$DIR/$tdir/$tfile
10437         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10438                 error "setstripe failed"
10439         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10440                 error "getstripe failed"
10441         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10442         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10443
10444         local testfile2=${testfile}2
10445         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10446                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10447
10448         $RUNAS $MCREATE $testfile2
10449         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10450         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10451         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10452         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10453         [ $stripe_count -eq $STRIPECOUNT ] ||
10454                 error "stripe count $stripe_count != $STRIPECOUNT"
10455 }
10456 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10457
10458 compare_stripe_info1() {
10459         local stripe_index_all_zero=true
10460
10461         for num in 1 2 3 4; do
10462                 for count in $(seq 1 $STRIPE_COUNT); do
10463                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10464                                 local size=$((STRIPE_SIZE * num))
10465                                 local file=file"$num-$offset-$count"
10466                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10467                                 [[ $stripe_size -ne $size ]] &&
10468                                     error "$file: size $stripe_size != $size"
10469                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10470                                 # allow fewer stripes to be created, ORI-601
10471                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10472                                     error "$file: count $stripe_count != $count"
10473                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10474                                 [[ $stripe_index -ne 0 ]] &&
10475                                         stripe_index_all_zero=false
10476                         done
10477                 done
10478         done
10479         $stripe_index_all_zero &&
10480                 error "all files are being extracted starting from OST index 0"
10481         return 0
10482 }
10483
10484 have_xattrs_include() {
10485         tar --help | grep -q xattrs-include &&
10486                 echo --xattrs-include="lustre.*"
10487 }
10488
10489 test_102d() {
10490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10491         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10492
10493         XINC=$(have_xattrs_include)
10494         setup_test102
10495         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10496         cd $DIR/$tdir/$tdir
10497         compare_stripe_info1
10498 }
10499 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10500
10501 test_102f() {
10502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10503         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10504
10505         XINC=$(have_xattrs_include)
10506         setup_test102
10507         test_mkdir $DIR/$tdir.restore
10508         cd $DIR
10509         tar cf - --xattrs $tdir | tar xf - \
10510                 -C $DIR/$tdir.restore --xattrs $XINC
10511         cd $DIR/$tdir.restore/$tdir
10512         compare_stripe_info1
10513 }
10514 run_test 102f "tar copy files, not keep osts"
10515
10516 grow_xattr() {
10517         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10518                 skip "must have user_xattr"
10519         [ -z "$(which setfattr 2>/dev/null)" ] &&
10520                 skip_env "could not find setfattr"
10521         [ -z "$(which getfattr 2>/dev/null)" ] &&
10522                 skip_env "could not find getfattr"
10523
10524         local xsize=${1:-1024}  # in bytes
10525         local file=$DIR/$tfile
10526         local value="$(generate_string $xsize)"
10527         local xbig=trusted.big
10528         local toobig=$2
10529
10530         touch $file
10531         log "save $xbig on $file"
10532         if [ -z "$toobig" ]
10533         then
10534                 setfattr -n $xbig -v $value $file ||
10535                         error "saving $xbig on $file failed"
10536         else
10537                 setfattr -n $xbig -v $value $file &&
10538                         error "saving $xbig on $file succeeded"
10539                 return 0
10540         fi
10541
10542         local orig=$(get_xattr_value $xbig $file)
10543         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10544
10545         local xsml=trusted.sml
10546         log "save $xsml on $file"
10547         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10548
10549         local new=$(get_xattr_value $xbig $file)
10550         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10551
10552         log "grow $xsml on $file"
10553         setfattr -n $xsml -v "$value" $file ||
10554                 error "growing $xsml on $file failed"
10555
10556         new=$(get_xattr_value $xbig $file)
10557         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10558         log "$xbig still valid after growing $xsml"
10559
10560         rm -f $file
10561 }
10562
10563 test_102h() { # bug 15777
10564         grow_xattr 1024
10565 }
10566 run_test 102h "grow xattr from inside inode to external block"
10567
10568 test_102ha() {
10569         large_xattr_enabled || skip_env "ea_inode feature disabled"
10570
10571         echo "setting xattr of max xattr size: $(max_xattr_size)"
10572         grow_xattr $(max_xattr_size)
10573
10574         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10575         echo "This should fail:"
10576         grow_xattr $(($(max_xattr_size) + 10)) 1
10577 }
10578 run_test 102ha "grow xattr from inside inode to external inode"
10579
10580 test_102i() { # bug 17038
10581         [ -z "$(which getfattr 2>/dev/null)" ] &&
10582                 skip "could not find getfattr"
10583
10584         touch $DIR/$tfile
10585         ln -s $DIR/$tfile $DIR/${tfile}link
10586         getfattr -n trusted.lov $DIR/$tfile ||
10587                 error "lgetxattr on $DIR/$tfile failed"
10588         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10589                 grep -i "no such attr" ||
10590                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10591         rm -f $DIR/$tfile $DIR/${tfile}link
10592 }
10593 run_test 102i "lgetxattr test on symbolic link ============"
10594
10595 test_102j() {
10596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10597         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10598
10599         XINC=$(have_xattrs_include)
10600         setup_test102 "$RUNAS"
10601         chown $RUNAS_ID $DIR/$tdir
10602         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10603         cd $DIR/$tdir/$tdir
10604         compare_stripe_info1 "$RUNAS"
10605 }
10606 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10607
10608 test_102k() {
10609         [ -z "$(which setfattr 2>/dev/null)" ] &&
10610                 skip "could not find setfattr"
10611
10612         touch $DIR/$tfile
10613         # b22187 just check that does not crash for regular file.
10614         setfattr -n trusted.lov $DIR/$tfile
10615         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10616         local test_kdir=$DIR/$tdir
10617         test_mkdir $test_kdir
10618         local default_size=$($LFS getstripe -S $test_kdir)
10619         local default_count=$($LFS getstripe -c $test_kdir)
10620         local default_offset=$($LFS getstripe -i $test_kdir)
10621         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10622                 error 'dir setstripe failed'
10623         setfattr -n trusted.lov $test_kdir
10624         local stripe_size=$($LFS getstripe -S $test_kdir)
10625         local stripe_count=$($LFS getstripe -c $test_kdir)
10626         local stripe_offset=$($LFS getstripe -i $test_kdir)
10627         [ $stripe_size -eq $default_size ] ||
10628                 error "stripe size $stripe_size != $default_size"
10629         [ $stripe_count -eq $default_count ] ||
10630                 error "stripe count $stripe_count != $default_count"
10631         [ $stripe_offset -eq $default_offset ] ||
10632                 error "stripe offset $stripe_offset != $default_offset"
10633         rm -rf $DIR/$tfile $test_kdir
10634 }
10635 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10636
10637 test_102l() {
10638         [ -z "$(which getfattr 2>/dev/null)" ] &&
10639                 skip "could not find getfattr"
10640
10641         # LU-532 trusted. xattr is invisible to non-root
10642         local testfile=$DIR/$tfile
10643
10644         touch $testfile
10645
10646         echo "listxattr as user..."
10647         chown $RUNAS_ID $testfile
10648         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10649             grep -q "trusted" &&
10650                 error "$testfile trusted xattrs are user visible"
10651
10652         return 0;
10653 }
10654 run_test 102l "listxattr size test =================================="
10655
10656 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10657         local path=$DIR/$tfile
10658         touch $path
10659
10660         listxattr_size_check $path || error "listattr_size_check $path failed"
10661 }
10662 run_test 102m "Ensure listxattr fails on small bufffer ========"
10663
10664 cleanup_test102
10665
10666 getxattr() { # getxattr path name
10667         # Return the base64 encoding of the value of xattr name on path.
10668         local path=$1
10669         local name=$2
10670
10671         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10672         # file: $path
10673         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10674         #
10675         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10676
10677         getfattr --absolute-names --encoding=base64 --name=$name $path |
10678                 awk -F= -v name=$name '$1 == name {
10679                         print substr($0, index($0, "=") + 1);
10680         }'
10681 }
10682
10683 test_102n() { # LU-4101 mdt: protect internal xattrs
10684         [ -z "$(which setfattr 2>/dev/null)" ] &&
10685                 skip "could not find setfattr"
10686         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10687         then
10688                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10689         fi
10690
10691         local file0=$DIR/$tfile.0
10692         local file1=$DIR/$tfile.1
10693         local xattr0=$TMP/$tfile.0
10694         local xattr1=$TMP/$tfile.1
10695         local namelist="lov lma lmv link fid version som hsm"
10696         local name
10697         local value
10698
10699         rm -rf $file0 $file1 $xattr0 $xattr1
10700         touch $file0 $file1
10701
10702         # Get 'before' xattrs of $file1.
10703         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10704
10705         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10706                 namelist+=" lfsck_namespace"
10707         for name in $namelist; do
10708                 # Try to copy xattr from $file0 to $file1.
10709                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10710
10711                 setfattr --name=trusted.$name --value="$value" $file1 ||
10712                         error "setxattr 'trusted.$name' failed"
10713
10714                 # Try to set a garbage xattr.
10715                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10716
10717                 if [[ x$name == "xlov" ]]; then
10718                         setfattr --name=trusted.lov --value="$value" $file1 &&
10719                         error "setxattr invalid 'trusted.lov' success"
10720                 else
10721                         setfattr --name=trusted.$name --value="$value" $file1 ||
10722                                 error "setxattr invalid 'trusted.$name' failed"
10723                 fi
10724
10725                 # Try to remove the xattr from $file1. We don't care if this
10726                 # appears to succeed or fail, we just don't want there to be
10727                 # any changes or crashes.
10728                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10729         done
10730
10731         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10732         then
10733                 name="lfsck_ns"
10734                 # Try to copy xattr from $file0 to $file1.
10735                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10736
10737                 setfattr --name=trusted.$name --value="$value" $file1 ||
10738                         error "setxattr 'trusted.$name' failed"
10739
10740                 # Try to set a garbage xattr.
10741                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10742
10743                 setfattr --name=trusted.$name --value="$value" $file1 ||
10744                         error "setxattr 'trusted.$name' failed"
10745
10746                 # Try to remove the xattr from $file1. We don't care if this
10747                 # appears to succeed or fail, we just don't want there to be
10748                 # any changes or crashes.
10749                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10750         fi
10751
10752         # Get 'after' xattrs of file1.
10753         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10754
10755         if ! diff $xattr0 $xattr1; then
10756                 error "before and after xattrs of '$file1' differ"
10757         fi
10758
10759         rm -rf $file0 $file1 $xattr0 $xattr1
10760
10761         return 0
10762 }
10763 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10764
10765 test_102p() { # LU-4703 setxattr did not check ownership
10766         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10767                 skip "MDS needs to be at least 2.5.56"
10768
10769         local testfile=$DIR/$tfile
10770
10771         touch $testfile
10772
10773         echo "setfacl as user..."
10774         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10775         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10776
10777         echo "setfattr as user..."
10778         setfacl -m "u:$RUNAS_ID:---" $testfile
10779         $RUNAS setfattr -x system.posix_acl_access $testfile
10780         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10781 }
10782 run_test 102p "check setxattr(2) correctly fails without permission"
10783
10784 test_102q() {
10785         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10786                 skip "MDS needs to be at least 2.6.92"
10787
10788         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10789 }
10790 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10791
10792 test_102r() {
10793         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10794                 skip "MDS needs to be at least 2.6.93"
10795
10796         touch $DIR/$tfile || error "touch"
10797         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10798         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10799         rm $DIR/$tfile || error "rm"
10800
10801         #normal directory
10802         mkdir -p $DIR/$tdir || error "mkdir"
10803         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10804         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10805         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10806                 error "$testfile error deleting user.author1"
10807         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10808                 grep "user.$(basename $tdir)" &&
10809                 error "$tdir did not delete user.$(basename $tdir)"
10810         rmdir $DIR/$tdir || error "rmdir"
10811
10812         #striped directory
10813         test_mkdir $DIR/$tdir
10814         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10815         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10816         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10817                 error "$testfile error deleting user.author1"
10818         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10819                 grep "user.$(basename $tdir)" &&
10820                 error "$tdir did not delete user.$(basename $tdir)"
10821         rmdir $DIR/$tdir || error "rm striped dir"
10822 }
10823 run_test 102r "set EAs with empty values"
10824
10825 test_102s() {
10826         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10827                 skip "MDS needs to be at least 2.11.52"
10828
10829         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10830
10831         save_lustre_params client "llite.*.xattr_cache" > $save
10832
10833         for cache in 0 1; do
10834                 lctl set_param llite.*.xattr_cache=$cache
10835
10836                 rm -f $DIR/$tfile
10837                 touch $DIR/$tfile || error "touch"
10838                 for prefix in lustre security system trusted user; do
10839                         # Note getxattr() may fail with 'Operation not
10840                         # supported' or 'No such attribute' depending
10841                         # on prefix and cache.
10842                         getfattr -n $prefix.n102s $DIR/$tfile &&
10843                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10844                 done
10845         done
10846
10847         restore_lustre_params < $save
10848 }
10849 run_test 102s "getting nonexistent xattrs should fail"
10850
10851 test_102t() {
10852         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10853                 skip "MDS needs to be at least 2.11.52"
10854
10855         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10856
10857         save_lustre_params client "llite.*.xattr_cache" > $save
10858
10859         for cache in 0 1; do
10860                 lctl set_param llite.*.xattr_cache=$cache
10861
10862                 for buf_size in 0 256; do
10863                         rm -f $DIR/$tfile
10864                         touch $DIR/$tfile || error "touch"
10865                         setfattr -n user.multiop $DIR/$tfile
10866                         $MULTIOP $DIR/$tfile oa$buf_size ||
10867                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10868                 done
10869         done
10870
10871         restore_lustre_params < $save
10872 }
10873 run_test 102t "zero length xattr values handled correctly"
10874
10875 run_acl_subtest()
10876 {
10877     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10878     return $?
10879 }
10880
10881 test_103a() {
10882         [ "$UID" != 0 ] && skip "must run as root"
10883         $GSS && skip_env "could not run under gss"
10884         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10885                 skip_env "must have acl enabled"
10886         [ -z "$(which setfacl 2>/dev/null)" ] &&
10887                 skip_env "could not find setfacl"
10888         remote_mds_nodsh && skip "remote MDS with nodsh"
10889
10890         gpasswd -a daemon bin                           # LU-5641
10891         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10892
10893         declare -a identity_old
10894
10895         for num in $(seq $MDSCOUNT); do
10896                 switch_identity $num true || identity_old[$num]=$?
10897         done
10898
10899         SAVE_UMASK=$(umask)
10900         umask 0022
10901         mkdir -p $DIR/$tdir
10902         cd $DIR/$tdir
10903
10904         echo "performing cp ..."
10905         run_acl_subtest cp || error "run_acl_subtest cp failed"
10906         echo "performing getfacl-noacl..."
10907         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10908         echo "performing misc..."
10909         run_acl_subtest misc || error  "misc test failed"
10910         echo "performing permissions..."
10911         run_acl_subtest permissions || error "permissions failed"
10912         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10913         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10914                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10915                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10916         then
10917                 echo "performing permissions xattr..."
10918                 run_acl_subtest permissions_xattr ||
10919                         error "permissions_xattr failed"
10920         fi
10921         echo "performing setfacl..."
10922         run_acl_subtest setfacl || error  "setfacl test failed"
10923
10924         # inheritance test got from HP
10925         echo "performing inheritance..."
10926         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10927         chmod +x make-tree || error "chmod +x failed"
10928         run_acl_subtest inheritance || error "inheritance test failed"
10929         rm -f make-tree
10930
10931         echo "LU-974 ignore umask when acl is enabled..."
10932         run_acl_subtest 974 || error "LU-974 umask test failed"
10933         if [ $MDSCOUNT -ge 2 ]; then
10934                 run_acl_subtest 974_remote ||
10935                         error "LU-974 umask test failed under remote dir"
10936         fi
10937
10938         echo "LU-2561 newly created file is same size as directory..."
10939         if [ "$mds1_FSTYPE" != "zfs" ]; then
10940                 run_acl_subtest 2561 || error "LU-2561 test failed"
10941         else
10942                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10943         fi
10944
10945         run_acl_subtest 4924 || error "LU-4924 test failed"
10946
10947         cd $SAVE_PWD
10948         umask $SAVE_UMASK
10949
10950         for num in $(seq $MDSCOUNT); do
10951                 if [ "${identity_old[$num]}" = 1 ]; then
10952                         switch_identity $num false || identity_old[$num]=$?
10953                 fi
10954         done
10955 }
10956 run_test 103a "acl test"
10957
10958 test_103b() {
10959         declare -a pids
10960         local U
10961
10962         for U in {0..511}; do
10963                 {
10964                 local O=$(printf "%04o" $U)
10965
10966                 umask $(printf "%04o" $((511 ^ $O)))
10967                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10968                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10969
10970                 (( $S == ($O & 0666) )) ||
10971                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10972
10973                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10974                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10975                 (( $S == ($O & 0666) )) ||
10976                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10977
10978                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10979                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10980                 (( $S == ($O & 0666) )) ||
10981                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10982                 rm -f $DIR/$tfile.[smp]$0
10983                 } &
10984                 local pid=$!
10985
10986                 # limit the concurrently running threads to 64. LU-11878
10987                 local idx=$((U % 64))
10988                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10989                 pids[idx]=$pid
10990         done
10991         wait
10992 }
10993 run_test 103b "umask lfs setstripe"
10994
10995 test_103c() {
10996         mkdir -p $DIR/$tdir
10997         cp -rp $DIR/$tdir $DIR/$tdir.bak
10998
10999         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11000                 error "$DIR/$tdir shouldn't contain default ACL"
11001         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11002                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11003         true
11004 }
11005 run_test 103c "'cp -rp' won't set empty acl"
11006
11007 test_103e() {
11008         local numacl
11009         local fileacl
11010         local saved_debug=$($LCTL get_param -n debug)
11011
11012         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11013                 skip "MDS needs to be at least 2.14.0"
11014
11015         large_xattr_enabled || skip_env "ea_inode feature disabled"
11016
11017         mkdir -p $DIR/$tdir
11018         # add big LOV EA to cause reply buffer overflow earlier
11019         $LFS setstripe -C 1000 $DIR/$tdir
11020         lctl set_param mdc.*-mdc*.stats=clear
11021
11022         $LCTL set_param debug=0
11023         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11024         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11025
11026         # add a large number of default ACLs (expect 8000+ for 2.13+)
11027         for U in {2..7000}; do
11028                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11029                         error "Able to add just $U default ACLs"
11030         done
11031         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11032         echo "$numacl default ACLs created"
11033
11034         stat $DIR/$tdir || error "Cannot stat directory"
11035         # check file creation
11036         touch $DIR/$tdir/$tfile ||
11037                 error "failed to create $tfile with $numacl default ACLs"
11038         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11039         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11040         echo "$fileacl ACLs were inherited"
11041         (( $fileacl == $numacl )) ||
11042                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11043         # check that new ACLs creation adds new ACLs to inherited ACLs
11044         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11045                 error "Cannot set new ACL"
11046         numacl=$((numacl + 1))
11047         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11048         (( $fileacl == $numacl )) ||
11049                 error "failed to add new ACL: $fileacl != $numacl as expected"
11050         # adds more ACLs to a file to reach their maximum at 8000+
11051         numacl=0
11052         for U in {20000..25000}; do
11053                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11054                 numacl=$((numacl + 1))
11055         done
11056         echo "Added $numacl more ACLs to the file"
11057         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11058         echo "Total $fileacl ACLs in file"
11059         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11060         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11061         rmdir $DIR/$tdir || error "Cannot remove directory"
11062 }
11063 run_test 103e "inheritance of big amount of default ACLs"
11064
11065 test_103f() {
11066         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11067                 skip "MDS needs to be at least 2.14.51"
11068
11069         large_xattr_enabled || skip_env "ea_inode feature disabled"
11070
11071         # enable changelog to consume more internal MDD buffers
11072         changelog_register
11073
11074         mkdir -p $DIR/$tdir
11075         # add big LOV EA
11076         $LFS setstripe -C 1000 $DIR/$tdir
11077         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11078         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11079         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11080         rmdir $DIR/$tdir || error "Cannot remove directory"
11081 }
11082 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11083
11084 test_104a() {
11085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11086
11087         touch $DIR/$tfile
11088         lfs df || error "lfs df failed"
11089         lfs df -ih || error "lfs df -ih failed"
11090         lfs df -h $DIR || error "lfs df -h $DIR failed"
11091         lfs df -i $DIR || error "lfs df -i $DIR failed"
11092         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11093         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11094
11095         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11096         lctl --device %$OSC deactivate
11097         lfs df || error "lfs df with deactivated OSC failed"
11098         lctl --device %$OSC activate
11099         # wait the osc back to normal
11100         wait_osc_import_ready client ost
11101
11102         lfs df || error "lfs df with reactivated OSC failed"
11103         rm -f $DIR/$tfile
11104 }
11105 run_test 104a "lfs df [-ih] [path] test ========================="
11106
11107 test_104b() {
11108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11109         [ $RUNAS_ID -eq $UID ] &&
11110                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11111
11112         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11113                         grep "Permission denied" | wc -l)))
11114         if [ $denied_cnt -ne 0 ]; then
11115                 error "lfs check servers test failed"
11116         fi
11117 }
11118 run_test 104b "$RUNAS lfs check servers test ===================="
11119
11120 #
11121 # Verify $1 is within range of $2.
11122 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11123 # $1 is <= 2% of $2. Else Fail.
11124 #
11125 value_in_range() {
11126         # Strip all units (M, G, T)
11127         actual=$(echo $1 | tr -d A-Z)
11128         expect=$(echo $2 | tr -d A-Z)
11129
11130         expect_lo=$(($expect * 98 / 100)) # 2% below
11131         expect_hi=$(($expect * 102 / 100)) # 2% above
11132
11133         # permit 2% drift above and below
11134         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11135 }
11136
11137 test_104c() {
11138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11139         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11140
11141         local ost_param="osd-zfs.$FSNAME-OST0000."
11142         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11143         local ofacets=$(get_facets OST)
11144         local mfacets=$(get_facets MDS)
11145         local saved_ost_blocks=
11146         local saved_mdt_blocks=
11147
11148         echo "Before recordsize change"
11149         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11150         df=($(df -h | grep "/mnt/lustre"$))
11151
11152         # For checking.
11153         echo "lfs output : ${lfs_df[*]}"
11154         echo "df  output : ${df[*]}"
11155
11156         for facet in ${ofacets//,/ }; do
11157                 if [ -z $saved_ost_blocks ]; then
11158                         saved_ost_blocks=$(do_facet $facet \
11159                                 lctl get_param -n $ost_param.blocksize)
11160                         echo "OST Blocksize: $saved_ost_blocks"
11161                 fi
11162                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11163                 do_facet $facet zfs set recordsize=32768 $ost
11164         done
11165
11166         # BS too small. Sufficient for functional testing.
11167         for facet in ${mfacets//,/ }; do
11168                 if [ -z $saved_mdt_blocks ]; then
11169                         saved_mdt_blocks=$(do_facet $facet \
11170                                 lctl get_param -n $mdt_param.blocksize)
11171                         echo "MDT Blocksize: $saved_mdt_blocks"
11172                 fi
11173                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11174                 do_facet $facet zfs set recordsize=32768 $mdt
11175         done
11176
11177         # Give new values chance to reflect change
11178         sleep 2
11179
11180         echo "After recordsize change"
11181         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11182         df_after=($(df -h | grep "/mnt/lustre"$))
11183
11184         # For checking.
11185         echo "lfs output : ${lfs_df_after[*]}"
11186         echo "df  output : ${df_after[*]}"
11187
11188         # Verify lfs df
11189         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11190                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11191         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11192                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11193         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11194                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11195
11196         # Verify df
11197         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11198                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11199         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11200                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11201         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11202                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11203
11204         # Restore MDT recordize back to original
11205         for facet in ${mfacets//,/ }; do
11206                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11207                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11208         done
11209
11210         # Restore OST recordize back to original
11211         for facet in ${ofacets//,/ }; do
11212                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11213                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11214         done
11215
11216         return 0
11217 }
11218 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11219
11220 test_105a() {
11221         # doesn't work on 2.4 kernels
11222         touch $DIR/$tfile
11223         if $(flock_is_enabled); then
11224                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11225         else
11226                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11227         fi
11228         rm -f $DIR/$tfile
11229 }
11230 run_test 105a "flock when mounted without -o flock test ========"
11231
11232 test_105b() {
11233         touch $DIR/$tfile
11234         if $(flock_is_enabled); then
11235                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11236         else
11237                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11238         fi
11239         rm -f $DIR/$tfile
11240 }
11241 run_test 105b "fcntl when mounted without -o flock test ========"
11242
11243 test_105c() {
11244         touch $DIR/$tfile
11245         if $(flock_is_enabled); then
11246                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11247         else
11248                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11249         fi
11250         rm -f $DIR/$tfile
11251 }
11252 run_test 105c "lockf when mounted without -o flock test"
11253
11254 test_105d() { # bug 15924
11255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11256
11257         test_mkdir $DIR/$tdir
11258         flock_is_enabled || skip_env "mount w/o flock enabled"
11259         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11260         $LCTL set_param fail_loc=0x80000315
11261         flocks_test 2 $DIR/$tdir
11262 }
11263 run_test 105d "flock race (should not freeze) ========"
11264
11265 test_105e() { # bug 22660 && 22040
11266         flock_is_enabled || skip_env "mount w/o flock enabled"
11267
11268         touch $DIR/$tfile
11269         flocks_test 3 $DIR/$tfile
11270 }
11271 run_test 105e "Two conflicting flocks from same process"
11272
11273 test_106() { #bug 10921
11274         test_mkdir $DIR/$tdir
11275         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11276         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11277 }
11278 run_test 106 "attempt exec of dir followed by chown of that dir"
11279
11280 test_107() {
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282
11283         CDIR=`pwd`
11284         local file=core
11285
11286         cd $DIR
11287         rm -f $file
11288
11289         local save_pattern=$(sysctl -n kernel.core_pattern)
11290         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11291         sysctl -w kernel.core_pattern=$file
11292         sysctl -w kernel.core_uses_pid=0
11293
11294         ulimit -c unlimited
11295         sleep 60 &
11296         SLEEPPID=$!
11297
11298         sleep 1
11299
11300         kill -s 11 $SLEEPPID
11301         wait $SLEEPPID
11302         if [ -e $file ]; then
11303                 size=`stat -c%s $file`
11304                 [ $size -eq 0 ] && error "Fail to create core file $file"
11305         else
11306                 error "Fail to create core file $file"
11307         fi
11308         rm -f $file
11309         sysctl -w kernel.core_pattern=$save_pattern
11310         sysctl -w kernel.core_uses_pid=$save_uses_pid
11311         cd $CDIR
11312 }
11313 run_test 107 "Coredump on SIG"
11314
11315 test_110() {
11316         test_mkdir $DIR/$tdir
11317         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11318         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11319                 error "mkdir with 256 char should fail, but did not"
11320         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11321                 error "create with 255 char failed"
11322         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11323                 error "create with 256 char should fail, but did not"
11324
11325         ls -l $DIR/$tdir
11326         rm -rf $DIR/$tdir
11327 }
11328 run_test 110 "filename length checking"
11329
11330 #
11331 # Purpose: To verify dynamic thread (OSS) creation.
11332 #
11333 test_115() {
11334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11335         remote_ost_nodsh && skip "remote OST with nodsh"
11336
11337         # Lustre does not stop service threads once they are started.
11338         # Reset number of running threads to default.
11339         stopall
11340         setupall
11341
11342         local OSTIO_pre
11343         local save_params="$TMP/sanity-$TESTNAME.parameters"
11344
11345         # Get ll_ost_io count before I/O
11346         OSTIO_pre=$(do_facet ost1 \
11347                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11348         # Exit if lustre is not running (ll_ost_io not running).
11349         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11350
11351         echo "Starting with $OSTIO_pre threads"
11352         local thread_max=$((OSTIO_pre * 2))
11353         local rpc_in_flight=$((thread_max * 2))
11354         # Number of I/O Process proposed to be started.
11355         local nfiles
11356         local facets=$(get_facets OST)
11357
11358         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11359         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11360
11361         # Set in_flight to $rpc_in_flight
11362         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11363                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11364         nfiles=${rpc_in_flight}
11365         # Set ost thread_max to $thread_max
11366         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11367
11368         # 5 Minutes should be sufficient for max number of OSS
11369         # threads(thread_max) to be created.
11370         local timeout=300
11371
11372         # Start I/O.
11373         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11374         test_mkdir $DIR/$tdir
11375         for i in $(seq $nfiles); do
11376                 local file=$DIR/$tdir/${tfile}-$i
11377                 $LFS setstripe -c -1 -i 0 $file
11378                 ($WTL $file $timeout)&
11379         done
11380
11381         # I/O Started - Wait for thread_started to reach thread_max or report
11382         # error if thread_started is more than thread_max.
11383         echo "Waiting for thread_started to reach thread_max"
11384         local thread_started=0
11385         local end_time=$((SECONDS + timeout))
11386
11387         while [ $SECONDS -le $end_time ] ; do
11388                 echo -n "."
11389                 # Get ost i/o thread_started count.
11390                 thread_started=$(do_facet ost1 \
11391                         "$LCTL get_param \
11392                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11393                 # Break out if thread_started is equal/greater than thread_max
11394                 if [[ $thread_started -ge $thread_max ]]; then
11395                         echo ll_ost_io thread_started $thread_started, \
11396                                 equal/greater than thread_max $thread_max
11397                         break
11398                 fi
11399                 sleep 1
11400         done
11401
11402         # Cleanup - We have the numbers, Kill i/o jobs if running.
11403         jobcount=($(jobs -p))
11404         for i in $(seq 0 $((${#jobcount[@]}-1)))
11405         do
11406                 kill -9 ${jobcount[$i]}
11407                 if [ $? -ne 0 ] ; then
11408                         echo Warning: \
11409                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11410                 fi
11411         done
11412
11413         # Cleanup files left by WTL binary.
11414         for i in $(seq $nfiles); do
11415                 local file=$DIR/$tdir/${tfile}-$i
11416                 rm -rf $file
11417                 if [ $? -ne 0 ] ; then
11418                         echo "Warning: Failed to delete file $file"
11419                 fi
11420         done
11421
11422         restore_lustre_params <$save_params
11423         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11424
11425         # Error out if no new thread has started or Thread started is greater
11426         # than thread max.
11427         if [[ $thread_started -le $OSTIO_pre ||
11428                         $thread_started -gt $thread_max ]]; then
11429                 error "ll_ost_io: thread_started $thread_started" \
11430                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11431                       "No new thread started or thread started greater " \
11432                       "than thread_max."
11433         fi
11434 }
11435 run_test 115 "verify dynamic thread creation===================="
11436
11437 free_min_max () {
11438         wait_delete_completed
11439         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11440         echo "OST kbytes available: ${AVAIL[@]}"
11441         MAXV=${AVAIL[0]}
11442         MAXI=0
11443         MINV=${AVAIL[0]}
11444         MINI=0
11445         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11446                 #echo OST $i: ${AVAIL[i]}kb
11447                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11448                         MAXV=${AVAIL[i]}
11449                         MAXI=$i
11450                 fi
11451                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11452                         MINV=${AVAIL[i]}
11453                         MINI=$i
11454                 fi
11455         done
11456         echo "Min free space: OST $MINI: $MINV"
11457         echo "Max free space: OST $MAXI: $MAXV"
11458 }
11459
11460 test_116a() { # was previously test_116()
11461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11462         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11463         remote_mds_nodsh && skip "remote MDS with nodsh"
11464
11465         echo -n "Free space priority "
11466         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11467                 head -n1
11468         declare -a AVAIL
11469         free_min_max
11470
11471         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11472         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11473         trap simple_cleanup_common EXIT
11474
11475         # Check if we need to generate uneven OSTs
11476         test_mkdir -p $DIR/$tdir/OST${MINI}
11477         local FILL=$((MINV / 4))
11478         local DIFF=$((MAXV - MINV))
11479         local DIFF2=$((DIFF * 100 / MINV))
11480
11481         local threshold=$(do_facet $SINGLEMDS \
11482                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11483         threshold=${threshold%%%}
11484         echo -n "Check for uneven OSTs: "
11485         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11486
11487         if [[ $DIFF2 -gt $threshold ]]; then
11488                 echo "ok"
11489                 echo "Don't need to fill OST$MINI"
11490         else
11491                 # generate uneven OSTs. Write 2% over the QOS threshold value
11492                 echo "no"
11493                 DIFF=$((threshold - DIFF2 + 2))
11494                 DIFF2=$((MINV * DIFF / 100))
11495                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11496                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11497                         error "setstripe failed"
11498                 DIFF=$((DIFF2 / 2048))
11499                 i=0
11500                 while [ $i -lt $DIFF ]; do
11501                         i=$((i + 1))
11502                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11503                                 bs=2M count=1 2>/dev/null
11504                         echo -n .
11505                 done
11506                 echo .
11507                 sync
11508                 sleep_maxage
11509                 free_min_max
11510         fi
11511
11512         DIFF=$((MAXV - MINV))
11513         DIFF2=$((DIFF * 100 / MINV))
11514         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11515         if [ $DIFF2 -gt $threshold ]; then
11516                 echo "ok"
11517         else
11518                 echo "failed - QOS mode won't be used"
11519                 simple_cleanup_common
11520                 skip "QOS imbalance criteria not met"
11521         fi
11522
11523         MINI1=$MINI
11524         MINV1=$MINV
11525         MAXI1=$MAXI
11526         MAXV1=$MAXV
11527
11528         # now fill using QOS
11529         $LFS setstripe -c 1 $DIR/$tdir
11530         FILL=$((FILL / 200))
11531         if [ $FILL -gt 600 ]; then
11532                 FILL=600
11533         fi
11534         echo "writing $FILL files to QOS-assigned OSTs"
11535         i=0
11536         while [ $i -lt $FILL ]; do
11537                 i=$((i + 1))
11538                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11539                         count=1 2>/dev/null
11540                 echo -n .
11541         done
11542         echo "wrote $i 200k files"
11543         sync
11544         sleep_maxage
11545
11546         echo "Note: free space may not be updated, so measurements might be off"
11547         free_min_max
11548         DIFF2=$((MAXV - MINV))
11549         echo "free space delta: orig $DIFF final $DIFF2"
11550         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11551         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11552         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11553         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11554         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11555         if [[ $DIFF -gt 0 ]]; then
11556                 FILL=$((DIFF2 * 100 / DIFF - 100))
11557                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11558         fi
11559
11560         # Figure out which files were written where
11561         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11562                awk '/'$MINI1': / {print $2; exit}')
11563         echo $UUID
11564         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11565         echo "$MINC files created on smaller OST $MINI1"
11566         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11567                awk '/'$MAXI1': / {print $2; exit}')
11568         echo $UUID
11569         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11570         echo "$MAXC files created on larger OST $MAXI1"
11571         if [[ $MINC -gt 0 ]]; then
11572                 FILL=$((MAXC * 100 / MINC - 100))
11573                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11574         fi
11575         [[ $MAXC -gt $MINC ]] ||
11576                 error_ignore LU-9 "stripe QOS didn't balance free space"
11577         simple_cleanup_common
11578 }
11579 run_test 116a "stripe QOS: free space balance ==================="
11580
11581 test_116b() { # LU-2093
11582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11583         remote_mds_nodsh && skip "remote MDS with nodsh"
11584
11585 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11586         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11587                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11588         [ -z "$old_rr" ] && skip "no QOS"
11589         do_facet $SINGLEMDS lctl set_param \
11590                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11591         mkdir -p $DIR/$tdir
11592         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11593         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11594         do_facet $SINGLEMDS lctl set_param fail_loc=0
11595         rm -rf $DIR/$tdir
11596         do_facet $SINGLEMDS lctl set_param \
11597                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11598 }
11599 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11600
11601 test_117() # bug 10891
11602 {
11603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11604
11605         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11606         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11607         lctl set_param fail_loc=0x21e
11608         > $DIR/$tfile || error "truncate failed"
11609         lctl set_param fail_loc=0
11610         echo "Truncate succeeded."
11611         rm -f $DIR/$tfile
11612 }
11613 run_test 117 "verify osd extend =========="
11614
11615 NO_SLOW_RESENDCOUNT=4
11616 export OLD_RESENDCOUNT=""
11617 set_resend_count () {
11618         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11619         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11620         lctl set_param -n $PROC_RESENDCOUNT $1
11621         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11622 }
11623
11624 # for reduce test_118* time (b=14842)
11625 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11626
11627 # Reset async IO behavior after error case
11628 reset_async() {
11629         FILE=$DIR/reset_async
11630
11631         # Ensure all OSCs are cleared
11632         $LFS setstripe -c -1 $FILE
11633         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11634         sync
11635         rm $FILE
11636 }
11637
11638 test_118a() #bug 11710
11639 {
11640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11641
11642         reset_async
11643
11644         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11645         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11646         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11647
11648         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11649                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11650                 return 1;
11651         fi
11652         rm -f $DIR/$tfile
11653 }
11654 run_test 118a "verify O_SYNC works =========="
11655
11656 test_118b()
11657 {
11658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11659         remote_ost_nodsh && skip "remote OST with nodsh"
11660
11661         reset_async
11662
11663         #define OBD_FAIL_SRV_ENOENT 0x217
11664         set_nodes_failloc "$(osts_nodes)" 0x217
11665         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11666         RC=$?
11667         set_nodes_failloc "$(osts_nodes)" 0
11668         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11669         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11670                     grep -c writeback)
11671
11672         if [[ $RC -eq 0 ]]; then
11673                 error "Must return error due to dropped pages, rc=$RC"
11674                 return 1;
11675         fi
11676
11677         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11678                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11679                 return 1;
11680         fi
11681
11682         echo "Dirty pages not leaked on ENOENT"
11683
11684         # Due to the above error the OSC will issue all RPCs syncronously
11685         # until a subsequent RPC completes successfully without error.
11686         $MULTIOP $DIR/$tfile Ow4096yc
11687         rm -f $DIR/$tfile
11688
11689         return 0
11690 }
11691 run_test 118b "Reclaim dirty pages on fatal error =========="
11692
11693 test_118c()
11694 {
11695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11696
11697         # for 118c, restore the original resend count, LU-1940
11698         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11699                                 set_resend_count $OLD_RESENDCOUNT
11700         remote_ost_nodsh && skip "remote OST with nodsh"
11701
11702         reset_async
11703
11704         #define OBD_FAIL_OST_EROFS               0x216
11705         set_nodes_failloc "$(osts_nodes)" 0x216
11706
11707         # multiop should block due to fsync until pages are written
11708         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11709         MULTIPID=$!
11710         sleep 1
11711
11712         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11713                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11714         fi
11715
11716         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11717                     grep -c writeback)
11718         if [[ $WRITEBACK -eq 0 ]]; then
11719                 error "No page in writeback, writeback=$WRITEBACK"
11720         fi
11721
11722         set_nodes_failloc "$(osts_nodes)" 0
11723         wait $MULTIPID
11724         RC=$?
11725         if [[ $RC -ne 0 ]]; then
11726                 error "Multiop fsync failed, rc=$RC"
11727         fi
11728
11729         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11730         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11731                     grep -c writeback)
11732         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11733                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11734         fi
11735
11736         rm -f $DIR/$tfile
11737         echo "Dirty pages flushed via fsync on EROFS"
11738         return 0
11739 }
11740 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11741
11742 # continue to use small resend count to reduce test_118* time (b=14842)
11743 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11744
11745 test_118d()
11746 {
11747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11748         remote_ost_nodsh && skip "remote OST with nodsh"
11749
11750         reset_async
11751
11752         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11753         set_nodes_failloc "$(osts_nodes)" 0x214
11754         # multiop should block due to fsync until pages are written
11755         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11756         MULTIPID=$!
11757         sleep 1
11758
11759         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11760                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11761         fi
11762
11763         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11764                     grep -c writeback)
11765         if [[ $WRITEBACK -eq 0 ]]; then
11766                 error "No page in writeback, writeback=$WRITEBACK"
11767         fi
11768
11769         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11770         set_nodes_failloc "$(osts_nodes)" 0
11771
11772         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11773         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11774                     grep -c writeback)
11775         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11776                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11777         fi
11778
11779         rm -f $DIR/$tfile
11780         echo "Dirty pages gaurenteed flushed via fsync"
11781         return 0
11782 }
11783 run_test 118d "Fsync validation inject a delay of the bulk =========="
11784
11785 test_118f() {
11786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11787
11788         reset_async
11789
11790         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11791         lctl set_param fail_loc=0x8000040a
11792
11793         # Should simulate EINVAL error which is fatal
11794         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11795         RC=$?
11796         if [[ $RC -eq 0 ]]; then
11797                 error "Must return error due to dropped pages, rc=$RC"
11798         fi
11799
11800         lctl set_param fail_loc=0x0
11801
11802         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11803         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11804         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11805                     grep -c writeback)
11806         if [[ $LOCKED -ne 0 ]]; then
11807                 error "Locked pages remain in cache, locked=$LOCKED"
11808         fi
11809
11810         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11811                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11812         fi
11813
11814         rm -f $DIR/$tfile
11815         echo "No pages locked after fsync"
11816
11817         reset_async
11818         return 0
11819 }
11820 run_test 118f "Simulate unrecoverable OSC side error =========="
11821
11822 test_118g() {
11823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11824
11825         reset_async
11826
11827         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11828         lctl set_param fail_loc=0x406
11829
11830         # simulate local -ENOMEM
11831         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11832         RC=$?
11833
11834         lctl set_param fail_loc=0
11835         if [[ $RC -eq 0 ]]; then
11836                 error "Must return error due to dropped pages, rc=$RC"
11837         fi
11838
11839         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11840         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11841         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11842                         grep -c writeback)
11843         if [[ $LOCKED -ne 0 ]]; then
11844                 error "Locked pages remain in cache, locked=$LOCKED"
11845         fi
11846
11847         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11848                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11849         fi
11850
11851         rm -f $DIR/$tfile
11852         echo "No pages locked after fsync"
11853
11854         reset_async
11855         return 0
11856 }
11857 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11858
11859 test_118h() {
11860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11861         remote_ost_nodsh && skip "remote OST with nodsh"
11862
11863         reset_async
11864
11865         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11866         set_nodes_failloc "$(osts_nodes)" 0x20e
11867         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11868         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11869         RC=$?
11870
11871         set_nodes_failloc "$(osts_nodes)" 0
11872         if [[ $RC -eq 0 ]]; then
11873                 error "Must return error due to dropped pages, rc=$RC"
11874         fi
11875
11876         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11877         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11878         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11879                     grep -c writeback)
11880         if [[ $LOCKED -ne 0 ]]; then
11881                 error "Locked pages remain in cache, locked=$LOCKED"
11882         fi
11883
11884         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11885                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11886         fi
11887
11888         rm -f $DIR/$tfile
11889         echo "No pages locked after fsync"
11890
11891         return 0
11892 }
11893 run_test 118h "Verify timeout in handling recoverables errors  =========="
11894
11895 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11896
11897 test_118i() {
11898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11899         remote_ost_nodsh && skip "remote OST with nodsh"
11900
11901         reset_async
11902
11903         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11904         set_nodes_failloc "$(osts_nodes)" 0x20e
11905
11906         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11907         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11908         PID=$!
11909         sleep 5
11910         set_nodes_failloc "$(osts_nodes)" 0
11911
11912         wait $PID
11913         RC=$?
11914         if [[ $RC -ne 0 ]]; then
11915                 error "got error, but should be not, rc=$RC"
11916         fi
11917
11918         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11919         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11920         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11921         if [[ $LOCKED -ne 0 ]]; then
11922                 error "Locked pages remain in cache, locked=$LOCKED"
11923         fi
11924
11925         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11926                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11927         fi
11928
11929         rm -f $DIR/$tfile
11930         echo "No pages locked after fsync"
11931
11932         return 0
11933 }
11934 run_test 118i "Fix error before timeout in recoverable error  =========="
11935
11936 [ "$SLOW" = "no" ] && set_resend_count 4
11937
11938 test_118j() {
11939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11940         remote_ost_nodsh && skip "remote OST with nodsh"
11941
11942         reset_async
11943
11944         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11945         set_nodes_failloc "$(osts_nodes)" 0x220
11946
11947         # return -EIO from OST
11948         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11949         RC=$?
11950         set_nodes_failloc "$(osts_nodes)" 0x0
11951         if [[ $RC -eq 0 ]]; then
11952                 error "Must return error due to dropped pages, rc=$RC"
11953         fi
11954
11955         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11956         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11957         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11958         if [[ $LOCKED -ne 0 ]]; then
11959                 error "Locked pages remain in cache, locked=$LOCKED"
11960         fi
11961
11962         # in recoverable error on OST we want resend and stay until it finished
11963         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11964                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11965         fi
11966
11967         rm -f $DIR/$tfile
11968         echo "No pages locked after fsync"
11969
11970         return 0
11971 }
11972 run_test 118j "Simulate unrecoverable OST side error =========="
11973
11974 test_118k()
11975 {
11976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11977         remote_ost_nodsh && skip "remote OSTs with nodsh"
11978
11979         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11980         set_nodes_failloc "$(osts_nodes)" 0x20e
11981         test_mkdir $DIR/$tdir
11982
11983         for ((i=0;i<10;i++)); do
11984                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11985                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11986                 SLEEPPID=$!
11987                 sleep 0.500s
11988                 kill $SLEEPPID
11989                 wait $SLEEPPID
11990         done
11991
11992         set_nodes_failloc "$(osts_nodes)" 0
11993         rm -rf $DIR/$tdir
11994 }
11995 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11996
11997 test_118l() # LU-646
11998 {
11999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12000
12001         test_mkdir $DIR/$tdir
12002         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12003         rm -rf $DIR/$tdir
12004 }
12005 run_test 118l "fsync dir"
12006
12007 test_118m() # LU-3066
12008 {
12009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12010
12011         test_mkdir $DIR/$tdir
12012         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12013         rm -rf $DIR/$tdir
12014 }
12015 run_test 118m "fdatasync dir ========="
12016
12017 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12018
12019 test_118n()
12020 {
12021         local begin
12022         local end
12023
12024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12025         remote_ost_nodsh && skip "remote OSTs with nodsh"
12026
12027         # Sleep to avoid a cached response.
12028         #define OBD_STATFS_CACHE_SECONDS 1
12029         sleep 2
12030
12031         # Inject a 10 second delay in the OST_STATFS handler.
12032         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12033         set_nodes_failloc "$(osts_nodes)" 0x242
12034
12035         begin=$SECONDS
12036         stat --file-system $MOUNT > /dev/null
12037         end=$SECONDS
12038
12039         set_nodes_failloc "$(osts_nodes)" 0
12040
12041         if ((end - begin > 20)); then
12042             error "statfs took $((end - begin)) seconds, expected 10"
12043         fi
12044 }
12045 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12046
12047 test_119a() # bug 11737
12048 {
12049         BSIZE=$((512 * 1024))
12050         directio write $DIR/$tfile 0 1 $BSIZE
12051         # We ask to read two blocks, which is more than a file size.
12052         # directio will indicate an error when requested and actual
12053         # sizes aren't equeal (a normal situation in this case) and
12054         # print actual read amount.
12055         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12056         if [ "$NOB" != "$BSIZE" ]; then
12057                 error "read $NOB bytes instead of $BSIZE"
12058         fi
12059         rm -f $DIR/$tfile
12060 }
12061 run_test 119a "Short directIO read must return actual read amount"
12062
12063 test_119b() # bug 11737
12064 {
12065         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12066
12067         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12069         sync
12070         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12071                 error "direct read failed"
12072         rm -f $DIR/$tfile
12073 }
12074 run_test 119b "Sparse directIO read must return actual read amount"
12075
12076 test_119c() # bug 13099
12077 {
12078         BSIZE=1048576
12079         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12080         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12081         rm -f $DIR/$tfile
12082 }
12083 run_test 119c "Testing for direct read hitting hole"
12084
12085 test_119d() # bug 15950
12086 {
12087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12088
12089         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12090         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12091         BSIZE=1048576
12092         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12093         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12094         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12095         lctl set_param fail_loc=0x40d
12096         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12097         pid_dio=$!
12098         sleep 1
12099         cat $DIR/$tfile > /dev/null &
12100         lctl set_param fail_loc=0
12101         pid_reads=$!
12102         wait $pid_dio
12103         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12104         sleep 2
12105         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12106         error "the read rpcs have not completed in 2s"
12107         rm -f $DIR/$tfile
12108         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12109 }
12110 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12111
12112 test_120a() {
12113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12114         remote_mds_nodsh && skip "remote MDS with nodsh"
12115         test_mkdir -i0 -c1 $DIR/$tdir
12116         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12117                 skip_env "no early lock cancel on server"
12118
12119         lru_resize_disable mdc
12120         lru_resize_disable osc
12121         cancel_lru_locks mdc
12122         # asynchronous object destroy at MDT could cause bl ast to client
12123         cancel_lru_locks osc
12124
12125         stat $DIR/$tdir > /dev/null
12126         can1=$(do_facet mds1 \
12127                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12128                awk '/ldlm_cancel/ {print $2}')
12129         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12130                awk '/ldlm_bl_callback/ {print $2}')
12131         test_mkdir -i0 -c1 $DIR/$tdir/d1
12132         can2=$(do_facet mds1 \
12133                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12134                awk '/ldlm_cancel/ {print $2}')
12135         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12136                awk '/ldlm_bl_callback/ {print $2}')
12137         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12138         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12139         lru_resize_enable mdc
12140         lru_resize_enable osc
12141 }
12142 run_test 120a "Early Lock Cancel: mkdir test"
12143
12144 test_120b() {
12145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12146         remote_mds_nodsh && skip "remote MDS with nodsh"
12147         test_mkdir $DIR/$tdir
12148         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12149                 skip_env "no early lock cancel on server"
12150
12151         lru_resize_disable mdc
12152         lru_resize_disable osc
12153         cancel_lru_locks mdc
12154         stat $DIR/$tdir > /dev/null
12155         can1=$(do_facet $SINGLEMDS \
12156                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12157                awk '/ldlm_cancel/ {print $2}')
12158         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12159                awk '/ldlm_bl_callback/ {print $2}')
12160         touch $DIR/$tdir/f1
12161         can2=$(do_facet $SINGLEMDS \
12162                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12163                awk '/ldlm_cancel/ {print $2}')
12164         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12165                awk '/ldlm_bl_callback/ {print $2}')
12166         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12167         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12168         lru_resize_enable mdc
12169         lru_resize_enable osc
12170 }
12171 run_test 120b "Early Lock Cancel: create test"
12172
12173 test_120c() {
12174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12175         remote_mds_nodsh && skip "remote MDS with nodsh"
12176         test_mkdir -i0 -c1 $DIR/$tdir
12177         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12178                 skip "no early lock cancel on server"
12179
12180         lru_resize_disable mdc
12181         lru_resize_disable osc
12182         test_mkdir -i0 -c1 $DIR/$tdir/d1
12183         test_mkdir -i0 -c1 $DIR/$tdir/d2
12184         touch $DIR/$tdir/d1/f1
12185         cancel_lru_locks mdc
12186         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12187         can1=$(do_facet mds1 \
12188                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12189                awk '/ldlm_cancel/ {print $2}')
12190         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12191                awk '/ldlm_bl_callback/ {print $2}')
12192         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12193         can2=$(do_facet mds1 \
12194                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12195                awk '/ldlm_cancel/ {print $2}')
12196         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12197                awk '/ldlm_bl_callback/ {print $2}')
12198         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12199         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12200         lru_resize_enable mdc
12201         lru_resize_enable osc
12202 }
12203 run_test 120c "Early Lock Cancel: link test"
12204
12205 test_120d() {
12206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12207         remote_mds_nodsh && skip "remote MDS with nodsh"
12208         test_mkdir -i0 -c1 $DIR/$tdir
12209         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12210                 skip_env "no early lock cancel on server"
12211
12212         lru_resize_disable mdc
12213         lru_resize_disable osc
12214         touch $DIR/$tdir
12215         cancel_lru_locks mdc
12216         stat $DIR/$tdir > /dev/null
12217         can1=$(do_facet mds1 \
12218                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12219                awk '/ldlm_cancel/ {print $2}')
12220         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12221                awk '/ldlm_bl_callback/ {print $2}')
12222         chmod a+x $DIR/$tdir
12223         can2=$(do_facet mds1 \
12224                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12225                awk '/ldlm_cancel/ {print $2}')
12226         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12227                awk '/ldlm_bl_callback/ {print $2}')
12228         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12229         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12230         lru_resize_enable mdc
12231         lru_resize_enable osc
12232 }
12233 run_test 120d "Early Lock Cancel: setattr test"
12234
12235 test_120e() {
12236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12237         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12238                 skip_env "no early lock cancel on server"
12239         remote_mds_nodsh && skip "remote MDS with nodsh"
12240
12241         local dlmtrace_set=false
12242
12243         test_mkdir -i0 -c1 $DIR/$tdir
12244         lru_resize_disable mdc
12245         lru_resize_disable osc
12246         ! $LCTL get_param debug | grep -q dlmtrace &&
12247                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12248         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12249         cancel_lru_locks mdc
12250         cancel_lru_locks osc
12251         dd if=$DIR/$tdir/f1 of=/dev/null
12252         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12253         # XXX client can not do early lock cancel of OST lock
12254         # during unlink (LU-4206), so cancel osc lock now.
12255         sleep 2
12256         cancel_lru_locks osc
12257         can1=$(do_facet mds1 \
12258                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12259                awk '/ldlm_cancel/ {print $2}')
12260         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12261                awk '/ldlm_bl_callback/ {print $2}')
12262         unlink $DIR/$tdir/f1
12263         sleep 5
12264         can2=$(do_facet mds1 \
12265                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12266                awk '/ldlm_cancel/ {print $2}')
12267         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12268                awk '/ldlm_bl_callback/ {print $2}')
12269         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12270                 $LCTL dk $TMP/cancel.debug.txt
12271         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12272                 $LCTL dk $TMP/blocking.debug.txt
12273         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12274         lru_resize_enable mdc
12275         lru_resize_enable osc
12276 }
12277 run_test 120e "Early Lock Cancel: unlink test"
12278
12279 test_120f() {
12280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12281         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12282                 skip_env "no early lock cancel on server"
12283         remote_mds_nodsh && skip "remote MDS with nodsh"
12284
12285         test_mkdir -i0 -c1 $DIR/$tdir
12286         lru_resize_disable mdc
12287         lru_resize_disable osc
12288         test_mkdir -i0 -c1 $DIR/$tdir/d1
12289         test_mkdir -i0 -c1 $DIR/$tdir/d2
12290         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12291         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12292         cancel_lru_locks mdc
12293         cancel_lru_locks osc
12294         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12295         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12296         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12297         # XXX client can not do early lock cancel of OST lock
12298         # during rename (LU-4206), so cancel osc lock now.
12299         sleep 2
12300         cancel_lru_locks osc
12301         can1=$(do_facet mds1 \
12302                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12303                awk '/ldlm_cancel/ {print $2}')
12304         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12305                awk '/ldlm_bl_callback/ {print $2}')
12306         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12307         sleep 5
12308         can2=$(do_facet mds1 \
12309                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12310                awk '/ldlm_cancel/ {print $2}')
12311         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12312                awk '/ldlm_bl_callback/ {print $2}')
12313         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12314         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12315         lru_resize_enable mdc
12316         lru_resize_enable osc
12317 }
12318 run_test 120f "Early Lock Cancel: rename test"
12319
12320 test_120g() {
12321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12322         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12323                 skip_env "no early lock cancel on server"
12324         remote_mds_nodsh && skip "remote MDS with nodsh"
12325
12326         lru_resize_disable mdc
12327         lru_resize_disable osc
12328         count=10000
12329         echo create $count files
12330         test_mkdir $DIR/$tdir
12331         cancel_lru_locks mdc
12332         cancel_lru_locks osc
12333         t0=$(date +%s)
12334
12335         can0=$(do_facet $SINGLEMDS \
12336                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12337                awk '/ldlm_cancel/ {print $2}')
12338         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12339                awk '/ldlm_bl_callback/ {print $2}')
12340         createmany -o $DIR/$tdir/f $count
12341         sync
12342         can1=$(do_facet $SINGLEMDS \
12343                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12344                awk '/ldlm_cancel/ {print $2}')
12345         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12346                awk '/ldlm_bl_callback/ {print $2}')
12347         t1=$(date +%s)
12348         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12349         echo rm $count files
12350         rm -r $DIR/$tdir
12351         sync
12352         can2=$(do_facet $SINGLEMDS \
12353                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12354                awk '/ldlm_cancel/ {print $2}')
12355         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12356                awk '/ldlm_bl_callback/ {print $2}')
12357         t2=$(date +%s)
12358         echo total: $count removes in $((t2-t1))
12359         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12360         sleep 2
12361         # wait for commitment of removal
12362         lru_resize_enable mdc
12363         lru_resize_enable osc
12364 }
12365 run_test 120g "Early Lock Cancel: performance test"
12366
12367 test_121() { #bug #10589
12368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12369
12370         rm -rf $DIR/$tfile
12371         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12372 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12373         lctl set_param fail_loc=0x310
12374         cancel_lru_locks osc > /dev/null
12375         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12376         lctl set_param fail_loc=0
12377         [[ $reads -eq $writes ]] ||
12378                 error "read $reads blocks, must be $writes blocks"
12379 }
12380 run_test 121 "read cancel race ========="
12381
12382 test_123a_base() { # was test 123, statahead(bug 11401)
12383         local lsx="$1"
12384
12385         SLOWOK=0
12386         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12387                 log "testing UP system. Performance may be lower than expected."
12388                 SLOWOK=1
12389         fi
12390
12391         rm -rf $DIR/$tdir
12392         test_mkdir $DIR/$tdir
12393         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12394         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12395         MULT=10
12396         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12397                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12398
12399                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12400                 lctl set_param -n llite.*.statahead_max 0
12401                 lctl get_param llite.*.statahead_max
12402                 cancel_lru_locks mdc
12403                 cancel_lru_locks osc
12404                 stime=$(date +%s)
12405                 time $lsx $DIR/$tdir | wc -l
12406                 etime=$(date +%s)
12407                 delta=$((etime - stime))
12408                 log "$lsx $i files without statahead: $delta sec"
12409                 lctl set_param llite.*.statahead_max=$max
12410
12411                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12412                         grep "statahead wrong:" | awk '{print $3}')
12413                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12414                 cancel_lru_locks mdc
12415                 cancel_lru_locks osc
12416                 stime=$(date +%s)
12417                 time $lsx $DIR/$tdir | wc -l
12418                 etime=$(date +%s)
12419                 delta_sa=$((etime - stime))
12420                 log "$lsx $i files with statahead: $delta_sa sec"
12421                 lctl get_param -n llite.*.statahead_stats
12422                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12423                         grep "statahead wrong:" | awk '{print $3}')
12424
12425                 [[ $swrong -lt $ewrong ]] &&
12426                         log "statahead was stopped, maybe too many locks held!"
12427                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12428
12429                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12430                         max=$(lctl get_param -n llite.*.statahead_max |
12431                                 head -n 1)
12432                         lctl set_param -n llite.*.statahead_max 0
12433                         lctl get_param llite.*.statahead_max
12434                         cancel_lru_locks mdc
12435                         cancel_lru_locks osc
12436                         stime=$(date +%s)
12437                         time $lsx $DIR/$tdir | wc -l
12438                         etime=$(date +%s)
12439                         delta=$((etime - stime))
12440                         log "$lsx $i files again without statahead: $delta sec"
12441                         lctl set_param llite.*.statahead_max=$max
12442                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12443                                 if [  $SLOWOK -eq 0 ]; then
12444                                         error "$lsx $i files is slower with statahead!"
12445                                 else
12446                                         log "$lsx $i files is slower with statahead!"
12447                                 fi
12448                                 break
12449                         fi
12450                 fi
12451
12452                 [ $delta -gt 20 ] && break
12453                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12454                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12455         done
12456         log "$lsx done"
12457
12458         stime=$(date +%s)
12459         rm -r $DIR/$tdir
12460         sync
12461         etime=$(date +%s)
12462         delta=$((etime - stime))
12463         log "rm -r $DIR/$tdir/: $delta seconds"
12464         log "rm done"
12465         lctl get_param -n llite.*.statahead_stats
12466 }
12467
12468 test_123aa() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470
12471         test_123a_base "ls -l"
12472 }
12473 run_test 123aa "verify statahead work"
12474
12475 test_123ab() {
12476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12477
12478         statx_supported || skip_env "Test must be statx() syscall supported"
12479
12480         test_123a_base "$STATX -l"
12481 }
12482 run_test 123ab "verify statahead work by using statx"
12483
12484 test_123ac() {
12485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12486
12487         statx_supported || skip_env "Test must be statx() syscall supported"
12488
12489         local rpcs_before
12490         local rpcs_after
12491         local agl_before
12492         local agl_after
12493
12494         cancel_lru_locks $OSC
12495         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12496         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12497                 awk '/agl.total:/ {print $3}')
12498         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12499         test_123a_base "$STATX --cached=always -D"
12500         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12501                 awk '/agl.total:/ {print $3}')
12502         [ $agl_before -eq $agl_after ] ||
12503                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12504         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12505         [ $rpcs_after -eq $rpcs_before ] ||
12506                 error "$STATX should not send glimpse RPCs to $OSC"
12507 }
12508 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12509
12510 test_123b () { # statahead(bug 15027)
12511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12512
12513         test_mkdir $DIR/$tdir
12514         createmany -o $DIR/$tdir/$tfile-%d 1000
12515
12516         cancel_lru_locks mdc
12517         cancel_lru_locks osc
12518
12519 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12520         lctl set_param fail_loc=0x80000803
12521         ls -lR $DIR/$tdir > /dev/null
12522         log "ls done"
12523         lctl set_param fail_loc=0x0
12524         lctl get_param -n llite.*.statahead_stats
12525         rm -r $DIR/$tdir
12526         sync
12527
12528 }
12529 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12530
12531 test_123c() {
12532         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12533
12534         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12535         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12536         touch $DIR/$tdir.1/{1..3}
12537         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12538
12539         remount_client $MOUNT
12540
12541         $MULTIOP $DIR/$tdir.0 Q
12542
12543         # let statahead to complete
12544         ls -l $DIR/$tdir.0 > /dev/null
12545
12546         testid=$(echo $TESTNAME | tr '_' ' ')
12547         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12548                 error "statahead warning" || true
12549 }
12550 run_test 123c "Can not initialize inode warning on DNE statahead"
12551
12552 test_124a() {
12553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12554         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12555                 skip_env "no lru resize on server"
12556
12557         local NR=2000
12558
12559         test_mkdir $DIR/$tdir
12560
12561         log "create $NR files at $DIR/$tdir"
12562         createmany -o $DIR/$tdir/f $NR ||
12563                 error "failed to create $NR files in $DIR/$tdir"
12564
12565         cancel_lru_locks mdc
12566         ls -l $DIR/$tdir > /dev/null
12567
12568         local NSDIR=""
12569         local LRU_SIZE=0
12570         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12571                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12572                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12573                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12574                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12575                         log "NSDIR=$NSDIR"
12576                         log "NS=$(basename $NSDIR)"
12577                         break
12578                 fi
12579         done
12580
12581         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12582                 skip "Not enough cached locks created!"
12583         fi
12584         log "LRU=$LRU_SIZE"
12585
12586         local SLEEP=30
12587
12588         # We know that lru resize allows one client to hold $LIMIT locks
12589         # for 10h. After that locks begin to be killed by client.
12590         local MAX_HRS=10
12591         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12592         log "LIMIT=$LIMIT"
12593         if [ $LIMIT -lt $LRU_SIZE ]; then
12594                 skip "Limit is too small $LIMIT"
12595         fi
12596
12597         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12598         # killing locks. Some time was spent for creating locks. This means
12599         # that up to the moment of sleep finish we must have killed some of
12600         # them (10-100 locks). This depends on how fast ther were created.
12601         # Many of them were touched in almost the same moment and thus will
12602         # be killed in groups.
12603         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12604
12605         # Use $LRU_SIZE_B here to take into account real number of locks
12606         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12607         local LRU_SIZE_B=$LRU_SIZE
12608         log "LVF=$LVF"
12609         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12610         log "OLD_LVF=$OLD_LVF"
12611         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12612
12613         # Let's make sure that we really have some margin. Client checks
12614         # cached locks every 10 sec.
12615         SLEEP=$((SLEEP+20))
12616         log "Sleep ${SLEEP} sec"
12617         local SEC=0
12618         while ((SEC<$SLEEP)); do
12619                 echo -n "..."
12620                 sleep 5
12621                 SEC=$((SEC+5))
12622                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12623                 echo -n "$LRU_SIZE"
12624         done
12625         echo ""
12626         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12627         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12628
12629         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12630                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12631                 unlinkmany $DIR/$tdir/f $NR
12632                 return
12633         }
12634
12635         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12636         log "unlink $NR files at $DIR/$tdir"
12637         unlinkmany $DIR/$tdir/f $NR
12638 }
12639 run_test 124a "lru resize ======================================="
12640
12641 get_max_pool_limit()
12642 {
12643         local limit=$($LCTL get_param \
12644                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12645         local max=0
12646         for l in $limit; do
12647                 if [[ $l -gt $max ]]; then
12648                         max=$l
12649                 fi
12650         done
12651         echo $max
12652 }
12653
12654 test_124b() {
12655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12656         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12657                 skip_env "no lru resize on server"
12658
12659         LIMIT=$(get_max_pool_limit)
12660
12661         NR=$(($(default_lru_size)*20))
12662         if [[ $NR -gt $LIMIT ]]; then
12663                 log "Limit lock number by $LIMIT locks"
12664                 NR=$LIMIT
12665         fi
12666
12667         IFree=$(mdsrate_inodes_available)
12668         if [ $IFree -lt $NR ]; then
12669                 log "Limit lock number by $IFree inodes"
12670                 NR=$IFree
12671         fi
12672
12673         lru_resize_disable mdc
12674         test_mkdir -p $DIR/$tdir/disable_lru_resize
12675
12676         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12677         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12678         cancel_lru_locks mdc
12679         stime=`date +%s`
12680         PID=""
12681         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12682         PID="$PID $!"
12683         sleep 2
12684         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12685         PID="$PID $!"
12686         sleep 2
12687         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12688         PID="$PID $!"
12689         wait $PID
12690         etime=`date +%s`
12691         nolruresize_delta=$((etime-stime))
12692         log "ls -la time: $nolruresize_delta seconds"
12693         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12694         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12695
12696         lru_resize_enable mdc
12697         test_mkdir -p $DIR/$tdir/enable_lru_resize
12698
12699         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12700         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12701         cancel_lru_locks mdc
12702         stime=`date +%s`
12703         PID=""
12704         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12705         PID="$PID $!"
12706         sleep 2
12707         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12708         PID="$PID $!"
12709         sleep 2
12710         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12711         PID="$PID $!"
12712         wait $PID
12713         etime=`date +%s`
12714         lruresize_delta=$((etime-stime))
12715         log "ls -la time: $lruresize_delta seconds"
12716         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12717
12718         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12719                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12720         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12721                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12722         else
12723                 log "lru resize performs the same with no lru resize"
12724         fi
12725         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12726 }
12727 run_test 124b "lru resize (performance test) ======================="
12728
12729 test_124c() {
12730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12731         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12732                 skip_env "no lru resize on server"
12733
12734         # cache ununsed locks on client
12735         local nr=100
12736         cancel_lru_locks mdc
12737         test_mkdir $DIR/$tdir
12738         createmany -o $DIR/$tdir/f $nr ||
12739                 error "failed to create $nr files in $DIR/$tdir"
12740         ls -l $DIR/$tdir > /dev/null
12741
12742         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12743         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12744         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12745         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12746         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12747
12748         # set lru_max_age to 1 sec
12749         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12750         echo "sleep $((recalc_p * 2)) seconds..."
12751         sleep $((recalc_p * 2))
12752
12753         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12754         # restore lru_max_age
12755         $LCTL set_param -n $nsdir.lru_max_age $max_age
12756         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12757         unlinkmany $DIR/$tdir/f $nr
12758 }
12759 run_test 124c "LRUR cancel very aged locks"
12760
12761 test_124d() {
12762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12763         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12764                 skip_env "no lru resize on server"
12765
12766         # cache ununsed locks on client
12767         local nr=100
12768
12769         lru_resize_disable mdc
12770         stack_trap "lru_resize_enable mdc" EXIT
12771
12772         cancel_lru_locks mdc
12773
12774         # asynchronous object destroy at MDT could cause bl ast to client
12775         test_mkdir $DIR/$tdir
12776         createmany -o $DIR/$tdir/f $nr ||
12777                 error "failed to create $nr files in $DIR/$tdir"
12778         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12779
12780         ls -l $DIR/$tdir > /dev/null
12781
12782         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12783         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12784         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12785         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12786
12787         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12788
12789         # set lru_max_age to 1 sec
12790         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12791         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12792
12793         echo "sleep $((recalc_p * 2)) seconds..."
12794         sleep $((recalc_p * 2))
12795
12796         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12797
12798         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12799 }
12800 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12801
12802 test_125() { # 13358
12803         $LCTL get_param -n llite.*.client_type | grep -q local ||
12804                 skip "must run as local client"
12805         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12806                 skip_env "must have acl enabled"
12807         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12808
12809         test_mkdir $DIR/$tdir
12810         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12811         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12812         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12813 }
12814 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12815
12816 test_126() { # bug 12829/13455
12817         $GSS && skip_env "must run as gss disabled"
12818         $LCTL get_param -n llite.*.client_type | grep -q local ||
12819                 skip "must run as local client"
12820         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12821
12822         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12823         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12824         rm -f $DIR/$tfile
12825         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12826 }
12827 run_test 126 "check that the fsgid provided by the client is taken into account"
12828
12829 test_127a() { # bug 15521
12830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12831         local name count samp unit min max sum sumsq
12832
12833         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12834         echo "stats before reset"
12835         $LCTL get_param osc.*.stats
12836         $LCTL set_param osc.*.stats=0
12837         local fsize=$((2048 * 1024))
12838
12839         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12840         cancel_lru_locks osc
12841         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12842
12843         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12844         stack_trap "rm -f $TMP/$tfile.tmp"
12845         while read name count samp unit min max sum sumsq; do
12846                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12847                 [ ! $min ] && error "Missing min value for $name proc entry"
12848                 eval $name=$count || error "Wrong proc format"
12849
12850                 case $name in
12851                 read_bytes|write_bytes)
12852                         [[ "$unit" =~ "bytes" ]] ||
12853                                 error "unit is not 'bytes': $unit"
12854                         (( $min >= 4096 )) || error "min is too small: $min"
12855                         (( $min <= $fsize )) || error "min is too big: $min"
12856                         (( $max >= 4096 )) || error "max is too small: $max"
12857                         (( $max <= $fsize )) || error "max is too big: $max"
12858                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12859                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12860                                 error "sumsquare is too small: $sumsq"
12861                         (( $sumsq <= $fsize * $fsize )) ||
12862                                 error "sumsquare is too big: $sumsq"
12863                         ;;
12864                 ost_read|ost_write)
12865                         [[ "$unit" =~ "usec" ]] ||
12866                                 error "unit is not 'usec': $unit"
12867                         ;;
12868                 *)      ;;
12869                 esac
12870         done < $DIR/$tfile.tmp
12871
12872         #check that we actually got some stats
12873         [ "$read_bytes" ] || error "Missing read_bytes stats"
12874         [ "$write_bytes" ] || error "Missing write_bytes stats"
12875         [ "$read_bytes" != 0 ] || error "no read done"
12876         [ "$write_bytes" != 0 ] || error "no write done"
12877 }
12878 run_test 127a "verify the client stats are sane"
12879
12880 test_127b() { # bug LU-333
12881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12882         local name count samp unit min max sum sumsq
12883
12884         echo "stats before reset"
12885         $LCTL get_param llite.*.stats
12886         $LCTL set_param llite.*.stats=0
12887
12888         # perform 2 reads and writes so MAX is different from SUM.
12889         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12890         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12891         cancel_lru_locks osc
12892         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12893         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12894
12895         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12896         stack_trap "rm -f $TMP/$tfile.tmp"
12897         while read name count samp unit min max sum sumsq; do
12898                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12899                 eval $name=$count || error "Wrong proc format"
12900
12901                 case $name in
12902                 read_bytes|write_bytes)
12903                         [[ "$unit" =~ "bytes" ]] ||
12904                                 error "unit is not 'bytes': $unit"
12905                         (( $count == 2 )) || error "count is not 2: $count"
12906                         (( $min == $PAGE_SIZE )) ||
12907                                 error "min is not $PAGE_SIZE: $min"
12908                         (( $max == $PAGE_SIZE )) ||
12909                                 error "max is not $PAGE_SIZE: $max"
12910                         (( $sum == $PAGE_SIZE * 2 )) ||
12911                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12912                         ;;
12913                 read|write)
12914                         [[ "$unit" =~ "usec" ]] ||
12915                                 error "unit is not 'usec': $unit"
12916                         ;;
12917                 *)      ;;
12918                 esac
12919         done < $TMP/$tfile.tmp
12920
12921         #check that we actually got some stats
12922         [ "$read_bytes" ] || error "Missing read_bytes stats"
12923         [ "$write_bytes" ] || error "Missing write_bytes stats"
12924         [ "$read_bytes" != 0 ] || error "no read done"
12925         [ "$write_bytes" != 0 ] || error "no write done"
12926 }
12927 run_test 127b "verify the llite client stats are sane"
12928
12929 test_127c() { # LU-12394
12930         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12931         local size
12932         local bsize
12933         local reads
12934         local writes
12935         local count
12936
12937         $LCTL set_param llite.*.extents_stats=1
12938         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12939
12940         # Use two stripes so there is enough space in default config
12941         $LFS setstripe -c 2 $DIR/$tfile
12942
12943         # Extent stats start at 0-4K and go in power of two buckets
12944         # LL_HIST_START = 12 --> 2^12 = 4K
12945         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12946         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12947         # small configs
12948         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12949                 do
12950                 # Write and read, 2x each, second time at a non-zero offset
12951                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12952                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12953                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12954                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12955                 rm -f $DIR/$tfile
12956         done
12957
12958         $LCTL get_param llite.*.extents_stats
12959
12960         count=2
12961         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12962                 do
12963                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12964                                 grep -m 1 $bsize)
12965                 reads=$(echo $bucket | awk '{print $5}')
12966                 writes=$(echo $bucket | awk '{print $9}')
12967                 [ "$reads" -eq $count ] ||
12968                         error "$reads reads in < $bsize bucket, expect $count"
12969                 [ "$writes" -eq $count ] ||
12970                         error "$writes writes in < $bsize bucket, expect $count"
12971         done
12972
12973         # Test mmap write and read
12974         $LCTL set_param llite.*.extents_stats=c
12975         size=512
12976         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12977         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12978         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12979
12980         $LCTL get_param llite.*.extents_stats
12981
12982         count=$(((size*1024) / PAGE_SIZE))
12983
12984         bsize=$((2 * PAGE_SIZE / 1024))K
12985
12986         bucket=$($LCTL get_param -n llite.*.extents_stats |
12987                         grep -m 1 $bsize)
12988         reads=$(echo $bucket | awk '{print $5}')
12989         writes=$(echo $bucket | awk '{print $9}')
12990         # mmap writes fault in the page first, creating an additonal read
12991         [ "$reads" -eq $((2 * count)) ] ||
12992                 error "$reads reads in < $bsize bucket, expect $count"
12993         [ "$writes" -eq $count ] ||
12994                 error "$writes writes in < $bsize bucket, expect $count"
12995 }
12996 run_test 127c "test llite extent stats with regular & mmap i/o"
12997
12998 test_128() { # bug 15212
12999         touch $DIR/$tfile
13000         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13001                 find $DIR/$tfile
13002                 find $DIR/$tfile
13003         EOF
13004
13005         result=$(grep error $TMP/$tfile.log)
13006         rm -f $DIR/$tfile $TMP/$tfile.log
13007         [ -z "$result" ] ||
13008                 error "consecutive find's under interactive lfs failed"
13009 }
13010 run_test 128 "interactive lfs for 2 consecutive find's"
13011
13012 set_dir_limits () {
13013         local mntdev
13014         local canondev
13015         local node
13016
13017         local ldproc=/proc/fs/ldiskfs
13018         local facets=$(get_facets MDS)
13019
13020         for facet in ${facets//,/ }; do
13021                 canondev=$(ldiskfs_canon \
13022                            *.$(convert_facet2label $facet).mntdev $facet)
13023                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13024                         ldproc=/sys/fs/ldiskfs
13025                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13026                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13027         done
13028 }
13029
13030 check_mds_dmesg() {
13031         local facets=$(get_facets MDS)
13032         for facet in ${facets//,/ }; do
13033                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13034         done
13035         return 1
13036 }
13037
13038 test_129() {
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13041                 skip "Need MDS version with at least 2.5.56"
13042         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13043                 skip_env "ldiskfs only test"
13044         fi
13045         remote_mds_nodsh && skip "remote MDS with nodsh"
13046
13047         local ENOSPC=28
13048         local has_warning=false
13049
13050         rm -rf $DIR/$tdir
13051         mkdir -p $DIR/$tdir
13052
13053         # block size of mds1
13054         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13055         set_dir_limits $maxsize $((maxsize * 6 / 8))
13056         stack_trap "set_dir_limits 0 0"
13057         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13058         local dirsize=$(stat -c%s "$DIR/$tdir")
13059         local nfiles=0
13060         while (( $dirsize <= $maxsize )); do
13061                 $MCREATE $DIR/$tdir/file_base_$nfiles
13062                 rc=$?
13063                 # check two errors:
13064                 # ENOSPC for ext4 max_dir_size, which has been used since
13065                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13066                 if (( rc == ENOSPC )); then
13067                         set_dir_limits 0 0
13068                         echo "rc=$rc returned as expected after $nfiles files"
13069
13070                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13071                                 error "create failed w/o dir size limit"
13072
13073                         # messages may be rate limited if test is run repeatedly
13074                         check_mds_dmesg '"is approaching max"' ||
13075                                 echo "warning message should be output"
13076                         check_mds_dmesg '"has reached max"' ||
13077                                 echo "reached message should be output"
13078
13079                         dirsize=$(stat -c%s "$DIR/$tdir")
13080
13081                         [[ $dirsize -ge $maxsize ]] && return 0
13082                         error "dirsize $dirsize < $maxsize after $nfiles files"
13083                 elif (( rc != 0 )); then
13084                         break
13085                 fi
13086                 nfiles=$((nfiles + 1))
13087                 dirsize=$(stat -c%s "$DIR/$tdir")
13088         done
13089
13090         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13091 }
13092 run_test 129 "test directory size limit ========================"
13093
13094 OLDIFS="$IFS"
13095 cleanup_130() {
13096         trap 0
13097         IFS="$OLDIFS"
13098 }
13099
13100 test_130a() {
13101         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13102         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13103
13104         trap cleanup_130 EXIT RETURN
13105
13106         local fm_file=$DIR/$tfile
13107         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13108         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13109                 error "dd failed for $fm_file"
13110
13111         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13112         filefrag -ves $fm_file
13113         RC=$?
13114         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13115                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13116         [ $RC != 0 ] && error "filefrag $fm_file failed"
13117
13118         filefrag_op=$(filefrag -ve -k $fm_file |
13119                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13120         lun=$($LFS getstripe -i $fm_file)
13121
13122         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13123         IFS=$'\n'
13124         tot_len=0
13125         for line in $filefrag_op
13126         do
13127                 frag_lun=`echo $line | cut -d: -f5`
13128                 ext_len=`echo $line | cut -d: -f4`
13129                 if (( $frag_lun != $lun )); then
13130                         cleanup_130
13131                         error "FIEMAP on 1-stripe file($fm_file) failed"
13132                         return
13133                 fi
13134                 (( tot_len += ext_len ))
13135         done
13136
13137         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13138                 cleanup_130
13139                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13140                 return
13141         fi
13142
13143         cleanup_130
13144
13145         echo "FIEMAP on single striped file succeeded"
13146 }
13147 run_test 130a "FIEMAP (1-stripe file)"
13148
13149 test_130b() {
13150         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13151
13152         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13153         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13154
13155         trap cleanup_130 EXIT RETURN
13156
13157         local fm_file=$DIR/$tfile
13158         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13159                         error "setstripe on $fm_file"
13160         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13161                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13162
13163         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13164                 error "dd failed on $fm_file"
13165
13166         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13167         filefrag_op=$(filefrag -ve -k $fm_file |
13168                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13169
13170         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13171                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13172
13173         IFS=$'\n'
13174         tot_len=0
13175         num_luns=1
13176         for line in $filefrag_op
13177         do
13178                 frag_lun=$(echo $line | cut -d: -f5 |
13179                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13180                 ext_len=$(echo $line | cut -d: -f4)
13181                 if (( $frag_lun != $last_lun )); then
13182                         if (( tot_len != 1024 )); then
13183                                 cleanup_130
13184                                 error "FIEMAP on $fm_file failed; returned " \
13185                                 "len $tot_len for OST $last_lun instead of 1024"
13186                                 return
13187                         else
13188                                 (( num_luns += 1 ))
13189                                 tot_len=0
13190                         fi
13191                 fi
13192                 (( tot_len += ext_len ))
13193                 last_lun=$frag_lun
13194         done
13195         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13196                 cleanup_130
13197                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13198                         "luns or wrong len for OST $last_lun"
13199                 return
13200         fi
13201
13202         cleanup_130
13203
13204         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13205 }
13206 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13207
13208 test_130c() {
13209         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13210
13211         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13212         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13213
13214         trap cleanup_130 EXIT RETURN
13215
13216         local fm_file=$DIR/$tfile
13217         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13218         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13219                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13220
13221         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13222                         error "dd failed on $fm_file"
13223
13224         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13225         filefrag_op=$(filefrag -ve -k $fm_file |
13226                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13227
13228         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13229                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13230
13231         IFS=$'\n'
13232         tot_len=0
13233         num_luns=1
13234         for line in $filefrag_op
13235         do
13236                 frag_lun=$(echo $line | cut -d: -f5 |
13237                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13238                 ext_len=$(echo $line | cut -d: -f4)
13239                 if (( $frag_lun != $last_lun )); then
13240                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13241                         if (( logical != 512 )); then
13242                                 cleanup_130
13243                                 error "FIEMAP on $fm_file failed; returned " \
13244                                 "logical start for lun $logical instead of 512"
13245                                 return
13246                         fi
13247                         if (( tot_len != 512 )); then
13248                                 cleanup_130
13249                                 error "FIEMAP on $fm_file failed; returned " \
13250                                 "len $tot_len for OST $last_lun instead of 1024"
13251                                 return
13252                         else
13253                                 (( num_luns += 1 ))
13254                                 tot_len=0
13255                         fi
13256                 fi
13257                 (( tot_len += ext_len ))
13258                 last_lun=$frag_lun
13259         done
13260         if (( num_luns != 2 || tot_len != 512 )); then
13261                 cleanup_130
13262                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13263                         "luns or wrong len for OST $last_lun"
13264                 return
13265         fi
13266
13267         cleanup_130
13268
13269         echo "FIEMAP on 2-stripe file with hole succeeded"
13270 }
13271 run_test 130c "FIEMAP (2-stripe file with hole)"
13272
13273 test_130d() {
13274         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13275
13276         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13277         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13278
13279         trap cleanup_130 EXIT RETURN
13280
13281         local fm_file=$DIR/$tfile
13282         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13283                         error "setstripe on $fm_file"
13284         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13285                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13286
13287         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13288         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13289                 error "dd failed on $fm_file"
13290
13291         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13292         filefrag_op=$(filefrag -ve -k $fm_file |
13293                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13294
13295         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13296                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13297
13298         IFS=$'\n'
13299         tot_len=0
13300         num_luns=1
13301         for line in $filefrag_op
13302         do
13303                 frag_lun=$(echo $line | cut -d: -f5 |
13304                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13305                 ext_len=$(echo $line | cut -d: -f4)
13306                 if (( $frag_lun != $last_lun )); then
13307                         if (( tot_len != 1024 )); then
13308                                 cleanup_130
13309                                 error "FIEMAP on $fm_file failed; returned " \
13310                                 "len $tot_len for OST $last_lun instead of 1024"
13311                                 return
13312                         else
13313                                 (( num_luns += 1 ))
13314                                 tot_len=0
13315                         fi
13316                 fi
13317                 (( tot_len += ext_len ))
13318                 last_lun=$frag_lun
13319         done
13320         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13321                 cleanup_130
13322                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13323                         "luns or wrong len for OST $last_lun"
13324                 return
13325         fi
13326
13327         cleanup_130
13328
13329         echo "FIEMAP on N-stripe file succeeded"
13330 }
13331 run_test 130d "FIEMAP (N-stripe file)"
13332
13333 test_130e() {
13334         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13335
13336         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13337         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13338
13339         trap cleanup_130 EXIT RETURN
13340
13341         local fm_file=$DIR/$tfile
13342         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13343
13344         NUM_BLKS=512
13345         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13346         for ((i = 0; i < $NUM_BLKS; i++)); do
13347                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13348                         conv=notrunc > /dev/null 2>&1
13349         done
13350
13351         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13352         filefrag_op=$(filefrag -ve -k $fm_file |
13353                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13354
13355         last_lun=$(echo $filefrag_op | cut -d: -f5)
13356
13357         IFS=$'\n'
13358         tot_len=0
13359         num_luns=1
13360         for line in $filefrag_op; do
13361                 frag_lun=$(echo $line | cut -d: -f5)
13362                 ext_len=$(echo $line | cut -d: -f4)
13363                 if [[ "$frag_lun" != "$last_lun" ]]; then
13364                         if (( tot_len != $EXPECTED_LEN )); then
13365                                 cleanup_130
13366                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13367                         else
13368                                 (( num_luns += 1 ))
13369                                 tot_len=0
13370                         fi
13371                 fi
13372                 (( tot_len += ext_len ))
13373                 last_lun=$frag_lun
13374         done
13375         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13376                 cleanup_130
13377                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13378         fi
13379
13380         echo "FIEMAP with continuation calls succeeded"
13381 }
13382 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13383
13384 test_130f() {
13385         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13386         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13387
13388         local fm_file=$DIR/$tfile
13389         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13390                 error "multiop create with lov_delay_create on $fm_file"
13391
13392         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13393         filefrag_extents=$(filefrag -vek $fm_file |
13394                            awk '/extents? found/ { print $2 }')
13395         if [[ "$filefrag_extents" != "0" ]]; then
13396                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13397         fi
13398
13399         rm -f $fm_file
13400 }
13401 run_test 130f "FIEMAP (unstriped file)"
13402
13403 test_130g() {
13404         local file=$DIR/$tfile
13405         local nr=$((OSTCOUNT * 100))
13406
13407         $LFS setstripe -C $nr $file ||
13408                 error "failed to setstripe -C $nr $file"
13409
13410         dd if=/dev/zero of=$file count=$nr bs=1M
13411         sync
13412         nr=$($LFS getstripe -c $file)
13413
13414         local extents=$(filefrag -v $file |
13415                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13416
13417         echo "filefrag list $extents extents in file with stripecount $nr"
13418         if (( extents < nr )); then
13419                 $LFS getstripe $file
13420                 filefrag -v $file
13421                 error "filefrag printed $extents < $nr extents"
13422         fi
13423
13424         rm -f $file
13425 }
13426 run_test 130g "FIEMAP (overstripe file)"
13427
13428 # Test for writev/readv
13429 test_131a() {
13430         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13431                 error "writev test failed"
13432         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13433                 error "readv failed"
13434         rm -f $DIR/$tfile
13435 }
13436 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13437
13438 test_131b() {
13439         local fsize=$((524288 + 1048576 + 1572864))
13440         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13441                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13442                         error "append writev test failed"
13443
13444         ((fsize += 1572864 + 1048576))
13445         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13446                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13447                         error "append writev test failed"
13448         rm -f $DIR/$tfile
13449 }
13450 run_test 131b "test append writev"
13451
13452 test_131c() {
13453         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13454         error "NOT PASS"
13455 }
13456 run_test 131c "test read/write on file w/o objects"
13457
13458 test_131d() {
13459         rwv -f $DIR/$tfile -w -n 1 1572864
13460         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13461         if [ "$NOB" != 1572864 ]; then
13462                 error "Short read filed: read $NOB bytes instead of 1572864"
13463         fi
13464         rm -f $DIR/$tfile
13465 }
13466 run_test 131d "test short read"
13467
13468 test_131e() {
13469         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13470         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13471         error "read hitting hole failed"
13472         rm -f $DIR/$tfile
13473 }
13474 run_test 131e "test read hitting hole"
13475
13476 check_stats() {
13477         local facet=$1
13478         local op=$2
13479         local want=${3:-0}
13480         local res
13481
13482         case $facet in
13483         mds*) res=$(do_facet $facet \
13484                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13485                  ;;
13486         ost*) res=$(do_facet $facet \
13487                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13488                  ;;
13489         *) error "Wrong facet '$facet'" ;;
13490         esac
13491         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13492         # if the argument $3 is zero, it means any stat increment is ok.
13493         if [[ $want -gt 0 ]]; then
13494                 local count=$(echo $res | awk '{ print $2 }')
13495                 [[ $count -ne $want ]] &&
13496                         error "The $op counter on $facet is $count, not $want"
13497         fi
13498 }
13499
13500 test_133a() {
13501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13502         remote_ost_nodsh && skip "remote OST with nodsh"
13503         remote_mds_nodsh && skip "remote MDS with nodsh"
13504         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13505                 skip_env "MDS doesn't support rename stats"
13506
13507         local testdir=$DIR/${tdir}/stats_testdir
13508
13509         mkdir -p $DIR/${tdir}
13510
13511         # clear stats.
13512         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13513         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13514
13515         # verify mdt stats first.
13516         mkdir ${testdir} || error "mkdir failed"
13517         check_stats $SINGLEMDS "mkdir" 1
13518         touch ${testdir}/${tfile} || error "touch failed"
13519         check_stats $SINGLEMDS "open" 1
13520         check_stats $SINGLEMDS "close" 1
13521         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13522                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13523                 check_stats $SINGLEMDS "mknod" 2
13524         }
13525         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13526         check_stats $SINGLEMDS "unlink" 1
13527         rm -f ${testdir}/${tfile} || error "file remove failed"
13528         check_stats $SINGLEMDS "unlink" 2
13529
13530         # remove working dir and check mdt stats again.
13531         rmdir ${testdir} || error "rmdir failed"
13532         check_stats $SINGLEMDS "rmdir" 1
13533
13534         local testdir1=$DIR/${tdir}/stats_testdir1
13535         mkdir -p ${testdir}
13536         mkdir -p ${testdir1}
13537         touch ${testdir1}/test1
13538         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13539         check_stats $SINGLEMDS "crossdir_rename" 1
13540
13541         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13542         check_stats $SINGLEMDS "samedir_rename" 1
13543
13544         rm -rf $DIR/${tdir}
13545 }
13546 run_test 133a "Verifying MDT stats ========================================"
13547
13548 test_133b() {
13549         local res
13550
13551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13552         remote_ost_nodsh && skip "remote OST with nodsh"
13553         remote_mds_nodsh && skip "remote MDS with nodsh"
13554
13555         local testdir=$DIR/${tdir}/stats_testdir
13556
13557         mkdir -p ${testdir} || error "mkdir failed"
13558         touch ${testdir}/${tfile} || error "touch failed"
13559         cancel_lru_locks mdc
13560
13561         # clear stats.
13562         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13563         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13564
13565         # extra mdt stats verification.
13566         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13567         check_stats $SINGLEMDS "setattr" 1
13568         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13569         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13570         then            # LU-1740
13571                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13572                 check_stats $SINGLEMDS "getattr" 1
13573         fi
13574         rm -rf $DIR/${tdir}
13575
13576         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13577         # so the check below is not reliable
13578         [ $MDSCOUNT -eq 1 ] || return 0
13579
13580         # Sleep to avoid a cached response.
13581         #define OBD_STATFS_CACHE_SECONDS 1
13582         sleep 2
13583         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13584         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13585         $LFS df || error "lfs failed"
13586         check_stats $SINGLEMDS "statfs" 1
13587
13588         # check aggregated statfs (LU-10018)
13589         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13590                 return 0
13591         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13592                 return 0
13593         sleep 2
13594         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13595         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13596         df $DIR
13597         check_stats $SINGLEMDS "statfs" 1
13598
13599         # We want to check that the client didn't send OST_STATFS to
13600         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13601         # extra care is needed here.
13602         if remote_mds; then
13603                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13604                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13605
13606                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13607                 [ "$res" ] && error "OST got STATFS"
13608         fi
13609
13610         return 0
13611 }
13612 run_test 133b "Verifying extra MDT stats =================================="
13613
13614 test_133c() {
13615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13616         remote_ost_nodsh && skip "remote OST with nodsh"
13617         remote_mds_nodsh && skip "remote MDS with nodsh"
13618
13619         local testdir=$DIR/$tdir/stats_testdir
13620
13621         test_mkdir -p $testdir
13622
13623         # verify obdfilter stats.
13624         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13625         sync
13626         cancel_lru_locks osc
13627         wait_delete_completed
13628
13629         # clear stats.
13630         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13631         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13632
13633         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13634                 error "dd failed"
13635         sync
13636         cancel_lru_locks osc
13637         check_stats ost1 "write" 1
13638
13639         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13640         check_stats ost1 "read" 1
13641
13642         > $testdir/$tfile || error "truncate failed"
13643         check_stats ost1 "punch" 1
13644
13645         rm -f $testdir/$tfile || error "file remove failed"
13646         wait_delete_completed
13647         check_stats ost1 "destroy" 1
13648
13649         rm -rf $DIR/$tdir
13650 }
13651 run_test 133c "Verifying OST stats ========================================"
13652
13653 order_2() {
13654         local value=$1
13655         local orig=$value
13656         local order=1
13657
13658         while [ $value -ge 2 ]; do
13659                 order=$((order*2))
13660                 value=$((value/2))
13661         done
13662
13663         if [ $orig -gt $order ]; then
13664                 order=$((order*2))
13665         fi
13666         echo $order
13667 }
13668
13669 size_in_KMGT() {
13670     local value=$1
13671     local size=('K' 'M' 'G' 'T');
13672     local i=0
13673     local size_string=$value
13674
13675     while [ $value -ge 1024 ]; do
13676         if [ $i -gt 3 ]; then
13677             #T is the biggest unit we get here, if that is bigger,
13678             #just return XXXT
13679             size_string=${value}T
13680             break
13681         fi
13682         value=$((value >> 10))
13683         if [ $value -lt 1024 ]; then
13684             size_string=${value}${size[$i]}
13685             break
13686         fi
13687         i=$((i + 1))
13688     done
13689
13690     echo $size_string
13691 }
13692
13693 get_rename_size() {
13694         local size=$1
13695         local context=${2:-.}
13696         local sample=$(do_facet $SINGLEMDS $LCTL \
13697                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13698                 grep -A1 $context |
13699                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13700         echo $sample
13701 }
13702
13703 test_133d() {
13704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13705         remote_ost_nodsh && skip "remote OST with nodsh"
13706         remote_mds_nodsh && skip "remote MDS with nodsh"
13707         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13708                 skip_env "MDS doesn't support rename stats"
13709
13710         local testdir1=$DIR/${tdir}/stats_testdir1
13711         local testdir2=$DIR/${tdir}/stats_testdir2
13712         mkdir -p $DIR/${tdir}
13713
13714         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13715
13716         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13717         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13718
13719         createmany -o $testdir1/test 512 || error "createmany failed"
13720
13721         # check samedir rename size
13722         mv ${testdir1}/test0 ${testdir1}/test_0
13723
13724         local testdir1_size=$(ls -l $DIR/${tdir} |
13725                 awk '/stats_testdir1/ {print $5}')
13726         local testdir2_size=$(ls -l $DIR/${tdir} |
13727                 awk '/stats_testdir2/ {print $5}')
13728
13729         testdir1_size=$(order_2 $testdir1_size)
13730         testdir2_size=$(order_2 $testdir2_size)
13731
13732         testdir1_size=$(size_in_KMGT $testdir1_size)
13733         testdir2_size=$(size_in_KMGT $testdir2_size)
13734
13735         echo "source rename dir size: ${testdir1_size}"
13736         echo "target rename dir size: ${testdir2_size}"
13737
13738         local cmd="do_facet $SINGLEMDS $LCTL "
13739         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13740
13741         eval $cmd || error "$cmd failed"
13742         local samedir=$($cmd | grep 'same_dir')
13743         local same_sample=$(get_rename_size $testdir1_size)
13744         [ -z "$samedir" ] && error "samedir_rename_size count error"
13745         [[ $same_sample -eq 1 ]] ||
13746                 error "samedir_rename_size error $same_sample"
13747         echo "Check same dir rename stats success"
13748
13749         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13750
13751         # check crossdir rename size
13752         mv ${testdir1}/test_0 ${testdir2}/test_0
13753
13754         testdir1_size=$(ls -l $DIR/${tdir} |
13755                 awk '/stats_testdir1/ {print $5}')
13756         testdir2_size=$(ls -l $DIR/${tdir} |
13757                 awk '/stats_testdir2/ {print $5}')
13758
13759         testdir1_size=$(order_2 $testdir1_size)
13760         testdir2_size=$(order_2 $testdir2_size)
13761
13762         testdir1_size=$(size_in_KMGT $testdir1_size)
13763         testdir2_size=$(size_in_KMGT $testdir2_size)
13764
13765         echo "source rename dir size: ${testdir1_size}"
13766         echo "target rename dir size: ${testdir2_size}"
13767
13768         eval $cmd || error "$cmd failed"
13769         local crossdir=$($cmd | grep 'crossdir')
13770         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13771         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13772         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13773         [[ $src_sample -eq 1 ]] ||
13774                 error "crossdir_rename_size error $src_sample"
13775         [[ $tgt_sample -eq 1 ]] ||
13776                 error "crossdir_rename_size error $tgt_sample"
13777         echo "Check cross dir rename stats success"
13778         rm -rf $DIR/${tdir}
13779 }
13780 run_test 133d "Verifying rename_stats ========================================"
13781
13782 test_133e() {
13783         remote_mds_nodsh && skip "remote MDS with nodsh"
13784         remote_ost_nodsh && skip "remote OST with nodsh"
13785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13786
13787         local testdir=$DIR/${tdir}/stats_testdir
13788         local ctr f0 f1 bs=32768 count=42 sum
13789
13790         mkdir -p ${testdir} || error "mkdir failed"
13791
13792         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13793
13794         for ctr in {write,read}_bytes; do
13795                 sync
13796                 cancel_lru_locks osc
13797
13798                 do_facet ost1 $LCTL set_param -n \
13799                         "obdfilter.*.exports.clear=clear"
13800
13801                 if [ $ctr = write_bytes ]; then
13802                         f0=/dev/zero
13803                         f1=${testdir}/${tfile}
13804                 else
13805                         f0=${testdir}/${tfile}
13806                         f1=/dev/null
13807                 fi
13808
13809                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13810                         error "dd failed"
13811                 sync
13812                 cancel_lru_locks osc
13813
13814                 sum=$(do_facet ost1 $LCTL get_param \
13815                         "obdfilter.*.exports.*.stats" |
13816                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13817                                 $1 == ctr { sum += $7 }
13818                                 END { printf("%0.0f", sum) }')
13819
13820                 if ((sum != bs * count)); then
13821                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13822                 fi
13823         done
13824
13825         rm -rf $DIR/${tdir}
13826 }
13827 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13828
13829 test_133f() {
13830         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13831                 skip "too old lustre for get_param -R ($facet_ver)"
13832
13833         # verifying readability.
13834         $LCTL get_param -R '*' &> /dev/null
13835
13836         # Verifing writability with badarea_io.
13837         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13838         local skipped_params='force_lbug|changelog_mask|daemon_file'
13839         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13840                 egrep -v "$skipped_params" |
13841                 xargs -n 1 find $proc_dirs -name |
13842                 xargs -n 1 badarea_io ||
13843                 error "client badarea_io failed"
13844
13845         # remount the FS in case writes/reads /proc break the FS
13846         cleanup || error "failed to unmount"
13847         setup || error "failed to setup"
13848 }
13849 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13850
13851 test_133g() {
13852         remote_mds_nodsh && skip "remote MDS with nodsh"
13853         remote_ost_nodsh && skip "remote OST with nodsh"
13854
13855         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13856         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
13857         local facet
13858         for facet in mds1 ost1; do
13859                 local facet_ver=$(lustre_version_code $facet)
13860                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13861                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13862                 else
13863                         log "$facet: too old lustre for get_param -R"
13864                 fi
13865                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13866                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13867                                 tr -d = | egrep -v $skipped_params |
13868                                 xargs -n 1 find $proc_dirs -name |
13869                                 xargs -n 1 badarea_io" ||
13870                                         error "$facet badarea_io failed"
13871                 else
13872                         skip_noexit "$facet: too old lustre for get_param -R"
13873                 fi
13874         done
13875
13876         # remount the FS in case writes/reads /proc break the FS
13877         cleanup || error "failed to unmount"
13878         setup || error "failed to setup"
13879 }
13880 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13881
13882 test_133h() {
13883         remote_mds_nodsh && skip "remote MDS with nodsh"
13884         remote_ost_nodsh && skip "remote OST with nodsh"
13885         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13886                 skip "Need MDS version at least 2.9.54"
13887
13888         local facet
13889         for facet in client mds1 ost1; do
13890                 # Get the list of files that are missing the terminating newline
13891                 local plist=$(do_facet $facet
13892                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13893                 local ent
13894                 for ent in $plist; do
13895                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13896                                 awk -v FS='\v' -v RS='\v\v' \
13897                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13898                                         print FILENAME}'" 2>/dev/null)
13899                         [ -z $missing ] || {
13900                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13901                                 error "file does not end with newline: $facet-$ent"
13902                         }
13903                 done
13904         done
13905 }
13906 run_test 133h "Proc files should end with newlines"
13907
13908 test_134a() {
13909         remote_mds_nodsh && skip "remote MDS with nodsh"
13910         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13911                 skip "Need MDS version at least 2.7.54"
13912
13913         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13914         cancel_lru_locks mdc
13915
13916         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13917         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13918         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13919
13920         local nr=1000
13921         createmany -o $DIR/$tdir/f $nr ||
13922                 error "failed to create $nr files in $DIR/$tdir"
13923         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13924
13925         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13926         do_facet mds1 $LCTL set_param fail_loc=0x327
13927         do_facet mds1 $LCTL set_param fail_val=500
13928         touch $DIR/$tdir/m
13929
13930         echo "sleep 10 seconds ..."
13931         sleep 10
13932         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13933
13934         do_facet mds1 $LCTL set_param fail_loc=0
13935         do_facet mds1 $LCTL set_param fail_val=0
13936         [ $lck_cnt -lt $unused ] ||
13937                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13938
13939         rm $DIR/$tdir/m
13940         unlinkmany $DIR/$tdir/f $nr
13941 }
13942 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13943
13944 test_134b() {
13945         remote_mds_nodsh && skip "remote MDS with nodsh"
13946         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13947                 skip "Need MDS version at least 2.7.54"
13948
13949         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13950         cancel_lru_locks mdc
13951
13952         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13953                         ldlm.lock_reclaim_threshold_mb)
13954         # disable reclaim temporarily
13955         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13956
13957         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13958         do_facet mds1 $LCTL set_param fail_loc=0x328
13959         do_facet mds1 $LCTL set_param fail_val=500
13960
13961         $LCTL set_param debug=+trace
13962
13963         local nr=600
13964         createmany -o $DIR/$tdir/f $nr &
13965         local create_pid=$!
13966
13967         echo "Sleep $TIMEOUT seconds ..."
13968         sleep $TIMEOUT
13969         if ! ps -p $create_pid  > /dev/null 2>&1; then
13970                 do_facet mds1 $LCTL set_param fail_loc=0
13971                 do_facet mds1 $LCTL set_param fail_val=0
13972                 do_facet mds1 $LCTL set_param \
13973                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13974                 error "createmany finished incorrectly!"
13975         fi
13976         do_facet mds1 $LCTL set_param fail_loc=0
13977         do_facet mds1 $LCTL set_param fail_val=0
13978         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13979         wait $create_pid || return 1
13980
13981         unlinkmany $DIR/$tdir/f $nr
13982 }
13983 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13984
13985 test_135() {
13986         remote_mds_nodsh && skip "remote MDS with nodsh"
13987         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13988                 skip "Need MDS version at least 2.13.50"
13989         local fname
13990
13991         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13992
13993 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13994         #set only one record at plain llog
13995         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13996
13997         #fill already existed plain llog each 64767
13998         #wrapping whole catalog
13999         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14000
14001         createmany -o $DIR/$tdir/$tfile_ 64700
14002         for (( i = 0; i < 64700; i = i + 2 ))
14003         do
14004                 rm $DIR/$tdir/$tfile_$i &
14005                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14006                 local pid=$!
14007                 wait $pid
14008         done
14009
14010         #waiting osp synchronization
14011         wait_delete_completed
14012 }
14013 run_test 135 "Race catalog processing"
14014
14015 test_136() {
14016         remote_mds_nodsh && skip "remote MDS with nodsh"
14017         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14018                 skip "Need MDS version at least 2.13.50"
14019         local fname
14020
14021         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14022         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14023         #set only one record at plain llog
14024 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14025         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14026
14027         #fill already existed 2 plain llogs each 64767
14028         #wrapping whole catalog
14029         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14030         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14031         wait_delete_completed
14032
14033         createmany -o $DIR/$tdir/$tfile_ 10
14034         sleep 25
14035
14036         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14037         for (( i = 0; i < 10; i = i + 3 ))
14038         do
14039                 rm $DIR/$tdir/$tfile_$i &
14040                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14041                 local pid=$!
14042                 wait $pid
14043                 sleep 7
14044                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14045         done
14046
14047         #waiting osp synchronization
14048         wait_delete_completed
14049 }
14050 run_test 136 "Race catalog processing 2"
14051
14052 test_140() { #bug-17379
14053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14054
14055         test_mkdir $DIR/$tdir
14056         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14057         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14058
14059         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14060         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14061         local i=0
14062         while i=$((i + 1)); do
14063                 test_mkdir $i
14064                 cd $i || error "Changing to $i"
14065                 ln -s ../stat stat || error "Creating stat symlink"
14066                 # Read the symlink until ELOOP present,
14067                 # not LBUGing the system is considered success,
14068                 # we didn't overrun the stack.
14069                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14070                 if [ $ret -ne 0 ]; then
14071                         if [ $ret -eq 40 ]; then
14072                                 break  # -ELOOP
14073                         else
14074                                 error "Open stat symlink"
14075                                         return
14076                         fi
14077                 fi
14078         done
14079         i=$((i - 1))
14080         echo "The symlink depth = $i"
14081         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14082                 error "Invalid symlink depth"
14083
14084         # Test recursive symlink
14085         ln -s symlink_self symlink_self
14086         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14087         echo "open symlink_self returns $ret"
14088         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14089 }
14090 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14091
14092 test_150a() {
14093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14094
14095         local TF="$TMP/$tfile"
14096
14097         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14098         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14099         cp $TF $DIR/$tfile
14100         cancel_lru_locks $OSC
14101         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14102         remount_client $MOUNT
14103         df -P $MOUNT
14104         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14105
14106         $TRUNCATE $TF 6000
14107         $TRUNCATE $DIR/$tfile 6000
14108         cancel_lru_locks $OSC
14109         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14110
14111         echo "12345" >>$TF
14112         echo "12345" >>$DIR/$tfile
14113         cancel_lru_locks $OSC
14114         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14115
14116         echo "12345" >>$TF
14117         echo "12345" >>$DIR/$tfile
14118         cancel_lru_locks $OSC
14119         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14120 }
14121 run_test 150a "truncate/append tests"
14122
14123 test_150b() {
14124         check_set_fallocate_or_skip
14125
14126         touch $DIR/$tfile
14127         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14128         check_fallocate $DIR/$tfile || error "fallocate failed"
14129 }
14130 run_test 150b "Verify fallocate (prealloc) functionality"
14131
14132 test_150bb() {
14133         check_set_fallocate_or_skip
14134
14135         touch $DIR/$tfile
14136         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14137         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14138         > $DIR/$tfile
14139         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14140         # precomputed md5sum for 20MB of zeroes
14141         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14142         local sum=($(md5sum $DIR/$tfile))
14143
14144         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14145
14146         check_set_fallocate 1
14147
14148         > $DIR/$tfile
14149         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14150         sum=($(md5sum $DIR/$tfile))
14151
14152         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14153 }
14154 run_test 150bb "Verify fallocate modes both zero space"
14155
14156 test_150c() {
14157         check_set_fallocate_or_skip
14158
14159         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14160         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14161         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14162         sync; sync_all_data
14163         cancel_lru_locks $OSC
14164         sleep 5
14165         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14166         want=$((OSTCOUNT * 1048576))
14167
14168         # Must allocate all requested space, not more than 5% extra
14169         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14170                 error "bytes $bytes is not $want"
14171
14172         rm -f $DIR/$tfile
14173         # verify fallocate on PFL file
14174         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14175                 error "Create $DIR/$tfile failed"
14176         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14177                         error "fallocate failed"
14178         sync; sync_all_data
14179         cancel_lru_locks $OSC
14180         sleep 5
14181         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14182         local want=$((1024 * 1048576))
14183
14184         # Must allocate all requested space, not more than 5% extra
14185         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14186                 error "bytes $bytes is not $want"
14187 }
14188 run_test 150c "Verify fallocate Size and Blocks"
14189
14190 test_150d() {
14191         check_set_fallocate_or_skip
14192
14193         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14194         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14195         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14196         sync; sync_all_data
14197         cancel_lru_locks $OSC
14198         sleep 5
14199         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14200         local want=$((OSTCOUNT * 1048576))
14201
14202         # Must allocate all requested space, not more than 5% extra
14203         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14204                 error "bytes $bytes is not $want"
14205 }
14206 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14207
14208 test_150e() {
14209         check_set_fallocate_or_skip
14210
14211         echo "df before:"
14212         $LFS df
14213         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14214         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14215                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14216
14217         # Find OST with Minimum Size
14218         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14219                        sort -un | head -1)
14220
14221         # Get 100MB per OST of the available space to reduce run time
14222         # else 60% of the available space if we are running SLOW tests
14223         if [ $SLOW == "no" ]; then
14224                 local space=$((1024 * 100 * OSTCOUNT))
14225         else
14226                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14227         fi
14228
14229         fallocate -l${space}k $DIR/$tfile ||
14230                 error "fallocate ${space}k $DIR/$tfile failed"
14231         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14232
14233         # get size immediately after fallocate. This should be correctly
14234         # updated
14235         local size=$(stat -c '%s' $DIR/$tfile)
14236         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14237
14238         # Sleep for a while for statfs to get updated. And not pull from cache.
14239         sleep 2
14240
14241         echo "df after fallocate:"
14242         $LFS df
14243
14244         (( size / 1024 == space )) || error "size $size != requested $space"
14245         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14246                 error "used $used < space $space"
14247
14248         rm $DIR/$tfile || error "rm failed"
14249         sync
14250         wait_delete_completed
14251
14252         echo "df after unlink:"
14253         $LFS df
14254 }
14255 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14256
14257 test_150f() {
14258         local size
14259         local blocks
14260         local want_size_before=20480 # in bytes
14261         local want_blocks_before=40 # 512 sized blocks
14262         local want_blocks_after=24  # 512 sized blocks
14263         local length=$(((want_blocks_before - want_blocks_after) * 512))
14264
14265         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14266                 skip "need at least 2.14.0 for fallocate punch"
14267
14268         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14269                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14270         fi
14271
14272         check_set_fallocate_or_skip
14273         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14274
14275         echo "Verify fallocate punch: Range within the file range"
14276         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14277                 error "dd failed for bs 4096 and count 5"
14278
14279         # Call fallocate with punch range which is within the file range
14280         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14281                 error "fallocate failed: offset 4096 and length $length"
14282         # client must see changes immediately after fallocate
14283         size=$(stat -c '%s' $DIR/$tfile)
14284         blocks=$(stat -c '%b' $DIR/$tfile)
14285
14286         # Verify punch worked.
14287         (( blocks == want_blocks_after )) ||
14288                 error "punch failed: blocks $blocks != $want_blocks_after"
14289
14290         (( size == want_size_before )) ||
14291                 error "punch failed: size $size != $want_size_before"
14292
14293         # Verify there is hole in file
14294         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14295         # precomputed md5sum
14296         local expect="4a9a834a2db02452929c0a348273b4aa"
14297
14298         cksum=($(md5sum $DIR/$tfile))
14299         [[ "${cksum[0]}" == "$expect" ]] ||
14300                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14301
14302         # Start second sub-case for fallocate punch.
14303         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14304         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14305                 error "dd failed for bs 4096 and count 5"
14306
14307         # Punch range less than block size will have no change in block count
14308         want_blocks_after=40  # 512 sized blocks
14309
14310         # Punch overlaps two blocks and less than blocksize
14311         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14312                 error "fallocate failed: offset 4000 length 3000"
14313         size=$(stat -c '%s' $DIR/$tfile)
14314         blocks=$(stat -c '%b' $DIR/$tfile)
14315
14316         # Verify punch worked.
14317         (( blocks == want_blocks_after )) ||
14318                 error "punch failed: blocks $blocks != $want_blocks_after"
14319
14320         (( size == want_size_before )) ||
14321                 error "punch failed: size $size != $want_size_before"
14322
14323         # Verify if range is really zero'ed out. We expect Zeros.
14324         # precomputed md5sum
14325         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14326         cksum=($(md5sum $DIR/$tfile))
14327         [[ "${cksum[0]}" == "$expect" ]] ||
14328                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14329 }
14330 run_test 150f "Verify fallocate punch functionality"
14331
14332 test_150g() {
14333         local space
14334         local size
14335         local blocks
14336         local blocks_after
14337         local size_after
14338         local BS=4096 # Block size in bytes
14339
14340         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14341                 skip "need at least 2.14.0 for fallocate punch"
14342
14343         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14344                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14345         fi
14346
14347         check_set_fallocate_or_skip
14348         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14349
14350         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14351                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14352
14353         # Get 100MB per OST of the available space to reduce run time
14354         # else 60% of the available space if we are running SLOW tests
14355         if [ $SLOW == "no" ]; then
14356                 space=$((1024 * 100 * OSTCOUNT))
14357         else
14358                 # Find OST with Minimum Size
14359                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14360                         sort -un | head -1)
14361                 echo "min size OST: $space"
14362                 space=$(((space * 60)/100 * OSTCOUNT))
14363         fi
14364         # space in 1k units, round to 4k blocks
14365         local blkcount=$((space * 1024 / $BS))
14366
14367         echo "Verify fallocate punch: Very large Range"
14368         fallocate -l${space}k $DIR/$tfile ||
14369                 error "fallocate ${space}k $DIR/$tfile failed"
14370         # write 1M at the end, start and in the middle
14371         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14372                 error "dd failed: bs $BS count 256"
14373         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14374                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14375         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14376                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14377
14378         # Gather stats.
14379         size=$(stat -c '%s' $DIR/$tfile)
14380
14381         # gather punch length.
14382         local punch_size=$((size - (BS * 2)))
14383
14384         echo "punch_size = $punch_size"
14385         echo "size - punch_size: $((size - punch_size))"
14386         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14387
14388         # Call fallocate to punch all except 2 blocks. We leave the
14389         # first and the last block
14390         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14391         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14392                 error "fallocate failed: offset $BS length $punch_size"
14393
14394         size_after=$(stat -c '%s' $DIR/$tfile)
14395         blocks_after=$(stat -c '%b' $DIR/$tfile)
14396
14397         # Verify punch worked.
14398         # Size should be kept
14399         (( size == size_after )) ||
14400                 error "punch failed: size $size != $size_after"
14401
14402         # two 4k data blocks to remain plus possible 1 extra extent block
14403         (( blocks_after <= ((BS / 512) * 3) )) ||
14404                 error "too many blocks remains: $blocks_after"
14405
14406         # Verify that file has hole between the first and the last blocks
14407         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14408         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14409
14410         echo "Hole at [$hole_start, $hole_end)"
14411         (( hole_start == BS )) ||
14412                 error "no hole at offset $BS after punch"
14413
14414         (( hole_end == BS + punch_size )) ||
14415                 error "data at offset $hole_end < $((BS + punch_size))"
14416 }
14417 run_test 150g "Verify fallocate punch on large range"
14418
14419 #LU-2902 roc_hit was not able to read all values from lproc
14420 function roc_hit_init() {
14421         local list=$(comma_list $(osts_nodes))
14422         local dir=$DIR/$tdir-check
14423         local file=$dir/$tfile
14424         local BEFORE
14425         local AFTER
14426         local idx
14427
14428         test_mkdir $dir
14429         #use setstripe to do a write to every ost
14430         for i in $(seq 0 $((OSTCOUNT-1))); do
14431                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14432                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14433                 idx=$(printf %04x $i)
14434                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14435                         awk '$1 == "cache_access" {sum += $7}
14436                                 END { printf("%0.0f", sum) }')
14437
14438                 cancel_lru_locks osc
14439                 cat $file >/dev/null
14440
14441                 AFTER=$(get_osd_param $list *OST*$idx stats |
14442                         awk '$1 == "cache_access" {sum += $7}
14443                                 END { printf("%0.0f", sum) }')
14444
14445                 echo BEFORE:$BEFORE AFTER:$AFTER
14446                 if ! let "AFTER - BEFORE == 4"; then
14447                         rm -rf $dir
14448                         error "roc_hit is not safe to use"
14449                 fi
14450                 rm $file
14451         done
14452
14453         rm -rf $dir
14454 }
14455
14456 function roc_hit() {
14457         local list=$(comma_list $(osts_nodes))
14458         echo $(get_osd_param $list '' stats |
14459                 awk '$1 == "cache_hit" {sum += $7}
14460                         END { printf("%0.0f", sum) }')
14461 }
14462
14463 function set_cache() {
14464         local on=1
14465
14466         if [ "$2" == "off" ]; then
14467                 on=0;
14468         fi
14469         local list=$(comma_list $(osts_nodes))
14470         set_osd_param $list '' $1_cache_enable $on
14471
14472         cancel_lru_locks osc
14473 }
14474
14475 test_151() {
14476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14477         remote_ost_nodsh && skip "remote OST with nodsh"
14478
14479         local CPAGES=3
14480         local list=$(comma_list $(osts_nodes))
14481
14482         # check whether obdfilter is cache capable at all
14483         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14484                 skip "not cache-capable obdfilter"
14485         fi
14486
14487         # check cache is enabled on all obdfilters
14488         if get_osd_param $list '' read_cache_enable | grep 0; then
14489                 skip "oss cache is disabled"
14490         fi
14491
14492         set_osd_param $list '' writethrough_cache_enable 1
14493
14494         # check write cache is enabled on all obdfilters
14495         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14496                 skip "oss write cache is NOT enabled"
14497         fi
14498
14499         roc_hit_init
14500
14501         #define OBD_FAIL_OBD_NO_LRU  0x609
14502         do_nodes $list $LCTL set_param fail_loc=0x609
14503
14504         # pages should be in the case right after write
14505         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14506                 error "dd failed"
14507
14508         local BEFORE=$(roc_hit)
14509         cancel_lru_locks osc
14510         cat $DIR/$tfile >/dev/null
14511         local AFTER=$(roc_hit)
14512
14513         do_nodes $list $LCTL set_param fail_loc=0
14514
14515         if ! let "AFTER - BEFORE == CPAGES"; then
14516                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14517         fi
14518
14519         cancel_lru_locks osc
14520         # invalidates OST cache
14521         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14522         set_osd_param $list '' read_cache_enable 0
14523         cat $DIR/$tfile >/dev/null
14524
14525         # now data shouldn't be found in the cache
14526         BEFORE=$(roc_hit)
14527         cancel_lru_locks osc
14528         cat $DIR/$tfile >/dev/null
14529         AFTER=$(roc_hit)
14530         if let "AFTER - BEFORE != 0"; then
14531                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14532         fi
14533
14534         set_osd_param $list '' read_cache_enable 1
14535         rm -f $DIR/$tfile
14536 }
14537 run_test 151 "test cache on oss and controls ==============================="
14538
14539 test_152() {
14540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14541
14542         local TF="$TMP/$tfile"
14543
14544         # simulate ENOMEM during write
14545 #define OBD_FAIL_OST_NOMEM      0x226
14546         lctl set_param fail_loc=0x80000226
14547         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14548         cp $TF $DIR/$tfile
14549         sync || error "sync failed"
14550         lctl set_param fail_loc=0
14551
14552         # discard client's cache
14553         cancel_lru_locks osc
14554
14555         # simulate ENOMEM during read
14556         lctl set_param fail_loc=0x80000226
14557         cmp $TF $DIR/$tfile || error "cmp failed"
14558         lctl set_param fail_loc=0
14559
14560         rm -f $TF
14561 }
14562 run_test 152 "test read/write with enomem ============================"
14563
14564 test_153() {
14565         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14566 }
14567 run_test 153 "test if fdatasync does not crash ======================="
14568
14569 dot_lustre_fid_permission_check() {
14570         local fid=$1
14571         local ffid=$MOUNT/.lustre/fid/$fid
14572         local test_dir=$2
14573
14574         echo "stat fid $fid"
14575         stat $ffid > /dev/null || error "stat $ffid failed."
14576         echo "touch fid $fid"
14577         touch $ffid || error "touch $ffid failed."
14578         echo "write to fid $fid"
14579         cat /etc/hosts > $ffid || error "write $ffid failed."
14580         echo "read fid $fid"
14581         diff /etc/hosts $ffid || error "read $ffid failed."
14582         echo "append write to fid $fid"
14583         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14584         echo "rename fid $fid"
14585         mv $ffid $test_dir/$tfile.1 &&
14586                 error "rename $ffid to $tfile.1 should fail."
14587         touch $test_dir/$tfile.1
14588         mv $test_dir/$tfile.1 $ffid &&
14589                 error "rename $tfile.1 to $ffid should fail."
14590         rm -f $test_dir/$tfile.1
14591         echo "truncate fid $fid"
14592         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14593         echo "link fid $fid"
14594         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14595         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14596                 echo "setfacl fid $fid"
14597                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14598                 echo "getfacl fid $fid"
14599                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14600         fi
14601         echo "unlink fid $fid"
14602         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14603         echo "mknod fid $fid"
14604         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14605
14606         fid=[0xf00000400:0x1:0x0]
14607         ffid=$MOUNT/.lustre/fid/$fid
14608
14609         echo "stat non-exist fid $fid"
14610         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14611         echo "write to non-exist fid $fid"
14612         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14613         echo "link new fid $fid"
14614         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14615
14616         mkdir -p $test_dir/$tdir
14617         touch $test_dir/$tdir/$tfile
14618         fid=$($LFS path2fid $test_dir/$tdir)
14619         rc=$?
14620         [ $rc -ne 0 ] &&
14621                 error "error: could not get fid for $test_dir/$dir/$tfile."
14622
14623         ffid=$MOUNT/.lustre/fid/$fid
14624
14625         echo "ls $fid"
14626         ls $ffid > /dev/null || error "ls $ffid failed."
14627         echo "touch $fid/$tfile.1"
14628         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14629
14630         echo "touch $MOUNT/.lustre/fid/$tfile"
14631         touch $MOUNT/.lustre/fid/$tfile && \
14632                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14633
14634         echo "setxattr to $MOUNT/.lustre/fid"
14635         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14636
14637         echo "listxattr for $MOUNT/.lustre/fid"
14638         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14639
14640         echo "delxattr from $MOUNT/.lustre/fid"
14641         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14642
14643         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14644         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14645                 error "touch invalid fid should fail."
14646
14647         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14648         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14649                 error "touch non-normal fid should fail."
14650
14651         echo "rename $tdir to $MOUNT/.lustre/fid"
14652         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14653                 error "rename to $MOUNT/.lustre/fid should fail."
14654
14655         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14656         then            # LU-3547
14657                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14658                 local new_obf_mode=777
14659
14660                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14661                 chmod $new_obf_mode $DIR/.lustre/fid ||
14662                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14663
14664                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14665                 [ $obf_mode -eq $new_obf_mode ] ||
14666                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14667
14668                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14669                 chmod $old_obf_mode $DIR/.lustre/fid ||
14670                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14671         fi
14672
14673         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14674         fid=$($LFS path2fid $test_dir/$tfile-2)
14675
14676         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14677         then # LU-5424
14678                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14679                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14680                         error "create lov data thru .lustre failed"
14681         fi
14682         echo "cp /etc/passwd $test_dir/$tfile-2"
14683         cp /etc/passwd $test_dir/$tfile-2 ||
14684                 error "copy to $test_dir/$tfile-2 failed."
14685         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14686         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14687                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14688
14689         rm -rf $test_dir/tfile.lnk
14690         rm -rf $test_dir/$tfile-2
14691 }
14692
14693 test_154A() {
14694         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14695                 skip "Need MDS version at least 2.4.1"
14696
14697         local tf=$DIR/$tfile
14698         touch $tf
14699
14700         local fid=$($LFS path2fid $tf)
14701         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14702
14703         # check that we get the same pathname back
14704         local rootpath
14705         local found
14706         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14707                 echo "$rootpath $fid"
14708                 found=$($LFS fid2path $rootpath "$fid")
14709                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14710                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14711         done
14712
14713         # check wrong root path format
14714         rootpath=$MOUNT"_wrong"
14715         found=$($LFS fid2path $rootpath "$fid")
14716         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14717 }
14718 run_test 154A "lfs path2fid and fid2path basic checks"
14719
14720 test_154B() {
14721         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14722                 skip "Need MDS version at least 2.4.1"
14723
14724         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14725         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14726         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14727         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14728
14729         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14730         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14731
14732         # check that we get the same pathname
14733         echo "PFID: $PFID, name: $name"
14734         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14735         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14736         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14737                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14738
14739         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14740 }
14741 run_test 154B "verify the ll_decode_linkea tool"
14742
14743 test_154a() {
14744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14745         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14746         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14747                 skip "Need MDS version at least 2.2.51"
14748         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14749
14750         cp /etc/hosts $DIR/$tfile
14751
14752         fid=$($LFS path2fid $DIR/$tfile)
14753         rc=$?
14754         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14755
14756         dot_lustre_fid_permission_check "$fid" $DIR ||
14757                 error "dot lustre permission check $fid failed"
14758
14759         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14760
14761         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14762
14763         touch $MOUNT/.lustre/file &&
14764                 error "creation is not allowed under .lustre"
14765
14766         mkdir $MOUNT/.lustre/dir &&
14767                 error "mkdir is not allowed under .lustre"
14768
14769         rm -rf $DIR/$tfile
14770 }
14771 run_test 154a "Open-by-FID"
14772
14773 test_154b() {
14774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14775         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14776         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14777         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14778                 skip "Need MDS version at least 2.2.51"
14779
14780         local remote_dir=$DIR/$tdir/remote_dir
14781         local MDTIDX=1
14782         local rc=0
14783
14784         mkdir -p $DIR/$tdir
14785         $LFS mkdir -i $MDTIDX $remote_dir ||
14786                 error "create remote directory failed"
14787
14788         cp /etc/hosts $remote_dir/$tfile
14789
14790         fid=$($LFS path2fid $remote_dir/$tfile)
14791         rc=$?
14792         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14793
14794         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14795                 error "dot lustre permission check $fid failed"
14796         rm -rf $DIR/$tdir
14797 }
14798 run_test 154b "Open-by-FID for remote directory"
14799
14800 test_154c() {
14801         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14802                 skip "Need MDS version at least 2.4.1"
14803
14804         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14805         local FID1=$($LFS path2fid $DIR/$tfile.1)
14806         local FID2=$($LFS path2fid $DIR/$tfile.2)
14807         local FID3=$($LFS path2fid $DIR/$tfile.3)
14808
14809         local N=1
14810         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14811                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14812                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14813                 local want=FID$N
14814                 [ "$FID" = "${!want}" ] ||
14815                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14816                 N=$((N + 1))
14817         done
14818
14819         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14820         do
14821                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14822                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14823                 N=$((N + 1))
14824         done
14825 }
14826 run_test 154c "lfs path2fid and fid2path multiple arguments"
14827
14828 test_154d() {
14829         remote_mds_nodsh && skip "remote MDS with nodsh"
14830         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14831                 skip "Need MDS version at least 2.5.53"
14832
14833         if remote_mds; then
14834                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14835         else
14836                 nid="0@lo"
14837         fi
14838         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14839         local fd
14840         local cmd
14841
14842         rm -f $DIR/$tfile
14843         touch $DIR/$tfile
14844
14845         local fid=$($LFS path2fid $DIR/$tfile)
14846         # Open the file
14847         fd=$(free_fd)
14848         cmd="exec $fd<$DIR/$tfile"
14849         eval $cmd
14850         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14851         echo "$fid_list" | grep "$fid"
14852         rc=$?
14853
14854         cmd="exec $fd>/dev/null"
14855         eval $cmd
14856         if [ $rc -ne 0 ]; then
14857                 error "FID $fid not found in open files list $fid_list"
14858         fi
14859 }
14860 run_test 154d "Verify open file fid"
14861
14862 test_154e()
14863 {
14864         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14865                 skip "Need MDS version at least 2.6.50"
14866
14867         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14868                 error ".lustre returned by readdir"
14869         fi
14870 }
14871 run_test 154e ".lustre is not returned by readdir"
14872
14873 test_154f() {
14874         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14875
14876         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14877         mkdir_on_mdt0 $DIR/$tdir
14878         # test dirs inherit from its stripe
14879         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
14880         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
14881         cp /etc/hosts $DIR/$tdir/foo1/$tfile
14882         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
14883         touch $DIR/f
14884
14885         # get fid of parents
14886         local FID0=$($LFS path2fid $DIR/$tdir)
14887         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
14888         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
14889         local FID3=$($LFS path2fid $DIR)
14890
14891         # check that path2fid --parents returns expected <parent_fid>/name
14892         # 1) test for a directory (single parent)
14893         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
14894         [ "$parent" == "$FID0/foo1" ] ||
14895                 error "expected parent: $FID0/foo1, got: $parent"
14896
14897         # 2) test for a file with nlink > 1 (multiple parents)
14898         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
14899         echo "$parent" | grep -F "$FID1/$tfile" ||
14900                 error "$FID1/$tfile not returned in parent list"
14901         echo "$parent" | grep -F "$FID2/link" ||
14902                 error "$FID2/link not returned in parent list"
14903
14904         # 3) get parent by fid
14905         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
14906         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14907         echo "$parent" | grep -F "$FID1/$tfile" ||
14908                 error "$FID1/$tfile not returned in parent list (by fid)"
14909         echo "$parent" | grep -F "$FID2/link" ||
14910                 error "$FID2/link not returned in parent list (by fid)"
14911
14912         # 4) test for entry in root directory
14913         parent=$($LFS path2fid --parents $DIR/f)
14914         echo "$parent" | grep -F "$FID3/f" ||
14915                 error "$FID3/f not returned in parent list"
14916
14917         # 5) test it on root directory
14918         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14919                 error "$MOUNT should not have parents"
14920
14921         # enable xattr caching and check that linkea is correctly updated
14922         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14923         save_lustre_params client "llite.*.xattr_cache" > $save
14924         lctl set_param llite.*.xattr_cache 1
14925
14926         # 6.1) linkea update on rename
14927         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
14928
14929         # get parents by fid
14930         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14931         # foo1 should no longer be returned in parent list
14932         echo "$parent" | grep -F "$FID1" &&
14933                 error "$FID1 should no longer be in parent list"
14934         # the new path should appear
14935         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14936                 error "$FID2/$tfile.moved is not in parent list"
14937
14938         # 6.2) linkea update on unlink
14939         rm -f $DIR/$tdir/foo2/link
14940         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14941         # foo2/link should no longer be returned in parent list
14942         echo "$parent" | grep -F "$FID2/link" &&
14943                 error "$FID2/link should no longer be in parent list"
14944         true
14945
14946         rm -f $DIR/f
14947         restore_lustre_params < $save
14948         rm -f $save
14949 }
14950 run_test 154f "get parent fids by reading link ea"
14951
14952 test_154g()
14953 {
14954         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14955         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14956            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14957                 skip "Need MDS version at least 2.6.92"
14958
14959         mkdir_on_mdt0 $DIR/$tdir
14960         llapi_fid_test -d $DIR/$tdir
14961 }
14962 run_test 154g "various llapi FID tests"
14963
14964 test_155_small_load() {
14965     local temp=$TMP/$tfile
14966     local file=$DIR/$tfile
14967
14968     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14969         error "dd of=$temp bs=6096 count=1 failed"
14970     cp $temp $file
14971     cancel_lru_locks $OSC
14972     cmp $temp $file || error "$temp $file differ"
14973
14974     $TRUNCATE $temp 6000
14975     $TRUNCATE $file 6000
14976     cmp $temp $file || error "$temp $file differ (truncate1)"
14977
14978     echo "12345" >>$temp
14979     echo "12345" >>$file
14980     cmp $temp $file || error "$temp $file differ (append1)"
14981
14982     echo "12345" >>$temp
14983     echo "12345" >>$file
14984     cmp $temp $file || error "$temp $file differ (append2)"
14985
14986     rm -f $temp $file
14987     true
14988 }
14989
14990 test_155_big_load() {
14991         remote_ost_nodsh && skip "remote OST with nodsh"
14992
14993         local temp=$TMP/$tfile
14994         local file=$DIR/$tfile
14995
14996         free_min_max
14997         local cache_size=$(do_facet ost$((MAXI+1)) \
14998                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14999         local large_file_size=$((cache_size * 2))
15000
15001         echo "OSS cache size: $cache_size KB"
15002         echo "Large file size: $large_file_size KB"
15003
15004         [ $MAXV -le $large_file_size ] &&
15005                 skip_env "max available OST size needs > $large_file_size KB"
15006
15007         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15008
15009         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15010                 error "dd of=$temp bs=$large_file_size count=1k failed"
15011         cp $temp $file
15012         ls -lh $temp $file
15013         cancel_lru_locks osc
15014         cmp $temp $file || error "$temp $file differ"
15015
15016         rm -f $temp $file
15017         true
15018 }
15019
15020 save_writethrough() {
15021         local facets=$(get_facets OST)
15022
15023         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15024 }
15025
15026 test_155a() {
15027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15028
15029         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15030
15031         save_writethrough $p
15032
15033         set_cache read on
15034         set_cache writethrough on
15035         test_155_small_load
15036         restore_lustre_params < $p
15037         rm -f $p
15038 }
15039 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15040
15041 test_155b() {
15042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15043
15044         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15045
15046         save_writethrough $p
15047
15048         set_cache read on
15049         set_cache writethrough off
15050         test_155_small_load
15051         restore_lustre_params < $p
15052         rm -f $p
15053 }
15054 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15055
15056 test_155c() {
15057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15058
15059         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15060
15061         save_writethrough $p
15062
15063         set_cache read off
15064         set_cache writethrough on
15065         test_155_small_load
15066         restore_lustre_params < $p
15067         rm -f $p
15068 }
15069 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15070
15071 test_155d() {
15072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15073
15074         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15075
15076         save_writethrough $p
15077
15078         set_cache read off
15079         set_cache writethrough off
15080         test_155_small_load
15081         restore_lustre_params < $p
15082         rm -f $p
15083 }
15084 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15085
15086 test_155e() {
15087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15088
15089         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15090
15091         save_writethrough $p
15092
15093         set_cache read on
15094         set_cache writethrough on
15095         test_155_big_load
15096         restore_lustre_params < $p
15097         rm -f $p
15098 }
15099 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15100
15101 test_155f() {
15102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15103
15104         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15105
15106         save_writethrough $p
15107
15108         set_cache read on
15109         set_cache writethrough off
15110         test_155_big_load
15111         restore_lustre_params < $p
15112         rm -f $p
15113 }
15114 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15115
15116 test_155g() {
15117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15118
15119         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15120
15121         save_writethrough $p
15122
15123         set_cache read off
15124         set_cache writethrough on
15125         test_155_big_load
15126         restore_lustre_params < $p
15127         rm -f $p
15128 }
15129 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15130
15131 test_155h() {
15132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15133
15134         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15135
15136         save_writethrough $p
15137
15138         set_cache read off
15139         set_cache writethrough off
15140         test_155_big_load
15141         restore_lustre_params < $p
15142         rm -f $p
15143 }
15144 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15145
15146 test_156() {
15147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15148         remote_ost_nodsh && skip "remote OST with nodsh"
15149         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15150                 skip "stats not implemented on old servers"
15151         [ "$ost1_FSTYPE" = "zfs" ] &&
15152                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15153
15154         local CPAGES=3
15155         local BEFORE
15156         local AFTER
15157         local file="$DIR/$tfile"
15158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15159
15160         save_writethrough $p
15161         roc_hit_init
15162
15163         log "Turn on read and write cache"
15164         set_cache read on
15165         set_cache writethrough on
15166
15167         log "Write data and read it back."
15168         log "Read should be satisfied from the cache."
15169         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15170         BEFORE=$(roc_hit)
15171         cancel_lru_locks osc
15172         cat $file >/dev/null
15173         AFTER=$(roc_hit)
15174         if ! let "AFTER - BEFORE == CPAGES"; then
15175                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15176         else
15177                 log "cache hits: before: $BEFORE, after: $AFTER"
15178         fi
15179
15180         log "Read again; it should be satisfied from the cache."
15181         BEFORE=$AFTER
15182         cancel_lru_locks osc
15183         cat $file >/dev/null
15184         AFTER=$(roc_hit)
15185         if ! let "AFTER - BEFORE == CPAGES"; then
15186                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15187         else
15188                 log "cache hits:: before: $BEFORE, after: $AFTER"
15189         fi
15190
15191         log "Turn off the read cache and turn on the write cache"
15192         set_cache read off
15193         set_cache writethrough on
15194
15195         log "Read again; it should be satisfied from the cache."
15196         BEFORE=$(roc_hit)
15197         cancel_lru_locks osc
15198         cat $file >/dev/null
15199         AFTER=$(roc_hit)
15200         if ! let "AFTER - BEFORE == CPAGES"; then
15201                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15202         else
15203                 log "cache hits:: before: $BEFORE, after: $AFTER"
15204         fi
15205
15206         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15207                 # > 2.12.56 uses pagecache if cached
15208                 log "Read again; it should not be satisfied from the cache."
15209                 BEFORE=$AFTER
15210                 cancel_lru_locks osc
15211                 cat $file >/dev/null
15212                 AFTER=$(roc_hit)
15213                 if ! let "AFTER - BEFORE == 0"; then
15214                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15215                 else
15216                         log "cache hits:: before: $BEFORE, after: $AFTER"
15217                 fi
15218         fi
15219
15220         log "Write data and read it back."
15221         log "Read should be satisfied from the cache."
15222         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15223         BEFORE=$(roc_hit)
15224         cancel_lru_locks osc
15225         cat $file >/dev/null
15226         AFTER=$(roc_hit)
15227         if ! let "AFTER - BEFORE == CPAGES"; then
15228                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15229         else
15230                 log "cache hits:: before: $BEFORE, after: $AFTER"
15231         fi
15232
15233         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15234                 # > 2.12.56 uses pagecache if cached
15235                 log "Read again; it should not be satisfied from the cache."
15236                 BEFORE=$AFTER
15237                 cancel_lru_locks osc
15238                 cat $file >/dev/null
15239                 AFTER=$(roc_hit)
15240                 if ! let "AFTER - BEFORE == 0"; then
15241                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15242                 else
15243                         log "cache hits:: before: $BEFORE, after: $AFTER"
15244                 fi
15245         fi
15246
15247         log "Turn off read and write cache"
15248         set_cache read off
15249         set_cache writethrough off
15250
15251         log "Write data and read it back"
15252         log "It should not be satisfied from the cache."
15253         rm -f $file
15254         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15255         cancel_lru_locks osc
15256         BEFORE=$(roc_hit)
15257         cat $file >/dev/null
15258         AFTER=$(roc_hit)
15259         if ! let "AFTER - BEFORE == 0"; then
15260                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15261         else
15262                 log "cache hits:: before: $BEFORE, after: $AFTER"
15263         fi
15264
15265         log "Turn on the read cache and turn off the write cache"
15266         set_cache read on
15267         set_cache writethrough off
15268
15269         log "Write data and read it back"
15270         log "It should not be satisfied from the cache."
15271         rm -f $file
15272         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15273         BEFORE=$(roc_hit)
15274         cancel_lru_locks osc
15275         cat $file >/dev/null
15276         AFTER=$(roc_hit)
15277         if ! let "AFTER - BEFORE == 0"; then
15278                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15279         else
15280                 log "cache hits:: before: $BEFORE, after: $AFTER"
15281         fi
15282
15283         log "Read again; it should be satisfied from the cache."
15284         BEFORE=$(roc_hit)
15285         cancel_lru_locks osc
15286         cat $file >/dev/null
15287         AFTER=$(roc_hit)
15288         if ! let "AFTER - BEFORE == CPAGES"; then
15289                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15290         else
15291                 log "cache hits:: before: $BEFORE, after: $AFTER"
15292         fi
15293
15294         restore_lustre_params < $p
15295         rm -f $p $file
15296 }
15297 run_test 156 "Verification of tunables"
15298
15299 test_160a() {
15300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15301         remote_mds_nodsh && skip "remote MDS with nodsh"
15302         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15303                 skip "Need MDS version at least 2.2.0"
15304
15305         changelog_register || error "changelog_register failed"
15306         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15307         changelog_users $SINGLEMDS | grep -q $cl_user ||
15308                 error "User $cl_user not found in changelog_users"
15309
15310         mkdir_on_mdt0 $DIR/$tdir
15311
15312         # change something
15313         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15314         changelog_clear 0 || error "changelog_clear failed"
15315         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15316         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15317         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15318         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15319         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15320         rm $DIR/$tdir/pics/desktop.jpg
15321
15322         echo "verifying changelog mask"
15323         changelog_chmask "-MKDIR"
15324         changelog_chmask "-CLOSE"
15325
15326         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15327         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15328
15329         changelog_chmask "+MKDIR"
15330         changelog_chmask "+CLOSE"
15331
15332         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15333         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15334
15335         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15336         CLOSES=$(changelog_dump | grep -c "CLOSE")
15337         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15338         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15339
15340         # verify contents
15341         echo "verifying target fid"
15342         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15343         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15344         [ "$fidc" == "$fidf" ] ||
15345                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15346         echo "verifying parent fid"
15347         # The FID returned from the Changelog may be the directory shard on
15348         # a different MDT, and not the FID returned by path2fid on the parent.
15349         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15350         # since this is what will matter when recreating this file in the tree.
15351         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15352         local pathp=$($LFS fid2path $MOUNT "$fidp")
15353         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15354                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15355
15356         echo "getting records for $cl_user"
15357         changelog_users $SINGLEMDS
15358         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15359         local nclr=3
15360         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15361                 error "changelog_clear failed"
15362         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15363         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15364         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15365                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15366
15367         local min0_rec=$(changelog_users $SINGLEMDS |
15368                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15369         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15370                           awk '{ print $1; exit; }')
15371
15372         changelog_dump | tail -n 5
15373         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15374         [ $first_rec == $((min0_rec + 1)) ] ||
15375                 error "first index should be $min0_rec + 1 not $first_rec"
15376
15377         # LU-3446 changelog index reset on MDT restart
15378         local cur_rec1=$(changelog_users $SINGLEMDS |
15379                          awk '/^current.index:/ { print $NF }')
15380         changelog_clear 0 ||
15381                 error "clear all changelog records for $cl_user failed"
15382         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15383         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15384                 error "Fail to start $SINGLEMDS"
15385         local cur_rec2=$(changelog_users $SINGLEMDS |
15386                          awk '/^current.index:/ { print $NF }')
15387         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15388         [ $cur_rec1 == $cur_rec2 ] ||
15389                 error "current index should be $cur_rec1 not $cur_rec2"
15390
15391         echo "verifying users from this test are deregistered"
15392         changelog_deregister || error "changelog_deregister failed"
15393         changelog_users $SINGLEMDS | grep -q $cl_user &&
15394                 error "User '$cl_user' still in changelog_users"
15395
15396         # lctl get_param -n mdd.*.changelog_users
15397         # current_index: 144
15398         # ID    index (idle seconds)
15399         # cl3   144   (2) mask=<list>
15400         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15401                 # this is the normal case where all users were deregistered
15402                 # make sure no new records are added when no users are present
15403                 local last_rec1=$(changelog_users $SINGLEMDS |
15404                                   awk '/^current.index:/ { print $NF }')
15405                 touch $DIR/$tdir/chloe
15406                 local last_rec2=$(changelog_users $SINGLEMDS |
15407                                   awk '/^current.index:/ { print $NF }')
15408                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15409                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15410         else
15411                 # any changelog users must be leftovers from a previous test
15412                 changelog_users $SINGLEMDS
15413                 echo "other changelog users; can't verify off"
15414         fi
15415 }
15416 run_test 160a "changelog sanity"
15417
15418 test_160b() { # LU-3587
15419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15420         remote_mds_nodsh && skip "remote MDS with nodsh"
15421         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15422                 skip "Need MDS version at least 2.2.0"
15423
15424         changelog_register || error "changelog_register failed"
15425         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15426         changelog_users $SINGLEMDS | grep -q $cl_user ||
15427                 error "User '$cl_user' not found in changelog_users"
15428
15429         local longname1=$(str_repeat a 255)
15430         local longname2=$(str_repeat b 255)
15431
15432         cd $DIR
15433         echo "creating very long named file"
15434         touch $longname1 || error "create of '$longname1' failed"
15435         echo "renaming very long named file"
15436         mv $longname1 $longname2
15437
15438         changelog_dump | grep RENME | tail -n 5
15439         rm -f $longname2
15440 }
15441 run_test 160b "Verify that very long rename doesn't crash in changelog"
15442
15443 test_160c() {
15444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15445         remote_mds_nodsh && skip "remote MDS with nodsh"
15446
15447         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15448                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15449                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15450                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15451
15452         local rc=0
15453
15454         # Registration step
15455         changelog_register || error "changelog_register failed"
15456
15457         rm -rf $DIR/$tdir
15458         mkdir -p $DIR/$tdir
15459         $MCREATE $DIR/$tdir/foo_160c
15460         changelog_chmask "-TRUNC"
15461         $TRUNCATE $DIR/$tdir/foo_160c 200
15462         changelog_chmask "+TRUNC"
15463         $TRUNCATE $DIR/$tdir/foo_160c 199
15464         changelog_dump | tail -n 5
15465         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15466         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15467 }
15468 run_test 160c "verify that changelog log catch the truncate event"
15469
15470 test_160d() {
15471         remote_mds_nodsh && skip "remote MDS with nodsh"
15472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15474         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15475                 skip "Need MDS version at least 2.7.60"
15476
15477         # Registration step
15478         changelog_register || error "changelog_register failed"
15479
15480         mkdir -p $DIR/$tdir/migrate_dir
15481         changelog_clear 0 || error "changelog_clear failed"
15482
15483         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15484         changelog_dump | tail -n 5
15485         local migrates=$(changelog_dump | grep -c "MIGRT")
15486         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15487 }
15488 run_test 160d "verify that changelog log catch the migrate event"
15489
15490 test_160e() {
15491         remote_mds_nodsh && skip "remote MDS with nodsh"
15492
15493         # Create a user
15494         changelog_register || error "changelog_register failed"
15495
15496         # Delete a future user (expect fail)
15497         local MDT0=$(facet_svc $SINGLEMDS)
15498         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15499         local rc=$?
15500
15501         if [ $rc -eq 0 ]; then
15502                 error "Deleted non-existant user cl77"
15503         elif [ $rc -ne 2 ]; then
15504                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15505         fi
15506
15507         # Clear to a bad index (1 billion should be safe)
15508         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15509         rc=$?
15510
15511         if [ $rc -eq 0 ]; then
15512                 error "Successfully cleared to invalid CL index"
15513         elif [ $rc -ne 22 ]; then
15514                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15515         fi
15516 }
15517 run_test 160e "changelog negative testing (should return errors)"
15518
15519 test_160f() {
15520         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15521         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15522                 skip "Need MDS version at least 2.10.56"
15523
15524         local mdts=$(comma_list $(mdts_nodes))
15525
15526         # Create a user
15527         changelog_register || error "first changelog_register failed"
15528         changelog_register || error "second changelog_register failed"
15529         local cl_users
15530         declare -A cl_user1
15531         declare -A cl_user2
15532         local user_rec1
15533         local user_rec2
15534         local i
15535
15536         # generate some changelog records to accumulate on each MDT
15537         # use all_char because created files should be evenly distributed
15538         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15539                 error "test_mkdir $tdir failed"
15540         log "$(date +%s): creating first files"
15541         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15542                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15543                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15544         done
15545
15546         # check changelogs have been generated
15547         local start=$SECONDS
15548         local idle_time=$((MDSCOUNT * 5 + 5))
15549         local nbcl=$(changelog_dump | wc -l)
15550         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15551
15552         for param in "changelog_max_idle_time=$idle_time" \
15553                      "changelog_gc=1" \
15554                      "changelog_min_gc_interval=2" \
15555                      "changelog_min_free_cat_entries=3"; do
15556                 local MDT0=$(facet_svc $SINGLEMDS)
15557                 local var="${param%=*}"
15558                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15559
15560                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15561                 do_nodes $mdts $LCTL set_param mdd.*.$param
15562         done
15563
15564         # force cl_user2 to be idle (1st part), but also cancel the
15565         # cl_user1 records so that it is not evicted later in the test.
15566         local sleep1=$((idle_time / 2))
15567         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15568         sleep $sleep1
15569
15570         # simulate changelog catalog almost full
15571         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15572         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15573
15574         for i in $(seq $MDSCOUNT); do
15575                 cl_users=(${CL_USERS[mds$i]})
15576                 cl_user1[mds$i]="${cl_users[0]}"
15577                 cl_user2[mds$i]="${cl_users[1]}"
15578
15579                 [ -n "${cl_user1[mds$i]}" ] ||
15580                         error "mds$i: no user registered"
15581                 [ -n "${cl_user2[mds$i]}" ] ||
15582                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15583
15584                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15585                 [ -n "$user_rec1" ] ||
15586                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15587                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15588                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15589                 [ -n "$user_rec2" ] ||
15590                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15591                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15592                      "$user_rec1 + 2 == $user_rec2"
15593                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15594                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15595                               "$user_rec1 + 2, but is $user_rec2"
15596                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15597                 [ -n "$user_rec2" ] ||
15598                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15599                 [ $user_rec1 == $user_rec2 ] ||
15600                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15601                               "$user_rec1, but is $user_rec2"
15602         done
15603
15604         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15605         local sleep2=$((idle_time - (SECONDS - start) + 1))
15606         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15607         sleep $sleep2
15608
15609         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15610         # cl_user1 should be OK because it recently processed records.
15611         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15612         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15613                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15614                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15615         done
15616
15617         # ensure gc thread is done
15618         for i in $(mdts_nodes); do
15619                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15620                         error "$i: GC-thread not done"
15621         done
15622
15623         local first_rec
15624         for (( i = 1; i <= MDSCOUNT; i++ )); do
15625                 # check cl_user1 still registered
15626                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15627                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15628                 # check cl_user2 unregistered
15629                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15630                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15631
15632                 # check changelogs are present and starting at $user_rec1 + 1
15633                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15634                 [ -n "$user_rec1" ] ||
15635                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15636                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15637                             awk '{ print $1; exit; }')
15638
15639                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15640                 [ $((user_rec1 + 1)) == $first_rec ] ||
15641                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15642         done
15643 }
15644 run_test 160f "changelog garbage collect (timestamped users)"
15645
15646 test_160g() {
15647         remote_mds_nodsh && skip "remote MDS with nodsh"
15648         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15649                 skip "Need MDS version at least 2.10.56"
15650
15651         local mdts=$(comma_list $(mdts_nodes))
15652
15653         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15654         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15655
15656         # Create a user
15657         changelog_register || error "first changelog_register failed"
15658         changelog_register || error "second changelog_register failed"
15659         local cl_users
15660         declare -A cl_user1
15661         declare -A cl_user2
15662         local user_rec1
15663         local user_rec2
15664         local i
15665
15666         # generate some changelog records to accumulate on each MDT
15667         # use all_char because created files should be evenly distributed
15668         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15669                 error "test_mkdir $tdir failed"
15670         for ((i = 0; i < MDSCOUNT; i++)); do
15671                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15672                         error "create $DIR/$tdir/d$i.1 failed"
15673         done
15674
15675         # check changelogs have been generated
15676         local nbcl=$(changelog_dump | wc -l)
15677         (( $nbcl > 0 )) || error "no changelogs found"
15678
15679         # reduce the max_idle_indexes value to make sure we exceed it
15680         for param in "changelog_max_idle_indexes=1" \
15681                      "changelog_gc=1" \
15682                      "changelog_min_gc_interval=2" \
15683                      "changelog_min_free_cat_entries=3"; do
15684                 local MDT0=$(facet_svc $SINGLEMDS)
15685                 local var="${param%=*}"
15686                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15687
15688                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15689                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15690                         error "unable to set mdd.*.$param"
15691         done
15692
15693         # simulate changelog catalog almost full
15694         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15695         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15696
15697         local start=$SECONDS
15698         for i in $(seq $MDSCOUNT); do
15699                 cl_users=(${CL_USERS[mds$i]})
15700                 cl_user1[mds$i]="${cl_users[0]}"
15701                 cl_user2[mds$i]="${cl_users[1]}"
15702
15703                 [ -n "${cl_user1[mds$i]}" ] ||
15704                         error "mds$i: no user registered"
15705                 [ -n "${cl_user2[mds$i]}" ] ||
15706                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15707
15708                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15709                 [ -n "$user_rec1" ] ||
15710                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15711                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15712                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15713                 [ -n "$user_rec2" ] ||
15714                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15715                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15716                      "$user_rec1 + 2 == $user_rec2"
15717                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15718                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15719                               "$user_rec1 + 2, but is $user_rec2"
15720                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15721                 [ -n "$user_rec2" ] ||
15722                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15723                 [ $user_rec1 == $user_rec2 ] ||
15724                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15725                               "$user_rec1, but is $user_rec2"
15726         done
15727
15728         # ensure we are past the previous changelog_min_gc_interval set above
15729         local sleep2=$((start + 2 - SECONDS))
15730         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15731
15732         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15733         # cl_user1 should be OK because it recently processed records.
15734         for ((i = 0; i < MDSCOUNT; i++)); do
15735                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15736                         error "create $DIR/$tdir/d$i.3 failed"
15737         done
15738
15739         # ensure gc thread is done
15740         for i in $(mdts_nodes); do
15741                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15742                         error "$i: GC-thread not done"
15743         done
15744
15745         local first_rec
15746         for (( i = 1; i <= MDSCOUNT; i++ )); do
15747                 # check cl_user1 still registered
15748                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15749                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15750                 # check cl_user2 unregistered
15751                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15752                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15753
15754                 # check changelogs are present and starting at $user_rec1 + 1
15755                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15756                 [ -n "$user_rec1" ] ||
15757                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15758                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15759                             awk '{ print $1; exit; }')
15760
15761                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15762                 [ $((user_rec1 + 1)) == $first_rec ] ||
15763                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15764         done
15765 }
15766 run_test 160g "changelog garbage collect (old users)"
15767
15768 test_160h() {
15769         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15770         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15771                 skip "Need MDS version at least 2.10.56"
15772
15773         local mdts=$(comma_list $(mdts_nodes))
15774
15775         # Create a user
15776         changelog_register || error "first changelog_register failed"
15777         changelog_register || error "second changelog_register failed"
15778         local cl_users
15779         declare -A cl_user1
15780         declare -A cl_user2
15781         local user_rec1
15782         local user_rec2
15783         local i
15784
15785         # generate some changelog records to accumulate on each MDT
15786         # use all_char because created files should be evenly distributed
15787         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15788                 error "test_mkdir $tdir failed"
15789         for ((i = 0; i < MDSCOUNT; i++)); do
15790                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15791                         error "create $DIR/$tdir/d$i.1 failed"
15792         done
15793
15794         # check changelogs have been generated
15795         local nbcl=$(changelog_dump | wc -l)
15796         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15797
15798         for param in "changelog_max_idle_time=10" \
15799                      "changelog_gc=1" \
15800                      "changelog_min_gc_interval=2"; do
15801                 local MDT0=$(facet_svc $SINGLEMDS)
15802                 local var="${param%=*}"
15803                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15804
15805                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15806                 do_nodes $mdts $LCTL set_param mdd.*.$param
15807         done
15808
15809         # force cl_user2 to be idle (1st part)
15810         sleep 9
15811
15812         for i in $(seq $MDSCOUNT); do
15813                 cl_users=(${CL_USERS[mds$i]})
15814                 cl_user1[mds$i]="${cl_users[0]}"
15815                 cl_user2[mds$i]="${cl_users[1]}"
15816
15817                 [ -n "${cl_user1[mds$i]}" ] ||
15818                         error "mds$i: no user registered"
15819                 [ -n "${cl_user2[mds$i]}" ] ||
15820                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15821
15822                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15823                 [ -n "$user_rec1" ] ||
15824                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15825                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15826                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15827                 [ -n "$user_rec2" ] ||
15828                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15829                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15830                      "$user_rec1 + 2 == $user_rec2"
15831                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15832                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15833                               "$user_rec1 + 2, but is $user_rec2"
15834                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15835                 [ -n "$user_rec2" ] ||
15836                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15837                 [ $user_rec1 == $user_rec2 ] ||
15838                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15839                               "$user_rec1, but is $user_rec2"
15840         done
15841
15842         # force cl_user2 to be idle (2nd part) and to reach
15843         # changelog_max_idle_time
15844         sleep 2
15845
15846         # force each GC-thread start and block then
15847         # one per MDT/MDD, set fail_val accordingly
15848         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15849         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15850
15851         # generate more changelogs to trigger fail_loc
15852         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15853                 error "create $DIR/$tdir/${tfile}bis failed"
15854
15855         # stop MDT to stop GC-thread, should be done in back-ground as it will
15856         # block waiting for the thread to be released and exit
15857         declare -A stop_pids
15858         for i in $(seq $MDSCOUNT); do
15859                 stop mds$i &
15860                 stop_pids[mds$i]=$!
15861         done
15862
15863         for i in $(mdts_nodes); do
15864                 local facet
15865                 local nb=0
15866                 local facets=$(facets_up_on_host $i)
15867
15868                 for facet in ${facets//,/ }; do
15869                         if [[ $facet == mds* ]]; then
15870                                 nb=$((nb + 1))
15871                         fi
15872                 done
15873                 # ensure each MDS's gc threads are still present and all in "R"
15874                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15875                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15876                         error "$i: expected $nb GC-thread"
15877                 wait_update $i \
15878                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15879                         "R" 20 ||
15880                         error "$i: GC-thread not found in R-state"
15881                 # check umounts of each MDT on MDS have reached kthread_stop()
15882                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15883                         error "$i: expected $nb umount"
15884                 wait_update $i \
15885                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15886                         error "$i: umount not found in D-state"
15887         done
15888
15889         # release all GC-threads
15890         do_nodes $mdts $LCTL set_param fail_loc=0
15891
15892         # wait for MDT stop to complete
15893         for i in $(seq $MDSCOUNT); do
15894                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15895         done
15896
15897         # XXX
15898         # may try to check if any orphan changelog records are present
15899         # via ldiskfs/zfs and llog_reader...
15900
15901         # re-start/mount MDTs
15902         for i in $(seq $MDSCOUNT); do
15903                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15904                         error "Fail to start mds$i"
15905         done
15906
15907         local first_rec
15908         for i in $(seq $MDSCOUNT); do
15909                 # check cl_user1 still registered
15910                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15911                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15912                 # check cl_user2 unregistered
15913                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15914                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15915
15916                 # check changelogs are present and starting at $user_rec1 + 1
15917                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15918                 [ -n "$user_rec1" ] ||
15919                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15920                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15921                             awk '{ print $1; exit; }')
15922
15923                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15924                 [ $((user_rec1 + 1)) == $first_rec ] ||
15925                         error "mds$i: first index should be $user_rec1 + 1, " \
15926                               "but is $first_rec"
15927         done
15928 }
15929 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15930               "during mount"
15931
15932 test_160i() {
15933
15934         local mdts=$(comma_list $(mdts_nodes))
15935
15936         changelog_register || error "first changelog_register failed"
15937
15938         # generate some changelog records to accumulate on each MDT
15939         # use all_char because created files should be evenly distributed
15940         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15941                 error "test_mkdir $tdir failed"
15942         for ((i = 0; i < MDSCOUNT; i++)); do
15943                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15944                         error "create $DIR/$tdir/d$i.1 failed"
15945         done
15946
15947         # check changelogs have been generated
15948         local nbcl=$(changelog_dump | wc -l)
15949         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15950
15951         # simulate race between register and unregister
15952         # XXX as fail_loc is set per-MDS, with DNE configs the race
15953         # simulation will only occur for one MDT per MDS and for the
15954         # others the normal race scenario will take place
15955         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15956         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15957         do_nodes $mdts $LCTL set_param fail_val=1
15958
15959         # unregister 1st user
15960         changelog_deregister &
15961         local pid1=$!
15962         # wait some time for deregister work to reach race rdv
15963         sleep 2
15964         # register 2nd user
15965         changelog_register || error "2nd user register failed"
15966
15967         wait $pid1 || error "1st user deregister failed"
15968
15969         local i
15970         local last_rec
15971         declare -A LAST_REC
15972         for i in $(seq $MDSCOUNT); do
15973                 if changelog_users mds$i | grep "^cl"; then
15974                         # make sure new records are added with one user present
15975                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15976                                           awk '/^current.index:/ { print $NF }')
15977                 else
15978                         error "mds$i has no user registered"
15979                 fi
15980         done
15981
15982         # generate more changelog records to accumulate on each MDT
15983         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15984                 error "create $DIR/$tdir/${tfile}bis failed"
15985
15986         for i in $(seq $MDSCOUNT); do
15987                 last_rec=$(changelog_users $SINGLEMDS |
15988                            awk '/^current.index:/ { print $NF }')
15989                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15990                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15991                         error "changelogs are off on mds$i"
15992         done
15993 }
15994 run_test 160i "changelog user register/unregister race"
15995
15996 test_160j() {
15997         remote_mds_nodsh && skip "remote MDS with nodsh"
15998         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15999                 skip "Need MDS version at least 2.12.56"
16000
16001         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16002         stack_trap "umount $MOUNT2" EXIT
16003
16004         changelog_register || error "first changelog_register failed"
16005         stack_trap "changelog_deregister" EXIT
16006
16007         # generate some changelog
16008         # use all_char because created files should be evenly distributed
16009         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16010                 error "mkdir $tdir failed"
16011         for ((i = 0; i < MDSCOUNT; i++)); do
16012                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16013                         error "create $DIR/$tdir/d$i.1 failed"
16014         done
16015
16016         # open the changelog device
16017         exec 3>/dev/changelog-$FSNAME-MDT0000
16018         stack_trap "exec 3>&-" EXIT
16019         exec 4</dev/changelog-$FSNAME-MDT0000
16020         stack_trap "exec 4<&-" EXIT
16021
16022         # umount the first lustre mount
16023         umount $MOUNT
16024         stack_trap "mount_client $MOUNT" EXIT
16025
16026         # read changelog, which may or may not fail, but should not crash
16027         cat <&4 >/dev/null
16028
16029         # clear changelog
16030         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16031         changelog_users $SINGLEMDS | grep -q $cl_user ||
16032                 error "User $cl_user not found in changelog_users"
16033
16034         printf 'clear:'$cl_user':0' >&3
16035 }
16036 run_test 160j "client can be umounted while its chanangelog is being used"
16037
16038 test_160k() {
16039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16040         remote_mds_nodsh && skip "remote MDS with nodsh"
16041
16042         mkdir -p $DIR/$tdir/1/1
16043
16044         changelog_register || error "changelog_register failed"
16045         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16046
16047         changelog_users $SINGLEMDS | grep -q $cl_user ||
16048                 error "User '$cl_user' not found in changelog_users"
16049 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16050         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16051         rmdir $DIR/$tdir/1/1 & sleep 1
16052         mkdir $DIR/$tdir/2
16053         touch $DIR/$tdir/2/2
16054         rm -rf $DIR/$tdir/2
16055
16056         wait
16057         sleep 4
16058
16059         changelog_dump | grep rmdir || error "rmdir not recorded"
16060 }
16061 run_test 160k "Verify that changelog records are not lost"
16062
16063 # Verifies that a file passed as a parameter has recently had an operation
16064 # performed on it that has generated an MTIME changelog which contains the
16065 # correct parent FID. As files might reside on a different MDT from the
16066 # parent directory in DNE configurations, the FIDs are translated to paths
16067 # before being compared, which should be identical
16068 compare_mtime_changelog() {
16069         local file="${1}"
16070         local mdtidx
16071         local mtime
16072         local cl_fid
16073         local pdir
16074         local dir
16075
16076         mdtidx=$($LFS getstripe --mdt-index $file)
16077         mdtidx=$(printf "%04x" $mdtidx)
16078
16079         # Obtain the parent FID from the MTIME changelog
16080         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16081         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16082
16083         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16084         [ -z "$cl_fid" ] && error "parent FID not present"
16085
16086         # Verify that the path for the parent FID is the same as the path for
16087         # the test directory
16088         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16089
16090         dir=$(dirname $1)
16091
16092         [[ "${pdir%/}" == "$dir" ]] ||
16093                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16094 }
16095
16096 test_160l() {
16097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16098
16099         remote_mds_nodsh && skip "remote MDS with nodsh"
16100         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16101                 skip "Need MDS version at least 2.13.55"
16102
16103         local cl_user
16104
16105         changelog_register || error "changelog_register failed"
16106         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16107
16108         changelog_users $SINGLEMDS | grep -q $cl_user ||
16109                 error "User '$cl_user' not found in changelog_users"
16110
16111         # Clear some types so that MTIME changelogs are generated
16112         changelog_chmask "-CREAT"
16113         changelog_chmask "-CLOSE"
16114
16115         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16116
16117         # Test CL_MTIME during setattr
16118         touch $DIR/$tdir/$tfile
16119         compare_mtime_changelog $DIR/$tdir/$tfile
16120
16121         # Test CL_MTIME during close
16122         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16123         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16124 }
16125 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16126
16127 test_160m() {
16128         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16129         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16130                 skip "Need MDS version at least 2.14.51"
16131         local cl_users
16132         local cl_user1
16133         local cl_user2
16134         local pid1
16135
16136         # Create a user
16137         changelog_register || error "first changelog_register failed"
16138         changelog_register || error "second changelog_register failed"
16139
16140         cl_users=(${CL_USERS[mds1]})
16141         cl_user1="${cl_users[0]}"
16142         cl_user2="${cl_users[1]}"
16143         # generate some changelog records to accumulate on MDT0
16144         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16145         createmany -m $DIR/$tdir/$tfile 50 ||
16146                 error "create $DIR/$tdir/$tfile failed"
16147         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16148         rm -f $DIR/$tdir
16149
16150         # check changelogs have been generated
16151         local nbcl=$(changelog_dump | wc -l)
16152         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16153
16154 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16155         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16156
16157         __changelog_clear mds1 $cl_user1 +10
16158         __changelog_clear mds1 $cl_user2 0 &
16159         pid1=$!
16160         sleep 2
16161         __changelog_clear mds1 $cl_user1 0 ||
16162                 error "fail to cancel record for $cl_user1"
16163         wait $pid1
16164         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16165 }
16166 run_test 160m "Changelog clear race"
16167
16168 test_160n() {
16169         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16170         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16171                 skip "Need MDS version at least 2.14.51"
16172         local cl_users
16173         local cl_user1
16174         local cl_user2
16175         local pid1
16176         local first_rec
16177         local last_rec=0
16178
16179         # Create a user
16180         changelog_register || error "first changelog_register failed"
16181
16182         cl_users=(${CL_USERS[mds1]})
16183         cl_user1="${cl_users[0]}"
16184
16185         # generate some changelog records to accumulate on MDT0
16186         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16187         first_rec=$(changelog_users $SINGLEMDS |
16188                         awk '/^current.index:/ { print $NF }')
16189         while (( last_rec < (( first_rec + 65000)) )); do
16190                 createmany -m $DIR/$tdir/$tfile 10000 ||
16191                         error "create $DIR/$tdir/$tfile failed"
16192
16193                 for i in $(seq 0 10000); do
16194                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16195                                 > /dev/null
16196                 done
16197
16198                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16199                         error "unlinkmany failed unlink"
16200                 last_rec=$(changelog_users $SINGLEMDS |
16201                         awk '/^current.index:/ { print $NF }')
16202                 echo last record $last_rec
16203                 (( last_rec == 0 )) && error "no changelog found"
16204         done
16205
16206 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16207         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16208
16209         __changelog_clear mds1 $cl_user1 0 &
16210         pid1=$!
16211         sleep 2
16212         __changelog_clear mds1 $cl_user1 0 ||
16213                 error "fail to cancel record for $cl_user1"
16214         wait $pid1
16215         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16216 }
16217 run_test 160n "Changelog destroy race"
16218
16219 test_160o() {
16220         local mdt="$(facet_svc $SINGLEMDS)"
16221
16222         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16223         remote_mds_nodsh && skip "remote MDS with nodsh"
16224         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16225                 skip "Need MDS version at least 2.14.52"
16226
16227         changelog_register --user test_160o -m unlnk+close+open ||
16228                 error "changelog_register failed"
16229         # drop server mask so it doesn't interfere
16230         do_facet $SINGLEMDS $LCTL --device $mdt \
16231                                 changelog_register -u "Tt3_-#" &&
16232                 error "bad symbols in name should fail"
16233
16234         do_facet $SINGLEMDS $LCTL --device $mdt \
16235                                 changelog_register -u test_160o &&
16236                 error "the same name registration should fail"
16237
16238         do_facet $SINGLEMDS $LCTL --device $mdt \
16239                         changelog_register -u test_160toolongname &&
16240                 error "too long name registration should fail"
16241
16242         changelog_chmask "MARK+HSM"
16243         lctl get_param mdd.*.changelog*mask
16244         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16245         changelog_users $SINGLEMDS | grep -q $cl_user ||
16246                 error "User $cl_user not found in changelog_users"
16247         #verify username
16248         echo $cl_user | grep -q test_160o ||
16249                 error "User $cl_user has no specific name 'test160o'"
16250
16251         # change something
16252         changelog_clear 0 || error "changelog_clear failed"
16253         # generate some changelog records to accumulate on MDT0
16254         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16255         touch $DIR/$tdir/$tfile                 # open 1
16256
16257         OPENS=$(changelog_dump | grep -c "OPEN")
16258         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16259
16260         # must be no MKDIR it wasn't set as user mask
16261         MKDIR=$(changelog_dump | grep -c "MKDIR")
16262         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16263
16264         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16265                                 mdd.$mdt.changelog_current_mask -n)
16266         # register maskless user
16267         changelog_register || error "changelog_register failed"
16268         # effective mask should be not changed because it is not minimal
16269         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16270                                 mdd.$mdt.changelog_current_mask -n)
16271         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16272         # set server mask to minimal value
16273         changelog_chmask "MARK"
16274         # check effective mask again, should be treated as DEFMASK now
16275         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16276                                 mdd.$mdt.changelog_current_mask -n)
16277         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16278
16279         do_facet $SINGLEMDS $LCTL --device $mdt \
16280                                 changelog_deregister -u test_160o ||
16281                 error "cannot deregister by name"
16282 }
16283 run_test 160o "changelog user name and mask"
16284
16285 test_160p() {
16286         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16287         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16288                 skip "Need MDS version at least 2.14.51"
16289         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16290         local cl_users
16291         local cl_user1
16292         local entry_count
16293
16294         # Create a user
16295         changelog_register || error "first changelog_register failed"
16296
16297         cl_users=(${CL_USERS[mds1]})
16298         cl_user1="${cl_users[0]}"
16299
16300         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16301         createmany -m $DIR/$tdir/$tfile 50 ||
16302                 error "create $DIR/$tdir/$tfile failed"
16303         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16304         rm -rf $DIR/$tdir
16305
16306         # check changelogs have been generated
16307         entry_count=$(changelog_dump | wc -l)
16308         ((entry_count != 0)) || error "no changelog entries found"
16309
16310         # remove changelog_users and check that orphan entries are removed
16311         stop mds1
16312         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16313         start mds1 || error "cannot start mdt"
16314         entry_count=$(changelog_dump | wc -l)
16315         ((entry_count == 0)) ||
16316                 error "found $entry_count changelog entries, expected none"
16317 }
16318 run_test 160p "Changelog orphan cleanup with no users"
16319
16320 test_161a() {
16321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16322
16323         test_mkdir -c1 $DIR/$tdir
16324         cp /etc/hosts $DIR/$tdir/$tfile
16325         test_mkdir -c1 $DIR/$tdir/foo1
16326         test_mkdir -c1 $DIR/$tdir/foo2
16327         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16328         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16329         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16330         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16331         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16332         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16333                 $LFS fid2path $DIR $FID
16334                 error "bad link ea"
16335         fi
16336         # middle
16337         rm $DIR/$tdir/foo2/zachary
16338         # last
16339         rm $DIR/$tdir/foo2/thor
16340         # first
16341         rm $DIR/$tdir/$tfile
16342         # rename
16343         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16344         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16345                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16346         rm $DIR/$tdir/foo2/maggie
16347
16348         # overflow the EA
16349         local longname=$tfile.avg_len_is_thirty_two_
16350         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16351                 error_noexit 'failed to unlink many hardlinks'" EXIT
16352         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16353                 error "failed to hardlink many files"
16354         links=$($LFS fid2path $DIR $FID | wc -l)
16355         echo -n "${links}/1000 links in link EA"
16356         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16357 }
16358 run_test 161a "link ea sanity"
16359
16360 test_161b() {
16361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16362         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16363
16364         local MDTIDX=1
16365         local remote_dir=$DIR/$tdir/remote_dir
16366
16367         mkdir -p $DIR/$tdir
16368         $LFS mkdir -i $MDTIDX $remote_dir ||
16369                 error "create remote directory failed"
16370
16371         cp /etc/hosts $remote_dir/$tfile
16372         mkdir -p $remote_dir/foo1
16373         mkdir -p $remote_dir/foo2
16374         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16375         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16376         ln $remote_dir/$tfile $remote_dir/foo1/luna
16377         ln $remote_dir/$tfile $remote_dir/foo2/thor
16378
16379         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16380                      tr -d ']')
16381         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16382                 $LFS fid2path $DIR $FID
16383                 error "bad link ea"
16384         fi
16385         # middle
16386         rm $remote_dir/foo2/zachary
16387         # last
16388         rm $remote_dir/foo2/thor
16389         # first
16390         rm $remote_dir/$tfile
16391         # rename
16392         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16393         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16394         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16395                 $LFS fid2path $DIR $FID
16396                 error "bad link rename"
16397         fi
16398         rm $remote_dir/foo2/maggie
16399
16400         # overflow the EA
16401         local longname=filename_avg_len_is_thirty_two_
16402         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16403                 error "failed to hardlink many files"
16404         links=$($LFS fid2path $DIR $FID | wc -l)
16405         echo -n "${links}/1000 links in link EA"
16406         [[ ${links} -gt 60 ]] ||
16407                 error "expected at least 60 links in link EA"
16408         unlinkmany $remote_dir/foo2/$longname 1000 ||
16409         error "failed to unlink many hardlinks"
16410 }
16411 run_test 161b "link ea sanity under remote directory"
16412
16413 test_161c() {
16414         remote_mds_nodsh && skip "remote MDS with nodsh"
16415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16416         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16417                 skip "Need MDS version at least 2.1.5"
16418
16419         # define CLF_RENAME_LAST 0x0001
16420         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16421         changelog_register || error "changelog_register failed"
16422
16423         rm -rf $DIR/$tdir
16424         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16425         touch $DIR/$tdir/foo_161c
16426         touch $DIR/$tdir/bar_161c
16427         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16428         changelog_dump | grep RENME | tail -n 5
16429         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16430         changelog_clear 0 || error "changelog_clear failed"
16431         if [ x$flags != "x0x1" ]; then
16432                 error "flag $flags is not 0x1"
16433         fi
16434
16435         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16436         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16437         touch $DIR/$tdir/foo_161c
16438         touch $DIR/$tdir/bar_161c
16439         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16440         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16441         changelog_dump | grep RENME | tail -n 5
16442         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16443         changelog_clear 0 || error "changelog_clear failed"
16444         if [ x$flags != "x0x0" ]; then
16445                 error "flag $flags is not 0x0"
16446         fi
16447         echo "rename overwrite a target having nlink > 1," \
16448                 "changelog record has flags of $flags"
16449
16450         # rename doesn't overwrite a target (changelog flag 0x0)
16451         touch $DIR/$tdir/foo_161c
16452         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16453         changelog_dump | grep RENME | tail -n 5
16454         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16455         changelog_clear 0 || error "changelog_clear failed"
16456         if [ x$flags != "x0x0" ]; then
16457                 error "flag $flags is not 0x0"
16458         fi
16459         echo "rename doesn't overwrite a target," \
16460                 "changelog record has flags of $flags"
16461
16462         # define CLF_UNLINK_LAST 0x0001
16463         # unlink a file having nlink = 1 (changelog flag 0x1)
16464         rm -f $DIR/$tdir/foo2_161c
16465         changelog_dump | grep UNLNK | tail -n 5
16466         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16467         changelog_clear 0 || error "changelog_clear failed"
16468         if [ x$flags != "x0x1" ]; then
16469                 error "flag $flags is not 0x1"
16470         fi
16471         echo "unlink a file having nlink = 1," \
16472                 "changelog record has flags of $flags"
16473
16474         # unlink a file having nlink > 1 (changelog flag 0x0)
16475         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16476         rm -f $DIR/$tdir/foobar_161c
16477         changelog_dump | grep UNLNK | tail -n 5
16478         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16479         changelog_clear 0 || error "changelog_clear failed"
16480         if [ x$flags != "x0x0" ]; then
16481                 error "flag $flags is not 0x0"
16482         fi
16483         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16484 }
16485 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16486
16487 test_161d() {
16488         remote_mds_nodsh && skip "remote MDS with nodsh"
16489         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16490
16491         local pid
16492         local fid
16493
16494         changelog_register || error "changelog_register failed"
16495
16496         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16497         # interfer with $MOUNT/.lustre/fid/ access
16498         mkdir $DIR/$tdir
16499         [[ $? -eq 0 ]] || error "mkdir failed"
16500
16501         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16502         $LCTL set_param fail_loc=0x8000140c
16503         # 5s pause
16504         $LCTL set_param fail_val=5
16505
16506         # create file
16507         echo foofoo > $DIR/$tdir/$tfile &
16508         pid=$!
16509
16510         # wait for create to be delayed
16511         sleep 2
16512
16513         ps -p $pid
16514         [[ $? -eq 0 ]] || error "create should be blocked"
16515
16516         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16517         stack_trap "rm -f $tempfile"
16518         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16519         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16520         # some delay may occur during ChangeLog publishing and file read just
16521         # above, that could allow file write to happen finally
16522         [[ -s $tempfile ]] && echo "file should be empty"
16523
16524         $LCTL set_param fail_loc=0
16525
16526         wait $pid
16527         [[ $? -eq 0 ]] || error "create failed"
16528 }
16529 run_test 161d "create with concurrent .lustre/fid access"
16530
16531 check_path() {
16532         local expected="$1"
16533         shift
16534         local fid="$2"
16535
16536         local path
16537         path=$($LFS fid2path "$@")
16538         local rc=$?
16539
16540         if [ $rc -ne 0 ]; then
16541                 error "path looked up of '$expected' failed: rc=$rc"
16542         elif [ "$path" != "$expected" ]; then
16543                 error "path looked up '$path' instead of '$expected'"
16544         else
16545                 echo "FID '$fid' resolves to path '$path' as expected"
16546         fi
16547 }
16548
16549 test_162a() { # was test_162
16550         test_mkdir -p -c1 $DIR/$tdir/d2
16551         touch $DIR/$tdir/d2/$tfile
16552         touch $DIR/$tdir/d2/x1
16553         touch $DIR/$tdir/d2/x2
16554         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16555         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16556         # regular file
16557         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16558         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16559
16560         # softlink
16561         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16562         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16563         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16564
16565         # softlink to wrong file
16566         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16567         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16568         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16569
16570         # hardlink
16571         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16572         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16573         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16574         # fid2path dir/fsname should both work
16575         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16576         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16577
16578         # hardlink count: check that there are 2 links
16579         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16580         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16581
16582         # hardlink indexing: remove the first link
16583         rm $DIR/$tdir/d2/p/q/r/hlink
16584         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16585 }
16586 run_test 162a "path lookup sanity"
16587
16588 test_162b() {
16589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16590         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16591
16592         mkdir $DIR/$tdir
16593         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16594                                 error "create striped dir failed"
16595
16596         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16597                                         tail -n 1 | awk '{print $2}')
16598         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16599
16600         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16601         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16602
16603         # regular file
16604         for ((i=0;i<5;i++)); do
16605                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16606                         error "get fid for f$i failed"
16607                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16608
16609                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16610                         error "get fid for d$i failed"
16611                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16612         done
16613
16614         return 0
16615 }
16616 run_test 162b "striped directory path lookup sanity"
16617
16618 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16619 test_162c() {
16620         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16621                 skip "Need MDS version at least 2.7.51"
16622
16623         local lpath=$tdir.local
16624         local rpath=$tdir.remote
16625
16626         test_mkdir $DIR/$lpath
16627         test_mkdir $DIR/$rpath
16628
16629         for ((i = 0; i <= 101; i++)); do
16630                 lpath="$lpath/$i"
16631                 mkdir $DIR/$lpath
16632                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16633                         error "get fid for local directory $DIR/$lpath failed"
16634                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16635
16636                 rpath="$rpath/$i"
16637                 test_mkdir $DIR/$rpath
16638                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16639                         error "get fid for remote directory $DIR/$rpath failed"
16640                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16641         done
16642
16643         return 0
16644 }
16645 run_test 162c "fid2path works with paths 100 or more directories deep"
16646
16647 oalr_event_count() {
16648         local event="${1}"
16649         local trace="${2}"
16650
16651         awk -v name="${FSNAME}-OST0000" \
16652             -v event="${event}" \
16653             '$1 == "TRACE" && $2 == event && $3 == name' \
16654             "${trace}" |
16655         wc -l
16656 }
16657
16658 oalr_expect_event_count() {
16659         local event="${1}"
16660         local trace="${2}"
16661         local expect="${3}"
16662         local count
16663
16664         count=$(oalr_event_count "${event}" "${trace}")
16665         if ((count == expect)); then
16666                 return 0
16667         fi
16668
16669         error_noexit "${event} event count was '${count}', expected ${expect}"
16670         cat "${trace}" >&2
16671         exit 1
16672 }
16673
16674 cleanup_165() {
16675         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16676         stop ost1
16677         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16678 }
16679
16680 setup_165() {
16681         sync # Flush previous IOs so we can count log entries.
16682         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16683         stack_trap cleanup_165 EXIT
16684 }
16685
16686 test_165a() {
16687         local trace="/tmp/${tfile}.trace"
16688         local rc
16689         local count
16690
16691         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16692                 skip "OFD access log unsupported"
16693
16694         setup_165
16695         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16696         sleep 5
16697
16698         do_facet ost1 ofd_access_log_reader --list
16699         stop ost1
16700
16701         do_facet ost1 killall -TERM ofd_access_log_reader
16702         wait
16703         rc=$?
16704
16705         if ((rc != 0)); then
16706                 error "ofd_access_log_reader exited with rc = '${rc}'"
16707         fi
16708
16709         # Parse trace file for discovery events:
16710         oalr_expect_event_count alr_log_add "${trace}" 1
16711         oalr_expect_event_count alr_log_eof "${trace}" 1
16712         oalr_expect_event_count alr_log_free "${trace}" 1
16713 }
16714 run_test 165a "ofd access log discovery"
16715
16716 test_165b() {
16717         local trace="/tmp/${tfile}.trace"
16718         local file="${DIR}/${tfile}"
16719         local pfid1
16720         local pfid2
16721         local -a entry
16722         local rc
16723         local count
16724         local size
16725         local flags
16726
16727         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16728                 skip "OFD access log unsupported"
16729
16730         setup_165
16731         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16732         sleep 5
16733
16734         do_facet ost1 ofd_access_log_reader --list
16735
16736         lfs setstripe -c 1 -i 0 "${file}"
16737         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16738                 error "cannot create '${file}'"
16739
16740         sleep 5
16741         do_facet ost1 killall -TERM ofd_access_log_reader
16742         wait
16743         rc=$?
16744
16745         if ((rc != 0)); then
16746                 error "ofd_access_log_reader exited with rc = '${rc}'"
16747         fi
16748
16749         oalr_expect_event_count alr_log_entry "${trace}" 1
16750
16751         pfid1=$($LFS path2fid "${file}")
16752
16753         # 1     2             3   4    5     6   7    8    9     10
16754         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16755         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16756
16757         echo "entry = '${entry[*]}'" >&2
16758
16759         pfid2=${entry[4]}
16760         if [[ "${pfid1}" != "${pfid2}" ]]; then
16761                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16762         fi
16763
16764         size=${entry[8]}
16765         if ((size != 1048576)); then
16766                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16767         fi
16768
16769         flags=${entry[10]}
16770         if [[ "${flags}" != "w" ]]; then
16771                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16772         fi
16773
16774         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16775         sleep 5
16776
16777         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16778                 error "cannot read '${file}'"
16779         sleep 5
16780
16781         do_facet ost1 killall -TERM ofd_access_log_reader
16782         wait
16783         rc=$?
16784
16785         if ((rc != 0)); then
16786                 error "ofd_access_log_reader exited with rc = '${rc}'"
16787         fi
16788
16789         oalr_expect_event_count alr_log_entry "${trace}" 1
16790
16791         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16792         echo "entry = '${entry[*]}'" >&2
16793
16794         pfid2=${entry[4]}
16795         if [[ "${pfid1}" != "${pfid2}" ]]; then
16796                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16797         fi
16798
16799         size=${entry[8]}
16800         if ((size != 524288)); then
16801                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16802         fi
16803
16804         flags=${entry[10]}
16805         if [[ "${flags}" != "r" ]]; then
16806                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16807         fi
16808 }
16809 run_test 165b "ofd access log entries are produced and consumed"
16810
16811 test_165c() {
16812         local trace="/tmp/${tfile}.trace"
16813         local file="${DIR}/${tdir}/${tfile}"
16814
16815         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16816                 skip "OFD access log unsupported"
16817
16818         test_mkdir "${DIR}/${tdir}"
16819
16820         setup_165
16821         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16822         sleep 5
16823
16824         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16825
16826         # 4096 / 64 = 64. Create twice as many entries.
16827         for ((i = 0; i < 128; i++)); do
16828                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16829                         error "cannot create file"
16830         done
16831
16832         sync
16833
16834         do_facet ost1 killall -TERM ofd_access_log_reader
16835         wait
16836         rc=$?
16837         if ((rc != 0)); then
16838                 error "ofd_access_log_reader exited with rc = '${rc}'"
16839         fi
16840
16841         unlinkmany  "${file}-%d" 128
16842 }
16843 run_test 165c "full ofd access logs do not block IOs"
16844
16845 oal_get_read_count() {
16846         local stats="$1"
16847
16848         # STATS lustre-OST0001 alr_read_count 1
16849
16850         do_facet ost1 cat "${stats}" |
16851         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16852              END { print count; }'
16853 }
16854
16855 oal_expect_read_count() {
16856         local stats="$1"
16857         local count
16858         local expect="$2"
16859
16860         # Ask ofd_access_log_reader to write stats.
16861         do_facet ost1 killall -USR1 ofd_access_log_reader
16862
16863         # Allow some time for things to happen.
16864         sleep 1
16865
16866         count=$(oal_get_read_count "${stats}")
16867         if ((count == expect)); then
16868                 return 0
16869         fi
16870
16871         error_noexit "bad read count, got ${count}, expected ${expect}"
16872         do_facet ost1 cat "${stats}" >&2
16873         exit 1
16874 }
16875
16876 test_165d() {
16877         local stats="/tmp/${tfile}.stats"
16878         local file="${DIR}/${tdir}/${tfile}"
16879         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16880
16881         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16882                 skip "OFD access log unsupported"
16883
16884         test_mkdir "${DIR}/${tdir}"
16885
16886         setup_165
16887         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16888         sleep 5
16889
16890         lfs setstripe -c 1 -i 0 "${file}"
16891
16892         do_facet ost1 lctl set_param "${param}=rw"
16893         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16894                 error "cannot create '${file}'"
16895         oal_expect_read_count "${stats}" 1
16896
16897         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16898                 error "cannot read '${file}'"
16899         oal_expect_read_count "${stats}" 2
16900
16901         do_facet ost1 lctl set_param "${param}=r"
16902         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16903                 error "cannot create '${file}'"
16904         oal_expect_read_count "${stats}" 2
16905
16906         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16907                 error "cannot read '${file}'"
16908         oal_expect_read_count "${stats}" 3
16909
16910         do_facet ost1 lctl set_param "${param}=w"
16911         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16912                 error "cannot create '${file}'"
16913         oal_expect_read_count "${stats}" 4
16914
16915         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16916                 error "cannot read '${file}'"
16917         oal_expect_read_count "${stats}" 4
16918
16919         do_facet ost1 lctl set_param "${param}=0"
16920         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16921                 error "cannot create '${file}'"
16922         oal_expect_read_count "${stats}" 4
16923
16924         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16925                 error "cannot read '${file}'"
16926         oal_expect_read_count "${stats}" 4
16927
16928         do_facet ost1 killall -TERM ofd_access_log_reader
16929         wait
16930         rc=$?
16931         if ((rc != 0)); then
16932                 error "ofd_access_log_reader exited with rc = '${rc}'"
16933         fi
16934 }
16935 run_test 165d "ofd_access_log mask works"
16936
16937 test_165e() {
16938         local stats="/tmp/${tfile}.stats"
16939         local file0="${DIR}/${tdir}-0/${tfile}"
16940         local file1="${DIR}/${tdir}-1/${tfile}"
16941
16942         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16943                 skip "OFD access log unsupported"
16944
16945         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16946
16947         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16948         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16949
16950         lfs setstripe -c 1 -i 0 "${file0}"
16951         lfs setstripe -c 1 -i 0 "${file1}"
16952
16953         setup_165
16954         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16955         sleep 5
16956
16957         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16958                 error "cannot create '${file0}'"
16959         sync
16960         oal_expect_read_count "${stats}" 0
16961
16962         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16963                 error "cannot create '${file1}'"
16964         sync
16965         oal_expect_read_count "${stats}" 1
16966
16967         do_facet ost1 killall -TERM ofd_access_log_reader
16968         wait
16969         rc=$?
16970         if ((rc != 0)); then
16971                 error "ofd_access_log_reader exited with rc = '${rc}'"
16972         fi
16973 }
16974 run_test 165e "ofd_access_log MDT index filter works"
16975
16976 test_165f() {
16977         local trace="/tmp/${tfile}.trace"
16978         local rc
16979         local count
16980
16981         setup_165
16982         do_facet ost1 timeout 60 ofd_access_log_reader \
16983                 --exit-on-close --debug=- --trace=- > "${trace}" &
16984         sleep 5
16985         stop ost1
16986
16987         wait
16988         rc=$?
16989
16990         if ((rc != 0)); then
16991                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16992                 cat "${trace}"
16993                 exit 1
16994         fi
16995 }
16996 run_test 165f "ofd_access_log_reader --exit-on-close works"
16997
16998 test_169() {
16999         # do directio so as not to populate the page cache
17000         log "creating a 10 Mb file"
17001         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17002                 error "multiop failed while creating a file"
17003         log "starting reads"
17004         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17005         log "truncating the file"
17006         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17007                 error "multiop failed while truncating the file"
17008         log "killing dd"
17009         kill %+ || true # reads might have finished
17010         echo "wait until dd is finished"
17011         wait
17012         log "removing the temporary file"
17013         rm -rf $DIR/$tfile || error "tmp file removal failed"
17014 }
17015 run_test 169 "parallel read and truncate should not deadlock"
17016
17017 test_170() {
17018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17019
17020         $LCTL clear     # bug 18514
17021         $LCTL debug_daemon start $TMP/${tfile}_log_good
17022         touch $DIR/$tfile
17023         $LCTL debug_daemon stop
17024         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17025                 error "sed failed to read log_good"
17026
17027         $LCTL debug_daemon start $TMP/${tfile}_log_good
17028         rm -rf $DIR/$tfile
17029         $LCTL debug_daemon stop
17030
17031         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17032                error "lctl df log_bad failed"
17033
17034         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17035         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17036
17037         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17038         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17039
17040         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17041                 error "bad_line good_line1 good_line2 are empty"
17042
17043         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17044         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17045         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17046
17047         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17048         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17049         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17050
17051         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17052                 error "bad_line_new good_line_new are empty"
17053
17054         local expected_good=$((good_line1 + good_line2*2))
17055
17056         rm -f $TMP/${tfile}*
17057         # LU-231, short malformed line may not be counted into bad lines
17058         if [ $bad_line -ne $bad_line_new ] &&
17059                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17060                 error "expected $bad_line bad lines, but got $bad_line_new"
17061                 return 1
17062         fi
17063
17064         if [ $expected_good -ne $good_line_new ]; then
17065                 error "expected $expected_good good lines, but got $good_line_new"
17066                 return 2
17067         fi
17068         true
17069 }
17070 run_test 170 "test lctl df to handle corrupted log ====================="
17071
17072 test_171() { # bug20592
17073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17074
17075         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17076         $LCTL set_param fail_loc=0x50e
17077         $LCTL set_param fail_val=3000
17078         multiop_bg_pause $DIR/$tfile O_s || true
17079         local MULTIPID=$!
17080         kill -USR1 $MULTIPID
17081         # cause log dump
17082         sleep 3
17083         wait $MULTIPID
17084         if dmesg | grep "recursive fault"; then
17085                 error "caught a recursive fault"
17086         fi
17087         $LCTL set_param fail_loc=0
17088         true
17089 }
17090 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17091
17092 # it would be good to share it with obdfilter-survey/iokit-libecho code
17093 setup_obdecho_osc () {
17094         local rc=0
17095         local ost_nid=$1
17096         local obdfilter_name=$2
17097         echo "Creating new osc for $obdfilter_name on $ost_nid"
17098         # make sure we can find loopback nid
17099         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17100
17101         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17102                            ${obdfilter_name}_osc_UUID || rc=2; }
17103         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17104                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17105         return $rc
17106 }
17107
17108 cleanup_obdecho_osc () {
17109         local obdfilter_name=$1
17110         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17111         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17112         return 0
17113 }
17114
17115 obdecho_test() {
17116         local OBD=$1
17117         local node=$2
17118         local pages=${3:-64}
17119         local rc=0
17120         local id
17121
17122         local count=10
17123         local obd_size=$(get_obd_size $node $OBD)
17124         local page_size=$(get_page_size $node)
17125         if [[ -n "$obd_size" ]]; then
17126                 local new_count=$((obd_size / (pages * page_size / 1024)))
17127                 [[ $new_count -ge $count ]] || count=$new_count
17128         fi
17129
17130         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17131         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17132                            rc=2; }
17133         if [ $rc -eq 0 ]; then
17134             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17135             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17136         fi
17137         echo "New object id is $id"
17138         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17139                            rc=4; }
17140         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17141                            "test_brw $count w v $pages $id" || rc=4; }
17142         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17143                            rc=4; }
17144         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17145                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17146         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17147                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17148         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17149         return $rc
17150 }
17151
17152 test_180a() {
17153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17154
17155         if ! [ -d /sys/fs/lustre/echo_client ] &&
17156            ! module_loaded obdecho; then
17157                 load_module obdecho/obdecho &&
17158                         stack_trap "rmmod obdecho" EXIT ||
17159                         error "unable to load obdecho on client"
17160         fi
17161
17162         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17163         local host=$($LCTL get_param -n osc.$osc.import |
17164                      awk '/current_connection:/ { print $2 }' )
17165         local target=$($LCTL get_param -n osc.$osc.import |
17166                        awk '/target:/ { print $2 }' )
17167         target=${target%_UUID}
17168
17169         if [ -n "$target" ]; then
17170                 setup_obdecho_osc $host $target &&
17171                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17172                         { error "obdecho setup failed with $?"; return; }
17173
17174                 obdecho_test ${target}_osc client ||
17175                         error "obdecho_test failed on ${target}_osc"
17176         else
17177                 $LCTL get_param osc.$osc.import
17178                 error "there is no osc.$osc.import target"
17179         fi
17180 }
17181 run_test 180a "test obdecho on osc"
17182
17183 test_180b() {
17184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17185         remote_ost_nodsh && skip "remote OST with nodsh"
17186
17187         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17188                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17189                 error "failed to load module obdecho"
17190
17191         local target=$(do_facet ost1 $LCTL dl |
17192                        awk '/obdfilter/ { print $4; exit; }')
17193
17194         if [ -n "$target" ]; then
17195                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17196         else
17197                 do_facet ost1 $LCTL dl
17198                 error "there is no obdfilter target on ost1"
17199         fi
17200 }
17201 run_test 180b "test obdecho directly on obdfilter"
17202
17203 test_180c() { # LU-2598
17204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17205         remote_ost_nodsh && skip "remote OST with nodsh"
17206         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17207                 skip "Need MDS version at least 2.4.0"
17208
17209         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17210                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17211                 error "failed to load module obdecho"
17212
17213         local target=$(do_facet ost1 $LCTL dl |
17214                        awk '/obdfilter/ { print $4; exit; }')
17215
17216         if [ -n "$target" ]; then
17217                 local pages=16384 # 64MB bulk I/O RPC size
17218
17219                 obdecho_test "$target" ost1 "$pages" ||
17220                         error "obdecho_test with pages=$pages failed with $?"
17221         else
17222                 do_facet ost1 $LCTL dl
17223                 error "there is no obdfilter target on ost1"
17224         fi
17225 }
17226 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17227
17228 test_181() { # bug 22177
17229         test_mkdir $DIR/$tdir
17230         # create enough files to index the directory
17231         createmany -o $DIR/$tdir/foobar 4000
17232         # print attributes for debug purpose
17233         lsattr -d .
17234         # open dir
17235         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17236         MULTIPID=$!
17237         # remove the files & current working dir
17238         unlinkmany $DIR/$tdir/foobar 4000
17239         rmdir $DIR/$tdir
17240         kill -USR1 $MULTIPID
17241         wait $MULTIPID
17242         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17243         return 0
17244 }
17245 run_test 181 "Test open-unlinked dir ========================"
17246
17247 test_182() {
17248         local fcount=1000
17249         local tcount=10
17250
17251         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17252
17253         $LCTL set_param mdc.*.rpc_stats=clear
17254
17255         for (( i = 0; i < $tcount; i++ )) ; do
17256                 mkdir $DIR/$tdir/$i
17257         done
17258
17259         for (( i = 0; i < $tcount; i++ )) ; do
17260                 createmany -o $DIR/$tdir/$i/f- $fcount &
17261         done
17262         wait
17263
17264         for (( i = 0; i < $tcount; i++ )) ; do
17265                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17266         done
17267         wait
17268
17269         $LCTL get_param mdc.*.rpc_stats
17270
17271         rm -rf $DIR/$tdir
17272 }
17273 run_test 182 "Test parallel modify metadata operations ================"
17274
17275 test_183() { # LU-2275
17276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17277         remote_mds_nodsh && skip "remote MDS with nodsh"
17278         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17279                 skip "Need MDS version at least 2.3.56"
17280
17281         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17282         echo aaa > $DIR/$tdir/$tfile
17283
17284 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17285         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17286
17287         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17288         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17289
17290         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17291
17292         # Flush negative dentry cache
17293         touch $DIR/$tdir/$tfile
17294
17295         # We are not checking for any leaked references here, they'll
17296         # become evident next time we do cleanup with module unload.
17297         rm -rf $DIR/$tdir
17298 }
17299 run_test 183 "No crash or request leak in case of strange dispositions ========"
17300
17301 # test suite 184 is for LU-2016, LU-2017
17302 test_184a() {
17303         check_swap_layouts_support
17304
17305         dir0=$DIR/$tdir/$testnum
17306         test_mkdir -p -c1 $dir0
17307         ref1=/etc/passwd
17308         ref2=/etc/group
17309         file1=$dir0/f1
17310         file2=$dir0/f2
17311         $LFS setstripe -c1 $file1
17312         cp $ref1 $file1
17313         $LFS setstripe -c2 $file2
17314         cp $ref2 $file2
17315         gen1=$($LFS getstripe -g $file1)
17316         gen2=$($LFS getstripe -g $file2)
17317
17318         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17319         gen=$($LFS getstripe -g $file1)
17320         [[ $gen1 != $gen ]] ||
17321                 "Layout generation on $file1 does not change"
17322         gen=$($LFS getstripe -g $file2)
17323         [[ $gen2 != $gen ]] ||
17324                 "Layout generation on $file2 does not change"
17325
17326         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17327         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17328
17329         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17330 }
17331 run_test 184a "Basic layout swap"
17332
17333 test_184b() {
17334         check_swap_layouts_support
17335
17336         dir0=$DIR/$tdir/$testnum
17337         mkdir -p $dir0 || error "creating dir $dir0"
17338         file1=$dir0/f1
17339         file2=$dir0/f2
17340         file3=$dir0/f3
17341         dir1=$dir0/d1
17342         dir2=$dir0/d2
17343         mkdir $dir1 $dir2
17344         $LFS setstripe -c1 $file1
17345         $LFS setstripe -c2 $file2
17346         $LFS setstripe -c1 $file3
17347         chown $RUNAS_ID $file3
17348         gen1=$($LFS getstripe -g $file1)
17349         gen2=$($LFS getstripe -g $file2)
17350
17351         $LFS swap_layouts $dir1 $dir2 &&
17352                 error "swap of directories layouts should fail"
17353         $LFS swap_layouts $dir1 $file1 &&
17354                 error "swap of directory and file layouts should fail"
17355         $RUNAS $LFS swap_layouts $file1 $file2 &&
17356                 error "swap of file we cannot write should fail"
17357         $LFS swap_layouts $file1 $file3 &&
17358                 error "swap of file with different owner should fail"
17359         /bin/true # to clear error code
17360 }
17361 run_test 184b "Forbidden layout swap (will generate errors)"
17362
17363 test_184c() {
17364         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17365         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17366         check_swap_layouts_support
17367         check_swap_layout_no_dom $DIR
17368
17369         local dir0=$DIR/$tdir/$testnum
17370         mkdir -p $dir0 || error "creating dir $dir0"
17371
17372         local ref1=$dir0/ref1
17373         local ref2=$dir0/ref2
17374         local file1=$dir0/file1
17375         local file2=$dir0/file2
17376         # create a file large enough for the concurrent test
17377         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17378         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17379         echo "ref file size: ref1($(stat -c %s $ref1))," \
17380              "ref2($(stat -c %s $ref2))"
17381
17382         cp $ref2 $file2
17383         dd if=$ref1 of=$file1 bs=16k &
17384         local DD_PID=$!
17385
17386         # Make sure dd starts to copy file, but wait at most 5 seconds
17387         local loops=0
17388         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17389
17390         $LFS swap_layouts $file1 $file2
17391         local rc=$?
17392         wait $DD_PID
17393         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17394         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17395
17396         # how many bytes copied before swapping layout
17397         local copied=$(stat -c %s $file2)
17398         local remaining=$(stat -c %s $ref1)
17399         remaining=$((remaining - copied))
17400         echo "Copied $copied bytes before swapping layout..."
17401
17402         cmp -n $copied $file1 $ref2 | grep differ &&
17403                 error "Content mismatch [0, $copied) of ref2 and file1"
17404         cmp -n $copied $file2 $ref1 ||
17405                 error "Content mismatch [0, $copied) of ref1 and file2"
17406         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17407                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17408
17409         # clean up
17410         rm -f $ref1 $ref2 $file1 $file2
17411 }
17412 run_test 184c "Concurrent write and layout swap"
17413
17414 test_184d() {
17415         check_swap_layouts_support
17416         check_swap_layout_no_dom $DIR
17417         [ -z "$(which getfattr 2>/dev/null)" ] &&
17418                 skip_env "no getfattr command"
17419
17420         local file1=$DIR/$tdir/$tfile-1
17421         local file2=$DIR/$tdir/$tfile-2
17422         local file3=$DIR/$tdir/$tfile-3
17423         local lovea1
17424         local lovea2
17425
17426         mkdir -p $DIR/$tdir
17427         touch $file1 || error "create $file1 failed"
17428         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17429                 error "create $file2 failed"
17430         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17431                 error "create $file3 failed"
17432         lovea1=$(get_layout_param $file1)
17433
17434         $LFS swap_layouts $file2 $file3 ||
17435                 error "swap $file2 $file3 layouts failed"
17436         $LFS swap_layouts $file1 $file2 ||
17437                 error "swap $file1 $file2 layouts failed"
17438
17439         lovea2=$(get_layout_param $file2)
17440         echo "$lovea1"
17441         echo "$lovea2"
17442         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17443
17444         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17445         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17446 }
17447 run_test 184d "allow stripeless layouts swap"
17448
17449 test_184e() {
17450         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17451                 skip "Need MDS version at least 2.6.94"
17452         check_swap_layouts_support
17453         check_swap_layout_no_dom $DIR
17454         [ -z "$(which getfattr 2>/dev/null)" ] &&
17455                 skip_env "no getfattr command"
17456
17457         local file1=$DIR/$tdir/$tfile-1
17458         local file2=$DIR/$tdir/$tfile-2
17459         local file3=$DIR/$tdir/$tfile-3
17460         local lovea
17461
17462         mkdir -p $DIR/$tdir
17463         touch $file1 || error "create $file1 failed"
17464         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17465                 error "create $file2 failed"
17466         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17467                 error "create $file3 failed"
17468
17469         $LFS swap_layouts $file1 $file2 ||
17470                 error "swap $file1 $file2 layouts failed"
17471
17472         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17473         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17474
17475         echo 123 > $file1 || error "Should be able to write into $file1"
17476
17477         $LFS swap_layouts $file1 $file3 ||
17478                 error "swap $file1 $file3 layouts failed"
17479
17480         echo 123 > $file1 || error "Should be able to write into $file1"
17481
17482         rm -rf $file1 $file2 $file3
17483 }
17484 run_test 184e "Recreate layout after stripeless layout swaps"
17485
17486 test_184f() {
17487         # Create a file with name longer than sizeof(struct stat) ==
17488         # 144 to see if we can get chars from the file name to appear
17489         # in the returned striping. Note that 'f' == 0x66.
17490         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17491
17492         mkdir -p $DIR/$tdir
17493         mcreate $DIR/$tdir/$file
17494         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17495                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17496         fi
17497 }
17498 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17499
17500 test_185() { # LU-2441
17501         # LU-3553 - no volatile file support in old servers
17502         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17503                 skip "Need MDS version at least 2.3.60"
17504
17505         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17506         touch $DIR/$tdir/spoo
17507         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17508         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17509                 error "cannot create/write a volatile file"
17510         [ "$FILESET" == "" ] &&
17511         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17512                 error "FID is still valid after close"
17513
17514         multiop_bg_pause $DIR/$tdir vVw4096_c
17515         local multi_pid=$!
17516
17517         local OLD_IFS=$IFS
17518         IFS=":"
17519         local fidv=($fid)
17520         IFS=$OLD_IFS
17521         # assume that the next FID for this client is sequential, since stdout
17522         # is unfortunately eaten by multiop_bg_pause
17523         local n=$((${fidv[1]} + 1))
17524         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17525         if [ "$FILESET" == "" ]; then
17526                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17527                         error "FID is missing before close"
17528         fi
17529         kill -USR1 $multi_pid
17530         # 1 second delay, so if mtime change we will see it
17531         sleep 1
17532         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17533         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17534 }
17535 run_test 185 "Volatile file support"
17536
17537 function create_check_volatile() {
17538         local idx=$1
17539         local tgt
17540
17541         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17542         local PID=$!
17543         sleep 1
17544         local FID=$(cat /tmp/${tfile}.fid)
17545         [ "$FID" == "" ] && error "can't get FID for volatile"
17546         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17547         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17548         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17549         kill -USR1 $PID
17550         wait
17551         sleep 1
17552         cancel_lru_locks mdc # flush opencache
17553         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17554         return 0
17555 }
17556
17557 test_185a(){
17558         # LU-12516 - volatile creation via .lustre
17559         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17560                 skip "Need MDS version at least 2.3.55"
17561
17562         create_check_volatile 0
17563         [ $MDSCOUNT -lt 2 ] && return 0
17564
17565         # DNE case
17566         create_check_volatile 1
17567
17568         return 0
17569 }
17570 run_test 185a "Volatile file creation in .lustre/fid/"
17571
17572 test_187a() {
17573         remote_mds_nodsh && skip "remote MDS with nodsh"
17574         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17575                 skip "Need MDS version at least 2.3.0"
17576
17577         local dir0=$DIR/$tdir/$testnum
17578         mkdir -p $dir0 || error "creating dir $dir0"
17579
17580         local file=$dir0/file1
17581         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17582         local dv1=$($LFS data_version $file)
17583         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17584         local dv2=$($LFS data_version $file)
17585         [[ $dv1 != $dv2 ]] ||
17586                 error "data version did not change on write $dv1 == $dv2"
17587
17588         # clean up
17589         rm -f $file1
17590 }
17591 run_test 187a "Test data version change"
17592
17593 test_187b() {
17594         remote_mds_nodsh && skip "remote MDS with nodsh"
17595         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17596                 skip "Need MDS version at least 2.3.0"
17597
17598         local dir0=$DIR/$tdir/$testnum
17599         mkdir -p $dir0 || error "creating dir $dir0"
17600
17601         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17602         [[ ${DV[0]} != ${DV[1]} ]] ||
17603                 error "data version did not change on write"\
17604                       " ${DV[0]} == ${DV[1]}"
17605
17606         # clean up
17607         rm -f $file1
17608 }
17609 run_test 187b "Test data version change on volatile file"
17610
17611 test_200() {
17612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17613         remote_mgs_nodsh && skip "remote MGS with nodsh"
17614         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17615
17616         local POOL=${POOL:-cea1}
17617         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17618         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17619         # Pool OST targets
17620         local first_ost=0
17621         local last_ost=$(($OSTCOUNT - 1))
17622         local ost_step=2
17623         local ost_list=$(seq $first_ost $ost_step $last_ost)
17624         local ost_range="$first_ost $last_ost $ost_step"
17625         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17626         local file_dir=$POOL_ROOT/file_tst
17627         local subdir=$test_path/subdir
17628         local rc=0
17629
17630         while : ; do
17631                 # former test_200a test_200b
17632                 pool_add $POOL                          || { rc=$? ; break; }
17633                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17634                 # former test_200c test_200d
17635                 mkdir -p $test_path
17636                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17637                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17638                 mkdir -p $subdir
17639                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17640                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17641                                                         || { rc=$? ; break; }
17642                 # former test_200e test_200f
17643                 local files=$((OSTCOUNT*3))
17644                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17645                                                         || { rc=$? ; break; }
17646                 pool_create_files $POOL $file_dir $files "$ost_list" \
17647                                                         || { rc=$? ; break; }
17648                 # former test_200g test_200h
17649                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17650                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17651
17652                 # former test_201a test_201b test_201c
17653                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17654
17655                 local f=$test_path/$tfile
17656                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17657                 pool_remove $POOL $f                    || { rc=$? ; break; }
17658                 break
17659         done
17660
17661         destroy_test_pools
17662
17663         return $rc
17664 }
17665 run_test 200 "OST pools"
17666
17667 # usage: default_attr <count | size | offset>
17668 default_attr() {
17669         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17670 }
17671
17672 # usage: check_default_stripe_attr
17673 check_default_stripe_attr() {
17674         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17675         case $1 in
17676         --stripe-count|-c)
17677                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17678         --stripe-size|-S)
17679                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17680         --stripe-index|-i)
17681                 EXPECTED=-1;;
17682         *)
17683                 error "unknown getstripe attr '$1'"
17684         esac
17685
17686         [ $ACTUAL == $EXPECTED ] ||
17687                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17688 }
17689
17690 test_204a() {
17691         test_mkdir $DIR/$tdir
17692         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17693
17694         check_default_stripe_attr --stripe-count
17695         check_default_stripe_attr --stripe-size
17696         check_default_stripe_attr --stripe-index
17697 }
17698 run_test 204a "Print default stripe attributes"
17699
17700 test_204b() {
17701         test_mkdir $DIR/$tdir
17702         $LFS setstripe --stripe-count 1 $DIR/$tdir
17703
17704         check_default_stripe_attr --stripe-size
17705         check_default_stripe_attr --stripe-index
17706 }
17707 run_test 204b "Print default stripe size and offset"
17708
17709 test_204c() {
17710         test_mkdir $DIR/$tdir
17711         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17712
17713         check_default_stripe_attr --stripe-count
17714         check_default_stripe_attr --stripe-index
17715 }
17716 run_test 204c "Print default stripe count and offset"
17717
17718 test_204d() {
17719         test_mkdir $DIR/$tdir
17720         $LFS setstripe --stripe-index 0 $DIR/$tdir
17721
17722         check_default_stripe_attr --stripe-count
17723         check_default_stripe_attr --stripe-size
17724 }
17725 run_test 204d "Print default stripe count and size"
17726
17727 test_204e() {
17728         test_mkdir $DIR/$tdir
17729         $LFS setstripe -d $DIR/$tdir
17730
17731         check_default_stripe_attr --stripe-count --raw
17732         check_default_stripe_attr --stripe-size --raw
17733         check_default_stripe_attr --stripe-index --raw
17734 }
17735 run_test 204e "Print raw stripe attributes"
17736
17737 test_204f() {
17738         test_mkdir $DIR/$tdir
17739         $LFS setstripe --stripe-count 1 $DIR/$tdir
17740
17741         check_default_stripe_attr --stripe-size --raw
17742         check_default_stripe_attr --stripe-index --raw
17743 }
17744 run_test 204f "Print raw stripe size and offset"
17745
17746 test_204g() {
17747         test_mkdir $DIR/$tdir
17748         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17749
17750         check_default_stripe_attr --stripe-count --raw
17751         check_default_stripe_attr --stripe-index --raw
17752 }
17753 run_test 204g "Print raw stripe count and offset"
17754
17755 test_204h() {
17756         test_mkdir $DIR/$tdir
17757         $LFS setstripe --stripe-index 0 $DIR/$tdir
17758
17759         check_default_stripe_attr --stripe-count --raw
17760         check_default_stripe_attr --stripe-size --raw
17761 }
17762 run_test 204h "Print raw stripe count and size"
17763
17764 # Figure out which job scheduler is being used, if any,
17765 # or use a fake one
17766 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17767         JOBENV=SLURM_JOB_ID
17768 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17769         JOBENV=LSB_JOBID
17770 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17771         JOBENV=PBS_JOBID
17772 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17773         JOBENV=LOADL_STEP_ID
17774 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17775         JOBENV=JOB_ID
17776 else
17777         $LCTL list_param jobid_name > /dev/null 2>&1
17778         if [ $? -eq 0 ]; then
17779                 JOBENV=nodelocal
17780         else
17781                 JOBENV=FAKE_JOBID
17782         fi
17783 fi
17784 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17785
17786 verify_jobstats() {
17787         local cmd=($1)
17788         shift
17789         local facets="$@"
17790
17791 # we don't really need to clear the stats for this test to work, since each
17792 # command has a unique jobid, but it makes debugging easier if needed.
17793 #       for facet in $facets; do
17794 #               local dev=$(convert_facet2label $facet)
17795 #               # clear old jobstats
17796 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17797 #       done
17798
17799         # use a new JobID for each test, or we might see an old one
17800         [ "$JOBENV" = "FAKE_JOBID" ] &&
17801                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17802
17803         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17804
17805         [ "$JOBENV" = "nodelocal" ] && {
17806                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17807                 $LCTL set_param jobid_name=$FAKE_JOBID
17808                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17809         }
17810
17811         log "Test: ${cmd[*]}"
17812         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17813
17814         if [ $JOBENV = "FAKE_JOBID" ]; then
17815                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17816         else
17817                 ${cmd[*]}
17818         fi
17819
17820         # all files are created on OST0000
17821         for facet in $facets; do
17822                 local stats="*.$(convert_facet2label $facet).job_stats"
17823
17824                 # strip out libtool wrappers for in-tree executables
17825                 if [ $(do_facet $facet lctl get_param $stats |
17826                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17827                         do_facet $facet lctl get_param $stats
17828                         error "No jobstats for $JOBVAL found on $facet::$stats"
17829                 fi
17830         done
17831 }
17832
17833 jobstats_set() {
17834         local new_jobenv=$1
17835
17836         set_persistent_param_and_check client "jobid_var" \
17837                 "$FSNAME.sys.jobid_var" $new_jobenv
17838 }
17839
17840 test_205a() { # Job stats
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17843                 skip "Need MDS version with at least 2.7.1"
17844         remote_mgs_nodsh && skip "remote MGS with nodsh"
17845         remote_mds_nodsh && skip "remote MDS with nodsh"
17846         remote_ost_nodsh && skip "remote OST with nodsh"
17847         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17848                 skip "Server doesn't support jobstats"
17849         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17850
17851         local old_jobenv=$($LCTL get_param -n jobid_var)
17852         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17853
17854         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17855                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17856         else
17857                 stack_trap "do_facet mgs $PERM_CMD \
17858                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17859         fi
17860         changelog_register
17861
17862         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17863                                 mdt.*.job_cleanup_interval | head -n 1)
17864         local new_interval=5
17865         do_facet $SINGLEMDS \
17866                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17867         stack_trap "do_facet $SINGLEMDS \
17868                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17869         local start=$SECONDS
17870
17871         local cmd
17872         # mkdir
17873         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17874         verify_jobstats "$cmd" "$SINGLEMDS"
17875         # rmdir
17876         cmd="rmdir $DIR/$tdir"
17877         verify_jobstats "$cmd" "$SINGLEMDS"
17878         # mkdir on secondary MDT
17879         if [ $MDSCOUNT -gt 1 ]; then
17880                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17881                 verify_jobstats "$cmd" "mds2"
17882         fi
17883         # mknod
17884         cmd="mknod $DIR/$tfile c 1 3"
17885         verify_jobstats "$cmd" "$SINGLEMDS"
17886         # unlink
17887         cmd="rm -f $DIR/$tfile"
17888         verify_jobstats "$cmd" "$SINGLEMDS"
17889         # create all files on OST0000 so verify_jobstats can find OST stats
17890         # open & close
17891         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17892         verify_jobstats "$cmd" "$SINGLEMDS"
17893         # setattr
17894         cmd="touch $DIR/$tfile"
17895         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17896         # write
17897         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17898         verify_jobstats "$cmd" "ost1"
17899         # read
17900         cancel_lru_locks osc
17901         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17902         verify_jobstats "$cmd" "ost1"
17903         # truncate
17904         cmd="$TRUNCATE $DIR/$tfile 0"
17905         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17906         # rename
17907         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17908         verify_jobstats "$cmd" "$SINGLEMDS"
17909         # jobstats expiry - sleep until old stats should be expired
17910         local left=$((new_interval + 5 - (SECONDS - start)))
17911         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17912                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17913                         "0" $left
17914         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17915         verify_jobstats "$cmd" "$SINGLEMDS"
17916         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17917             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17918
17919         # Ensure that jobid are present in changelog (if supported by MDS)
17920         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17921                 changelog_dump | tail -10
17922                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17923                 [ $jobids -eq 9 ] ||
17924                         error "Wrong changelog jobid count $jobids != 9"
17925
17926                 # LU-5862
17927                 JOBENV="disable"
17928                 jobstats_set $JOBENV
17929                 touch $DIR/$tfile
17930                 changelog_dump | grep $tfile
17931                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17932                 [ $jobids -eq 0 ] ||
17933                         error "Unexpected jobids when jobid_var=$JOBENV"
17934         fi
17935
17936         # test '%j' access to environment variable - if supported
17937         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17938                 JOBENV="JOBCOMPLEX"
17939                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17940
17941                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17942         fi
17943
17944         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17945                 JOBENV="JOBCOMPLEX"
17946                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17947
17948                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17949         fi
17950
17951         # test '%j' access to per-session jobid - if supported
17952         if lctl list_param jobid_this_session > /dev/null 2>&1
17953         then
17954                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17955                 lctl set_param jobid_this_session=$USER
17956
17957                 JOBENV="JOBCOMPLEX"
17958                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17959
17960                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17961         fi
17962 }
17963 run_test 205a "Verify job stats"
17964
17965 # LU-13117, LU-13597
17966 test_205b() {
17967         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
17968                 skip "Need MDS version at least 2.13.54.91"
17969
17970         job_stats="mdt.*.job_stats"
17971         $LCTL set_param $job_stats=clear
17972         # Setting jobid_var to USER might not be supported
17973         $LCTL set_param jobid_var=USER || true
17974         $LCTL set_param jobid_name="%e.%u"
17975         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17976         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17977                 grep "job_id:.*foolish" &&
17978                         error "Unexpected jobid found"
17979         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17980                 grep "open:.*min.*max.*sum" ||
17981                         error "wrong job_stats format found"
17982 }
17983 run_test 205b "Verify job stats jobid and output format"
17984
17985 # LU-13733
17986 test_205c() {
17987         $LCTL set_param llite.*.stats=0
17988         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17989         $LCTL get_param llite.*.stats
17990         $LCTL get_param llite.*.stats | grep \
17991                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17992                         error "wrong client stats format found"
17993 }
17994 run_test 205c "Verify client stats format"
17995
17996 # LU-1480, LU-1773 and LU-1657
17997 test_206() {
17998         mkdir -p $DIR/$tdir
17999         $LFS setstripe -c -1 $DIR/$tdir
18000 #define OBD_FAIL_LOV_INIT 0x1403
18001         $LCTL set_param fail_loc=0xa0001403
18002         $LCTL set_param fail_val=1
18003         touch $DIR/$tdir/$tfile || true
18004 }
18005 run_test 206 "fail lov_init_raid0() doesn't lbug"
18006
18007 test_207a() {
18008         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18009         local fsz=`stat -c %s $DIR/$tfile`
18010         cancel_lru_locks mdc
18011
18012         # do not return layout in getattr intent
18013 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18014         $LCTL set_param fail_loc=0x170
18015         local sz=`stat -c %s $DIR/$tfile`
18016
18017         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18018
18019         rm -rf $DIR/$tfile
18020 }
18021 run_test 207a "can refresh layout at glimpse"
18022
18023 test_207b() {
18024         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18025         local cksum=`md5sum $DIR/$tfile`
18026         local fsz=`stat -c %s $DIR/$tfile`
18027         cancel_lru_locks mdc
18028         cancel_lru_locks osc
18029
18030         # do not return layout in getattr intent
18031 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18032         $LCTL set_param fail_loc=0x171
18033
18034         # it will refresh layout after the file is opened but before read issues
18035         echo checksum is "$cksum"
18036         echo "$cksum" |md5sum -c --quiet || error "file differs"
18037
18038         rm -rf $DIR/$tfile
18039 }
18040 run_test 207b "can refresh layout at open"
18041
18042 test_208() {
18043         # FIXME: in this test suite, only RD lease is used. This is okay
18044         # for now as only exclusive open is supported. After generic lease
18045         # is done, this test suite should be revised. - Jinshan
18046
18047         remote_mds_nodsh && skip "remote MDS with nodsh"
18048         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18049                 skip "Need MDS version at least 2.4.52"
18050
18051         echo "==== test 1: verify get lease work"
18052         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18053
18054         echo "==== test 2: verify lease can be broken by upcoming open"
18055         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18056         local PID=$!
18057         sleep 1
18058
18059         $MULTIOP $DIR/$tfile oO_RDONLY:c
18060         kill -USR1 $PID && wait $PID || error "break lease error"
18061
18062         echo "==== test 3: verify lease can't be granted if an open already exists"
18063         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
18064         local PID=$!
18065         sleep 1
18066
18067         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
18068         kill -USR1 $PID && wait $PID || error "open file error"
18069
18070         echo "==== test 4: lease can sustain over recovery"
18071         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18072         PID=$!
18073         sleep 1
18074
18075         fail mds1
18076
18077         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18078
18079         echo "==== test 5: lease broken can't be regained by replay"
18080         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18081         PID=$!
18082         sleep 1
18083
18084         # open file to break lease and then recovery
18085         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18086         fail mds1
18087
18088         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18089
18090         rm -f $DIR/$tfile
18091 }
18092 run_test 208 "Exclusive open"
18093
18094 test_209() {
18095         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18096                 skip_env "must have disp_stripe"
18097
18098         touch $DIR/$tfile
18099         sync; sleep 5; sync;
18100
18101         echo 3 > /proc/sys/vm/drop_caches
18102         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18103                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18104         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18105
18106         # open/close 500 times
18107         for i in $(seq 500); do
18108                 cat $DIR/$tfile
18109         done
18110
18111         echo 3 > /proc/sys/vm/drop_caches
18112         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18113                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18114         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18115
18116         echo "before: $req_before, after: $req_after"
18117         [ $((req_after - req_before)) -ge 300 ] &&
18118                 error "open/close requests are not freed"
18119         return 0
18120 }
18121 run_test 209 "read-only open/close requests should be freed promptly"
18122
18123 test_210() {
18124         local pid
18125
18126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18127         pid=$!
18128         sleep 1
18129
18130         $LFS getstripe $DIR/$tfile
18131         kill -USR1 $pid
18132         wait $pid || error "multiop failed"
18133
18134         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18135         pid=$!
18136         sleep 1
18137
18138         $LFS getstripe $DIR/$tfile
18139         kill -USR1 $pid
18140         wait $pid || error "multiop failed"
18141 }
18142 run_test 210 "lfs getstripe does not break leases"
18143
18144 test_212() {
18145         size=`date +%s`
18146         size=$((size % 8192 + 1))
18147         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18148         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18149         rm -f $DIR/f212 $DIR/f212.xyz
18150 }
18151 run_test 212 "Sendfile test ============================================"
18152
18153 test_213() {
18154         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18155         cancel_lru_locks osc
18156         lctl set_param fail_loc=0x8000040f
18157         # generate a read lock
18158         cat $DIR/$tfile > /dev/null
18159         # write to the file, it will try to cancel the above read lock.
18160         cat /etc/hosts >> $DIR/$tfile
18161 }
18162 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18163
18164 test_214() { # for bug 20133
18165         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18166         for (( i=0; i < 340; i++ )) ; do
18167                 touch $DIR/$tdir/d214c/a$i
18168         done
18169
18170         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18171         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18172         ls $DIR/d214c || error "ls $DIR/d214c failed"
18173         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18174         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18175 }
18176 run_test 214 "hash-indexed directory test - bug 20133"
18177
18178 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18179 create_lnet_proc_files() {
18180         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18181 }
18182
18183 # counterpart of create_lnet_proc_files
18184 remove_lnet_proc_files() {
18185         rm -f $TMP/lnet_$1.sys
18186 }
18187
18188 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18189 # 3rd arg as regexp for body
18190 check_lnet_proc_stats() {
18191         local l=$(cat "$TMP/lnet_$1" |wc -l)
18192         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18193
18194         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18195 }
18196
18197 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18198 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18199 # optional and can be regexp for 2nd line (lnet.routes case)
18200 check_lnet_proc_entry() {
18201         local blp=2          # blp stands for 'position of 1st line of body'
18202         [ -z "$5" ] || blp=3 # lnet.routes case
18203
18204         local l=$(cat "$TMP/lnet_$1" |wc -l)
18205         # subtracting one from $blp because the body can be empty
18206         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18207
18208         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18209                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18210
18211         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18212                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18213
18214         # bail out if any unexpected line happened
18215         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18216         [ "$?" != 0 ] || error "$2 misformatted"
18217 }
18218
18219 test_215() { # for bugs 18102, 21079, 21517
18220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18221
18222         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18223         local P='[1-9][0-9]*'           # positive numeric
18224         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18225         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18226         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18227         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18228
18229         local L1 # regexp for 1st line
18230         local L2 # regexp for 2nd line (optional)
18231         local BR # regexp for the rest (body)
18232
18233         # lnet.stats should look as 11 space-separated non-negative numerics
18234         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18235         create_lnet_proc_files "stats"
18236         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18237         remove_lnet_proc_files "stats"
18238
18239         # lnet.routes should look like this:
18240         # Routing disabled/enabled
18241         # net hops priority state router
18242         # where net is a string like tcp0, hops > 0, priority >= 0,
18243         # state is up/down,
18244         # router is a string like 192.168.1.1@tcp2
18245         L1="^Routing (disabled|enabled)$"
18246         L2="^net +hops +priority +state +router$"
18247         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18248         create_lnet_proc_files "routes"
18249         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18250         remove_lnet_proc_files "routes"
18251
18252         # lnet.routers should look like this:
18253         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18254         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18255         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18256         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18257         L1="^ref +rtr_ref +alive +router$"
18258         BR="^$P +$P +(up|down) +$NID$"
18259         create_lnet_proc_files "routers"
18260         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18261         remove_lnet_proc_files "routers"
18262
18263         # lnet.peers should look like this:
18264         # nid refs state last max rtr min tx min queue
18265         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18266         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18267         # numeric (0 or >0 or <0), queue >= 0.
18268         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18269         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18270         create_lnet_proc_files "peers"
18271         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18272         remove_lnet_proc_files "peers"
18273
18274         # lnet.buffers  should look like this:
18275         # pages count credits min
18276         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18277         L1="^pages +count +credits +min$"
18278         BR="^ +$N +$N +$I +$I$"
18279         create_lnet_proc_files "buffers"
18280         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18281         remove_lnet_proc_files "buffers"
18282
18283         # lnet.nis should look like this:
18284         # nid status alive refs peer rtr max tx min
18285         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18286         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18287         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18288         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18289         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18290         create_lnet_proc_files "nis"
18291         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18292         remove_lnet_proc_files "nis"
18293
18294         # can we successfully write to lnet.stats?
18295         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18296 }
18297 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18298
18299 test_216() { # bug 20317
18300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18301         remote_ost_nodsh && skip "remote OST with nodsh"
18302
18303         local node
18304         local facets=$(get_facets OST)
18305         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18306
18307         save_lustre_params client "osc.*.contention_seconds" > $p
18308         save_lustre_params $facets \
18309                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18310         save_lustre_params $facets \
18311                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18312         save_lustre_params $facets \
18313                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18314         clear_stats osc.*.osc_stats
18315
18316         # agressive lockless i/o settings
18317         do_nodes $(comma_list $(osts_nodes)) \
18318                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18319                         ldlm.namespaces.filter-*.contended_locks=0 \
18320                         ldlm.namespaces.filter-*.contention_seconds=60"
18321         lctl set_param -n osc.*.contention_seconds=60
18322
18323         $DIRECTIO write $DIR/$tfile 0 10 4096
18324         $CHECKSTAT -s 40960 $DIR/$tfile
18325
18326         # disable lockless i/o
18327         do_nodes $(comma_list $(osts_nodes)) \
18328                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18329                         ldlm.namespaces.filter-*.contended_locks=32 \
18330                         ldlm.namespaces.filter-*.contention_seconds=0"
18331         lctl set_param -n osc.*.contention_seconds=0
18332         clear_stats osc.*.osc_stats
18333
18334         dd if=/dev/zero of=$DIR/$tfile count=0
18335         $CHECKSTAT -s 0 $DIR/$tfile
18336
18337         restore_lustre_params <$p
18338         rm -f $p
18339         rm $DIR/$tfile
18340 }
18341 run_test 216 "check lockless direct write updates file size and kms correctly"
18342
18343 test_217() { # bug 22430
18344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18345
18346         local node
18347         local nid
18348
18349         for node in $(nodes_list); do
18350                 nid=$(host_nids_address $node $NETTYPE)
18351                 if [[ $nid = *-* ]] ; then
18352                         echo "lctl ping $(h2nettype $nid)"
18353                         lctl ping $(h2nettype $nid)
18354                 else
18355                         echo "skipping $node (no hyphen detected)"
18356                 fi
18357         done
18358 }
18359 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18360
18361 test_218() {
18362        # do directio so as not to populate the page cache
18363        log "creating a 10 Mb file"
18364        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18365        log "starting reads"
18366        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18367        log "truncating the file"
18368        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18369        log "killing dd"
18370        kill %+ || true # reads might have finished
18371        echo "wait until dd is finished"
18372        wait
18373        log "removing the temporary file"
18374        rm -rf $DIR/$tfile || error "tmp file removal failed"
18375 }
18376 run_test 218 "parallel read and truncate should not deadlock"
18377
18378 test_219() {
18379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18380
18381         # write one partial page
18382         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18383         # set no grant so vvp_io_commit_write will do sync write
18384         $LCTL set_param fail_loc=0x411
18385         # write a full page at the end of file
18386         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18387
18388         $LCTL set_param fail_loc=0
18389         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18390         $LCTL set_param fail_loc=0x411
18391         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18392
18393         # LU-4201
18394         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18395         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18396 }
18397 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18398
18399 test_220() { #LU-325
18400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18401         remote_ost_nodsh && skip "remote OST with nodsh"
18402         remote_mds_nodsh && skip "remote MDS with nodsh"
18403         remote_mgs_nodsh && skip "remote MGS with nodsh"
18404
18405         local OSTIDX=0
18406
18407         # create on MDT0000 so the last_id and next_id are correct
18408         mkdir_on_mdt0 $DIR/$tdir
18409         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18410         OST=${OST%_UUID}
18411
18412         # on the mdt's osc
18413         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18414         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18415                         osp.$mdtosc_proc1.prealloc_last_id)
18416         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18417                         osp.$mdtosc_proc1.prealloc_next_id)
18418
18419         $LFS df -i
18420
18421         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18422         #define OBD_FAIL_OST_ENOINO              0x229
18423         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18424         create_pool $FSNAME.$TESTNAME || return 1
18425         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18426
18427         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18428
18429         MDSOBJS=$((last_id - next_id))
18430         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18431
18432         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18433         echo "OST still has $count kbytes free"
18434
18435         echo "create $MDSOBJS files @next_id..."
18436         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18437
18438         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18439                         osp.$mdtosc_proc1.prealloc_last_id)
18440         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18441                         osp.$mdtosc_proc1.prealloc_next_id)
18442
18443         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18444         $LFS df -i
18445
18446         echo "cleanup..."
18447
18448         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18449         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18450
18451         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18452                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18453         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18454                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18455         echo "unlink $MDSOBJS files @$next_id..."
18456         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18457 }
18458 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18459
18460 test_221() {
18461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18462
18463         dd if=`which date` of=$MOUNT/date oflag=sync
18464         chmod +x $MOUNT/date
18465
18466         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18467         $LCTL set_param fail_loc=0x80001401
18468
18469         $MOUNT/date > /dev/null
18470         rm -f $MOUNT/date
18471 }
18472 run_test 221 "make sure fault and truncate race to not cause OOM"
18473
18474 test_222a () {
18475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18476
18477         rm -rf $DIR/$tdir
18478         test_mkdir $DIR/$tdir
18479         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18480         createmany -o $DIR/$tdir/$tfile 10
18481         cancel_lru_locks mdc
18482         cancel_lru_locks osc
18483         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18484         $LCTL set_param fail_loc=0x31a
18485         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18486         $LCTL set_param fail_loc=0
18487         rm -r $DIR/$tdir
18488 }
18489 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18490
18491 test_222b () {
18492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18493
18494         rm -rf $DIR/$tdir
18495         test_mkdir $DIR/$tdir
18496         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18497         createmany -o $DIR/$tdir/$tfile 10
18498         cancel_lru_locks mdc
18499         cancel_lru_locks osc
18500         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18501         $LCTL set_param fail_loc=0x31a
18502         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18503         $LCTL set_param fail_loc=0
18504 }
18505 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18506
18507 test_223 () {
18508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18509
18510         rm -rf $DIR/$tdir
18511         test_mkdir $DIR/$tdir
18512         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18513         createmany -o $DIR/$tdir/$tfile 10
18514         cancel_lru_locks mdc
18515         cancel_lru_locks osc
18516         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18517         $LCTL set_param fail_loc=0x31b
18518         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18519         $LCTL set_param fail_loc=0
18520         rm -r $DIR/$tdir
18521 }
18522 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18523
18524 test_224a() { # LU-1039, MRP-303
18525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18526
18527         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18528         $LCTL set_param fail_loc=0x508
18529         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18530         $LCTL set_param fail_loc=0
18531         df $DIR
18532 }
18533 run_test 224a "Don't panic on bulk IO failure"
18534
18535 test_224b() { # LU-1039, MRP-303
18536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18537
18538         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18539         cancel_lru_locks osc
18540         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18541         $LCTL set_param fail_loc=0x515
18542         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18543         $LCTL set_param fail_loc=0
18544         df $DIR
18545 }
18546 run_test 224b "Don't panic on bulk IO failure"
18547
18548 test_224c() { # LU-6441
18549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18550         remote_mds_nodsh && skip "remote MDS with nodsh"
18551
18552         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18553         save_writethrough $p
18554         set_cache writethrough on
18555
18556         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18557         local at_max=$($LCTL get_param -n at_max)
18558         local timeout=$($LCTL get_param -n timeout)
18559         local test_at="at_max"
18560         local param_at="$FSNAME.sys.at_max"
18561         local test_timeout="timeout"
18562         local param_timeout="$FSNAME.sys.timeout"
18563
18564         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18565
18566         set_persistent_param_and_check client "$test_at" "$param_at" 0
18567         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18568
18569         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18570         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18571         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18572         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18573         sync
18574         do_facet ost1 "$LCTL set_param fail_loc=0"
18575
18576         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18577         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18578                 $timeout
18579
18580         $LCTL set_param -n $pages_per_rpc
18581         restore_lustre_params < $p
18582         rm -f $p
18583 }
18584 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18585
18586 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18587 test_225a () {
18588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18589         if [ -z ${MDSSURVEY} ]; then
18590                 skip_env "mds-survey not found"
18591         fi
18592         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18593                 skip "Need MDS version at least 2.2.51"
18594
18595         local mds=$(facet_host $SINGLEMDS)
18596         local target=$(do_nodes $mds 'lctl dl' |
18597                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18598
18599         local cmd1="file_count=1000 thrhi=4"
18600         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18601         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18602         local cmd="$cmd1 $cmd2 $cmd3"
18603
18604         rm -f ${TMP}/mds_survey*
18605         echo + $cmd
18606         eval $cmd || error "mds-survey with zero-stripe failed"
18607         cat ${TMP}/mds_survey*
18608         rm -f ${TMP}/mds_survey*
18609 }
18610 run_test 225a "Metadata survey sanity with zero-stripe"
18611
18612 test_225b () {
18613         if [ -z ${MDSSURVEY} ]; then
18614                 skip_env "mds-survey not found"
18615         fi
18616         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18617                 skip "Need MDS version at least 2.2.51"
18618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18619         remote_mds_nodsh && skip "remote MDS with nodsh"
18620         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18621                 skip_env "Need to mount OST to test"
18622         fi
18623
18624         local mds=$(facet_host $SINGLEMDS)
18625         local target=$(do_nodes $mds 'lctl dl' |
18626                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18627
18628         local cmd1="file_count=1000 thrhi=4"
18629         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18630         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18631         local cmd="$cmd1 $cmd2 $cmd3"
18632
18633         rm -f ${TMP}/mds_survey*
18634         echo + $cmd
18635         eval $cmd || error "mds-survey with stripe_count failed"
18636         cat ${TMP}/mds_survey*
18637         rm -f ${TMP}/mds_survey*
18638 }
18639 run_test 225b "Metadata survey sanity with stripe_count = 1"
18640
18641 mcreate_path2fid () {
18642         local mode=$1
18643         local major=$2
18644         local minor=$3
18645         local name=$4
18646         local desc=$5
18647         local path=$DIR/$tdir/$name
18648         local fid
18649         local rc
18650         local fid_path
18651
18652         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18653                 error "cannot create $desc"
18654
18655         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18656         rc=$?
18657         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18658
18659         fid_path=$($LFS fid2path $MOUNT $fid)
18660         rc=$?
18661         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18662
18663         [ "$path" == "$fid_path" ] ||
18664                 error "fid2path returned $fid_path, expected $path"
18665
18666         echo "pass with $path and $fid"
18667 }
18668
18669 test_226a () {
18670         rm -rf $DIR/$tdir
18671         mkdir -p $DIR/$tdir
18672
18673         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18674         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18675         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18676         mcreate_path2fid 0040666 0 0 dir "directory"
18677         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18678         mcreate_path2fid 0100666 0 0 file "regular file"
18679         mcreate_path2fid 0120666 0 0 link "symbolic link"
18680         mcreate_path2fid 0140666 0 0 sock "socket"
18681 }
18682 run_test 226a "call path2fid and fid2path on files of all type"
18683
18684 test_226b () {
18685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18686
18687         local MDTIDX=1
18688
18689         rm -rf $DIR/$tdir
18690         mkdir -p $DIR/$tdir
18691         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18692                 error "create remote directory failed"
18693         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18694         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18695                                 "character special file (null)"
18696         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18697                                 "character special file (no device)"
18698         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18699         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18700                                 "block special file (loop)"
18701         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18702         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18703         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18704 }
18705 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18706
18707 test_226c () {
18708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18709         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18710                 skip "Need MDS version at least 2.13.55"
18711
18712         local submnt=/mnt/submnt
18713         local srcfile=/etc/passwd
18714         local dstfile=$submnt/passwd
18715         local path
18716         local fid
18717
18718         rm -rf $DIR/$tdir
18719         rm -rf $submnt
18720         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18721                 error "create remote directory failed"
18722         mkdir -p $submnt || error "create $submnt failed"
18723         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18724                 error "mount $submnt failed"
18725         stack_trap "umount $submnt" EXIT
18726
18727         cp $srcfile $dstfile
18728         fid=$($LFS path2fid $dstfile)
18729         path=$($LFS fid2path $submnt "$fid")
18730         [ "$path" = "$dstfile" ] ||
18731                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18732 }
18733 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18734
18735 # LU-1299 Executing or running ldd on a truncated executable does not
18736 # cause an out-of-memory condition.
18737 test_227() {
18738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18739         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18740
18741         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18742         chmod +x $MOUNT/date
18743
18744         $MOUNT/date > /dev/null
18745         ldd $MOUNT/date > /dev/null
18746         rm -f $MOUNT/date
18747 }
18748 run_test 227 "running truncated executable does not cause OOM"
18749
18750 # LU-1512 try to reuse idle OI blocks
18751 test_228a() {
18752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18753         remote_mds_nodsh && skip "remote MDS with nodsh"
18754         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18755
18756         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18757         local myDIR=$DIR/$tdir
18758
18759         mkdir -p $myDIR
18760         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18761         $LCTL set_param fail_loc=0x80001002
18762         createmany -o $myDIR/t- 10000
18763         $LCTL set_param fail_loc=0
18764         # The guard is current the largest FID holder
18765         touch $myDIR/guard
18766         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18767                     tr -d '[')
18768         local IDX=$(($SEQ % 64))
18769
18770         do_facet $SINGLEMDS sync
18771         # Make sure journal flushed.
18772         sleep 6
18773         local blk1=$(do_facet $SINGLEMDS \
18774                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18775                      grep Blockcount | awk '{print $4}')
18776
18777         # Remove old files, some OI blocks will become idle.
18778         unlinkmany $myDIR/t- 10000
18779         # Create new files, idle OI blocks should be reused.
18780         createmany -o $myDIR/t- 2000
18781         do_facet $SINGLEMDS sync
18782         # Make sure journal flushed.
18783         sleep 6
18784         local blk2=$(do_facet $SINGLEMDS \
18785                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18786                      grep Blockcount | awk '{print $4}')
18787
18788         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18789 }
18790 run_test 228a "try to reuse idle OI blocks"
18791
18792 test_228b() {
18793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18794         remote_mds_nodsh && skip "remote MDS with nodsh"
18795         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18796
18797         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18798         local myDIR=$DIR/$tdir
18799
18800         mkdir -p $myDIR
18801         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18802         $LCTL set_param fail_loc=0x80001002
18803         createmany -o $myDIR/t- 10000
18804         $LCTL set_param fail_loc=0
18805         # The guard is current the largest FID holder
18806         touch $myDIR/guard
18807         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18808                     tr -d '[')
18809         local IDX=$(($SEQ % 64))
18810
18811         do_facet $SINGLEMDS sync
18812         # Make sure journal flushed.
18813         sleep 6
18814         local blk1=$(do_facet $SINGLEMDS \
18815                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18816                      grep Blockcount | awk '{print $4}')
18817
18818         # Remove old files, some OI blocks will become idle.
18819         unlinkmany $myDIR/t- 10000
18820
18821         # stop the MDT
18822         stop $SINGLEMDS || error "Fail to stop MDT."
18823         # remount the MDT
18824         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18825
18826         df $MOUNT || error "Fail to df."
18827         # Create new files, idle OI blocks should be reused.
18828         createmany -o $myDIR/t- 2000
18829         do_facet $SINGLEMDS sync
18830         # Make sure journal flushed.
18831         sleep 6
18832         local blk2=$(do_facet $SINGLEMDS \
18833                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18834                      grep Blockcount | awk '{print $4}')
18835
18836         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18837 }
18838 run_test 228b "idle OI blocks can be reused after MDT restart"
18839
18840 #LU-1881
18841 test_228c() {
18842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18843         remote_mds_nodsh && skip "remote MDS with nodsh"
18844         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18845
18846         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18847         local myDIR=$DIR/$tdir
18848
18849         mkdir -p $myDIR
18850         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18851         $LCTL set_param fail_loc=0x80001002
18852         # 20000 files can guarantee there are index nodes in the OI file
18853         createmany -o $myDIR/t- 20000
18854         $LCTL set_param fail_loc=0
18855         # The guard is current the largest FID holder
18856         touch $myDIR/guard
18857         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18858                     tr -d '[')
18859         local IDX=$(($SEQ % 64))
18860
18861         do_facet $SINGLEMDS sync
18862         # Make sure journal flushed.
18863         sleep 6
18864         local blk1=$(do_facet $SINGLEMDS \
18865                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18866                      grep Blockcount | awk '{print $4}')
18867
18868         # Remove old files, some OI blocks will become idle.
18869         unlinkmany $myDIR/t- 20000
18870         rm -f $myDIR/guard
18871         # The OI file should become empty now
18872
18873         # Create new files, idle OI blocks should be reused.
18874         createmany -o $myDIR/t- 2000
18875         do_facet $SINGLEMDS sync
18876         # Make sure journal flushed.
18877         sleep 6
18878         local blk2=$(do_facet $SINGLEMDS \
18879                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18880                      grep Blockcount | awk '{print $4}')
18881
18882         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18883 }
18884 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18885
18886 test_229() { # LU-2482, LU-3448
18887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18888         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18889         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18890                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18891
18892         rm -f $DIR/$tfile
18893
18894         # Create a file with a released layout and stripe count 2.
18895         $MULTIOP $DIR/$tfile H2c ||
18896                 error "failed to create file with released layout"
18897
18898         $LFS getstripe -v $DIR/$tfile
18899
18900         local pattern=$($LFS getstripe -L $DIR/$tfile)
18901         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18902
18903         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18904                 error "getstripe"
18905         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18906         stat $DIR/$tfile || error "failed to stat released file"
18907
18908         chown $RUNAS_ID $DIR/$tfile ||
18909                 error "chown $RUNAS_ID $DIR/$tfile failed"
18910
18911         chgrp $RUNAS_ID $DIR/$tfile ||
18912                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18913
18914         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18915         rm $DIR/$tfile || error "failed to remove released file"
18916 }
18917 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18918
18919 test_230a() {
18920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18921         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18922         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18923                 skip "Need MDS version at least 2.11.52"
18924
18925         local MDTIDX=1
18926
18927         test_mkdir $DIR/$tdir
18928         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18929         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18930         [ $mdt_idx -ne 0 ] &&
18931                 error "create local directory on wrong MDT $mdt_idx"
18932
18933         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18934                         error "create remote directory failed"
18935         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18936         [ $mdt_idx -ne $MDTIDX ] &&
18937                 error "create remote directory on wrong MDT $mdt_idx"
18938
18939         createmany -o $DIR/$tdir/test_230/t- 10 ||
18940                 error "create files on remote directory failed"
18941         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18942         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18943         rm -r $DIR/$tdir || error "unlink remote directory failed"
18944 }
18945 run_test 230a "Create remote directory and files under the remote directory"
18946
18947 test_230b() {
18948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18949         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18950         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18951                 skip "Need MDS version at least 2.11.52"
18952
18953         local MDTIDX=1
18954         local mdt_index
18955         local i
18956         local file
18957         local pid
18958         local stripe_count
18959         local migrate_dir=$DIR/$tdir/migrate_dir
18960         local other_dir=$DIR/$tdir/other_dir
18961
18962         test_mkdir $DIR/$tdir
18963         test_mkdir -i0 -c1 $migrate_dir
18964         test_mkdir -i0 -c1 $other_dir
18965         for ((i=0; i<10; i++)); do
18966                 mkdir -p $migrate_dir/dir_${i}
18967                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18968                         error "create files under remote dir failed $i"
18969         done
18970
18971         cp /etc/passwd $migrate_dir/$tfile
18972         cp /etc/passwd $other_dir/$tfile
18973         chattr +SAD $migrate_dir
18974         chattr +SAD $migrate_dir/$tfile
18975
18976         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18977         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18978         local old_dir_mode=$(stat -c%f $migrate_dir)
18979         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18980
18981         mkdir -p $migrate_dir/dir_default_stripe2
18982         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18983         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18984
18985         mkdir -p $other_dir
18986         ln $migrate_dir/$tfile $other_dir/luna
18987         ln $migrate_dir/$tfile $migrate_dir/sofia
18988         ln $other_dir/$tfile $migrate_dir/david
18989         ln -s $migrate_dir/$tfile $other_dir/zachary
18990         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18991         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18992
18993         local len
18994         local lnktgt
18995
18996         # inline symlink
18997         for len in 58 59 60; do
18998                 lnktgt=$(str_repeat 'l' $len)
18999                 touch $migrate_dir/$lnktgt
19000                 ln -s $lnktgt $migrate_dir/${len}char_ln
19001         done
19002
19003         # PATH_MAX
19004         for len in 4094 4095; do
19005                 lnktgt=$(str_repeat 'l' $len)
19006                 ln -s $lnktgt $migrate_dir/${len}char_ln
19007         done
19008
19009         # NAME_MAX
19010         for len in 254 255; do
19011                 touch $migrate_dir/$(str_repeat 'l' $len)
19012         done
19013
19014         $LFS migrate -m $MDTIDX $migrate_dir ||
19015                 error "fails on migrating remote dir to MDT1"
19016
19017         echo "migratate to MDT1, then checking.."
19018         for ((i = 0; i < 10; i++)); do
19019                 for file in $(find $migrate_dir/dir_${i}); do
19020                         mdt_index=$($LFS getstripe -m $file)
19021                         # broken symlink getstripe will fail
19022                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19023                                 error "$file is not on MDT${MDTIDX}"
19024                 done
19025         done
19026
19027         # the multiple link file should still in MDT0
19028         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19029         [ $mdt_index == 0 ] ||
19030                 error "$file is not on MDT${MDTIDX}"
19031
19032         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19033         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19034                 error " expect $old_dir_flag get $new_dir_flag"
19035
19036         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19037         [ "$old_file_flag" = "$new_file_flag" ] ||
19038                 error " expect $old_file_flag get $new_file_flag"
19039
19040         local new_dir_mode=$(stat -c%f $migrate_dir)
19041         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19042                 error "expect mode $old_dir_mode get $new_dir_mode"
19043
19044         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19045         [ "$old_file_mode" = "$new_file_mode" ] ||
19046                 error "expect mode $old_file_mode get $new_file_mode"
19047
19048         diff /etc/passwd $migrate_dir/$tfile ||
19049                 error "$tfile different after migration"
19050
19051         diff /etc/passwd $other_dir/luna ||
19052                 error "luna different after migration"
19053
19054         diff /etc/passwd $migrate_dir/sofia ||
19055                 error "sofia different after migration"
19056
19057         diff /etc/passwd $migrate_dir/david ||
19058                 error "david different after migration"
19059
19060         diff /etc/passwd $other_dir/zachary ||
19061                 error "zachary different after migration"
19062
19063         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19064                 error "${tfile}_ln different after migration"
19065
19066         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19067                 error "${tfile}_ln_other different after migration"
19068
19069         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19070         [ $stripe_count = 2 ] ||
19071                 error "dir strpe_count $d != 2 after migration."
19072
19073         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19074         [ $stripe_count = 2 ] ||
19075                 error "file strpe_count $d != 2 after migration."
19076
19077         #migrate back to MDT0
19078         MDTIDX=0
19079
19080         $LFS migrate -m $MDTIDX $migrate_dir ||
19081                 error "fails on migrating remote dir to MDT0"
19082
19083         echo "migrate back to MDT0, checking.."
19084         for file in $(find $migrate_dir); do
19085                 mdt_index=$($LFS getstripe -m $file)
19086                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19087                         error "$file is not on MDT${MDTIDX}"
19088         done
19089
19090         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19091         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19092                 error " expect $old_dir_flag get $new_dir_flag"
19093
19094         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19095         [ "$old_file_flag" = "$new_file_flag" ] ||
19096                 error " expect $old_file_flag get $new_file_flag"
19097
19098         local new_dir_mode=$(stat -c%f $migrate_dir)
19099         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19100                 error "expect mode $old_dir_mode get $new_dir_mode"
19101
19102         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19103         [ "$old_file_mode" = "$new_file_mode" ] ||
19104                 error "expect mode $old_file_mode get $new_file_mode"
19105
19106         diff /etc/passwd ${migrate_dir}/$tfile ||
19107                 error "$tfile different after migration"
19108
19109         diff /etc/passwd ${other_dir}/luna ||
19110                 error "luna different after migration"
19111
19112         diff /etc/passwd ${migrate_dir}/sofia ||
19113                 error "sofia different after migration"
19114
19115         diff /etc/passwd ${other_dir}/zachary ||
19116                 error "zachary different after migration"
19117
19118         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19119                 error "${tfile}_ln different after migration"
19120
19121         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19122                 error "${tfile}_ln_other different after migration"
19123
19124         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19125         [ $stripe_count = 2 ] ||
19126                 error "dir strpe_count $d != 2 after migration."
19127
19128         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19129         [ $stripe_count = 2 ] ||
19130                 error "file strpe_count $d != 2 after migration."
19131
19132         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19133 }
19134 run_test 230b "migrate directory"
19135
19136 test_230c() {
19137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19139         remote_mds_nodsh && skip "remote MDS with nodsh"
19140         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19141                 skip "Need MDS version at least 2.11.52"
19142
19143         local MDTIDX=1
19144         local total=3
19145         local mdt_index
19146         local file
19147         local migrate_dir=$DIR/$tdir/migrate_dir
19148
19149         #If migrating directory fails in the middle, all entries of
19150         #the directory is still accessiable.
19151         test_mkdir $DIR/$tdir
19152         test_mkdir -i0 -c1 $migrate_dir
19153         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19154         stat $migrate_dir
19155         createmany -o $migrate_dir/f $total ||
19156                 error "create files under ${migrate_dir} failed"
19157
19158         # fail after migrating top dir, and this will fail only once, so the
19159         # first sub file migration will fail (currently f3), others succeed.
19160         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19161         do_facet mds1 lctl set_param fail_loc=0x1801
19162         local t=$(ls $migrate_dir | wc -l)
19163         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19164                 error "migrate should fail"
19165         local u=$(ls $migrate_dir | wc -l)
19166         [ "$u" == "$t" ] || error "$u != $t during migration"
19167
19168         # add new dir/file should succeed
19169         mkdir $migrate_dir/dir ||
19170                 error "mkdir failed under migrating directory"
19171         touch $migrate_dir/file ||
19172                 error "create file failed under migrating directory"
19173
19174         # add file with existing name should fail
19175         for file in $migrate_dir/f*; do
19176                 stat $file > /dev/null || error "stat $file failed"
19177                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19178                         error "open(O_CREAT|O_EXCL) $file should fail"
19179                 $MULTIOP $file m && error "create $file should fail"
19180                 touch $DIR/$tdir/remote_dir/$tfile ||
19181                         error "touch $tfile failed"
19182                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19183                         error "link $file should fail"
19184                 mdt_index=$($LFS getstripe -m $file)
19185                 if [ $mdt_index == 0 ]; then
19186                         # file failed to migrate is not allowed to rename to
19187                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19188                                 error "rename to $file should fail"
19189                 else
19190                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19191                                 error "rename to $file failed"
19192                 fi
19193                 echo hello >> $file || error "write $file failed"
19194         done
19195
19196         # resume migration with different options should fail
19197         $LFS migrate -m 0 $migrate_dir &&
19198                 error "migrate -m 0 $migrate_dir should fail"
19199
19200         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19201                 error "migrate -c 2 $migrate_dir should fail"
19202
19203         # resume migration should succeed
19204         $LFS migrate -m $MDTIDX $migrate_dir ||
19205                 error "migrate $migrate_dir failed"
19206
19207         echo "Finish migration, then checking.."
19208         for file in $(find $migrate_dir); do
19209                 mdt_index=$($LFS getstripe -m $file)
19210                 [ $mdt_index == $MDTIDX ] ||
19211                         error "$file is not on MDT${MDTIDX}"
19212         done
19213
19214         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19215 }
19216 run_test 230c "check directory accessiblity if migration failed"
19217
19218 test_230d() {
19219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19220         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19221         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19222                 skip "Need MDS version at least 2.11.52"
19223         # LU-11235
19224         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19225
19226         local migrate_dir=$DIR/$tdir/migrate_dir
19227         local old_index
19228         local new_index
19229         local old_count
19230         local new_count
19231         local new_hash
19232         local mdt_index
19233         local i
19234         local j
19235
19236         old_index=$((RANDOM % MDSCOUNT))
19237         old_count=$((MDSCOUNT - old_index))
19238         new_index=$((RANDOM % MDSCOUNT))
19239         new_count=$((MDSCOUNT - new_index))
19240         new_hash=1 # for all_char
19241
19242         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19243         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19244
19245         test_mkdir $DIR/$tdir
19246         test_mkdir -i $old_index -c $old_count $migrate_dir
19247
19248         for ((i=0; i<100; i++)); do
19249                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19250                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19251                         error "create files under remote dir failed $i"
19252         done
19253
19254         echo -n "Migrate from MDT$old_index "
19255         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19256         echo -n "to MDT$new_index"
19257         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19258         echo
19259
19260         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19261         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19262                 error "migrate remote dir error"
19263
19264         echo "Finish migration, then checking.."
19265         for file in $(find $migrate_dir); do
19266                 mdt_index=$($LFS getstripe -m $file)
19267                 if [ $mdt_index -lt $new_index ] ||
19268                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19269                         error "$file is on MDT$mdt_index"
19270                 fi
19271         done
19272
19273         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19274 }
19275 run_test 230d "check migrate big directory"
19276
19277 test_230e() {
19278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19281                 skip "Need MDS version at least 2.11.52"
19282
19283         local i
19284         local j
19285         local a_fid
19286         local b_fid
19287
19288         mkdir_on_mdt0 $DIR/$tdir
19289         mkdir $DIR/$tdir/migrate_dir
19290         mkdir $DIR/$tdir/other_dir
19291         touch $DIR/$tdir/migrate_dir/a
19292         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19293         ls $DIR/$tdir/other_dir
19294
19295         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19296                 error "migrate dir fails"
19297
19298         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19299         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19300
19301         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19302         [ $mdt_index == 0 ] || error "a is not on MDT0"
19303
19304         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19305                 error "migrate dir fails"
19306
19307         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19308         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19309
19310         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19311         [ $mdt_index == 1 ] || error "a is not on MDT1"
19312
19313         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19314         [ $mdt_index == 1 ] || error "b is not on MDT1"
19315
19316         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19317         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19318
19319         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19320
19321         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19322 }
19323 run_test 230e "migrate mulitple local link files"
19324
19325 test_230f() {
19326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19328         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19329                 skip "Need MDS version at least 2.11.52"
19330
19331         local a_fid
19332         local ln_fid
19333
19334         mkdir -p $DIR/$tdir
19335         mkdir $DIR/$tdir/migrate_dir
19336         $LFS mkdir -i1 $DIR/$tdir/other_dir
19337         touch $DIR/$tdir/migrate_dir/a
19338         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19339         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19340         ls $DIR/$tdir/other_dir
19341
19342         # a should be migrated to MDT1, since no other links on MDT0
19343         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19344                 error "#1 migrate dir fails"
19345         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19346         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19347         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19348         [ $mdt_index == 1 ] || error "a is not on MDT1"
19349
19350         # a should stay on MDT1, because it is a mulitple link file
19351         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19352                 error "#2 migrate dir fails"
19353         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19354         [ $mdt_index == 1 ] || error "a is not on MDT1"
19355
19356         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19357                 error "#3 migrate dir fails"
19358
19359         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19360         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19361         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19362
19363         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19364         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19365
19366         # a should be migrated to MDT0, since no other links on MDT1
19367         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19368                 error "#4 migrate dir fails"
19369         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19370         [ $mdt_index == 0 ] || error "a is not on MDT0"
19371
19372         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19373 }
19374 run_test 230f "migrate mulitple remote link files"
19375
19376 test_230g() {
19377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19379         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19380                 skip "Need MDS version at least 2.11.52"
19381
19382         mkdir -p $DIR/$tdir/migrate_dir
19383
19384         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19385                 error "migrating dir to non-exist MDT succeeds"
19386         true
19387 }
19388 run_test 230g "migrate dir to non-exist MDT"
19389
19390 test_230h() {
19391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19393         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19394                 skip "Need MDS version at least 2.11.52"
19395
19396         local mdt_index
19397
19398         mkdir -p $DIR/$tdir/migrate_dir
19399
19400         $LFS migrate -m1 $DIR &&
19401                 error "migrating mountpoint1 should fail"
19402
19403         $LFS migrate -m1 $DIR/$tdir/.. &&
19404                 error "migrating mountpoint2 should fail"
19405
19406         # same as mv
19407         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19408                 error "migrating $tdir/migrate_dir/.. should fail"
19409
19410         true
19411 }
19412 run_test 230h "migrate .. and root"
19413
19414 test_230i() {
19415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19417         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19418                 skip "Need MDS version at least 2.11.52"
19419
19420         mkdir -p $DIR/$tdir/migrate_dir
19421
19422         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19423                 error "migration fails with a tailing slash"
19424
19425         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19426                 error "migration fails with two tailing slashes"
19427 }
19428 run_test 230i "lfs migrate -m tolerates trailing slashes"
19429
19430 test_230j() {
19431         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19432         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19433                 skip "Need MDS version at least 2.11.52"
19434
19435         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19436         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19437                 error "create $tfile failed"
19438         cat /etc/passwd > $DIR/$tdir/$tfile
19439
19440         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19441
19442         cmp /etc/passwd $DIR/$tdir/$tfile ||
19443                 error "DoM file mismatch after migration"
19444 }
19445 run_test 230j "DoM file data not changed after dir migration"
19446
19447 test_230k() {
19448         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19449         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19450                 skip "Need MDS version at least 2.11.56"
19451
19452         local total=20
19453         local files_on_starting_mdt=0
19454
19455         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19456         $LFS getdirstripe $DIR/$tdir
19457         for i in $(seq $total); do
19458                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19459                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19460                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19461         done
19462
19463         echo "$files_on_starting_mdt files on MDT0"
19464
19465         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19466         $LFS getdirstripe $DIR/$tdir
19467
19468         files_on_starting_mdt=0
19469         for i in $(seq $total); do
19470                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19471                         error "file $tfile.$i mismatch after migration"
19472                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19473                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19474         done
19475
19476         echo "$files_on_starting_mdt files on MDT1 after migration"
19477         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19478
19479         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19480         $LFS getdirstripe $DIR/$tdir
19481
19482         files_on_starting_mdt=0
19483         for i in $(seq $total); do
19484                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19485                         error "file $tfile.$i mismatch after 2nd migration"
19486                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19487                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19488         done
19489
19490         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19491         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19492
19493         true
19494 }
19495 run_test 230k "file data not changed after dir migration"
19496
19497 test_230l() {
19498         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19499         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19500                 skip "Need MDS version at least 2.11.56"
19501
19502         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19503         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19504                 error "create files under remote dir failed $i"
19505         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19506 }
19507 run_test 230l "readdir between MDTs won't crash"
19508
19509 test_230m() {
19510         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19511         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19512                 skip "Need MDS version at least 2.11.56"
19513
19514         local MDTIDX=1
19515         local mig_dir=$DIR/$tdir/migrate_dir
19516         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19517         local shortstr="b"
19518         local val
19519
19520         echo "Creating files and dirs with xattrs"
19521         test_mkdir $DIR/$tdir
19522         test_mkdir -i0 -c1 $mig_dir
19523         mkdir $mig_dir/dir
19524         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19525                 error "cannot set xattr attr1 on dir"
19526         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19527                 error "cannot set xattr attr2 on dir"
19528         touch $mig_dir/dir/f0
19529         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19530                 error "cannot set xattr attr1 on file"
19531         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19532                 error "cannot set xattr attr2 on file"
19533         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19534         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19535         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19536         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19537         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19538         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19539         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19540         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19541         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19542
19543         echo "Migrating to MDT1"
19544         $LFS migrate -m $MDTIDX $mig_dir ||
19545                 error "fails on migrating dir to MDT1"
19546
19547         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19548         echo "Checking xattrs"
19549         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19550         [ "$val" = $longstr ] ||
19551                 error "expecting xattr1 $longstr on dir, found $val"
19552         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19553         [ "$val" = $shortstr ] ||
19554                 error "expecting xattr2 $shortstr on dir, found $val"
19555         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19556         [ "$val" = $longstr ] ||
19557                 error "expecting xattr1 $longstr on file, found $val"
19558         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19559         [ "$val" = $shortstr ] ||
19560                 error "expecting xattr2 $shortstr on file, found $val"
19561 }
19562 run_test 230m "xattrs not changed after dir migration"
19563
19564 test_230n() {
19565         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19566         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19567                 skip "Need MDS version at least 2.13.53"
19568
19569         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19570         cat /etc/hosts > $DIR/$tdir/$tfile
19571         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19572         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19573
19574         cmp /etc/hosts $DIR/$tdir/$tfile ||
19575                 error "File data mismatch after migration"
19576 }
19577 run_test 230n "Dir migration with mirrored file"
19578
19579 test_230o() {
19580         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19581         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19582                 skip "Need MDS version at least 2.13.52"
19583
19584         local mdts=$(comma_list $(mdts_nodes))
19585         local timeout=100
19586         local restripe_status
19587         local delta
19588         local i
19589
19590         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19591
19592         # in case "crush" hash type is not set
19593         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19594
19595         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19596                            mdt.*MDT0000.enable_dir_restripe)
19597         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19598         stack_trap "do_nodes $mdts $LCTL set_param \
19599                     mdt.*.enable_dir_restripe=$restripe_status"
19600
19601         mkdir $DIR/$tdir
19602         createmany -m $DIR/$tdir/f 100 ||
19603                 error "create files under remote dir failed $i"
19604         createmany -d $DIR/$tdir/d 100 ||
19605                 error "create dirs under remote dir failed $i"
19606
19607         for i in $(seq 2 $MDSCOUNT); do
19608                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19609                 $LFS setdirstripe -c $i $DIR/$tdir ||
19610                         error "split -c $i $tdir failed"
19611                 wait_update $HOSTNAME \
19612                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19613                         error "dir split not finished"
19614                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19615                         awk '/migrate/ {sum += $2} END { print sum }')
19616                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19617                 # delta is around total_files/stripe_count
19618                 (( $delta < 200 / (i - 1) + 4 )) ||
19619                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19620         done
19621 }
19622 run_test 230o "dir split"
19623
19624 test_230p() {
19625         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19626         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19627                 skip "Need MDS version at least 2.13.52"
19628
19629         local mdts=$(comma_list $(mdts_nodes))
19630         local timeout=100
19631         local restripe_status
19632         local delta
19633         local c
19634
19635         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19636
19637         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19638
19639         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19640                            mdt.*MDT0000.enable_dir_restripe)
19641         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19642         stack_trap "do_nodes $mdts $LCTL set_param \
19643                     mdt.*.enable_dir_restripe=$restripe_status"
19644
19645         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19646         createmany -m $DIR/$tdir/f 100 ||
19647                 error "create files under remote dir failed"
19648         createmany -d $DIR/$tdir/d 100 ||
19649                 error "create dirs under remote dir failed"
19650
19651         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19652                 local mdt_hash="crush"
19653
19654                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19655                 $LFS setdirstripe -c $c $DIR/$tdir ||
19656                         error "split -c $c $tdir failed"
19657                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19658                         mdt_hash="$mdt_hash,fixed"
19659                 elif [ $c -eq 1 ]; then
19660                         mdt_hash="none"
19661                 fi
19662                 wait_update $HOSTNAME \
19663                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19664                         error "dir merge not finished"
19665                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19666                         awk '/migrate/ {sum += $2} END { print sum }')
19667                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19668                 # delta is around total_files/stripe_count
19669                 (( delta < 200 / c + 4 )) ||
19670                         error "$delta files migrated >= $((200 / c + 4))"
19671         done
19672 }
19673 run_test 230p "dir merge"
19674
19675 test_230q() {
19676         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19677         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19678                 skip "Need MDS version at least 2.13.52"
19679
19680         local mdts=$(comma_list $(mdts_nodes))
19681         local saved_threshold=$(do_facet mds1 \
19682                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19683         local saved_delta=$(do_facet mds1 \
19684                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19685         local threshold=100
19686         local delta=2
19687         local total=0
19688         local stripe_count=0
19689         local stripe_index
19690         local nr_files
19691         local create
19692
19693         # test with fewer files on ZFS
19694         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19695
19696         stack_trap "do_nodes $mdts $LCTL set_param \
19697                     mdt.*.dir_split_count=$saved_threshold"
19698         stack_trap "do_nodes $mdts $LCTL set_param \
19699                     mdt.*.dir_split_delta=$saved_delta"
19700         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19701         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19702         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19703         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19704         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19705         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19706
19707         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19708         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19709
19710         create=$((threshold * 3 / 2))
19711         while [ $stripe_count -lt $MDSCOUNT ]; do
19712                 createmany -m $DIR/$tdir/f $total $create ||
19713                         error "create sub files failed"
19714                 stat $DIR/$tdir > /dev/null
19715                 total=$((total + create))
19716                 stripe_count=$((stripe_count + delta))
19717                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19718
19719                 wait_update $HOSTNAME \
19720                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19721                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19722
19723                 wait_update $HOSTNAME \
19724                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19725                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19726
19727                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19728                 echo "$nr_files/$total files on MDT$stripe_index after split"
19729                 # allow 10% margin of imbalance with crush hash
19730                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19731                         error "$nr_files files on MDT$stripe_index after split"
19732
19733                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19734                 [ $nr_files -eq $total ] ||
19735                         error "total sub files $nr_files != $total"
19736         done
19737
19738         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19739
19740         echo "fixed layout directory won't auto split"
19741         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19742         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19743                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19744         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19745                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19746 }
19747 run_test 230q "dir auto split"
19748
19749 test_230r() {
19750         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19751         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19752         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19753                 skip "Need MDS version at least 2.13.54"
19754
19755         # maximum amount of local locks:
19756         # parent striped dir - 2 locks
19757         # new stripe in parent to migrate to - 1 lock
19758         # source and target - 2 locks
19759         # Total 5 locks for regular file
19760         mkdir -p $DIR/$tdir
19761         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19762         touch $DIR/$tdir/dir1/eee
19763
19764         # create 4 hardlink for 4 more locks
19765         # Total: 9 locks > RS_MAX_LOCKS (8)
19766         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19767         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19768         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19769         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19770         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19771         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19772         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19773         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19774
19775         cancel_lru_locks mdc
19776
19777         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19778                 error "migrate dir fails"
19779
19780         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19781 }
19782 run_test 230r "migrate with too many local locks"
19783
19784 test_230s() {
19785         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19786                 skip "Need MDS version at least 2.13.57"
19787
19788         local mdts=$(comma_list $(mdts_nodes))
19789         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19790                                 mdt.*MDT0000.enable_dir_restripe)
19791
19792         stack_trap "do_nodes $mdts $LCTL set_param \
19793                     mdt.*.enable_dir_restripe=$restripe_status"
19794
19795         local st
19796         for st in 0 1; do
19797                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19798                 test_mkdir $DIR/$tdir
19799                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19800                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19801                 rmdir $DIR/$tdir
19802         done
19803 }
19804 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19805
19806 test_230t()
19807 {
19808         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19809         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19810                 skip "Need MDS version at least 2.14.50"
19811
19812         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19813         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19814         $LFS project -p 1 -s $DIR/$tdir ||
19815                 error "set $tdir project id failed"
19816         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19817                 error "set subdir project id failed"
19818         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19819 }
19820 run_test 230t "migrate directory with project ID set"
19821
19822 test_231a()
19823 {
19824         # For simplicity this test assumes that max_pages_per_rpc
19825         # is the same across all OSCs
19826         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19827         local bulk_size=$((max_pages * PAGE_SIZE))
19828         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19829                                        head -n 1)
19830
19831         mkdir -p $DIR/$tdir
19832         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19833                 error "failed to set stripe with -S ${brw_size}M option"
19834
19835         # clear the OSC stats
19836         $LCTL set_param osc.*.stats=0 &>/dev/null
19837         stop_writeback
19838
19839         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19840         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19841                 oflag=direct &>/dev/null || error "dd failed"
19842
19843         sync; sleep 1; sync # just to be safe
19844         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19845         if [ x$nrpcs != "x1" ]; then
19846                 $LCTL get_param osc.*.stats
19847                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19848         fi
19849
19850         start_writeback
19851         # Drop the OSC cache, otherwise we will read from it
19852         cancel_lru_locks osc
19853
19854         # clear the OSC stats
19855         $LCTL set_param osc.*.stats=0 &>/dev/null
19856
19857         # Client reads $bulk_size.
19858         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19859                 iflag=direct &>/dev/null || error "dd failed"
19860
19861         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19862         if [ x$nrpcs != "x1" ]; then
19863                 $LCTL get_param osc.*.stats
19864                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19865         fi
19866 }
19867 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19868
19869 test_231b() {
19870         mkdir -p $DIR/$tdir
19871         local i
19872         for i in {0..1023}; do
19873                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19874                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19875                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19876         done
19877         sync
19878 }
19879 run_test 231b "must not assert on fully utilized OST request buffer"
19880
19881 test_232a() {
19882         mkdir -p $DIR/$tdir
19883         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19884
19885         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19886         do_facet ost1 $LCTL set_param fail_loc=0x31c
19887
19888         # ignore dd failure
19889         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19890
19891         do_facet ost1 $LCTL set_param fail_loc=0
19892         umount_client $MOUNT || error "umount failed"
19893         mount_client $MOUNT || error "mount failed"
19894         stop ost1 || error "cannot stop ost1"
19895         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19896 }
19897 run_test 232a "failed lock should not block umount"
19898
19899 test_232b() {
19900         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19901                 skip "Need MDS version at least 2.10.58"
19902
19903         mkdir -p $DIR/$tdir
19904         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19905         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19906         sync
19907         cancel_lru_locks osc
19908
19909         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19910         do_facet ost1 $LCTL set_param fail_loc=0x31c
19911
19912         # ignore failure
19913         $LFS data_version $DIR/$tdir/$tfile || true
19914
19915         do_facet ost1 $LCTL set_param fail_loc=0
19916         umount_client $MOUNT || error "umount failed"
19917         mount_client $MOUNT || error "mount failed"
19918         stop ost1 || error "cannot stop ost1"
19919         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19920 }
19921 run_test 232b "failed data version lock should not block umount"
19922
19923 test_233a() {
19924         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19925                 skip "Need MDS version at least 2.3.64"
19926         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19927
19928         local fid=$($LFS path2fid $MOUNT)
19929
19930         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19931                 error "cannot access $MOUNT using its FID '$fid'"
19932 }
19933 run_test 233a "checking that OBF of the FS root succeeds"
19934
19935 test_233b() {
19936         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19937                 skip "Need MDS version at least 2.5.90"
19938         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19939
19940         local fid=$($LFS path2fid $MOUNT/.lustre)
19941
19942         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19943                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19944
19945         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19946         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19947                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19948 }
19949 run_test 233b "checking that OBF of the FS .lustre succeeds"
19950
19951 test_234() {
19952         local p="$TMP/sanityN-$TESTNAME.parameters"
19953         save_lustre_params client "llite.*.xattr_cache" > $p
19954         lctl set_param llite.*.xattr_cache 1 ||
19955                 skip_env "xattr cache is not supported"
19956
19957         mkdir -p $DIR/$tdir || error "mkdir failed"
19958         touch $DIR/$tdir/$tfile || error "touch failed"
19959         # OBD_FAIL_LLITE_XATTR_ENOMEM
19960         $LCTL set_param fail_loc=0x1405
19961         getfattr -n user.attr $DIR/$tdir/$tfile &&
19962                 error "getfattr should have failed with ENOMEM"
19963         $LCTL set_param fail_loc=0x0
19964         rm -rf $DIR/$tdir
19965
19966         restore_lustre_params < $p
19967         rm -f $p
19968 }
19969 run_test 234 "xattr cache should not crash on ENOMEM"
19970
19971 test_235() {
19972         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19973                 skip "Need MDS version at least 2.4.52"
19974
19975         flock_deadlock $DIR/$tfile
19976         local RC=$?
19977         case $RC in
19978                 0)
19979                 ;;
19980                 124) error "process hangs on a deadlock"
19981                 ;;
19982                 *) error "error executing flock_deadlock $DIR/$tfile"
19983                 ;;
19984         esac
19985 }
19986 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19987
19988 #LU-2935
19989 test_236() {
19990         check_swap_layouts_support
19991
19992         local ref1=/etc/passwd
19993         local ref2=/etc/group
19994         local file1=$DIR/$tdir/f1
19995         local file2=$DIR/$tdir/f2
19996
19997         test_mkdir -c1 $DIR/$tdir
19998         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19999         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20000         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20001         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20002         local fd=$(free_fd)
20003         local cmd="exec $fd<>$file2"
20004         eval $cmd
20005         rm $file2
20006         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20007                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20008         cmd="exec $fd>&-"
20009         eval $cmd
20010         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20011
20012         #cleanup
20013         rm -rf $DIR/$tdir
20014 }
20015 run_test 236 "Layout swap on open unlinked file"
20016
20017 # LU-4659 linkea consistency
20018 test_238() {
20019         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20020                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20021                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20022                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20023
20024         touch $DIR/$tfile
20025         ln $DIR/$tfile $DIR/$tfile.lnk
20026         touch $DIR/$tfile.new
20027         mv $DIR/$tfile.new $DIR/$tfile
20028         local fid1=$($LFS path2fid $DIR/$tfile)
20029         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20030         local path1=$($LFS fid2path $FSNAME "$fid1")
20031         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20032         local path2=$($LFS fid2path $FSNAME "$fid2")
20033         [ $tfile.lnk == $path2 ] ||
20034                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20035         rm -f $DIR/$tfile*
20036 }
20037 run_test 238 "Verify linkea consistency"
20038
20039 test_239A() { # was test_239
20040         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20041                 skip "Need MDS version at least 2.5.60"
20042
20043         local list=$(comma_list $(mdts_nodes))
20044
20045         mkdir -p $DIR/$tdir
20046         createmany -o $DIR/$tdir/f- 5000
20047         unlinkmany $DIR/$tdir/f- 5000
20048         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20049                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20050         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20051                         osp.*MDT*.sync_in_flight" | calc_sum)
20052         [ "$changes" -eq 0 ] || error "$changes not synced"
20053 }
20054 run_test 239A "osp_sync test"
20055
20056 test_239a() { #LU-5297
20057         remote_mds_nodsh && skip "remote MDS with nodsh"
20058
20059         touch $DIR/$tfile
20060         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20061         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20062         chgrp $RUNAS_GID $DIR/$tfile
20063         wait_delete_completed
20064 }
20065 run_test 239a "process invalid osp sync record correctly"
20066
20067 test_239b() { #LU-5297
20068         remote_mds_nodsh && skip "remote MDS with nodsh"
20069
20070         touch $DIR/$tfile1
20071         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20072         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20073         chgrp $RUNAS_GID $DIR/$tfile1
20074         wait_delete_completed
20075         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20076         touch $DIR/$tfile2
20077         chgrp $RUNAS_GID $DIR/$tfile2
20078         wait_delete_completed
20079 }
20080 run_test 239b "process osp sync record with ENOMEM error correctly"
20081
20082 test_240() {
20083         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20084         remote_mds_nodsh && skip "remote MDS with nodsh"
20085
20086         mkdir -p $DIR/$tdir
20087
20088         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20089                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20090         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20091                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20092
20093         umount_client $MOUNT || error "umount failed"
20094         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20095         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20096         mount_client $MOUNT || error "failed to mount client"
20097
20098         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20099         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20100 }
20101 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20102
20103 test_241_bio() {
20104         local count=$1
20105         local bsize=$2
20106
20107         for LOOP in $(seq $count); do
20108                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20109                 cancel_lru_locks $OSC || true
20110         done
20111 }
20112
20113 test_241_dio() {
20114         local count=$1
20115         local bsize=$2
20116
20117         for LOOP in $(seq $1); do
20118                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20119                         2>/dev/null
20120         done
20121 }
20122
20123 test_241a() { # was test_241
20124         local bsize=$PAGE_SIZE
20125
20126         (( bsize < 40960 )) && bsize=40960
20127         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20128         ls -la $DIR/$tfile
20129         cancel_lru_locks $OSC
20130         test_241_bio 1000 $bsize &
20131         PID=$!
20132         test_241_dio 1000 $bsize
20133         wait $PID
20134 }
20135 run_test 241a "bio vs dio"
20136
20137 test_241b() {
20138         local bsize=$PAGE_SIZE
20139
20140         (( bsize < 40960 )) && bsize=40960
20141         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20142         ls -la $DIR/$tfile
20143         test_241_dio 1000 $bsize &
20144         PID=$!
20145         test_241_dio 1000 $bsize
20146         wait $PID
20147 }
20148 run_test 241b "dio vs dio"
20149
20150 test_242() {
20151         remote_mds_nodsh && skip "remote MDS with nodsh"
20152
20153         mkdir_on_mdt0 $DIR/$tdir
20154         touch $DIR/$tdir/$tfile
20155
20156         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20157         do_facet mds1 lctl set_param fail_loc=0x105
20158         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20159
20160         do_facet mds1 lctl set_param fail_loc=0
20161         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20162 }
20163 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20164
20165 test_243()
20166 {
20167         test_mkdir $DIR/$tdir
20168         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20169 }
20170 run_test 243 "various group lock tests"
20171
20172 test_244a()
20173 {
20174         test_mkdir $DIR/$tdir
20175         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20176         sendfile_grouplock $DIR/$tdir/$tfile || \
20177                 error "sendfile+grouplock failed"
20178         rm -rf $DIR/$tdir
20179 }
20180 run_test 244a "sendfile with group lock tests"
20181
20182 test_244b()
20183 {
20184         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20185
20186         local threads=50
20187         local size=$((1024*1024))
20188
20189         test_mkdir $DIR/$tdir
20190         for i in $(seq 1 $threads); do
20191                 local file=$DIR/$tdir/file_$((i / 10))
20192                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20193                 local pids[$i]=$!
20194         done
20195         for i in $(seq 1 $threads); do
20196                 wait ${pids[$i]}
20197         done
20198 }
20199 run_test 244b "multi-threaded write with group lock"
20200
20201 test_245() {
20202         local flagname="multi_mod_rpcs"
20203         local connect_data_name="max_mod_rpcs"
20204         local out
20205
20206         # check if multiple modify RPCs flag is set
20207         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20208                 grep "connect_flags:")
20209         echo "$out"
20210
20211         echo "$out" | grep -qw $flagname
20212         if [ $? -ne 0 ]; then
20213                 echo "connect flag $flagname is not set"
20214                 return
20215         fi
20216
20217         # check if multiple modify RPCs data is set
20218         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20219         echo "$out"
20220
20221         echo "$out" | grep -qw $connect_data_name ||
20222                 error "import should have connect data $connect_data_name"
20223 }
20224 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20225
20226 cleanup_247() {
20227         local submount=$1
20228
20229         trap 0
20230         umount_client $submount
20231         rmdir $submount
20232 }
20233
20234 test_247a() {
20235         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20236                 grep -q subtree ||
20237                 skip_env "Fileset feature is not supported"
20238
20239         local submount=${MOUNT}_$tdir
20240
20241         mkdir $MOUNT/$tdir
20242         mkdir -p $submount || error "mkdir $submount failed"
20243         FILESET="$FILESET/$tdir" mount_client $submount ||
20244                 error "mount $submount failed"
20245         trap "cleanup_247 $submount" EXIT
20246         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20247         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20248                 error "read $MOUNT/$tdir/$tfile failed"
20249         cleanup_247 $submount
20250 }
20251 run_test 247a "mount subdir as fileset"
20252
20253 test_247b() {
20254         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20255                 skip_env "Fileset feature is not supported"
20256
20257         local submount=${MOUNT}_$tdir
20258
20259         rm -rf $MOUNT/$tdir
20260         mkdir -p $submount || error "mkdir $submount failed"
20261         SKIP_FILESET=1
20262         FILESET="$FILESET/$tdir" mount_client $submount &&
20263                 error "mount $submount should fail"
20264         rmdir $submount
20265 }
20266 run_test 247b "mount subdir that dose not exist"
20267
20268 test_247c() {
20269         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20270                 skip_env "Fileset feature is not supported"
20271
20272         local submount=${MOUNT}_$tdir
20273
20274         mkdir -p $MOUNT/$tdir/dir1
20275         mkdir -p $submount || error "mkdir $submount failed"
20276         trap "cleanup_247 $submount" EXIT
20277         FILESET="$FILESET/$tdir" mount_client $submount ||
20278                 error "mount $submount failed"
20279         local fid=$($LFS path2fid $MOUNT/)
20280         $LFS fid2path $submount $fid && error "fid2path should fail"
20281         cleanup_247 $submount
20282 }
20283 run_test 247c "running fid2path outside subdirectory root"
20284
20285 test_247d() {
20286         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20287                 skip "Fileset feature is not supported"
20288
20289         local submount=${MOUNT}_$tdir
20290
20291         mkdir -p $MOUNT/$tdir/dir1
20292         mkdir -p $submount || error "mkdir $submount failed"
20293         FILESET="$FILESET/$tdir" mount_client $submount ||
20294                 error "mount $submount failed"
20295         trap "cleanup_247 $submount" EXIT
20296
20297         local td=$submount/dir1
20298         local fid=$($LFS path2fid $td)
20299         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20300
20301         # check that we get the same pathname back
20302         local rootpath
20303         local found
20304         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20305                 echo "$rootpath $fid"
20306                 found=$($LFS fid2path $rootpath "$fid")
20307                 [ -n "found" ] || error "fid2path should succeed"
20308                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20309         done
20310         # check wrong root path format
20311         rootpath=$submount"_wrong"
20312         found=$($LFS fid2path $rootpath "$fid")
20313         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20314
20315         cleanup_247 $submount
20316 }
20317 run_test 247d "running fid2path inside subdirectory root"
20318
20319 # LU-8037
20320 test_247e() {
20321         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20322                 grep -q subtree ||
20323                 skip "Fileset feature is not supported"
20324
20325         local submount=${MOUNT}_$tdir
20326
20327         mkdir $MOUNT/$tdir
20328         mkdir -p $submount || error "mkdir $submount failed"
20329         FILESET="$FILESET/.." mount_client $submount &&
20330                 error "mount $submount should fail"
20331         rmdir $submount
20332 }
20333 run_test 247e "mount .. as fileset"
20334
20335 test_247f() {
20336         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20337         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20338                 skip "Need at least version 2.13.52"
20339         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20340                 skip "Need at least version 2.14.50"
20341         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20342                 grep -q subtree ||
20343                 skip "Fileset feature is not supported"
20344
20345         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20346         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20347                 error "mkdir remote failed"
20348         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20349                 error "mkdir remote/subdir failed"
20350         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20351                 error "mkdir striped failed"
20352         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20353
20354         local submount=${MOUNT}_$tdir
20355
20356         mkdir -p $submount || error "mkdir $submount failed"
20357         stack_trap "rmdir $submount"
20358
20359         local dir
20360         local stat
20361         local fileset=$FILESET
20362         local mdts=$(comma_list $(mdts_nodes))
20363
20364         stat=$(do_facet mds1 $LCTL get_param -n \
20365                 mdt.*MDT0000.enable_remote_subdir_mount)
20366         stack_trap "do_nodes $mdts $LCTL set_param \
20367                 mdt.*.enable_remote_subdir_mount=$stat"
20368
20369         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20370         stack_trap "umount_client $submount"
20371         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20372                 error "mount remote dir $dir should fail"
20373
20374         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20375                 $tdir/striped/. ; do
20376                 FILESET="$fileset/$dir" mount_client $submount ||
20377                         error "mount $dir failed"
20378                 umount_client $submount
20379         done
20380
20381         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20382         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20383                 error "mount $tdir/remote failed"
20384 }
20385 run_test 247f "mount striped or remote directory as fileset"
20386
20387 test_247g() {
20388         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20389         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20390                 skip "Need at least version 2.14.50"
20391
20392         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20393                 error "mkdir $tdir failed"
20394         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20395
20396         local submount=${MOUNT}_$tdir
20397
20398         mkdir -p $submount || error "mkdir $submount failed"
20399         stack_trap "rmdir $submount"
20400
20401         FILESET="$fileset/$tdir" mount_client $submount ||
20402                 error "mount $dir failed"
20403         stack_trap "umount $submount"
20404
20405         local mdts=$(comma_list $(mdts_nodes))
20406
20407         local nrpcs
20408
20409         stat $submount > /dev/null
20410         cancel_lru_locks $MDC
20411         stat $submount > /dev/null
20412         stat $submount/$tfile > /dev/null
20413         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20414         stat $submount/$tfile > /dev/null
20415         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20416                 awk '/getattr/ {sum += $2} END {print sum}')
20417
20418         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20419 }
20420 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20421
20422 test_248a() {
20423         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20424         [ -z "$fast_read_sav" ] && skip "no fast read support"
20425
20426         # create a large file for fast read verification
20427         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20428
20429         # make sure the file is created correctly
20430         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20431                 { rm -f $DIR/$tfile; skip "file creation error"; }
20432
20433         echo "Test 1: verify that fast read is 4 times faster on cache read"
20434
20435         # small read with fast read enabled
20436         $LCTL set_param -n llite.*.fast_read=1
20437         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20438                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20439                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20440         # small read with fast read disabled
20441         $LCTL set_param -n llite.*.fast_read=0
20442         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20443                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20444                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20445
20446         # verify that fast read is 4 times faster for cache read
20447         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20448                 error_not_in_vm "fast read was not 4 times faster: " \
20449                            "$t_fast vs $t_slow"
20450
20451         echo "Test 2: verify the performance between big and small read"
20452         $LCTL set_param -n llite.*.fast_read=1
20453
20454         # 1k non-cache read
20455         cancel_lru_locks osc
20456         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20457                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20458                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20459
20460         # 1M non-cache read
20461         cancel_lru_locks osc
20462         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20463                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20464                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20465
20466         # verify that big IO is not 4 times faster than small IO
20467         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20468                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20469
20470         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20471         rm -f $DIR/$tfile
20472 }
20473 run_test 248a "fast read verification"
20474
20475 test_248b() {
20476         # Default short_io_bytes=16384, try both smaller and larger sizes.
20477         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20478         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20479         echo "bs=53248 count=113 normal buffered write"
20480         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20481                 error "dd of initial data file failed"
20482         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20483
20484         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20485         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20486                 error "dd with sync normal writes failed"
20487         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20488
20489         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20490         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20491                 error "dd with sync small writes failed"
20492         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20493
20494         cancel_lru_locks osc
20495
20496         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20497         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20498         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20499         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20500                 iflag=direct || error "dd with O_DIRECT small read failed"
20501         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20502         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20503                 error "compare $TMP/$tfile.1 failed"
20504
20505         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20506         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20507
20508         # just to see what the maximum tunable value is, and test parsing
20509         echo "test invalid parameter 2MB"
20510         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20511                 error "too-large short_io_bytes allowed"
20512         echo "test maximum parameter 512KB"
20513         # if we can set a larger short_io_bytes, run test regardless of version
20514         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20515                 # older clients may not allow setting it this large, that's OK
20516                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20517                         skip "Need at least client version 2.13.50"
20518                 error "medium short_io_bytes failed"
20519         fi
20520         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20521         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20522
20523         echo "test large parameter 64KB"
20524         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20525         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20526
20527         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20528         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20529                 error "dd with sync large writes failed"
20530         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20531
20532         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20533         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20534         num=$((113 * 4096 / PAGE_SIZE))
20535         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20536         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20537                 error "dd with O_DIRECT large writes failed"
20538         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20539                 error "compare $DIR/$tfile.3 failed"
20540
20541         cancel_lru_locks osc
20542
20543         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20544         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20545                 error "dd with O_DIRECT large read failed"
20546         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20547                 error "compare $TMP/$tfile.2 failed"
20548
20549         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20550         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20551                 error "dd with O_DIRECT large read failed"
20552         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20553                 error "compare $TMP/$tfile.3 failed"
20554 }
20555 run_test 248b "test short_io read and write for both small and large sizes"
20556
20557 test_249() { # LU-7890
20558         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20559                 skip "Need at least version 2.8.54"
20560
20561         rm -f $DIR/$tfile
20562         $LFS setstripe -c 1 $DIR/$tfile
20563         # Offset 2T == 4k * 512M
20564         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20565                 error "dd to 2T offset failed"
20566 }
20567 run_test 249 "Write above 2T file size"
20568
20569 test_250() {
20570         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20571          && skip "no 16TB file size limit on ZFS"
20572
20573         $LFS setstripe -c 1 $DIR/$tfile
20574         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20575         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20576         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20577         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20578                 conv=notrunc,fsync && error "append succeeded"
20579         return 0
20580 }
20581 run_test 250 "Write above 16T limit"
20582
20583 test_251() {
20584         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20585
20586         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20587         #Skip once - writing the first stripe will succeed
20588         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20589         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20590                 error "short write happened"
20591
20592         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20593         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20594                 error "short read happened"
20595
20596         rm -f $DIR/$tfile
20597 }
20598 run_test 251 "Handling short read and write correctly"
20599
20600 test_252() {
20601         remote_mds_nodsh && skip "remote MDS with nodsh"
20602         remote_ost_nodsh && skip "remote OST with nodsh"
20603         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20604                 skip_env "ldiskfs only test"
20605         fi
20606
20607         local tgt
20608         local dev
20609         local out
20610         local uuid
20611         local num
20612         local gen
20613
20614         # check lr_reader on OST0000
20615         tgt=ost1
20616         dev=$(facet_device $tgt)
20617         out=$(do_facet $tgt $LR_READER $dev)
20618         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20619         echo "$out"
20620         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20621         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20622                 error "Invalid uuid returned by $LR_READER on target $tgt"
20623         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20624
20625         # check lr_reader -c on MDT0000
20626         tgt=mds1
20627         dev=$(facet_device $tgt)
20628         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20629                 skip "$LR_READER does not support additional options"
20630         fi
20631         out=$(do_facet $tgt $LR_READER -c $dev)
20632         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20633         echo "$out"
20634         num=$(echo "$out" | grep -c "mdtlov")
20635         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20636                 error "Invalid number of mdtlov clients returned by $LR_READER"
20637         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20638
20639         # check lr_reader -cr on MDT0000
20640         out=$(do_facet $tgt $LR_READER -cr $dev)
20641         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20642         echo "$out"
20643         echo "$out" | grep -q "^reply_data:$" ||
20644                 error "$LR_READER should have returned 'reply_data' section"
20645         num=$(echo "$out" | grep -c "client_generation")
20646         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20647 }
20648 run_test 252 "check lr_reader tool"
20649
20650 test_253() {
20651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20652         remote_mds_nodsh && skip "remote MDS with nodsh"
20653         remote_mgs_nodsh && skip "remote MGS with nodsh"
20654
20655         local ostidx=0
20656         local rc=0
20657         local ost_name=$(ostname_from_index $ostidx)
20658
20659         # on the mdt's osc
20660         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20661         do_facet $SINGLEMDS $LCTL get_param -n \
20662                 osp.$mdtosc_proc1.reserved_mb_high ||
20663                 skip  "remote MDS does not support reserved_mb_high"
20664
20665         rm -rf $DIR/$tdir
20666         wait_mds_ost_sync
20667         wait_delete_completed
20668         mkdir $DIR/$tdir
20669
20670         pool_add $TESTNAME || error "Pool creation failed"
20671         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20672
20673         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20674                 error "Setstripe failed"
20675
20676         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20677
20678         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20679                     grep "watermarks")
20680         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20681
20682         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20683                         osp.$mdtosc_proc1.prealloc_status)
20684         echo "prealloc_status $oa_status"
20685
20686         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20687                 error "File creation should fail"
20688
20689         #object allocation was stopped, but we still able to append files
20690         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20691                 oflag=append || error "Append failed"
20692
20693         rm -f $DIR/$tdir/$tfile.0
20694
20695         # For this test, we want to delete the files we created to go out of
20696         # space but leave the watermark, so we remain nearly out of space
20697         ost_watermarks_enospc_delete_files $tfile $ostidx
20698
20699         wait_delete_completed
20700
20701         sleep_maxage
20702
20703         for i in $(seq 10 12); do
20704                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20705                         2>/dev/null || error "File creation failed after rm"
20706         done
20707
20708         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20709                         osp.$mdtosc_proc1.prealloc_status)
20710         echo "prealloc_status $oa_status"
20711
20712         if (( oa_status != 0 )); then
20713                 error "Object allocation still disable after rm"
20714         fi
20715 }
20716 run_test 253 "Check object allocation limit"
20717
20718 test_254() {
20719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20720         remote_mds_nodsh && skip "remote MDS with nodsh"
20721         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20722                 skip "MDS does not support changelog_size"
20723
20724         local cl_user
20725         local MDT0=$(facet_svc $SINGLEMDS)
20726
20727         changelog_register || error "changelog_register failed"
20728
20729         changelog_clear 0 || error "changelog_clear failed"
20730
20731         local size1=$(do_facet $SINGLEMDS \
20732                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20733         echo "Changelog size $size1"
20734
20735         rm -rf $DIR/$tdir
20736         $LFS mkdir -i 0 $DIR/$tdir
20737         # change something
20738         mkdir -p $DIR/$tdir/pics/2008/zachy
20739         touch $DIR/$tdir/pics/2008/zachy/timestamp
20740         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20741         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20742         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20743         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20744         rm $DIR/$tdir/pics/desktop.jpg
20745
20746         local size2=$(do_facet $SINGLEMDS \
20747                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20748         echo "Changelog size after work $size2"
20749
20750         (( $size2 > $size1 )) ||
20751                 error "new Changelog size=$size2 less than old size=$size1"
20752 }
20753 run_test 254 "Check changelog size"
20754
20755 ladvise_no_type()
20756 {
20757         local type=$1
20758         local file=$2
20759
20760         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20761                 awk -F: '{print $2}' | grep $type > /dev/null
20762         if [ $? -ne 0 ]; then
20763                 return 0
20764         fi
20765         return 1
20766 }
20767
20768 ladvise_no_ioctl()
20769 {
20770         local file=$1
20771
20772         lfs ladvise -a willread $file > /dev/null 2>&1
20773         if [ $? -eq 0 ]; then
20774                 return 1
20775         fi
20776
20777         lfs ladvise -a willread $file 2>&1 |
20778                 grep "Inappropriate ioctl for device" > /dev/null
20779         if [ $? -eq 0 ]; then
20780                 return 0
20781         fi
20782         return 1
20783 }
20784
20785 percent() {
20786         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20787 }
20788
20789 # run a random read IO workload
20790 # usage: random_read_iops <filename> <filesize> <iosize>
20791 random_read_iops() {
20792         local file=$1
20793         local fsize=$2
20794         local iosize=${3:-4096}
20795
20796         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20797                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20798 }
20799
20800 drop_file_oss_cache() {
20801         local file="$1"
20802         local nodes="$2"
20803
20804         $LFS ladvise -a dontneed $file 2>/dev/null ||
20805                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20806 }
20807
20808 ladvise_willread_performance()
20809 {
20810         local repeat=10
20811         local average_origin=0
20812         local average_cache=0
20813         local average_ladvise=0
20814
20815         for ((i = 1; i <= $repeat; i++)); do
20816                 echo "Iter $i/$repeat: reading without willread hint"
20817                 cancel_lru_locks osc
20818                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20819                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20820                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20821                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20822
20823                 cancel_lru_locks osc
20824                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20825                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20826                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20827
20828                 cancel_lru_locks osc
20829                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20830                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20831                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20832                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20833                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20834         done
20835         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20836         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20837         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20838
20839         speedup_cache=$(percent $average_cache $average_origin)
20840         speedup_ladvise=$(percent $average_ladvise $average_origin)
20841
20842         echo "Average uncached read: $average_origin"
20843         echo "Average speedup with OSS cached read: " \
20844                 "$average_cache = +$speedup_cache%"
20845         echo "Average speedup with ladvise willread: " \
20846                 "$average_ladvise = +$speedup_ladvise%"
20847
20848         local lowest_speedup=20
20849         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20850                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20851                         "got $average_cache%. Skipping ladvise willread check."
20852                 return 0
20853         fi
20854
20855         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20856         # it is still good to run until then to exercise 'ladvise willread'
20857         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20858                 [ "$ost1_FSTYPE" = "zfs" ] &&
20859                 echo "osd-zfs does not support dontneed or drop_caches" &&
20860                 return 0
20861
20862         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20863         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20864                 error_not_in_vm "Speedup with willread is less than " \
20865                         "$lowest_speedup%, got $average_ladvise%"
20866 }
20867
20868 test_255a() {
20869         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20870                 skip "lustre < 2.8.54 does not support ladvise "
20871         remote_ost_nodsh && skip "remote OST with nodsh"
20872
20873         stack_trap "rm -f $DIR/$tfile"
20874         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20875
20876         ladvise_no_type willread $DIR/$tfile &&
20877                 skip "willread ladvise is not supported"
20878
20879         ladvise_no_ioctl $DIR/$tfile &&
20880                 skip "ladvise ioctl is not supported"
20881
20882         local size_mb=100
20883         local size=$((size_mb * 1048576))
20884         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20885                 error "dd to $DIR/$tfile failed"
20886
20887         lfs ladvise -a willread $DIR/$tfile ||
20888                 error "Ladvise failed with no range argument"
20889
20890         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20891                 error "Ladvise failed with no -l or -e argument"
20892
20893         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20894                 error "Ladvise failed with only -e argument"
20895
20896         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20897                 error "Ladvise failed with only -l argument"
20898
20899         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20900                 error "End offset should not be smaller than start offset"
20901
20902         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20903                 error "End offset should not be equal to start offset"
20904
20905         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20906                 error "Ladvise failed with overflowing -s argument"
20907
20908         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20909                 error "Ladvise failed with overflowing -e argument"
20910
20911         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20912                 error "Ladvise failed with overflowing -l argument"
20913
20914         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20915                 error "Ladvise succeeded with conflicting -l and -e arguments"
20916
20917         echo "Synchronous ladvise should wait"
20918         local delay=4
20919 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20920         do_nodes $(comma_list $(osts_nodes)) \
20921                 $LCTL set_param fail_val=$delay fail_loc=0x237
20922
20923         local start_ts=$SECONDS
20924         lfs ladvise -a willread $DIR/$tfile ||
20925                 error "Ladvise failed with no range argument"
20926         local end_ts=$SECONDS
20927         local inteval_ts=$((end_ts - start_ts))
20928
20929         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20930                 error "Synchronous advice didn't wait reply"
20931         fi
20932
20933         echo "Asynchronous ladvise shouldn't wait"
20934         local start_ts=$SECONDS
20935         lfs ladvise -a willread -b $DIR/$tfile ||
20936                 error "Ladvise failed with no range argument"
20937         local end_ts=$SECONDS
20938         local inteval_ts=$((end_ts - start_ts))
20939
20940         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20941                 error "Asynchronous advice blocked"
20942         fi
20943
20944         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20945         ladvise_willread_performance
20946 }
20947 run_test 255a "check 'lfs ladvise -a willread'"
20948
20949 facet_meminfo() {
20950         local facet=$1
20951         local info=$2
20952
20953         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20954 }
20955
20956 test_255b() {
20957         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20958                 skip "lustre < 2.8.54 does not support ladvise "
20959         remote_ost_nodsh && skip "remote OST with nodsh"
20960
20961         stack_trap "rm -f $DIR/$tfile"
20962         lfs setstripe -c 1 -i 0 $DIR/$tfile
20963
20964         ladvise_no_type dontneed $DIR/$tfile &&
20965                 skip "dontneed ladvise is not supported"
20966
20967         ladvise_no_ioctl $DIR/$tfile &&
20968                 skip "ladvise ioctl is not supported"
20969
20970         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20971                 [ "$ost1_FSTYPE" = "zfs" ] &&
20972                 skip "zfs-osd does not support 'ladvise dontneed'"
20973
20974         local size_mb=100
20975         local size=$((size_mb * 1048576))
20976         # In order to prevent disturbance of other processes, only check 3/4
20977         # of the memory usage
20978         local kibibytes=$((size_mb * 1024 * 3 / 4))
20979
20980         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20981                 error "dd to $DIR/$tfile failed"
20982
20983         #force write to complete before dropping OST cache & checking memory
20984         sync
20985
20986         local total=$(facet_meminfo ost1 MemTotal)
20987         echo "Total memory: $total KiB"
20988
20989         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20990         local before_read=$(facet_meminfo ost1 Cached)
20991         echo "Cache used before read: $before_read KiB"
20992
20993         lfs ladvise -a willread $DIR/$tfile ||
20994                 error "Ladvise willread failed"
20995         local after_read=$(facet_meminfo ost1 Cached)
20996         echo "Cache used after read: $after_read KiB"
20997
20998         lfs ladvise -a dontneed $DIR/$tfile ||
20999                 error "Ladvise dontneed again failed"
21000         local no_read=$(facet_meminfo ost1 Cached)
21001         echo "Cache used after dontneed ladvise: $no_read KiB"
21002
21003         if [ $total -lt $((before_read + kibibytes)) ]; then
21004                 echo "Memory is too small, abort checking"
21005                 return 0
21006         fi
21007
21008         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21009                 error "Ladvise willread should use more memory" \
21010                         "than $kibibytes KiB"
21011         fi
21012
21013         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21014                 error "Ladvise dontneed should release more memory" \
21015                         "than $kibibytes KiB"
21016         fi
21017 }
21018 run_test 255b "check 'lfs ladvise -a dontneed'"
21019
21020 test_255c() {
21021         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21022                 skip "lustre < 2.10.50 does not support lockahead"
21023
21024         local ost1_imp=$(get_osc_import_name client ost1)
21025         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21026                          cut -d'.' -f2)
21027         local count
21028         local new_count
21029         local difference
21030         local i
21031         local rc
21032
21033         test_mkdir -p $DIR/$tdir
21034         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21035
21036         #test 10 returns only success/failure
21037         i=10
21038         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21039         rc=$?
21040         if [ $rc -eq 255 ]; then
21041                 error "Ladvise test${i} failed, ${rc}"
21042         fi
21043
21044         #test 11 counts lock enqueue requests, all others count new locks
21045         i=11
21046         count=$(do_facet ost1 \
21047                 $LCTL get_param -n ost.OSS.ost.stats)
21048         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21049
21050         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21051         rc=$?
21052         if [ $rc -eq 255 ]; then
21053                 error "Ladvise test${i} failed, ${rc}"
21054         fi
21055
21056         new_count=$(do_facet ost1 \
21057                 $LCTL get_param -n ost.OSS.ost.stats)
21058         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21059                    awk '{ print $2 }')
21060
21061         difference="$((new_count - count))"
21062         if [ $difference -ne $rc ]; then
21063                 error "Ladvise test${i}, bad enqueue count, returned " \
21064                       "${rc}, actual ${difference}"
21065         fi
21066
21067         for i in $(seq 12 21); do
21068                 # If we do not do this, we run the risk of having too many
21069                 # locks and starting lock cancellation while we are checking
21070                 # lock counts.
21071                 cancel_lru_locks osc
21072
21073                 count=$($LCTL get_param -n \
21074                        ldlm.namespaces.$imp_name.lock_unused_count)
21075
21076                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21077                 rc=$?
21078                 if [ $rc -eq 255 ]; then
21079                         error "Ladvise test ${i} failed, ${rc}"
21080                 fi
21081
21082                 new_count=$($LCTL get_param -n \
21083                        ldlm.namespaces.$imp_name.lock_unused_count)
21084                 difference="$((new_count - count))"
21085
21086                 # Test 15 output is divided by 100 to map down to valid return
21087                 if [ $i -eq 15 ]; then
21088                         rc="$((rc * 100))"
21089                 fi
21090
21091                 if [ $difference -ne $rc ]; then
21092                         error "Ladvise test ${i}, bad lock count, returned " \
21093                               "${rc}, actual ${difference}"
21094                 fi
21095         done
21096
21097         #test 22 returns only success/failure
21098         i=22
21099         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21100         rc=$?
21101         if [ $rc -eq 255 ]; then
21102                 error "Ladvise test${i} failed, ${rc}"
21103         fi
21104 }
21105 run_test 255c "suite of ladvise lockahead tests"
21106
21107 test_256() {
21108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21109         remote_mds_nodsh && skip "remote MDS with nodsh"
21110         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21111         changelog_users $SINGLEMDS | grep "^cl" &&
21112                 skip "active changelog user"
21113
21114         local cl_user
21115         local cat_sl
21116         local mdt_dev
21117
21118         mdt_dev=$(mdsdevname 1)
21119         echo $mdt_dev
21120
21121         changelog_register || error "changelog_register failed"
21122
21123         rm -rf $DIR/$tdir
21124         mkdir_on_mdt0 $DIR/$tdir
21125
21126         changelog_clear 0 || error "changelog_clear failed"
21127
21128         # change something
21129         touch $DIR/$tdir/{1..10}
21130
21131         # stop the MDT
21132         stop $SINGLEMDS || error "Fail to stop MDT"
21133
21134         # remount the MDT
21135
21136         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21137
21138         #after mount new plainllog is used
21139         touch $DIR/$tdir/{11..19}
21140         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21141         stack_trap "rm -f $tmpfile"
21142         cat_sl=$(do_facet $SINGLEMDS "sync; \
21143                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21144                  llog_reader $tmpfile | grep -c type=1064553b")
21145         do_facet $SINGLEMDS llog_reader $tmpfile
21146
21147         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21148
21149         changelog_clear 0 || error "changelog_clear failed"
21150
21151         cat_sl=$(do_facet $SINGLEMDS "sync; \
21152                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21153                  llog_reader $tmpfile | grep -c type=1064553b")
21154
21155         if (( cat_sl == 2 )); then
21156                 error "Empty plain llog was not deleted from changelog catalog"
21157         elif (( cat_sl != 1 )); then
21158                 error "Active plain llog shouldn't be deleted from catalog"
21159         fi
21160 }
21161 run_test 256 "Check llog delete for empty and not full state"
21162
21163 test_257() {
21164         remote_mds_nodsh && skip "remote MDS with nodsh"
21165         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21166                 skip "Need MDS version at least 2.8.55"
21167
21168         test_mkdir $DIR/$tdir
21169
21170         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21171                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21172         stat $DIR/$tdir
21173
21174 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21175         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21176         local facet=mds$((mdtidx + 1))
21177         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21178         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21179
21180         stop $facet || error "stop MDS failed"
21181         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21182                 error "start MDS fail"
21183         wait_recovery_complete $facet
21184 }
21185 run_test 257 "xattr locks are not lost"
21186
21187 # Verify we take the i_mutex when security requires it
21188 test_258a() {
21189 #define OBD_FAIL_IMUTEX_SEC 0x141c
21190         $LCTL set_param fail_loc=0x141c
21191         touch $DIR/$tfile
21192         chmod u+s $DIR/$tfile
21193         chmod a+rwx $DIR/$tfile
21194         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21195         RC=$?
21196         if [ $RC -ne 0 ]; then
21197                 error "error, failed to take i_mutex, rc=$?"
21198         fi
21199         rm -f $DIR/$tfile
21200 }
21201 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21202
21203 # Verify we do NOT take the i_mutex in the normal case
21204 test_258b() {
21205 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21206         $LCTL set_param fail_loc=0x141d
21207         touch $DIR/$tfile
21208         chmod a+rwx $DIR
21209         chmod a+rw $DIR/$tfile
21210         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21211         RC=$?
21212         if [ $RC -ne 0 ]; then
21213                 error "error, took i_mutex unnecessarily, rc=$?"
21214         fi
21215         rm -f $DIR/$tfile
21216
21217 }
21218 run_test 258b "verify i_mutex security behavior"
21219
21220 test_259() {
21221         local file=$DIR/$tfile
21222         local before
21223         local after
21224
21225         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21226
21227         stack_trap "rm -f $file" EXIT
21228
21229         wait_delete_completed
21230         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21231         echo "before: $before"
21232
21233         $LFS setstripe -i 0 -c 1 $file
21234         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21235         sync_all_data
21236         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21237         echo "after write: $after"
21238
21239 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21240         do_facet ost1 $LCTL set_param fail_loc=0x2301
21241         $TRUNCATE $file 0
21242         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21243         echo "after truncate: $after"
21244
21245         stop ost1
21246         do_facet ost1 $LCTL set_param fail_loc=0
21247         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21248         sleep 2
21249         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21250         echo "after restart: $after"
21251         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21252                 error "missing truncate?"
21253
21254         return 0
21255 }
21256 run_test 259 "crash at delayed truncate"
21257
21258 test_260() {
21259 #define OBD_FAIL_MDC_CLOSE               0x806
21260         $LCTL set_param fail_loc=0x80000806
21261         touch $DIR/$tfile
21262
21263 }
21264 run_test 260 "Check mdc_close fail"
21265
21266 ### Data-on-MDT sanity tests ###
21267 test_270a() {
21268         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21269                 skip "Need MDS version at least 2.10.55 for DoM"
21270
21271         # create DoM file
21272         local dom=$DIR/$tdir/dom_file
21273         local tmp=$DIR/$tdir/tmp_file
21274
21275         mkdir_on_mdt0 $DIR/$tdir
21276
21277         # basic checks for DoM component creation
21278         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21279                 error "Can set MDT layout to non-first entry"
21280
21281         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21282                 error "Can define multiple entries as MDT layout"
21283
21284         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21285
21286         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21287         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21288         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21289
21290         local mdtidx=$($LFS getstripe -m $dom)
21291         local mdtname=MDT$(printf %04x $mdtidx)
21292         local facet=mds$((mdtidx + 1))
21293         local space_check=1
21294
21295         # Skip free space checks with ZFS
21296         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21297
21298         # write
21299         sync
21300         local size_tmp=$((65536 * 3))
21301         local mdtfree1=$(do_facet $facet \
21302                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21303
21304         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21305         # check also direct IO along write
21306         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21307         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21308         sync
21309         cmp $tmp $dom || error "file data is different"
21310         [ $(stat -c%s $dom) == $size_tmp ] ||
21311                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21312         if [ $space_check == 1 ]; then
21313                 local mdtfree2=$(do_facet $facet \
21314                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21315
21316                 # increase in usage from by $size_tmp
21317                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21318                         error "MDT free space wrong after write: " \
21319                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21320         fi
21321
21322         # truncate
21323         local size_dom=10000
21324
21325         $TRUNCATE $dom $size_dom
21326         [ $(stat -c%s $dom) == $size_dom ] ||
21327                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21328         if [ $space_check == 1 ]; then
21329                 mdtfree1=$(do_facet $facet \
21330                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21331                 # decrease in usage from $size_tmp to new $size_dom
21332                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21333                   $(((size_tmp - size_dom) / 1024)) ] ||
21334                         error "MDT free space is wrong after truncate: " \
21335                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21336         fi
21337
21338         # append
21339         cat $tmp >> $dom
21340         sync
21341         size_dom=$((size_dom + size_tmp))
21342         [ $(stat -c%s $dom) == $size_dom ] ||
21343                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21344         if [ $space_check == 1 ]; then
21345                 mdtfree2=$(do_facet $facet \
21346                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21347                 # increase in usage by $size_tmp from previous
21348                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21349                         error "MDT free space is wrong after append: " \
21350                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21351         fi
21352
21353         # delete
21354         rm $dom
21355         if [ $space_check == 1 ]; then
21356                 mdtfree1=$(do_facet $facet \
21357                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21358                 # decrease in usage by $size_dom from previous
21359                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21360                         error "MDT free space is wrong after removal: " \
21361                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21362         fi
21363
21364         # combined striping
21365         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21366                 error "Can't create DoM + OST striping"
21367
21368         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21369         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21370         # check also direct IO along write
21371         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21372         sync
21373         cmp $tmp $dom || error "file data is different"
21374         [ $(stat -c%s $dom) == $size_tmp ] ||
21375                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21376         rm $dom $tmp
21377
21378         return 0
21379 }
21380 run_test 270a "DoM: basic functionality tests"
21381
21382 test_270b() {
21383         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21384                 skip "Need MDS version at least 2.10.55"
21385
21386         local dom=$DIR/$tdir/dom_file
21387         local max_size=1048576
21388
21389         mkdir -p $DIR/$tdir
21390         $LFS setstripe -E $max_size -L mdt $dom
21391
21392         # truncate over the limit
21393         $TRUNCATE $dom $(($max_size + 1)) &&
21394                 error "successful truncate over the maximum size"
21395         # write over the limit
21396         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21397                 error "successful write over the maximum size"
21398         # append over the limit
21399         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21400         echo "12345" >> $dom && error "successful append over the maximum size"
21401         rm $dom
21402
21403         return 0
21404 }
21405 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21406
21407 test_270c() {
21408         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21409                 skip "Need MDS version at least 2.10.55"
21410
21411         mkdir -p $DIR/$tdir
21412         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21413
21414         # check files inherit DoM EA
21415         touch $DIR/$tdir/first
21416         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21417                 error "bad pattern"
21418         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21419                 error "bad stripe count"
21420         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21421                 error "bad stripe size"
21422
21423         # check directory inherits DoM EA and uses it as default
21424         mkdir $DIR/$tdir/subdir
21425         touch $DIR/$tdir/subdir/second
21426         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21427                 error "bad pattern in sub-directory"
21428         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21429                 error "bad stripe count in sub-directory"
21430         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21431                 error "bad stripe size in sub-directory"
21432         return 0
21433 }
21434 run_test 270c "DoM: DoM EA inheritance tests"
21435
21436 test_270d() {
21437         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21438                 skip "Need MDS version at least 2.10.55"
21439
21440         mkdir -p $DIR/$tdir
21441         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21442
21443         # inherit default DoM striping
21444         mkdir $DIR/$tdir/subdir
21445         touch $DIR/$tdir/subdir/f1
21446
21447         # change default directory striping
21448         $LFS setstripe -c 1 $DIR/$tdir/subdir
21449         touch $DIR/$tdir/subdir/f2
21450         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21451                 error "wrong default striping in file 2"
21452         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21453                 error "bad pattern in file 2"
21454         return 0
21455 }
21456 run_test 270d "DoM: change striping from DoM to RAID0"
21457
21458 test_270e() {
21459         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21460                 skip "Need MDS version at least 2.10.55"
21461
21462         mkdir -p $DIR/$tdir/dom
21463         mkdir -p $DIR/$tdir/norm
21464         DOMFILES=20
21465         NORMFILES=10
21466         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21467         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21468
21469         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21470         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21471
21472         # find DoM files by layout
21473         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21474         [ $NUM -eq  $DOMFILES ] ||
21475                 error "lfs find -L: found $NUM, expected $DOMFILES"
21476         echo "Test 1: lfs find 20 DOM files by layout: OK"
21477
21478         # there should be 1 dir with default DOM striping
21479         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21480         [ $NUM -eq  1 ] ||
21481                 error "lfs find -L: found $NUM, expected 1 dir"
21482         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21483
21484         # find DoM files by stripe size
21485         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21486         [ $NUM -eq  $DOMFILES ] ||
21487                 error "lfs find -S: found $NUM, expected $DOMFILES"
21488         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21489
21490         # find files by stripe offset except DoM files
21491         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21492         [ $NUM -eq  $NORMFILES ] ||
21493                 error "lfs find -i: found $NUM, expected $NORMFILES"
21494         echo "Test 5: lfs find no DOM files by stripe index: OK"
21495         return 0
21496 }
21497 run_test 270e "DoM: lfs find with DoM files test"
21498
21499 test_270f() {
21500         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21501                 skip "Need MDS version at least 2.10.55"
21502
21503         local mdtname=${FSNAME}-MDT0000-mdtlov
21504         local dom=$DIR/$tdir/dom_file
21505         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21506                                                 lod.$mdtname.dom_stripesize)
21507         local dom_limit=131072
21508
21509         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21510         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21511                                                 lod.$mdtname.dom_stripesize)
21512         [ ${dom_limit} -eq ${dom_current} ] ||
21513                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21514
21515         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21516         $LFS setstripe -d $DIR/$tdir
21517         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21518                 error "Can't set directory default striping"
21519
21520         # exceed maximum stripe size
21521         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21522                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21523         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21524                 error "Able to create DoM component size more than LOD limit"
21525
21526         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21527         dom_current=$(do_facet mds1 $LCTL get_param -n \
21528                                                 lod.$mdtname.dom_stripesize)
21529         [ 0 -eq ${dom_current} ] ||
21530                 error "Can't set zero DoM stripe limit"
21531         rm $dom
21532
21533         # attempt to create DoM file on server with disabled DoM should
21534         # remove DoM entry from layout and be succeed
21535         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21536                 error "Can't create DoM file (DoM is disabled)"
21537         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21538                 error "File has DoM component while DoM is disabled"
21539         rm $dom
21540
21541         # attempt to create DoM file with only DoM stripe should return error
21542         $LFS setstripe -E $dom_limit -L mdt $dom &&
21543                 error "Able to create DoM-only file while DoM is disabled"
21544
21545         # too low values to be aligned with smallest stripe size 64K
21546         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21547         dom_current=$(do_facet mds1 $LCTL get_param -n \
21548                                                 lod.$mdtname.dom_stripesize)
21549         [ 30000 -eq ${dom_current} ] &&
21550                 error "Can set too small DoM stripe limit"
21551
21552         # 64K is a minimal stripe size in Lustre, expect limit of that size
21553         [ 65536 -eq ${dom_current} ] ||
21554                 error "Limit is not set to 64K but ${dom_current}"
21555
21556         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21557         dom_current=$(do_facet mds1 $LCTL get_param -n \
21558                                                 lod.$mdtname.dom_stripesize)
21559         echo $dom_current
21560         [ 2147483648 -eq ${dom_current} ] &&
21561                 error "Can set too large DoM stripe limit"
21562
21563         do_facet mds1 $LCTL set_param -n \
21564                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21565         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21566                 error "Can't create DoM component size after limit change"
21567         do_facet mds1 $LCTL set_param -n \
21568                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21569         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21570                 error "Can't create DoM file after limit decrease"
21571         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21572                 error "Can create big DoM component after limit decrease"
21573         touch ${dom}_def ||
21574                 error "Can't create file with old default layout"
21575
21576         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21577         return 0
21578 }
21579 run_test 270f "DoM: maximum DoM stripe size checks"
21580
21581 test_270g() {
21582         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21583                 skip "Need MDS version at least 2.13.52"
21584         local dom=$DIR/$tdir/$tfile
21585
21586         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21587         local lodname=${FSNAME}-MDT0000-mdtlov
21588
21589         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21590         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21591         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21592         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21593
21594         local dom_limit=1024
21595         local dom_threshold="50%"
21596
21597         $LFS setstripe -d $DIR/$tdir
21598         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21599                 error "Can't set directory default striping"
21600
21601         do_facet mds1 $LCTL set_param -n \
21602                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21603         # set 0 threshold and create DOM file to change tunable stripesize
21604         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21605         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21606                 error "Failed to create $dom file"
21607         # now tunable dom_cur_stripesize should reach maximum
21608         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21609                                         lod.${lodname}.dom_stripesize_cur_kb)
21610         [[ $dom_current == $dom_limit ]] ||
21611                 error "Current DOM stripesize is not maximum"
21612         rm $dom
21613
21614         # set threshold for further tests
21615         do_facet mds1 $LCTL set_param -n \
21616                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21617         echo "DOM threshold is $dom_threshold free space"
21618         local dom_def
21619         local dom_set
21620         # Spoof bfree to exceed threshold
21621         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21622         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21623         for spfree in 40 20 0 15 30 55; do
21624                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21625                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21626                         error "Failed to create $dom file"
21627                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21628                                         lod.${lodname}.dom_stripesize_cur_kb)
21629                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21630                 [[ $dom_def != $dom_current ]] ||
21631                         error "Default stripe size was not changed"
21632                 if [[ $spfree > 0 ]] ; then
21633                         dom_set=$($LFS getstripe -S $dom)
21634                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21635                                 error "DOM component size is still old"
21636                 else
21637                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21638                                 error "DoM component is set with no free space"
21639                 fi
21640                 rm $dom
21641                 dom_current=$dom_def
21642         done
21643 }
21644 run_test 270g "DoM: default DoM stripe size depends on free space"
21645
21646 test_270h() {
21647         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21648                 skip "Need MDS version at least 2.13.53"
21649
21650         local mdtname=${FSNAME}-MDT0000-mdtlov
21651         local dom=$DIR/$tdir/$tfile
21652         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21653
21654         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21655         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21656
21657         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21658         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21659                 error "can't create OST file"
21660         # mirrored file with DOM entry in the second mirror
21661         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21662                 error "can't create mirror with DoM component"
21663
21664         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21665
21666         # DOM component in the middle and has other enries in the same mirror,
21667         # should succeed but lost DoM component
21668         $LFS setstripe --copy=${dom}_1 $dom ||
21669                 error "Can't create file from OST|DOM mirror layout"
21670         # check new file has no DoM layout after all
21671         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21672                 error "File has DoM component while DoM is disabled"
21673 }
21674 run_test 270h "DoM: DoM stripe removal when disabled on server"
21675
21676 test_271a() {
21677         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21678                 skip "Need MDS version at least 2.10.55"
21679
21680         local dom=$DIR/$tdir/dom
21681
21682         mkdir -p $DIR/$tdir
21683
21684         $LFS setstripe -E 1024K -L mdt $dom
21685
21686         lctl set_param -n mdc.*.stats=clear
21687         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21688         cat $dom > /dev/null
21689         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21690         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21691         ls $dom
21692         rm -f $dom
21693 }
21694 run_test 271a "DoM: data is cached for read after write"
21695
21696 test_271b() {
21697         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21698                 skip "Need MDS version at least 2.10.55"
21699
21700         local dom=$DIR/$tdir/dom
21701
21702         mkdir -p $DIR/$tdir
21703
21704         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21705
21706         lctl set_param -n mdc.*.stats=clear
21707         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21708         cancel_lru_locks mdc
21709         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21710         # second stat to check size is cached on client
21711         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21712         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21713         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21714         rm -f $dom
21715 }
21716 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21717
21718 test_271ba() {
21719         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21720                 skip "Need MDS version at least 2.10.55"
21721
21722         local dom=$DIR/$tdir/dom
21723
21724         mkdir -p $DIR/$tdir
21725
21726         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21727
21728         lctl set_param -n mdc.*.stats=clear
21729         lctl set_param -n osc.*.stats=clear
21730         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21731         cancel_lru_locks mdc
21732         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21733         # second stat to check size is cached on client
21734         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21735         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21736         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21737         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21738         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21739         rm -f $dom
21740 }
21741 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21742
21743
21744 get_mdc_stats() {
21745         local mdtidx=$1
21746         local param=$2
21747         local mdt=MDT$(printf %04x $mdtidx)
21748
21749         if [ -z $param ]; then
21750                 lctl get_param -n mdc.*$mdt*.stats
21751         else
21752                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21753         fi
21754 }
21755
21756 test_271c() {
21757         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21758                 skip "Need MDS version at least 2.10.55"
21759
21760         local dom=$DIR/$tdir/dom
21761
21762         mkdir -p $DIR/$tdir
21763
21764         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21765
21766         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21767         local facet=mds$((mdtidx + 1))
21768
21769         cancel_lru_locks mdc
21770         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21771         createmany -o $dom 1000
21772         lctl set_param -n mdc.*.stats=clear
21773         smalliomany -w $dom 1000 200
21774         get_mdc_stats $mdtidx
21775         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21776         # Each file has 1 open, 1 IO enqueues, total 2000
21777         # but now we have also +1 getxattr for security.capability, total 3000
21778         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21779         unlinkmany $dom 1000
21780
21781         cancel_lru_locks mdc
21782         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21783         createmany -o $dom 1000
21784         lctl set_param -n mdc.*.stats=clear
21785         smalliomany -w $dom 1000 200
21786         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21787         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21788         # for OPEN and IO lock.
21789         [ $((enq - enq_2)) -ge 1000 ] ||
21790                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21791         unlinkmany $dom 1000
21792         return 0
21793 }
21794 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21795
21796 cleanup_271def_tests() {
21797         trap 0
21798         rm -f $1
21799 }
21800
21801 test_271d() {
21802         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21803                 skip "Need MDS version at least 2.10.57"
21804
21805         local dom=$DIR/$tdir/dom
21806         local tmp=$TMP/$tfile
21807         trap "cleanup_271def_tests $tmp" EXIT
21808
21809         mkdir -p $DIR/$tdir
21810
21811         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21812
21813         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21814
21815         cancel_lru_locks mdc
21816         dd if=/dev/urandom of=$tmp bs=1000 count=1
21817         dd if=$tmp of=$dom bs=1000 count=1
21818         cancel_lru_locks mdc
21819
21820         cat /etc/hosts >> $tmp
21821         lctl set_param -n mdc.*.stats=clear
21822
21823         # append data to the same file it should update local page
21824         echo "Append to the same page"
21825         cat /etc/hosts >> $dom
21826         local num=$(get_mdc_stats $mdtidx ost_read)
21827         local ra=$(get_mdc_stats $mdtidx req_active)
21828         local rw=$(get_mdc_stats $mdtidx req_waittime)
21829
21830         [ -z $num ] || error "$num READ RPC occured"
21831         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21832         echo "... DONE"
21833
21834         # compare content
21835         cmp $tmp $dom || error "file miscompare"
21836
21837         cancel_lru_locks mdc
21838         lctl set_param -n mdc.*.stats=clear
21839
21840         echo "Open and read file"
21841         cat $dom > /dev/null
21842         local num=$(get_mdc_stats $mdtidx ost_read)
21843         local ra=$(get_mdc_stats $mdtidx req_active)
21844         local rw=$(get_mdc_stats $mdtidx req_waittime)
21845
21846         [ -z $num ] || error "$num READ RPC occured"
21847         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21848         echo "... DONE"
21849
21850         # compare content
21851         cmp $tmp $dom || error "file miscompare"
21852
21853         return 0
21854 }
21855 run_test 271d "DoM: read on open (1K file in reply buffer)"
21856
21857 test_271f() {
21858         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21859                 skip "Need MDS version at least 2.10.57"
21860
21861         local dom=$DIR/$tdir/dom
21862         local tmp=$TMP/$tfile
21863         trap "cleanup_271def_tests $tmp" EXIT
21864
21865         mkdir -p $DIR/$tdir
21866
21867         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21868
21869         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21870
21871         cancel_lru_locks mdc
21872         dd if=/dev/urandom of=$tmp bs=265000 count=1
21873         dd if=$tmp of=$dom bs=265000 count=1
21874         cancel_lru_locks mdc
21875         cat /etc/hosts >> $tmp
21876         lctl set_param -n mdc.*.stats=clear
21877
21878         echo "Append to the same page"
21879         cat /etc/hosts >> $dom
21880         local num=$(get_mdc_stats $mdtidx ost_read)
21881         local ra=$(get_mdc_stats $mdtidx req_active)
21882         local rw=$(get_mdc_stats $mdtidx req_waittime)
21883
21884         [ -z $num ] || error "$num READ RPC occured"
21885         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21886         echo "... DONE"
21887
21888         # compare content
21889         cmp $tmp $dom || error "file miscompare"
21890
21891         cancel_lru_locks mdc
21892         lctl set_param -n mdc.*.stats=clear
21893
21894         echo "Open and read file"
21895         cat $dom > /dev/null
21896         local num=$(get_mdc_stats $mdtidx ost_read)
21897         local ra=$(get_mdc_stats $mdtidx req_active)
21898         local rw=$(get_mdc_stats $mdtidx req_waittime)
21899
21900         [ -z $num ] && num=0
21901         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21902         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21903         echo "... DONE"
21904
21905         # compare content
21906         cmp $tmp $dom || error "file miscompare"
21907
21908         return 0
21909 }
21910 run_test 271f "DoM: read on open (200K file and read tail)"
21911
21912 test_271g() {
21913         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21914                 skip "Skipping due to old client or server version"
21915
21916         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21917         # to get layout
21918         $CHECKSTAT -t file $DIR1/$tfile
21919
21920         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21921         MULTIOP_PID=$!
21922         sleep 1
21923         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21924         $LCTL set_param fail_loc=0x80000314
21925         rm $DIR1/$tfile || error "Unlink fails"
21926         RC=$?
21927         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21928         [ $RC -eq 0 ] || error "Failed write to stale object"
21929 }
21930 run_test 271g "Discard DoM data vs client flush race"
21931
21932 test_272a() {
21933         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21934                 skip "Need MDS version at least 2.11.50"
21935
21936         local dom=$DIR/$tdir/dom
21937         mkdir -p $DIR/$tdir
21938
21939         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21940         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21941                 error "failed to write data into $dom"
21942         local old_md5=$(md5sum $dom)
21943
21944         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21945                 error "failed to migrate to the same DoM component"
21946
21947         local new_md5=$(md5sum $dom)
21948
21949         [ "$old_md5" == "$new_md5" ] ||
21950                 error "md5sum differ: $old_md5, $new_md5"
21951
21952         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21953                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21954 }
21955 run_test 272a "DoM migration: new layout with the same DOM component"
21956
21957 test_272b() {
21958         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21959                 skip "Need MDS version at least 2.11.50"
21960
21961         local dom=$DIR/$tdir/dom
21962         mkdir -p $DIR/$tdir
21963         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21964
21965         local mdtidx=$($LFS getstripe -m $dom)
21966         local mdtname=MDT$(printf %04x $mdtidx)
21967         local facet=mds$((mdtidx + 1))
21968
21969         local mdtfree1=$(do_facet $facet \
21970                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21971         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21972                 error "failed to write data into $dom"
21973         local old_md5=$(md5sum $dom)
21974         cancel_lru_locks mdc
21975         local mdtfree1=$(do_facet $facet \
21976                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21977
21978         $LFS migrate -c2 $dom ||
21979                 error "failed to migrate to the new composite layout"
21980         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21981                 error "MDT stripe was not removed"
21982
21983         cancel_lru_locks mdc
21984         local new_md5=$(md5sum $dom)
21985         [ "$old_md5" == "$new_md5" ] ||
21986                 error "$old_md5 != $new_md5"
21987
21988         # Skip free space checks with ZFS
21989         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21990                 local mdtfree2=$(do_facet $facet \
21991                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21992                 [ $mdtfree2 -gt $mdtfree1 ] ||
21993                         error "MDT space is not freed after migration"
21994         fi
21995         return 0
21996 }
21997 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21998
21999 test_272c() {
22000         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22001                 skip "Need MDS version at least 2.11.50"
22002
22003         local dom=$DIR/$tdir/$tfile
22004         mkdir -p $DIR/$tdir
22005         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22006
22007         local mdtidx=$($LFS getstripe -m $dom)
22008         local mdtname=MDT$(printf %04x $mdtidx)
22009         local facet=mds$((mdtidx + 1))
22010
22011         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22012                 error "failed to write data into $dom"
22013         local old_md5=$(md5sum $dom)
22014         cancel_lru_locks mdc
22015         local mdtfree1=$(do_facet $facet \
22016                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22017
22018         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22019                 error "failed to migrate to the new composite layout"
22020         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22021                 error "MDT stripe was not removed"
22022
22023         cancel_lru_locks mdc
22024         local new_md5=$(md5sum $dom)
22025         [ "$old_md5" == "$new_md5" ] ||
22026                 error "$old_md5 != $new_md5"
22027
22028         # Skip free space checks with ZFS
22029         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22030                 local mdtfree2=$(do_facet $facet \
22031                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22032                 [ $mdtfree2 -gt $mdtfree1 ] ||
22033                         error "MDS space is not freed after migration"
22034         fi
22035         return 0
22036 }
22037 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22038
22039 test_272d() {
22040         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22041                 skip "Need MDS version at least 2.12.55"
22042
22043         local dom=$DIR/$tdir/$tfile
22044         mkdir -p $DIR/$tdir
22045         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22046
22047         local mdtidx=$($LFS getstripe -m $dom)
22048         local mdtname=MDT$(printf %04x $mdtidx)
22049         local facet=mds$((mdtidx + 1))
22050
22051         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22052                 error "failed to write data into $dom"
22053         local old_md5=$(md5sum $dom)
22054         cancel_lru_locks mdc
22055         local mdtfree1=$(do_facet $facet \
22056                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22057
22058         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22059                 error "failed mirroring to the new composite layout"
22060         $LFS mirror resync $dom ||
22061                 error "failed mirror resync"
22062         $LFS mirror split --mirror-id 1 -d $dom ||
22063                 error "failed mirror split"
22064
22065         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22066                 error "MDT stripe was not removed"
22067
22068         cancel_lru_locks mdc
22069         local new_md5=$(md5sum $dom)
22070         [ "$old_md5" == "$new_md5" ] ||
22071                 error "$old_md5 != $new_md5"
22072
22073         # Skip free space checks with ZFS
22074         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22075                 local mdtfree2=$(do_facet $facet \
22076                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22077                 [ $mdtfree2 -gt $mdtfree1 ] ||
22078                         error "MDS space is not freed after DOM mirror deletion"
22079         fi
22080         return 0
22081 }
22082 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22083
22084 test_272e() {
22085         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22086                 skip "Need MDS version at least 2.12.55"
22087
22088         local dom=$DIR/$tdir/$tfile
22089         mkdir -p $DIR/$tdir
22090         $LFS setstripe -c 2 $dom
22091
22092         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22093                 error "failed to write data into $dom"
22094         local old_md5=$(md5sum $dom)
22095         cancel_lru_locks mdc
22096
22097         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22098                 error "failed mirroring to the DOM layout"
22099         $LFS mirror resync $dom ||
22100                 error "failed mirror resync"
22101         $LFS mirror split --mirror-id 1 -d $dom ||
22102                 error "failed mirror split"
22103
22104         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22105                 error "MDT stripe was not removed"
22106
22107         cancel_lru_locks mdc
22108         local new_md5=$(md5sum $dom)
22109         [ "$old_md5" == "$new_md5" ] ||
22110                 error "$old_md5 != $new_md5"
22111
22112         return 0
22113 }
22114 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22115
22116 test_272f() {
22117         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22118                 skip "Need MDS version at least 2.12.55"
22119
22120         local dom=$DIR/$tdir/$tfile
22121         mkdir -p $DIR/$tdir
22122         $LFS setstripe -c 2 $dom
22123
22124         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22125                 error "failed to write data into $dom"
22126         local old_md5=$(md5sum $dom)
22127         cancel_lru_locks mdc
22128
22129         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22130                 error "failed migrating to the DOM file"
22131
22132         cancel_lru_locks mdc
22133         local new_md5=$(md5sum $dom)
22134         [ "$old_md5" != "$new_md5" ] &&
22135                 error "$old_md5 != $new_md5"
22136
22137         return 0
22138 }
22139 run_test 272f "DoM migration: OST-striped file to DOM file"
22140
22141 test_273a() {
22142         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22143                 skip "Need MDS version at least 2.11.50"
22144
22145         # Layout swap cannot be done if either file has DOM component,
22146         # this will never be supported, migration should be used instead
22147
22148         local dom=$DIR/$tdir/$tfile
22149         mkdir -p $DIR/$tdir
22150
22151         $LFS setstripe -c2 ${dom}_plain
22152         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22153         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22154                 error "can swap layout with DoM component"
22155         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22156                 error "can swap layout with DoM component"
22157
22158         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22159         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22160                 error "can swap layout with DoM component"
22161         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22162                 error "can swap layout with DoM component"
22163         return 0
22164 }
22165 run_test 273a "DoM: layout swapping should fail with DOM"
22166
22167 test_273b() {
22168         mkdir -p $DIR/$tdir
22169         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22170
22171 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22172         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22173
22174         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22175 }
22176 run_test 273b "DoM: race writeback and object destroy"
22177
22178 test_275() {
22179         remote_ost_nodsh && skip "remote OST with nodsh"
22180         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22181                 skip "Need OST version >= 2.10.57"
22182
22183         local file=$DIR/$tfile
22184         local oss
22185
22186         oss=$(comma_list $(osts_nodes))
22187
22188         dd if=/dev/urandom of=$file bs=1M count=2 ||
22189                 error "failed to create a file"
22190         cancel_lru_locks osc
22191
22192         #lock 1
22193         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22194                 error "failed to read a file"
22195
22196 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22197         $LCTL set_param fail_loc=0x8000031f
22198
22199         cancel_lru_locks osc &
22200         sleep 1
22201
22202 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22203         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22204         #IO takes another lock, but matches the PENDING one
22205         #and places it to the IO RPC
22206         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22207                 error "failed to read a file with PENDING lock"
22208 }
22209 run_test 275 "Read on a canceled duplicate lock"
22210
22211 test_276() {
22212         remote_ost_nodsh && skip "remote OST with nodsh"
22213         local pid
22214
22215         do_facet ost1 "(while true; do \
22216                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22217                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22218         pid=$!
22219
22220         for LOOP in $(seq 20); do
22221                 stop ost1
22222                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22223         done
22224         kill -9 $pid
22225         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22226                 rm $TMP/sanity_276_pid"
22227 }
22228 run_test 276 "Race between mount and obd_statfs"
22229
22230 test_277() {
22231         $LCTL set_param ldlm.namespaces.*.lru_size=0
22232         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22233         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22234                         grep ^used_mb | awk '{print $2}')
22235         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22236         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22237                 oflag=direct conv=notrunc
22238         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22239                         grep ^used_mb | awk '{print $2}')
22240         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22241 }
22242 run_test 277 "Direct IO shall drop page cache"
22243
22244 test_278() {
22245         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22246         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22247         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22248                 skip "needs the same host for mdt1 mdt2" && return
22249
22250         local pid1
22251         local pid2
22252
22253 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22254         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22255         stop mds2 &
22256         pid2=$!
22257
22258         stop mds1
22259
22260         echo "Starting MDTs"
22261         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22262         wait $pid2
22263 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22264 #will return NULL
22265         do_facet mds2 $LCTL set_param fail_loc=0
22266
22267         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22268         wait_recovery_complete mds2
22269 }
22270 run_test 278 "Race starting MDS between MDTs stop/start"
22271
22272 test_280() {
22273         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22274                 skip "Need MGS version at least 2.13.52"
22275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22276         combined_mgs_mds || skip "needs combined MGS/MDT"
22277
22278         umount_client $MOUNT
22279 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22280         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22281
22282         mount_client $MOUNT &
22283         sleep 1
22284         stop mgs || error "stop mgs failed"
22285         #for a race mgs would crash
22286         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22287         # make sure we unmount client before remounting
22288         wait
22289         umount_client $MOUNT
22290         mount_client $MOUNT || error "mount client failed"
22291 }
22292 run_test 280 "Race between MGS umount and client llog processing"
22293
22294 cleanup_test_300() {
22295         trap 0
22296         umask $SAVE_UMASK
22297 }
22298 test_striped_dir() {
22299         local mdt_index=$1
22300         local stripe_count
22301         local stripe_index
22302
22303         mkdir -p $DIR/$tdir
22304
22305         SAVE_UMASK=$(umask)
22306         trap cleanup_test_300 RETURN EXIT
22307
22308         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22309                                                 $DIR/$tdir/striped_dir ||
22310                 error "set striped dir error"
22311
22312         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22313         [ "$mode" = "755" ] || error "expect 755 got $mode"
22314
22315         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22316                 error "getdirstripe failed"
22317         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22318         if [ "$stripe_count" != "2" ]; then
22319                 error "1:stripe_count is $stripe_count, expect 2"
22320         fi
22321         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22322         if [ "$stripe_count" != "2" ]; then
22323                 error "2:stripe_count is $stripe_count, expect 2"
22324         fi
22325
22326         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22327         if [ "$stripe_index" != "$mdt_index" ]; then
22328                 error "stripe_index is $stripe_index, expect $mdt_index"
22329         fi
22330
22331         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22332                 error "nlink error after create striped dir"
22333
22334         mkdir $DIR/$tdir/striped_dir/a
22335         mkdir $DIR/$tdir/striped_dir/b
22336
22337         stat $DIR/$tdir/striped_dir/a ||
22338                 error "create dir under striped dir failed"
22339         stat $DIR/$tdir/striped_dir/b ||
22340                 error "create dir under striped dir failed"
22341
22342         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22343                 error "nlink error after mkdir"
22344
22345         rmdir $DIR/$tdir/striped_dir/a
22346         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22347                 error "nlink error after rmdir"
22348
22349         rmdir $DIR/$tdir/striped_dir/b
22350         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22351                 error "nlink error after rmdir"
22352
22353         chattr +i $DIR/$tdir/striped_dir
22354         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22355                 error "immutable flags not working under striped dir!"
22356         chattr -i $DIR/$tdir/striped_dir
22357
22358         rmdir $DIR/$tdir/striped_dir ||
22359                 error "rmdir striped dir error"
22360
22361         cleanup_test_300
22362
22363         true
22364 }
22365
22366 test_300a() {
22367         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22368                 skip "skipped for lustre < 2.7.0"
22369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22371
22372         test_striped_dir 0 || error "failed on striped dir on MDT0"
22373         test_striped_dir 1 || error "failed on striped dir on MDT0"
22374 }
22375 run_test 300a "basic striped dir sanity test"
22376
22377 test_300b() {
22378         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22379                 skip "skipped for lustre < 2.7.0"
22380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22382
22383         local i
22384         local mtime1
22385         local mtime2
22386         local mtime3
22387
22388         test_mkdir $DIR/$tdir || error "mkdir fail"
22389         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22390                 error "set striped dir error"
22391         for i in {0..9}; do
22392                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22393                 sleep 1
22394                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22395                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22396                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22397                 sleep 1
22398                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22399                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22400                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22401         done
22402         true
22403 }
22404 run_test 300b "check ctime/mtime for striped dir"
22405
22406 test_300c() {
22407         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22408                 skip "skipped for lustre < 2.7.0"
22409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22411
22412         local file_count
22413
22414         mkdir_on_mdt0 $DIR/$tdir
22415         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22416                 error "set striped dir error"
22417
22418         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22419                 error "chown striped dir failed"
22420
22421         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22422                 error "create 5k files failed"
22423
22424         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22425
22426         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22427
22428         rm -rf $DIR/$tdir
22429 }
22430 run_test 300c "chown && check ls under striped directory"
22431
22432 test_300d() {
22433         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22434                 skip "skipped for lustre < 2.7.0"
22435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22437
22438         local stripe_count
22439         local file
22440
22441         mkdir -p $DIR/$tdir
22442         $LFS setstripe -c 2 $DIR/$tdir
22443
22444         #local striped directory
22445         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22446                 error "set striped dir error"
22447         #look at the directories for debug purposes
22448         ls -l $DIR/$tdir
22449         $LFS getdirstripe $DIR/$tdir
22450         ls -l $DIR/$tdir/striped_dir
22451         $LFS getdirstripe $DIR/$tdir/striped_dir
22452         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22453                 error "create 10 files failed"
22454
22455         #remote striped directory
22456         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22457                 error "set striped dir error"
22458         #look at the directories for debug purposes
22459         ls -l $DIR/$tdir
22460         $LFS getdirstripe $DIR/$tdir
22461         ls -l $DIR/$tdir/remote_striped_dir
22462         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22463         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22464                 error "create 10 files failed"
22465
22466         for file in $(find $DIR/$tdir); do
22467                 stripe_count=$($LFS getstripe -c $file)
22468                 [ $stripe_count -eq 2 ] ||
22469                         error "wrong stripe $stripe_count for $file"
22470         done
22471
22472         rm -rf $DIR/$tdir
22473 }
22474 run_test 300d "check default stripe under striped directory"
22475
22476 test_300e() {
22477         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22478                 skip "Need MDS version at least 2.7.55"
22479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22481
22482         local stripe_count
22483         local file
22484
22485         mkdir -p $DIR/$tdir
22486
22487         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22488                 error "set striped dir error"
22489
22490         touch $DIR/$tdir/striped_dir/a
22491         touch $DIR/$tdir/striped_dir/b
22492         touch $DIR/$tdir/striped_dir/c
22493
22494         mkdir $DIR/$tdir/striped_dir/dir_a
22495         mkdir $DIR/$tdir/striped_dir/dir_b
22496         mkdir $DIR/$tdir/striped_dir/dir_c
22497
22498         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22499                 error "set striped adir under striped dir error"
22500
22501         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22502                 error "set striped bdir under striped dir error"
22503
22504         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22505                 error "set striped cdir under striped dir error"
22506
22507         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22508                 error "rename dir under striped dir fails"
22509
22510         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22511                 error "rename dir under different stripes fails"
22512
22513         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22514                 error "rename file under striped dir should succeed"
22515
22516         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22517                 error "rename dir under striped dir should succeed"
22518
22519         rm -rf $DIR/$tdir
22520 }
22521 run_test 300e "check rename under striped directory"
22522
22523 test_300f() {
22524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22526         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22527                 skip "Need MDS version at least 2.7.55"
22528
22529         local stripe_count
22530         local file
22531
22532         rm -rf $DIR/$tdir
22533         mkdir -p $DIR/$tdir
22534
22535         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22536                 error "set striped dir error"
22537
22538         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22539                 error "set striped dir error"
22540
22541         touch $DIR/$tdir/striped_dir/a
22542         mkdir $DIR/$tdir/striped_dir/dir_a
22543         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22544                 error "create striped dir under striped dir fails"
22545
22546         touch $DIR/$tdir/striped_dir1/b
22547         mkdir $DIR/$tdir/striped_dir1/dir_b
22548         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22549                 error "create striped dir under striped dir fails"
22550
22551         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22552                 error "rename dir under different striped dir should fail"
22553
22554         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22555                 error "rename striped dir under diff striped dir should fail"
22556
22557         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22558                 error "rename file under diff striped dirs fails"
22559
22560         rm -rf $DIR/$tdir
22561 }
22562 run_test 300f "check rename cross striped directory"
22563
22564 test_300_check_default_striped_dir()
22565 {
22566         local dirname=$1
22567         local default_count=$2
22568         local default_index=$3
22569         local stripe_count
22570         local stripe_index
22571         local dir_stripe_index
22572         local dir
22573
22574         echo "checking $dirname $default_count $default_index"
22575         $LFS setdirstripe -D -c $default_count -i $default_index \
22576                                 -H all_char $DIR/$tdir/$dirname ||
22577                 error "set default stripe on striped dir error"
22578         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22579         [ $stripe_count -eq $default_count ] ||
22580                 error "expect $default_count get $stripe_count for $dirname"
22581
22582         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22583         [ $stripe_index -eq $default_index ] ||
22584                 error "expect $default_index get $stripe_index for $dirname"
22585
22586         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22587                                                 error "create dirs failed"
22588
22589         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22590         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22591         for dir in $(find $DIR/$tdir/$dirname/*); do
22592                 stripe_count=$($LFS getdirstripe -c $dir)
22593                 (( $stripe_count == $default_count )) ||
22594                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22595                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22596                 error "stripe count $default_count != $stripe_count for $dir"
22597
22598                 stripe_index=$($LFS getdirstripe -i $dir)
22599                 [ $default_index -eq -1 ] ||
22600                         [ $stripe_index -eq $default_index ] ||
22601                         error "$stripe_index != $default_index for $dir"
22602
22603                 #check default stripe
22604                 stripe_count=$($LFS getdirstripe -D -c $dir)
22605                 [ $stripe_count -eq $default_count ] ||
22606                 error "default count $default_count != $stripe_count for $dir"
22607
22608                 stripe_index=$($LFS getdirstripe -D -i $dir)
22609                 [ $stripe_index -eq $default_index ] ||
22610                 error "default index $default_index != $stripe_index for $dir"
22611         done
22612         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22613 }
22614
22615 test_300g() {
22616         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22617         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22618                 skip "Need MDS version at least 2.7.55"
22619
22620         local dir
22621         local stripe_count
22622         local stripe_index
22623
22624         mkdir_on_mdt0 $DIR/$tdir
22625         mkdir $DIR/$tdir/normal_dir
22626
22627         #Checking when client cache stripe index
22628         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22629         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22630                 error "create striped_dir failed"
22631
22632         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22633                 error "create dir0 fails"
22634         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22635         [ $stripe_index -eq 0 ] ||
22636                 error "dir0 expect index 0 got $stripe_index"
22637
22638         mkdir $DIR/$tdir/striped_dir/dir1 ||
22639                 error "create dir1 fails"
22640         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22641         [ $stripe_index -eq 1 ] ||
22642                 error "dir1 expect index 1 got $stripe_index"
22643
22644         #check default stripe count/stripe index
22645         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22646         test_300_check_default_striped_dir normal_dir 1 0
22647         test_300_check_default_striped_dir normal_dir -1 1
22648         test_300_check_default_striped_dir normal_dir 2 -1
22649
22650         #delete default stripe information
22651         echo "delete default stripeEA"
22652         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22653                 error "set default stripe on striped dir error"
22654
22655         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22656         for dir in $(find $DIR/$tdir/normal_dir/*); do
22657                 stripe_count=$($LFS getdirstripe -c $dir)
22658                 [ $stripe_count -eq 0 ] ||
22659                         error "expect 1 get $stripe_count for $dir"
22660         done
22661 }
22662 run_test 300g "check default striped directory for normal directory"
22663
22664 test_300h() {
22665         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22666         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22667                 skip "Need MDS version at least 2.7.55"
22668
22669         local dir
22670         local stripe_count
22671
22672         mkdir $DIR/$tdir
22673         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22674                 error "set striped dir error"
22675
22676         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22677         test_300_check_default_striped_dir striped_dir 1 0
22678         test_300_check_default_striped_dir striped_dir -1 1
22679         test_300_check_default_striped_dir striped_dir 2 -1
22680
22681         #delete default stripe information
22682         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22683                 error "set default stripe on striped dir error"
22684
22685         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22686         for dir in $(find $DIR/$tdir/striped_dir/*); do
22687                 stripe_count=$($LFS getdirstripe -c $dir)
22688                 [ $stripe_count -eq 0 ] ||
22689                         error "expect 1 get $stripe_count for $dir"
22690         done
22691 }
22692 run_test 300h "check default striped directory for striped directory"
22693
22694 test_300i() {
22695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22697         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22698                 skip "Need MDS version at least 2.7.55"
22699
22700         local stripe_count
22701         local file
22702
22703         mkdir $DIR/$tdir
22704
22705         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22706                 error "set striped dir error"
22707
22708         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22709                 error "create files under striped dir failed"
22710
22711         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22712                 error "set striped hashdir error"
22713
22714         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22715                 error "create dir0 under hash dir failed"
22716         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22717                 error "create dir1 under hash dir failed"
22718         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22719                 error "create dir2 under hash dir failed"
22720
22721         # unfortunately, we need to umount to clear dir layout cache for now
22722         # once we fully implement dir layout, we can drop this
22723         umount_client $MOUNT || error "umount failed"
22724         mount_client $MOUNT || error "mount failed"
22725
22726         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22727         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22728         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22729
22730         #set the stripe to be unknown hash type
22731         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22732         $LCTL set_param fail_loc=0x1901
22733         for ((i = 0; i < 10; i++)); do
22734                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22735                         error "stat f-$i failed"
22736                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22737         done
22738
22739         touch $DIR/$tdir/striped_dir/f0 &&
22740                 error "create under striped dir with unknown hash should fail"
22741
22742         $LCTL set_param fail_loc=0
22743
22744         umount_client $MOUNT || error "umount failed"
22745         mount_client $MOUNT || error "mount failed"
22746
22747         return 0
22748 }
22749 run_test 300i "client handle unknown hash type striped directory"
22750
22751 test_300j() {
22752         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22754         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22755                 skip "Need MDS version at least 2.7.55"
22756
22757         local stripe_count
22758         local file
22759
22760         mkdir $DIR/$tdir
22761
22762         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22763         $LCTL set_param fail_loc=0x1702
22764         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22765                 error "set striped dir error"
22766
22767         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22768                 error "create files under striped dir failed"
22769
22770         $LCTL set_param fail_loc=0
22771
22772         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22773
22774         return 0
22775 }
22776 run_test 300j "test large update record"
22777
22778 test_300k() {
22779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22780         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22781         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22782                 skip "Need MDS version at least 2.7.55"
22783
22784         # this test needs a huge transaction
22785         local kb
22786         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22787              osd*.$FSNAME-MDT0000.kbytestotal")
22788         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22789
22790         local stripe_count
22791         local file
22792
22793         mkdir $DIR/$tdir
22794
22795         #define OBD_FAIL_LARGE_STRIPE   0x1703
22796         $LCTL set_param fail_loc=0x1703
22797         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22798                 error "set striped dir error"
22799         $LCTL set_param fail_loc=0
22800
22801         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22802                 error "getstripeddir fails"
22803         rm -rf $DIR/$tdir/striped_dir ||
22804                 error "unlink striped dir fails"
22805
22806         return 0
22807 }
22808 run_test 300k "test large striped directory"
22809
22810 test_300l() {
22811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22813         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22814                 skip "Need MDS version at least 2.7.55"
22815
22816         local stripe_index
22817
22818         test_mkdir -p $DIR/$tdir/striped_dir
22819         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22820                         error "chown $RUNAS_ID failed"
22821         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22822                 error "set default striped dir failed"
22823
22824         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22825         $LCTL set_param fail_loc=0x80000158
22826         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22827
22828         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22829         [ $stripe_index -eq 1 ] ||
22830                 error "expect 1 get $stripe_index for $dir"
22831 }
22832 run_test 300l "non-root user to create dir under striped dir with stale layout"
22833
22834 test_300m() {
22835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22836         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22837         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22838                 skip "Need MDS version at least 2.7.55"
22839
22840         mkdir -p $DIR/$tdir/striped_dir
22841         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22842                 error "set default stripes dir error"
22843
22844         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22845
22846         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22847         [ $stripe_count -eq 0 ] ||
22848                         error "expect 0 get $stripe_count for a"
22849
22850         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22851                 error "set default stripes dir error"
22852
22853         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22854
22855         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22856         [ $stripe_count -eq 0 ] ||
22857                         error "expect 0 get $stripe_count for b"
22858
22859         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22860                 error "set default stripes dir error"
22861
22862         mkdir $DIR/$tdir/striped_dir/c &&
22863                 error "default stripe_index is invalid, mkdir c should fails"
22864
22865         rm -rf $DIR/$tdir || error "rmdir fails"
22866 }
22867 run_test 300m "setstriped directory on single MDT FS"
22868
22869 cleanup_300n() {
22870         local list=$(comma_list $(mdts_nodes))
22871
22872         trap 0
22873         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22874 }
22875
22876 test_300n() {
22877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22879         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22880                 skip "Need MDS version at least 2.7.55"
22881         remote_mds_nodsh && skip "remote MDS with nodsh"
22882
22883         local stripe_index
22884         local list=$(comma_list $(mdts_nodes))
22885
22886         trap cleanup_300n RETURN EXIT
22887         mkdir -p $DIR/$tdir
22888         chmod 777 $DIR/$tdir
22889         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22890                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22891                 error "create striped dir succeeds with gid=0"
22892
22893         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22894         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22895                 error "create striped dir fails with gid=-1"
22896
22897         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22898         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22899                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22900                 error "set default striped dir succeeds with gid=0"
22901
22902
22903         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22904         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22905                 error "set default striped dir fails with gid=-1"
22906
22907
22908         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22909         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22910                                         error "create test_dir fails"
22911         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22912                                         error "create test_dir1 fails"
22913         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22914                                         error "create test_dir2 fails"
22915         cleanup_300n
22916 }
22917 run_test 300n "non-root user to create dir under striped dir with default EA"
22918
22919 test_300o() {
22920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22921         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22922         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22923                 skip "Need MDS version at least 2.7.55"
22924
22925         local numfree1
22926         local numfree2
22927
22928         mkdir -p $DIR/$tdir
22929
22930         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22931         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22932         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22933                 skip "not enough free inodes $numfree1 $numfree2"
22934         fi
22935
22936         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22937         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22938         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22939                 skip "not enough free space $numfree1 $numfree2"
22940         fi
22941
22942         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22943                 error "setdirstripe fails"
22944
22945         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22946                 error "create dirs fails"
22947
22948         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22949         ls $DIR/$tdir/striped_dir > /dev/null ||
22950                 error "ls striped dir fails"
22951         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22952                 error "unlink big striped dir fails"
22953 }
22954 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22955
22956 test_300p() {
22957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22959         remote_mds_nodsh && skip "remote MDS with nodsh"
22960
22961         mkdir_on_mdt0 $DIR/$tdir
22962
22963         #define OBD_FAIL_OUT_ENOSPC     0x1704
22964         do_facet mds2 lctl set_param fail_loc=0x80001704
22965         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22966                  && error "create striped directory should fail"
22967
22968         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22969
22970         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22971         true
22972 }
22973 run_test 300p "create striped directory without space"
22974
22975 test_300q() {
22976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22978
22979         local fd=$(free_fd)
22980         local cmd="exec $fd<$tdir"
22981         cd $DIR
22982         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22983         eval $cmd
22984         cmd="exec $fd<&-"
22985         trap "eval $cmd" EXIT
22986         cd $tdir || error "cd $tdir fails"
22987         rmdir  ../$tdir || error "rmdir $tdir fails"
22988         mkdir local_dir && error "create dir succeeds"
22989         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22990         eval $cmd
22991         return 0
22992 }
22993 run_test 300q "create remote directory under orphan directory"
22994
22995 test_300r() {
22996         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22997                 skip "Need MDS version at least 2.7.55" && return
22998         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22999
23000         mkdir $DIR/$tdir
23001
23002         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23003                 error "set striped dir error"
23004
23005         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23006                 error "getstripeddir fails"
23007
23008         local stripe_count
23009         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23010                       awk '/lmv_stripe_count:/ { print $2 }')
23011
23012         [ $MDSCOUNT -ne $stripe_count ] &&
23013                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23014
23015         rm -rf $DIR/$tdir/striped_dir ||
23016                 error "unlink striped dir fails"
23017 }
23018 run_test 300r "test -1 striped directory"
23019
23020 test_300s_helper() {
23021         local count=$1
23022
23023         local stripe_dir=$DIR/$tdir/striped_dir.$count
23024
23025         $LFS mkdir -c $count $stripe_dir ||
23026                 error "lfs mkdir -c error"
23027
23028         $LFS getdirstripe $stripe_dir ||
23029                 error "lfs getdirstripe fails"
23030
23031         local stripe_count
23032         stripe_count=$($LFS getdirstripe $stripe_dir |
23033                       awk '/lmv_stripe_count:/ { print $2 }')
23034
23035         [ $count -ne $stripe_count ] &&
23036                 error_noexit "bad stripe count $stripe_count expected $count"
23037
23038         local dupe_stripes
23039         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23040                 awk '/0x/ {count[$1] += 1}; END {
23041                         for (idx in count) {
23042                                 if (count[idx]>1) {
23043                                         print "index " idx " count " count[idx]
23044                                 }
23045                         }
23046                 }')
23047
23048         if [[ -n "$dupe_stripes" ]] ; then
23049                 lfs getdirstripe $stripe_dir
23050                 error_noexit "Dupe MDT above: $dupe_stripes "
23051         fi
23052
23053         rm -rf $stripe_dir ||
23054                 error_noexit "unlink $stripe_dir fails"
23055 }
23056
23057 test_300s() {
23058         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23059                 skip "Need MDS version at least 2.7.55" && return
23060         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23061
23062         mkdir $DIR/$tdir
23063         for count in $(seq 2 $MDSCOUNT); do
23064                 test_300s_helper $count
23065         done
23066 }
23067 run_test 300s "test lfs mkdir -c without -i"
23068
23069
23070 prepare_remote_file() {
23071         mkdir $DIR/$tdir/src_dir ||
23072                 error "create remote source failed"
23073
23074         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23075                  error "cp to remote source failed"
23076         touch $DIR/$tdir/src_dir/a
23077
23078         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23079                 error "create remote target dir failed"
23080
23081         touch $DIR/$tdir/tgt_dir/b
23082
23083         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23084                 error "rename dir cross MDT failed!"
23085
23086         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23087                 error "src_child still exists after rename"
23088
23089         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23090                 error "missing file(a) after rename"
23091
23092         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23093                 error "diff after rename"
23094 }
23095
23096 test_310a() {
23097         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23099
23100         local remote_file=$DIR/$tdir/tgt_dir/b
23101
23102         mkdir -p $DIR/$tdir
23103
23104         prepare_remote_file || error "prepare remote file failed"
23105
23106         #open-unlink file
23107         $OPENUNLINK $remote_file $remote_file ||
23108                 error "openunlink $remote_file failed"
23109         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23110 }
23111 run_test 310a "open unlink remote file"
23112
23113 test_310b() {
23114         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23116
23117         local remote_file=$DIR/$tdir/tgt_dir/b
23118
23119         mkdir -p $DIR/$tdir
23120
23121         prepare_remote_file || error "prepare remote file failed"
23122
23123         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23124         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23125         $CHECKSTAT -t file $remote_file || error "check file failed"
23126 }
23127 run_test 310b "unlink remote file with multiple links while open"
23128
23129 test_310c() {
23130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23131         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23132
23133         local remote_file=$DIR/$tdir/tgt_dir/b
23134
23135         mkdir -p $DIR/$tdir
23136
23137         prepare_remote_file || error "prepare remote file failed"
23138
23139         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23140         multiop_bg_pause $remote_file O_uc ||
23141                         error "mulitop failed for remote file"
23142         MULTIPID=$!
23143         $MULTIOP $DIR/$tfile Ouc
23144         kill -USR1 $MULTIPID
23145         wait $MULTIPID
23146 }
23147 run_test 310c "open-unlink remote file with multiple links"
23148
23149 #LU-4825
23150 test_311() {
23151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23152         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23153         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23154                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23155         remote_mds_nodsh && skip "remote MDS with nodsh"
23156
23157         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23158         local mdts=$(comma_list $(mdts_nodes))
23159
23160         mkdir -p $DIR/$tdir
23161         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23162         createmany -o $DIR/$tdir/$tfile. 1000
23163
23164         # statfs data is not real time, let's just calculate it
23165         old_iused=$((old_iused + 1000))
23166
23167         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23168                         osp.*OST0000*MDT0000.create_count")
23169         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23170                                 osp.*OST0000*MDT0000.max_create_count")
23171         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23172
23173         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23174         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23175         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23176
23177         unlinkmany $DIR/$tdir/$tfile. 1000
23178
23179         do_nodes $mdts "$LCTL set_param -n \
23180                         osp.*OST0000*.max_create_count=$max_count"
23181         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23182                 do_nodes $mdts "$LCTL set_param -n \
23183                                 osp.*OST0000*.create_count=$count"
23184         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23185                         grep "=0" && error "create_count is zero"
23186
23187         local new_iused
23188         for i in $(seq 120); do
23189                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23190                 # system may be too busy to destroy all objs in time, use
23191                 # a somewhat small value to not fail autotest
23192                 [ $((old_iused - new_iused)) -gt 400 ] && break
23193                 sleep 1
23194         done
23195
23196         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23197         [ $((old_iused - new_iused)) -gt 400 ] ||
23198                 error "objs not destroyed after unlink"
23199 }
23200 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23201
23202 zfs_oid_to_objid()
23203 {
23204         local ost=$1
23205         local objid=$2
23206
23207         local vdevdir=$(dirname $(facet_vdevice $ost))
23208         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23209         local zfs_zapid=$(do_facet $ost $cmd |
23210                           grep -w "/O/0/d$((objid%32))" -C 5 |
23211                           awk '/Object/{getline; print $1}')
23212         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23213                           awk "/$objid = /"'{printf $3}')
23214
23215         echo $zfs_objid
23216 }
23217
23218 zfs_object_blksz() {
23219         local ost=$1
23220         local objid=$2
23221
23222         local vdevdir=$(dirname $(facet_vdevice $ost))
23223         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23224         local blksz=$(do_facet $ost $cmd $objid |
23225                       awk '/dblk/{getline; printf $4}')
23226
23227         case "${blksz: -1}" in
23228                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23229                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23230                 *) ;;
23231         esac
23232
23233         echo $blksz
23234 }
23235
23236 test_312() { # LU-4856
23237         remote_ost_nodsh && skip "remote OST with nodsh"
23238         [ "$ost1_FSTYPE" = "zfs" ] ||
23239                 skip_env "the test only applies to zfs"
23240
23241         local max_blksz=$(do_facet ost1 \
23242                           $ZFS get -p recordsize $(facet_device ost1) |
23243                           awk '!/VALUE/{print $3}')
23244
23245         # to make life a little bit easier
23246         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23247         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23248
23249         local tf=$DIR/$tdir/$tfile
23250         touch $tf
23251         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23252
23253         # Get ZFS object id
23254         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23255         # block size change by sequential overwrite
23256         local bs
23257
23258         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23259                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23260
23261                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23262                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23263         done
23264         rm -f $tf
23265
23266         # block size change by sequential append write
23267         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23268         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23269         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23270         local count
23271
23272         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23273                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23274                         oflag=sync conv=notrunc
23275
23276                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23277                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23278                         error "blksz error, actual $blksz, " \
23279                                 "expected: 2 * $count * $PAGE_SIZE"
23280         done
23281         rm -f $tf
23282
23283         # random write
23284         touch $tf
23285         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23286         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23287
23288         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23289         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23290         [ $blksz -eq $PAGE_SIZE ] ||
23291                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23292
23293         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23294         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23295         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23296
23297         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23298         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23299         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23300 }
23301 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23302
23303 test_313() {
23304         remote_ost_nodsh && skip "remote OST with nodsh"
23305
23306         local file=$DIR/$tfile
23307
23308         rm -f $file
23309         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23310
23311         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23312         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23313         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23314                 error "write should failed"
23315         do_facet ost1 "$LCTL set_param fail_loc=0"
23316         rm -f $file
23317 }
23318 run_test 313 "io should fail after last_rcvd update fail"
23319
23320 test_314() {
23321         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23322
23323         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23324         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23325         rm -f $DIR/$tfile
23326         wait_delete_completed
23327         do_facet ost1 "$LCTL set_param fail_loc=0"
23328 }
23329 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23330
23331 test_315() { # LU-618
23332         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23333
23334         local file=$DIR/$tfile
23335         rm -f $file
23336
23337         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23338                 error "multiop file write failed"
23339         $MULTIOP $file oO_RDONLY:r4063232_c &
23340         PID=$!
23341
23342         sleep 2
23343
23344         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23345         kill -USR1 $PID
23346
23347         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23348         rm -f $file
23349 }
23350 run_test 315 "read should be accounted"
23351
23352 test_316() {
23353         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23354         large_xattr_enabled || skip_env "ea_inode feature disabled"
23355
23356         rm -rf $DIR/$tdir/d
23357         mkdir -p $DIR/$tdir/d
23358         chown nobody $DIR/$tdir/d
23359         touch $DIR/$tdir/d/file
23360
23361         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23362 }
23363 run_test 316 "lfs mv"
23364
23365 test_317() {
23366         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23367                 skip "Need MDS version at least 2.11.53"
23368         if [ "$ost1_FSTYPE" == "zfs" ]; then
23369                 skip "LU-10370: no implementation for ZFS"
23370         fi
23371
23372         local trunc_sz
23373         local grant_blk_size
23374
23375         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23376                         awk '/grant_block_size:/ { print $2; exit; }')
23377         #
23378         # Create File of size 5M. Truncate it to below size's and verify
23379         # blocks count.
23380         #
23381         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23382                 error "Create file $DIR/$tfile failed"
23383         stack_trap "rm -f $DIR/$tfile" EXIT
23384
23385         for trunc_sz in 2097152 4097 4000 509 0; do
23386                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23387                         error "truncate $tfile to $trunc_sz failed"
23388                 local sz=$(stat --format=%s $DIR/$tfile)
23389                 local blk=$(stat --format=%b $DIR/$tfile)
23390                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23391                                      grant_blk_size) * 8))
23392
23393                 if [[ $blk -ne $trunc_blk ]]; then
23394                         $(which stat) $DIR/$tfile
23395                         error "Expected Block $trunc_blk got $blk for $tfile"
23396                 fi
23397
23398                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23399                         error "Expected Size $trunc_sz got $sz for $tfile"
23400         done
23401
23402         #
23403         # sparse file test
23404         # Create file with a hole and write actual two blocks. Block count
23405         # must be 16.
23406         #
23407         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23408                 conv=fsync || error "Create file : $DIR/$tfile"
23409
23410         # Calculate the final truncate size.
23411         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23412
23413         #
23414         # truncate to size $trunc_sz bytes. Strip the last block
23415         # The block count must drop to 8
23416         #
23417         $TRUNCATE $DIR/$tfile $trunc_sz ||
23418                 error "truncate $tfile to $trunc_sz failed"
23419
23420         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23421         sz=$(stat --format=%s $DIR/$tfile)
23422         blk=$(stat --format=%b $DIR/$tfile)
23423
23424         if [[ $blk -ne $trunc_bsz ]]; then
23425                 $(which stat) $DIR/$tfile
23426                 error "Expected Block $trunc_bsz got $blk for $tfile"
23427         fi
23428
23429         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23430                 error "Expected Size $trunc_sz got $sz for $tfile"
23431 }
23432 run_test 317 "Verify blocks get correctly update after truncate"
23433
23434 test_318() {
23435         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23436         local old_max_active=$($LCTL get_param -n \
23437                             ${llite_name}.max_read_ahead_async_active \
23438                             2>/dev/null)
23439
23440         $LCTL set_param llite.*.max_read_ahead_async_active=256
23441         local max_active=$($LCTL get_param -n \
23442                            ${llite_name}.max_read_ahead_async_active \
23443                            2>/dev/null)
23444         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23445
23446         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23447                 error "set max_read_ahead_async_active should succeed"
23448
23449         $LCTL set_param llite.*.max_read_ahead_async_active=512
23450         max_active=$($LCTL get_param -n \
23451                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23452         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23453
23454         # restore @max_active
23455         [ $old_max_active -ne 0 ] && $LCTL set_param \
23456                 llite.*.max_read_ahead_async_active=$old_max_active
23457
23458         local old_threshold=$($LCTL get_param -n \
23459                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23460         local max_per_file_mb=$($LCTL get_param -n \
23461                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23462
23463         local invalid=$(($max_per_file_mb + 1))
23464         $LCTL set_param \
23465                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23466                         && error "set $invalid should fail"
23467
23468         local valid=$(($invalid - 1))
23469         $LCTL set_param \
23470                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23471                         error "set $valid should succeed"
23472         local threshold=$($LCTL get_param -n \
23473                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23474         [ $threshold -eq $valid ] || error \
23475                 "expect threshold $valid got $threshold"
23476         $LCTL set_param \
23477                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23478 }
23479 run_test 318 "Verify async readahead tunables"
23480
23481 test_319() {
23482         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23483
23484         local before=$(date +%s)
23485         local evict
23486         local mdir=$DIR/$tdir
23487         local file=$mdir/xxx
23488
23489         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23490         touch $file
23491
23492 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23493         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23494         $LFS mv -m1 $file &
23495
23496         sleep 1
23497         dd if=$file of=/dev/null
23498         wait
23499         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23500           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23501
23502         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23503 }
23504 run_test 319 "lost lease lock on migrate error"
23505
23506 test_398a() { # LU-4198
23507         local ost1_imp=$(get_osc_import_name client ost1)
23508         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23509                          cut -d'.' -f2)
23510
23511         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23512         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23513
23514         # request a new lock on client
23515         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23516
23517         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23518         local lock_count=$($LCTL get_param -n \
23519                            ldlm.namespaces.$imp_name.lru_size)
23520         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23521
23522         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23523
23524         # no lock cached, should use lockless IO and not enqueue new lock
23525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23526         lock_count=$($LCTL get_param -n \
23527                      ldlm.namespaces.$imp_name.lru_size)
23528         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23529 }
23530 run_test 398a "direct IO should cancel lock otherwise lockless"
23531
23532 test_398b() { # LU-4198
23533         which fio || skip_env "no fio installed"
23534         $LFS setstripe -c -1 $DIR/$tfile
23535
23536         local size=12
23537         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23538
23539         local njobs=4
23540         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23541         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23542                 --numjobs=$njobs --fallocate=none \
23543                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23544                 --filename=$DIR/$tfile &
23545         bg_pid=$!
23546
23547         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23548         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23549                 --numjobs=$njobs --fallocate=none \
23550                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23551                 --filename=$DIR/$tfile || true
23552         wait $bg_pid
23553
23554         rm -f $DIR/$tfile
23555 }
23556 run_test 398b "DIO and buffer IO race"
23557
23558 test_398c() { # LU-4198
23559         local ost1_imp=$(get_osc_import_name client ost1)
23560         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23561                          cut -d'.' -f2)
23562
23563         which fio || skip_env "no fio installed"
23564
23565         saved_debug=$($LCTL get_param -n debug)
23566         $LCTL set_param debug=0
23567
23568         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23569         ((size /= 1024)) # by megabytes
23570         ((size /= 2)) # write half of the OST at most
23571         [ $size -gt 40 ] && size=40 #reduce test time anyway
23572
23573         $LFS setstripe -c 1 $DIR/$tfile
23574
23575         # it seems like ldiskfs reserves more space than necessary if the
23576         # writing blocks are not mapped, so it extends the file firstly
23577         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23578         cancel_lru_locks osc
23579
23580         # clear and verify rpc_stats later
23581         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23582
23583         local njobs=4
23584         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23585         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23586                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23587                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23588                 --filename=$DIR/$tfile
23589         [ $? -eq 0 ] || error "fio write error"
23590
23591         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23592                 error "Locks were requested while doing AIO"
23593
23594         # get the percentage of 1-page I/O
23595         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23596                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23597                 awk '{print $7}')
23598         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23599
23600         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23601         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23602                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23603                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23604                 --filename=$DIR/$tfile
23605         [ $? -eq 0 ] || error "fio mixed read write error"
23606
23607         echo "AIO with large block size ${size}M"
23608         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23609                 --numjobs=1 --fallocate=none --ioengine=libaio \
23610                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23611                 --filename=$DIR/$tfile
23612         [ $? -eq 0 ] || error "fio large block size failed"
23613
23614         rm -f $DIR/$tfile
23615         $LCTL set_param debug="$saved_debug"
23616 }
23617 run_test 398c "run fio to test AIO"
23618
23619 test_398d() { #  LU-13846
23620         which aiocp || skip_env "no aiocp installed"
23621         local aio_file=$DIR/$tfile.aio
23622
23623         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23624
23625         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23626         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23627         stack_trap "rm -f $DIR/$tfile $aio_file"
23628
23629         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23630
23631         # make sure we don't crash and fail properly
23632         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23633                 error "aio not aligned with PAGE SIZE should fail"
23634
23635         rm -f $DIR/$tfile $aio_file
23636 }
23637 run_test 398d "run aiocp to verify block size > stripe size"
23638
23639 test_398e() {
23640         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23641         touch $DIR/$tfile.new
23642         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23643 }
23644 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23645
23646 test_398f() { #  LU-14687
23647         which aiocp || skip_env "no aiocp installed"
23648         local aio_file=$DIR/$tfile.aio
23649
23650         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23651
23652         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23653         stack_trap "rm -f $DIR/$tfile $aio_file"
23654
23655         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23656         $LCTL set_param fail_loc=0x1418
23657         # make sure we don't crash and fail properly
23658         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23659                 error "aio with page allocation failure succeeded"
23660         $LCTL set_param fail_loc=0
23661         diff $DIR/$tfile $aio_file
23662         [[ $? != 0 ]] || error "no diff after failed aiocp"
23663 }
23664 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23665
23666 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23667 # stripe and i/o size must be > stripe size
23668 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23669 # single RPC in flight.  This test shows async DIO submission is working by
23670 # showing multiple RPCs in flight.
23671 test_398g() { #  LU-13798
23672         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23673
23674         # We need to do some i/o first to acquire enough grant to put our RPCs
23675         # in flight; otherwise a new connection may not have enough grant
23676         # available
23677         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23678                 error "parallel dio failed"
23679         stack_trap "rm -f $DIR/$tfile"
23680
23681         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23682         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23683         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23684         stack_trap "$LCTL set_param -n $pages_per_rpc"
23685
23686         # Recreate file so it's empty
23687         rm -f $DIR/$tfile
23688         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23689         #Pause rpc completion to guarantee we see multiple rpcs in flight
23690         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23691         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23692         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23693
23694         # Clear rpc stats
23695         $LCTL set_param osc.*.rpc_stats=c
23696
23697         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23698                 error "parallel dio failed"
23699         stack_trap "rm -f $DIR/$tfile"
23700
23701         $LCTL get_param osc.*-OST0000-*.rpc_stats
23702         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23703                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23704                 grep "8:" | awk '{print $8}')
23705         # We look at the "8 rpcs in flight" field, and verify A) it is present
23706         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23707         # as expected for an 8M DIO to a file with 1M stripes.
23708         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23709
23710         # Verify turning off parallel dio works as expected
23711         # Clear rpc stats
23712         $LCTL set_param osc.*.rpc_stats=c
23713         $LCTL set_param llite.*.parallel_dio=0
23714         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23715
23716         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23717                 error "dio with parallel dio disabled failed"
23718
23719         # Ideally, we would see only one RPC in flight here, but there is an
23720         # unavoidable race between i/o completion and RPC in flight counting,
23721         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23722         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23723         # So instead we just verify it's always < 8.
23724         $LCTL get_param osc.*-OST0000-*.rpc_stats
23725         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23726                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23727                 grep '^$' -B1 | grep . | awk '{print $1}')
23728         [ $ret != "8:" ] ||
23729                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23730 }
23731 run_test 398g "verify parallel dio async RPC submission"
23732
23733 test_398h() { #  LU-13798
23734         local dio_file=$DIR/$tfile.dio
23735
23736         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23737
23738         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23739         stack_trap "rm -f $DIR/$tfile $dio_file"
23740
23741         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23742                 error "parallel dio failed"
23743         diff $DIR/$tfile $dio_file
23744         [[ $? == 0 ]] || error "file diff after aiocp"
23745 }
23746 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23747
23748 test_398i() { #  LU-13798
23749         local dio_file=$DIR/$tfile.dio
23750
23751         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23752
23753         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23754         stack_trap "rm -f $DIR/$tfile $dio_file"
23755
23756         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23757         $LCTL set_param fail_loc=0x1418
23758         # make sure we don't crash and fail properly
23759         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23760                 error "parallel dio page allocation failure succeeded"
23761         diff $DIR/$tfile $dio_file
23762         [[ $? != 0 ]] || error "no diff after failed aiocp"
23763 }
23764 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23765
23766 test_398j() { #  LU-13798
23767         # Stripe size > RPC size but less than i/o size tests split across
23768         # stripes and RPCs for individual i/o op
23769         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23770
23771         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23772         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23773         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23774         stack_trap "$LCTL set_param -n $pages_per_rpc"
23775
23776         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23777                 error "parallel dio write failed"
23778         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23779
23780         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23781                 error "parallel dio read failed"
23782         diff $DIR/$tfile $DIR/$tfile.2
23783         [[ $? == 0 ]] || error "file diff after parallel dio read"
23784 }
23785 run_test 398j "test parallel dio where stripe size > rpc_size"
23786
23787 test_398k() { #  LU-13798
23788         wait_delete_completed
23789         wait_mds_ost_sync
23790
23791         # 4 stripe file; we will cause out of space on OST0
23792         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23793
23794         # Fill OST0 (if it's not too large)
23795         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23796                    head -n1)
23797         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23798                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23799         fi
23800         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23801         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23802                 error "dd should fill OST0"
23803         stack_trap "rm -f $DIR/$tfile.1"
23804
23805         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23806         err=$?
23807
23808         ls -la $DIR/$tfile
23809         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23810                 error "file is not 0 bytes in size"
23811
23812         # dd above should not succeed, but don't error until here so we can
23813         # get debug info above
23814         [[ $err != 0 ]] ||
23815                 error "parallel dio write with enospc succeeded"
23816         stack_trap "rm -f $DIR/$tfile"
23817 }
23818 run_test 398k "test enospc on first stripe"
23819
23820 test_398l() { #  LU-13798
23821         wait_delete_completed
23822         wait_mds_ost_sync
23823
23824         # 4 stripe file; we will cause out of space on OST0
23825         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23826         # happens on the second i/o chunk we issue
23827         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23828
23829         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23830         stack_trap "rm -f $DIR/$tfile"
23831
23832         # Fill OST0 (if it's not too large)
23833         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23834                    head -n1)
23835         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23836                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23837         fi
23838         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23839         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23840                 error "dd should fill OST0"
23841         stack_trap "rm -f $DIR/$tfile.1"
23842
23843         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23844         err=$?
23845         stack_trap "rm -f $DIR/$tfile.2"
23846
23847         # Check that short write completed as expected
23848         ls -la $DIR/$tfile.2
23849         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23850                 error "file is not 1M in size"
23851
23852         # dd above should not succeed, but don't error until here so we can
23853         # get debug info above
23854         [[ $err != 0 ]] ||
23855                 error "parallel dio write with enospc succeeded"
23856
23857         # Truncate source file to same length as output file and diff them
23858         $TRUNCATE $DIR/$tfile 1048576
23859         diff $DIR/$tfile $DIR/$tfile.2
23860         [[ $? == 0 ]] || error "data incorrect after short write"
23861 }
23862 run_test 398l "test enospc on intermediate stripe/RPC"
23863
23864 test_398m() { #  LU-13798
23865         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23866
23867         # Set up failure on OST0, the first stripe:
23868         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23869         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23870         # So this fail_val specifies OST0
23871         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23872         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23873
23874         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23875                 error "parallel dio write with failure on first stripe succeeded"
23876         stack_trap "rm -f $DIR/$tfile"
23877         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23878
23879         # Place data in file for read
23880         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23881                 error "parallel dio write failed"
23882
23883         # Fail read on OST0, first stripe
23884         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23885         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
23886         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23887                 error "parallel dio read with error on first stripe succeeded"
23888         rm -f $DIR/$tfile.2
23889         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23890
23891         # Switch to testing on OST1, second stripe
23892         # Clear file contents, maintain striping
23893         echo > $DIR/$tfile
23894         # Set up failure on OST1, second stripe:
23895         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
23896         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23897
23898         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23899                 error "parallel dio write with failure on first stripe succeeded"
23900         stack_trap "rm -f $DIR/$tfile"
23901         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23902
23903         # Place data in file for read
23904         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23905                 error "parallel dio write failed"
23906
23907         # Fail read on OST1, second stripe
23908         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23909         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
23910         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23911                 error "parallel dio read with error on first stripe succeeded"
23912         rm -f $DIR/$tfile.2
23913         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
23914 }
23915 run_test 398m "test RPC failures with parallel dio"
23916
23917 # Parallel submission of DIO should not cause problems for append, but it's
23918 # important to verify.
23919 test_398n() { #  LU-13798
23920         $LFS setstripe -C 2 -S 1M $DIR/$tfile
23921
23922         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
23923                 error "dd to create source file failed"
23924         stack_trap "rm -f $DIR/$tfile"
23925
23926         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
23927                 error "parallel dio write with failure on second stripe succeeded"
23928         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
23929         diff $DIR/$tfile $DIR/$tfile.1
23930         [[ $? == 0 ]] || error "data incorrect after append"
23931
23932 }
23933 run_test 398n "test append with parallel DIO"
23934
23935 test_fake_rw() {
23936         local read_write=$1
23937         if [ "$read_write" = "write" ]; then
23938                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23939         elif [ "$read_write" = "read" ]; then
23940                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23941         else
23942                 error "argument error"
23943         fi
23944
23945         # turn off debug for performance testing
23946         local saved_debug=$($LCTL get_param -n debug)
23947         $LCTL set_param debug=0
23948
23949         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23950
23951         # get ost1 size - $FSNAME-OST0000
23952         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23953         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23954         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23955
23956         if [ "$read_write" = "read" ]; then
23957                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23958         fi
23959
23960         local start_time=$(date +%s.%N)
23961         $dd_cmd bs=1M count=$blocks oflag=sync ||
23962                 error "real dd $read_write error"
23963         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23964
23965         if [ "$read_write" = "write" ]; then
23966                 rm -f $DIR/$tfile
23967         fi
23968
23969         # define OBD_FAIL_OST_FAKE_RW           0x238
23970         do_facet ost1 $LCTL set_param fail_loc=0x238
23971
23972         local start_time=$(date +%s.%N)
23973         $dd_cmd bs=1M count=$blocks oflag=sync ||
23974                 error "fake dd $read_write error"
23975         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23976
23977         if [ "$read_write" = "write" ]; then
23978                 # verify file size
23979                 cancel_lru_locks osc
23980                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23981                         error "$tfile size not $blocks MB"
23982         fi
23983         do_facet ost1 $LCTL set_param fail_loc=0
23984
23985         echo "fake $read_write $duration_fake vs. normal $read_write" \
23986                 "$duration in seconds"
23987         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23988                 error_not_in_vm "fake write is slower"
23989
23990         $LCTL set_param -n debug="$saved_debug"
23991         rm -f $DIR/$tfile
23992 }
23993 test_399a() { # LU-7655 for OST fake write
23994         remote_ost_nodsh && skip "remote OST with nodsh"
23995
23996         test_fake_rw write
23997 }
23998 run_test 399a "fake write should not be slower than normal write"
23999
24000 test_399b() { # LU-8726 for OST fake read
24001         remote_ost_nodsh && skip "remote OST with nodsh"
24002         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24003                 skip_env "ldiskfs only test"
24004         fi
24005
24006         test_fake_rw read
24007 }
24008 run_test 399b "fake read should not be slower than normal read"
24009
24010 test_400a() { # LU-1606, was conf-sanity test_74
24011         if ! which $CC > /dev/null 2>&1; then
24012                 skip_env "$CC is not installed"
24013         fi
24014
24015         local extra_flags=''
24016         local out=$TMP/$tfile
24017         local prefix=/usr/include/lustre
24018         local prog
24019
24020         # Oleg removes c files in his test rig so test if any c files exist
24021         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24022                 skip_env "Needed c test files are missing"
24023
24024         if ! [[ -d $prefix ]]; then
24025                 # Assume we're running in tree and fixup the include path.
24026                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24027                 extra_flags+=" -L$LUSTRE/utils/.lib"
24028         fi
24029
24030         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24031                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24032                         error "client api broken"
24033         done
24034         rm -f $out
24035 }
24036 run_test 400a "Lustre client api program can compile and link"
24037
24038 test_400b() { # LU-1606, LU-5011
24039         local header
24040         local out=$TMP/$tfile
24041         local prefix=/usr/include/linux/lustre
24042
24043         # We use a hard coded prefix so that this test will not fail
24044         # when run in tree. There are headers in lustre/include/lustre/
24045         # that are not packaged (like lustre_idl.h) and have more
24046         # complicated include dependencies (like config.h and lnet/types.h).
24047         # Since this test about correct packaging we just skip them when
24048         # they don't exist (see below) rather than try to fixup cppflags.
24049
24050         if ! which $CC > /dev/null 2>&1; then
24051                 skip_env "$CC is not installed"
24052         fi
24053
24054         for header in $prefix/*.h; do
24055                 if ! [[ -f "$header" ]]; then
24056                         continue
24057                 fi
24058
24059                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24060                         continue # lustre_ioctl.h is internal header
24061                 fi
24062
24063                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24064                         error "cannot compile '$header'"
24065         done
24066         rm -f $out
24067 }
24068 run_test 400b "packaged headers can be compiled"
24069
24070 test_401a() { #LU-7437
24071         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24072         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24073
24074         #count the number of parameters by "list_param -R"
24075         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24076         #count the number of parameters by listing proc files
24077         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24078         echo "proc_dirs='$proc_dirs'"
24079         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24080         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24081                       sort -u | wc -l)
24082
24083         [ $params -eq $procs ] ||
24084                 error "found $params parameters vs. $procs proc files"
24085
24086         # test the list_param -D option only returns directories
24087         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24088         #count the number of parameters by listing proc directories
24089         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24090                 sort -u | wc -l)
24091
24092         [ $params -eq $procs ] ||
24093                 error "found $params parameters vs. $procs proc files"
24094 }
24095 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24096
24097 test_401b() {
24098         # jobid_var may not allow arbitrary values, so use jobid_name
24099         # if available
24100         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24101                 local testname=jobid_name tmp='testing%p'
24102         else
24103                 local testname=jobid_var tmp=testing
24104         fi
24105
24106         local save=$($LCTL get_param -n $testname)
24107
24108         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24109                 error "no error returned when setting bad parameters"
24110
24111         local jobid_new=$($LCTL get_param -n foe $testname baz)
24112         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24113
24114         $LCTL set_param -n fog=bam $testname=$save bat=fog
24115         local jobid_old=$($LCTL get_param -n foe $testname bag)
24116         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24117 }
24118 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24119
24120 test_401c() {
24121         # jobid_var may not allow arbitrary values, so use jobid_name
24122         # if available
24123         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24124                 local testname=jobid_name
24125         else
24126                 local testname=jobid_var
24127         fi
24128
24129         local jobid_var_old=$($LCTL get_param -n $testname)
24130         local jobid_var_new
24131
24132         $LCTL set_param $testname= &&
24133                 error "no error returned for 'set_param a='"
24134
24135         jobid_var_new=$($LCTL get_param -n $testname)
24136         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24137                 error "$testname was changed by setting without value"
24138
24139         $LCTL set_param $testname &&
24140                 error "no error returned for 'set_param a'"
24141
24142         jobid_var_new=$($LCTL get_param -n $testname)
24143         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24144                 error "$testname was changed by setting without value"
24145 }
24146 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24147
24148 test_401d() {
24149         # jobid_var may not allow arbitrary values, so use jobid_name
24150         # if available
24151         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24152                 local testname=jobid_name new_value='foo=bar%p'
24153         else
24154                 local testname=jobid_var new_valuie=foo=bar
24155         fi
24156
24157         local jobid_var_old=$($LCTL get_param -n $testname)
24158         local jobid_var_new
24159
24160         $LCTL set_param $testname=$new_value ||
24161                 error "'set_param a=b' did not accept a value containing '='"
24162
24163         jobid_var_new=$($LCTL get_param -n $testname)
24164         [[ "$jobid_var_new" == "$new_value" ]] ||
24165                 error "'set_param a=b' failed on a value containing '='"
24166
24167         # Reset the $testname to test the other format
24168         $LCTL set_param $testname=$jobid_var_old
24169         jobid_var_new=$($LCTL get_param -n $testname)
24170         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24171                 error "failed to reset $testname"
24172
24173         $LCTL set_param $testname $new_value ||
24174                 error "'set_param a b' did not accept a value containing '='"
24175
24176         jobid_var_new=$($LCTL get_param -n $testname)
24177         [[ "$jobid_var_new" == "$new_value" ]] ||
24178                 error "'set_param a b' failed on a value containing '='"
24179
24180         $LCTL set_param $testname $jobid_var_old
24181         jobid_var_new=$($LCTL get_param -n $testname)
24182         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24183                 error "failed to reset $testname"
24184 }
24185 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24186
24187 test_401e() { # LU-14779
24188         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24189                 error "lctl list_param MGC* failed"
24190         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24191         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24192                 error "lctl get_param lru_size failed"
24193 }
24194 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24195
24196 test_402() {
24197         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24198         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24199                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24200         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24201                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24202                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24203         remote_mds_nodsh && skip "remote MDS with nodsh"
24204
24205         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24206 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24207         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24208         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24209                 echo "Touch failed - OK"
24210 }
24211 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24212
24213 test_403() {
24214         local file1=$DIR/$tfile.1
24215         local file2=$DIR/$tfile.2
24216         local tfile=$TMP/$tfile
24217
24218         rm -f $file1 $file2 $tfile
24219
24220         touch $file1
24221         ln $file1 $file2
24222
24223         # 30 sec OBD_TIMEOUT in ll_getattr()
24224         # right before populating st_nlink
24225         $LCTL set_param fail_loc=0x80001409
24226         stat -c %h $file1 > $tfile &
24227
24228         # create an alias, drop all locks and reclaim the dentry
24229         < $file2
24230         cancel_lru_locks mdc
24231         cancel_lru_locks osc
24232         sysctl -w vm.drop_caches=2
24233
24234         wait
24235
24236         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24237
24238         rm -f $tfile $file1 $file2
24239 }
24240 run_test 403 "i_nlink should not drop to zero due to aliasing"
24241
24242 test_404() { # LU-6601
24243         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24244                 skip "Need server version newer than 2.8.52"
24245         remote_mds_nodsh && skip "remote MDS with nodsh"
24246
24247         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24248                 awk '/osp .*-osc-MDT/ { print $4}')
24249
24250         local osp
24251         for osp in $mosps; do
24252                 echo "Deactivate: " $osp
24253                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24254                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24255                         awk -vp=$osp '$4 == p { print $2 }')
24256                 [ $stat = IN ] || {
24257                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24258                         error "deactivate error"
24259                 }
24260                 echo "Activate: " $osp
24261                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24262                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24263                         awk -vp=$osp '$4 == p { print $2 }')
24264                 [ $stat = UP ] || {
24265                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24266                         error "activate error"
24267                 }
24268         done
24269 }
24270 run_test 404 "validate manual {de}activated works properly for OSPs"
24271
24272 test_405() {
24273         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24274         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24275                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24276                         skip "Layout swap lock is not supported"
24277
24278         check_swap_layouts_support
24279         check_swap_layout_no_dom $DIR
24280
24281         test_mkdir $DIR/$tdir
24282         swap_lock_test -d $DIR/$tdir ||
24283                 error "One layout swap locked test failed"
24284 }
24285 run_test 405 "Various layout swap lock tests"
24286
24287 test_406() {
24288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24289         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24290         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24292         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24293                 skip "Need MDS version at least 2.8.50"
24294
24295         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24296         local test_pool=$TESTNAME
24297
24298         pool_add $test_pool || error "pool_add failed"
24299         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24300                 error "pool_add_targets failed"
24301
24302         save_layout_restore_at_exit $MOUNT
24303
24304         # parent set default stripe count only, child will stripe from both
24305         # parent and fs default
24306         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24307                 error "setstripe $MOUNT failed"
24308         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24309         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24310         for i in $(seq 10); do
24311                 local f=$DIR/$tdir/$tfile.$i
24312                 touch $f || error "touch failed"
24313                 local count=$($LFS getstripe -c $f)
24314                 [ $count -eq $OSTCOUNT ] ||
24315                         error "$f stripe count $count != $OSTCOUNT"
24316                 local offset=$($LFS getstripe -i $f)
24317                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24318                 local size=$($LFS getstripe -S $f)
24319                 [ $size -eq $((def_stripe_size * 2)) ] ||
24320                         error "$f stripe size $size != $((def_stripe_size * 2))"
24321                 local pool=$($LFS getstripe -p $f)
24322                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24323         done
24324
24325         # change fs default striping, delete parent default striping, now child
24326         # will stripe from new fs default striping only
24327         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24328                 error "change $MOUNT default stripe failed"
24329         $LFS setstripe -c 0 $DIR/$tdir ||
24330                 error "delete $tdir default stripe failed"
24331         for i in $(seq 11 20); do
24332                 local f=$DIR/$tdir/$tfile.$i
24333                 touch $f || error "touch $f failed"
24334                 local count=$($LFS getstripe -c $f)
24335                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24336                 local offset=$($LFS getstripe -i $f)
24337                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24338                 local size=$($LFS getstripe -S $f)
24339                 [ $size -eq $def_stripe_size ] ||
24340                         error "$f stripe size $size != $def_stripe_size"
24341                 local pool=$($LFS getstripe -p $f)
24342                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24343         done
24344
24345         unlinkmany $DIR/$tdir/$tfile. 1 20
24346
24347         local f=$DIR/$tdir/$tfile
24348         pool_remove_all_targets $test_pool $f
24349         pool_remove $test_pool $f
24350 }
24351 run_test 406 "DNE support fs default striping"
24352
24353 test_407() {
24354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24355         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24356                 skip "Need MDS version at least 2.8.55"
24357         remote_mds_nodsh && skip "remote MDS with nodsh"
24358
24359         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24360                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24361         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24362                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24363         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24364
24365         #define OBD_FAIL_DT_TXN_STOP    0x2019
24366         for idx in $(seq $MDSCOUNT); do
24367                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24368         done
24369         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24370         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24371                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24372         true
24373 }
24374 run_test 407 "transaction fail should cause operation fail"
24375
24376 test_408() {
24377         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24378
24379         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24380         lctl set_param fail_loc=0x8000040a
24381         # let ll_prepare_partial_page() fail
24382         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24383
24384         rm -f $DIR/$tfile
24385
24386         # create at least 100 unused inodes so that
24387         # shrink_icache_memory(0) should not return 0
24388         touch $DIR/$tfile-{0..100}
24389         rm -f $DIR/$tfile-{0..100}
24390         sync
24391
24392         echo 2 > /proc/sys/vm/drop_caches
24393 }
24394 run_test 408 "drop_caches should not hang due to page leaks"
24395
24396 test_409()
24397 {
24398         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24399
24400         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24401         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24402         touch $DIR/$tdir/guard || error "(2) Fail to create"
24403
24404         local PREFIX=$(str_repeat 'A' 128)
24405         echo "Create 1K hard links start at $(date)"
24406         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24407                 error "(3) Fail to hard link"
24408
24409         echo "Links count should be right although linkEA overflow"
24410         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24411         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24412         [ $linkcount -eq 1001 ] ||
24413                 error "(5) Unexpected hard links count: $linkcount"
24414
24415         echo "List all links start at $(date)"
24416         ls -l $DIR/$tdir/foo > /dev/null ||
24417                 error "(6) Fail to list $DIR/$tdir/foo"
24418
24419         echo "Unlink hard links start at $(date)"
24420         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24421                 error "(7) Fail to unlink"
24422         echo "Unlink hard links finished at $(date)"
24423 }
24424 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24425
24426 test_410()
24427 {
24428         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24429                 skip "Need client version at least 2.9.59"
24430         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24431                 skip "Need MODULES build"
24432
24433         # Create a file, and stat it from the kernel
24434         local testfile=$DIR/$tfile
24435         touch $testfile
24436
24437         local run_id=$RANDOM
24438         local my_ino=$(stat --format "%i" $testfile)
24439
24440         # Try to insert the module. This will always fail as the
24441         # module is designed to not be inserted.
24442         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24443             &> /dev/null
24444
24445         # Anything but success is a test failure
24446         dmesg | grep -q \
24447             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24448             error "no inode match"
24449 }
24450 run_test 410 "Test inode number returned from kernel thread"
24451
24452 cleanup_test411_cgroup() {
24453         trap 0
24454         rmdir "$1"
24455 }
24456
24457 test_411() {
24458         local cg_basedir=/sys/fs/cgroup/memory
24459         # LU-9966
24460         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24461                 skip "no setup for cgroup"
24462
24463         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24464                 error "test file creation failed"
24465         cancel_lru_locks osc
24466
24467         # Create a very small memory cgroup to force a slab allocation error
24468         local cgdir=$cg_basedir/osc_slab_alloc
24469         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24470         trap "cleanup_test411_cgroup $cgdir" EXIT
24471         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24472         echo 1M > $cgdir/memory.limit_in_bytes
24473
24474         # Should not LBUG, just be killed by oom-killer
24475         # dd will return 0 even allocation failure in some environment.
24476         # So don't check return value
24477         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24478         cleanup_test411_cgroup $cgdir
24479
24480         return 0
24481 }
24482 run_test 411 "Slab allocation error with cgroup does not LBUG"
24483
24484 test_412() {
24485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24486         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24487                 skip "Need server version at least 2.10.55"
24488         fi
24489
24490         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24491                 error "mkdir failed"
24492         $LFS getdirstripe $DIR/$tdir
24493         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24494         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24495                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24496         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24497         [ $stripe_count -eq 2 ] ||
24498                 error "expect 2 get $stripe_count"
24499 }
24500 run_test 412 "mkdir on specific MDTs"
24501
24502 generate_uneven_mdts() {
24503         local threshold=$1
24504         local ffree
24505         local bavail
24506         local max
24507         local min
24508         local max_index
24509         local min_index
24510         local tmp
24511         local i
24512
24513         echo
24514         echo "Check for uneven MDTs: "
24515
24516         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24517         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24518         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24519
24520         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24521         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24522         max_index=0
24523         min_index=0
24524         for ((i = 1; i < ${#ffree[@]}; i++)); do
24525                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24526                 if [ $tmp -gt $max ]; then
24527                         max=$tmp
24528                         max_index=$i
24529                 fi
24530                 if [ $tmp -lt $min ]; then
24531                         min=$tmp
24532                         min_index=$i
24533                 fi
24534         done
24535
24536         # Check if we need to generate uneven MDTs
24537         local diff=$(((max - min) * 100 / min))
24538         local testdir=$DIR/$tdir-fillmdt
24539
24540         mkdir -p $testdir
24541
24542         i=0
24543         while (( diff < threshold )); do
24544                 # generate uneven MDTs, create till $threshold% diff
24545                 echo -n "weight diff=$diff% must be > $threshold% ..."
24546                 echo "Fill MDT$min_index with 100 files: loop $i"
24547                 testdir=$DIR/$tdir-fillmdt/$i
24548                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24549                         error "mkdir $testdir failed"
24550                 $LFS setstripe -E 1M -L mdt $testdir ||
24551                         error "setstripe $testdir failed"
24552                 for F in f.{0..99}; do
24553                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24554                                 /dev/null 2>&1 || error "dd $F failed"
24555                 done
24556
24557                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24558                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24559                 max=$(((${ffree[max_index]} >> 8) * \
24560                         (${bavail[max_index]} * bsize >> 16)))
24561                 min=$(((${ffree[min_index]} >> 8) * \
24562                         (${bavail[min_index]} * bsize >> 16)))
24563                 diff=$(((max - min) * 100 / min))
24564                 i=$((i + 1))
24565         done
24566
24567         echo "MDT filesfree available: ${ffree[@]}"
24568         echo "MDT blocks available: ${bavail[@]}"
24569         echo "weight diff=$diff%"
24570 }
24571
24572 test_qos_mkdir() {
24573         local mkdir_cmd=$1
24574         local stripe_count=$2
24575         local mdts=$(comma_list $(mdts_nodes))
24576
24577         local testdir
24578         local lmv_qos_prio_free
24579         local lmv_qos_threshold_rr
24580         local lmv_qos_maxage
24581         local lod_qos_prio_free
24582         local lod_qos_threshold_rr
24583         local lod_qos_maxage
24584         local count
24585         local i
24586
24587         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24588         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24589         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24590                 head -n1)
24591         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24592         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24593         stack_trap "$LCTL set_param \
24594                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24595         stack_trap "$LCTL set_param \
24596                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24597         stack_trap "$LCTL set_param \
24598                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24599
24600         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24601                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24602         lod_qos_prio_free=${lod_qos_prio_free%%%}
24603         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24604                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24605         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24606         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24607                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24608         stack_trap "do_nodes $mdts $LCTL set_param \
24609                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24610         stack_trap "do_nodes $mdts $LCTL set_param \
24611                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24612         stack_trap "do_nodes $mdts $LCTL set_param \
24613                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24614
24615         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24616         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24617
24618         testdir=$DIR/$tdir-s$stripe_count/rr
24619
24620         local stripe_index=$($LFS getstripe -m $testdir)
24621         local test_mkdir_rr=true
24622
24623         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24624         getfattr -d -m dmv -e hex $testdir | grep dmv
24625         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24626                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24627                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24628                         test_mkdir_rr=false
24629         fi
24630
24631         echo
24632         $test_mkdir_rr &&
24633                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24634                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24635
24636         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24637         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24638                 eval $mkdir_cmd $testdir/subdir$i ||
24639                         error "$mkdir_cmd subdir$i failed"
24640         done
24641
24642         for (( i = 0; i < $MDSCOUNT; i++ )); do
24643                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24644                 echo "$count directories created on MDT$i"
24645                 if $test_mkdir_rr; then
24646                         (( $count == 100 )) ||
24647                                 error "subdirs are not evenly distributed"
24648                 elif (( $i == $stripe_index )); then
24649                         (( $count == 100 * MDSCOUNT )) ||
24650                                 error "$count subdirs created on MDT$i"
24651                 else
24652                         (( $count == 0 )) ||
24653                                 error "$count subdirs created on MDT$i"
24654                 fi
24655
24656                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24657                         count=$($LFS getdirstripe $testdir/* |
24658                                 grep -c -P "^\s+$i\t")
24659                         echo "$count stripes created on MDT$i"
24660                         # deviation should < 5% of average
24661                         (( $count >= 95 * stripe_count &&
24662                            $count <= 105 * stripe_count)) ||
24663                                 error "stripes are not evenly distributed"
24664                 fi
24665         done
24666
24667         echo
24668         echo "Check for uneven MDTs: "
24669
24670         local ffree
24671         local bavail
24672         local max
24673         local min
24674         local max_index
24675         local min_index
24676         local tmp
24677
24678         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24679         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24680         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24681
24682         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24683         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24684         max_index=0
24685         min_index=0
24686         for ((i = 1; i < ${#ffree[@]}; i++)); do
24687                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24688                 if [ $tmp -gt $max ]; then
24689                         max=$tmp
24690                         max_index=$i
24691                 fi
24692                 if [ $tmp -lt $min ]; then
24693                         min=$tmp
24694                         min_index=$i
24695                 fi
24696         done
24697
24698         (( ${ffree[min_index]} > 0 )) ||
24699                 skip "no free files in MDT$min_index"
24700         (( ${ffree[min_index]} < 100000000 )) ||
24701                 skip "too many free files in MDT$min_index"
24702
24703         echo "MDT filesfree available: ${ffree[@]}"
24704         echo "MDT blocks available: ${bavail[@]}"
24705         echo "weight diff=$(((max - min) * 100 / min))%"
24706         echo
24707         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24708
24709         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24710         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24711         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24712         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24713         # decrease statfs age, so that it can be updated in time
24714         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24715         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24716
24717         sleep 1
24718
24719         testdir=$DIR/$tdir-s$stripe_count/qos
24720         local num=200
24721
24722         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24723         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24724                 eval $mkdir_cmd $testdir/subdir$i ||
24725                         error "$mkdir_cmd subdir$i failed"
24726         done
24727
24728         for (( i = 0; i < $MDSCOUNT; i++ )); do
24729                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24730                 echo "$count directories created on MDT$i"
24731
24732                 if [ $stripe_count -gt 1 ]; then
24733                         count=$($LFS getdirstripe $testdir/* |
24734                                 grep -c -P "^\s+$i\t")
24735                         echo "$count stripes created on MDT$i"
24736                 fi
24737         done
24738
24739         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24740         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24741
24742         # D-value should > 10% of averge
24743         (( max - min >= num / 10 )) ||
24744                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24745
24746         # 5% for stripes
24747         if (( stripe_count > 1 )); then
24748                 max=$($LFS getdirstripe $testdir/* |
24749                       grep -c -P "^\s+$max_index\t")
24750                 min=$($LFS getdirstripe $testdir/* |
24751                         grep -c -P "^\s+$min_index\t")
24752                 (( max - min >= num * stripe_count / 20 )) ||
24753                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24754         fi
24755 }
24756
24757 most_full_mdt() {
24758         local ffree
24759         local bavail
24760         local bsize
24761         local min
24762         local min_index
24763         local tmp
24764
24765         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24766         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24767         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24768
24769         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24770         min_index=0
24771         for ((i = 1; i < ${#ffree[@]}; i++)); do
24772                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24773                 (( tmp < min )) && min=$tmp && min_index=$i
24774         done
24775
24776         echo -n $min_index
24777 }
24778
24779 test_413a() {
24780         [ $MDSCOUNT -lt 2 ] &&
24781                 skip "We need at least 2 MDTs for this test"
24782
24783         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24784                 skip "Need server version at least 2.12.52"
24785
24786         local stripe_count
24787
24788         generate_uneven_mdts 100
24789         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24790                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24791                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24792                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
24793                         error "mkdir failed"
24794                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
24795         done
24796 }
24797 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24798
24799 test_413b() {
24800         [ $MDSCOUNT -lt 2 ] &&
24801                 skip "We need at least 2 MDTs for this test"
24802
24803         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24804                 skip "Need server version at least 2.12.52"
24805
24806         local testdir
24807         local stripe_count
24808
24809         generate_uneven_mdts 100
24810         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24811                 testdir=$DIR/$tdir-s$stripe_count
24812                 mkdir $testdir || error "mkdir $testdir failed"
24813                 mkdir $testdir/rr || error "mkdir rr failed"
24814                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
24815                         error "mkdir qos failed"
24816                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24817                         $testdir/rr || error "setdirstripe rr failed"
24818                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24819                         error "setdirstripe failed"
24820                 test_qos_mkdir "mkdir" $stripe_count
24821         done
24822 }
24823 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24824
24825 test_413c() {
24826         (( $MDSCOUNT >= 2 )) ||
24827                 skip "We need at least 2 MDTs for this test"
24828
24829         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
24830                 skip "Need server version at least 2.14.51"
24831
24832         local testdir
24833         local inherit
24834         local inherit_rr
24835
24836         testdir=$DIR/${tdir}-s1
24837         mkdir $testdir || error "mkdir $testdir failed"
24838         mkdir $testdir/rr || error "mkdir rr failed"
24839         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
24840         # default max_inherit is -1, default max_inherit_rr is 0
24841         $LFS setdirstripe -D -c 1 $testdir/rr ||
24842                 error "setdirstripe rr failed"
24843         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24844                 error "setdirstripe qos failed"
24845         test_qos_mkdir "mkdir" 1
24846
24847         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24848         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24849         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24850         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24851         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
24852
24853         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24854         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24855         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24856         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24857         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
24858         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24859         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
24860                 error "level2 shouldn't have default LMV" || true
24861 }
24862 run_test 413c "mkdir with default LMV max inherit rr"
24863
24864 test_413z() {
24865         local pids=""
24866         local subdir
24867         local pid
24868
24869         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
24870                 unlinkmany $subdir/f. 100 &
24871                 pids="$pids $!"
24872         done
24873
24874         for pid in $pids; do
24875                 wait $pid
24876         done
24877 }
24878 run_test 413z "413 test cleanup"
24879
24880 test_414() {
24881 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24882         $LCTL set_param fail_loc=0x80000521
24883         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24884         rm -f $DIR/$tfile
24885 }
24886 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24887
24888 test_415() {
24889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24890         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24891                 skip "Need server version at least 2.11.52"
24892
24893         # LU-11102
24894         local total
24895         local setattr_pid
24896         local start_time
24897         local end_time
24898         local duration
24899
24900         total=500
24901         # this test may be slow on ZFS
24902         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24903
24904         # though this test is designed for striped directory, let's test normal
24905         # directory too since lock is always saved as CoS lock.
24906         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24907         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24908
24909         (
24910                 while true; do
24911                         touch $DIR/$tdir
24912                 done
24913         ) &
24914         setattr_pid=$!
24915
24916         start_time=$(date +%s)
24917         for i in $(seq $total); do
24918                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24919                         > /dev/null
24920         done
24921         end_time=$(date +%s)
24922         duration=$((end_time - start_time))
24923
24924         kill -9 $setattr_pid
24925
24926         echo "rename $total files took $duration sec"
24927         [ $duration -lt 100 ] || error "rename took $duration sec"
24928 }
24929 run_test 415 "lock revoke is not missing"
24930
24931 test_416() {
24932         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24933                 skip "Need server version at least 2.11.55"
24934
24935         # define OBD_FAIL_OSD_TXN_START    0x19a
24936         do_facet mds1 lctl set_param fail_loc=0x19a
24937
24938         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24939
24940         true
24941 }
24942 run_test 416 "transaction start failure won't cause system hung"
24943
24944 cleanup_417() {
24945         trap 0
24946         do_nodes $(comma_list $(mdts_nodes)) \
24947                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24948         do_nodes $(comma_list $(mdts_nodes)) \
24949                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24950         do_nodes $(comma_list $(mdts_nodes)) \
24951                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24952 }
24953
24954 test_417() {
24955         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24956         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24957                 skip "Need MDS version at least 2.11.56"
24958
24959         trap cleanup_417 RETURN EXIT
24960
24961         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24962         do_nodes $(comma_list $(mdts_nodes)) \
24963                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24964         $LFS migrate -m 0 $DIR/$tdir.1 &&
24965                 error "migrate dir $tdir.1 should fail"
24966
24967         do_nodes $(comma_list $(mdts_nodes)) \
24968                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24969         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24970                 error "create remote dir $tdir.2 should fail"
24971
24972         do_nodes $(comma_list $(mdts_nodes)) \
24973                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24974         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24975                 error "create striped dir $tdir.3 should fail"
24976         true
24977 }
24978 run_test 417 "disable remote dir, striped dir and dir migration"
24979
24980 # Checks that the outputs of df [-i] and lfs df [-i] match
24981 #
24982 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24983 check_lfs_df() {
24984         local dir=$2
24985         local inodes
24986         local df_out
24987         local lfs_df_out
24988         local count
24989         local passed=false
24990
24991         # blocks or inodes
24992         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24993
24994         for count in {1..100}; do
24995                 cancel_lru_locks
24996                 sync; sleep 0.2
24997
24998                 # read the lines of interest
24999                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25000                         error "df $inodes $dir | tail -n +2 failed"
25001                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25002                         error "lfs df $inodes $dir | grep summary: failed"
25003
25004                 # skip first substrings of each output as they are different
25005                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25006                 # compare the two outputs
25007                 passed=true
25008                 for i in {1..5}; do
25009                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25010                 done
25011                 $passed && break
25012         done
25013
25014         if ! $passed; then
25015                 df -P $inodes $dir
25016                 echo
25017                 lfs df $inodes $dir
25018                 error "df and lfs df $1 output mismatch: "      \
25019                       "df ${inodes}: ${df_out[*]}, "            \
25020                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25021         fi
25022 }
25023
25024 test_418() {
25025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25026
25027         local dir=$DIR/$tdir
25028         local numfiles=$((RANDOM % 4096 + 2))
25029         local numblocks=$((RANDOM % 256 + 1))
25030
25031         wait_delete_completed
25032         test_mkdir $dir
25033
25034         # check block output
25035         check_lfs_df blocks $dir
25036         # check inode output
25037         check_lfs_df inodes $dir
25038
25039         # create a single file and retest
25040         echo "Creating a single file and testing"
25041         createmany -o $dir/$tfile- 1 &>/dev/null ||
25042                 error "creating 1 file in $dir failed"
25043         check_lfs_df blocks $dir
25044         check_lfs_df inodes $dir
25045
25046         # create a random number of files
25047         echo "Creating $((numfiles - 1)) files and testing"
25048         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25049                 error "creating $((numfiles - 1)) files in $dir failed"
25050
25051         # write a random number of blocks to the first test file
25052         echo "Writing $numblocks 4K blocks and testing"
25053         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25054                 count=$numblocks &>/dev/null ||
25055                 error "dd to $dir/${tfile}-0 failed"
25056
25057         # retest
25058         check_lfs_df blocks $dir
25059         check_lfs_df inodes $dir
25060
25061         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25062                 error "unlinking $numfiles files in $dir failed"
25063 }
25064 run_test 418 "df and lfs df outputs match"
25065
25066 test_419()
25067 {
25068         local dir=$DIR/$tdir
25069
25070         mkdir -p $dir
25071         touch $dir/file
25072
25073         cancel_lru_locks mdc
25074
25075         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25076         $LCTL set_param fail_loc=0x1410
25077         cat $dir/file
25078         $LCTL set_param fail_loc=0
25079         rm -rf $dir
25080 }
25081 run_test 419 "Verify open file by name doesn't crash kernel"
25082
25083 test_420()
25084 {
25085         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25086                 skip "Need MDS version at least 2.12.53"
25087
25088         local SAVE_UMASK=$(umask)
25089         local dir=$DIR/$tdir
25090         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25091
25092         mkdir -p $dir
25093         umask 0000
25094         mkdir -m03777 $dir/testdir
25095         ls -dn $dir/testdir
25096         # Need to remove trailing '.' when SELinux is enabled
25097         local dirperms=$(ls -dn $dir/testdir |
25098                          awk '{ sub(/\.$/, "", $1); print $1}')
25099         [ $dirperms == "drwxrwsrwt" ] ||
25100                 error "incorrect perms on $dir/testdir"
25101
25102         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25103                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25104         ls -n $dir/testdir/testfile
25105         local fileperms=$(ls -n $dir/testdir/testfile |
25106                           awk '{ sub(/\.$/, "", $1); print $1}')
25107         [ $fileperms == "-rwxr-xr-x" ] ||
25108                 error "incorrect perms on $dir/testdir/testfile"
25109
25110         umask $SAVE_UMASK
25111 }
25112 run_test 420 "clear SGID bit on non-directories for non-members"
25113
25114 test_421a() {
25115         local cnt
25116         local fid1
25117         local fid2
25118
25119         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25120                 skip "Need MDS version at least 2.12.54"
25121
25122         test_mkdir $DIR/$tdir
25123         createmany -o $DIR/$tdir/f 3
25124         cnt=$(ls -1 $DIR/$tdir | wc -l)
25125         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25126
25127         fid1=$(lfs path2fid $DIR/$tdir/f1)
25128         fid2=$(lfs path2fid $DIR/$tdir/f2)
25129         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25130
25131         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25132         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25133
25134         cnt=$(ls -1 $DIR/$tdir | wc -l)
25135         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25136
25137         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25138         createmany -o $DIR/$tdir/f 3
25139         cnt=$(ls -1 $DIR/$tdir | wc -l)
25140         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25141
25142         fid1=$(lfs path2fid $DIR/$tdir/f1)
25143         fid2=$(lfs path2fid $DIR/$tdir/f2)
25144         echo "remove using fsname $FSNAME"
25145         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25146
25147         cnt=$(ls -1 $DIR/$tdir | wc -l)
25148         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25149 }
25150 run_test 421a "simple rm by fid"
25151
25152 test_421b() {
25153         local cnt
25154         local FID1
25155         local FID2
25156
25157         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25158                 skip "Need MDS version at least 2.12.54"
25159
25160         test_mkdir $DIR/$tdir
25161         createmany -o $DIR/$tdir/f 3
25162         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25163         MULTIPID=$!
25164
25165         FID1=$(lfs path2fid $DIR/$tdir/f1)
25166         FID2=$(lfs path2fid $DIR/$tdir/f2)
25167         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25168
25169         kill -USR1 $MULTIPID
25170         wait
25171
25172         cnt=$(ls $DIR/$tdir | wc -l)
25173         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25174 }
25175 run_test 421b "rm by fid on open file"
25176
25177 test_421c() {
25178         local cnt
25179         local FIDS
25180
25181         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25182                 skip "Need MDS version at least 2.12.54"
25183
25184         test_mkdir $DIR/$tdir
25185         createmany -o $DIR/$tdir/f 3
25186         touch $DIR/$tdir/$tfile
25187         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25188         cnt=$(ls -1 $DIR/$tdir | wc -l)
25189         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25190
25191         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25192         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25193
25194         cnt=$(ls $DIR/$tdir | wc -l)
25195         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25196 }
25197 run_test 421c "rm by fid against hardlinked files"
25198
25199 test_421d() {
25200         local cnt
25201         local FIDS
25202
25203         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25204                 skip "Need MDS version at least 2.12.54"
25205
25206         test_mkdir $DIR/$tdir
25207         createmany -o $DIR/$tdir/f 4097
25208         cnt=$(ls -1 $DIR/$tdir | wc -l)
25209         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25210
25211         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25212         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25213
25214         cnt=$(ls $DIR/$tdir | wc -l)
25215         rm -rf $DIR/$tdir
25216         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25217 }
25218 run_test 421d "rmfid en masse"
25219
25220 test_421e() {
25221         local cnt
25222         local FID
25223
25224         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25225         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25226                 skip "Need MDS version at least 2.12.54"
25227
25228         mkdir -p $DIR/$tdir
25229         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25230         createmany -o $DIR/$tdir/striped_dir/f 512
25231         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25232         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25233
25234         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25235                 sed "s/[/][^:]*://g")
25236         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25237
25238         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25239         rm -rf $DIR/$tdir
25240         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25241 }
25242 run_test 421e "rmfid in DNE"
25243
25244 test_421f() {
25245         local cnt
25246         local FID
25247
25248         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25249                 skip "Need MDS version at least 2.12.54"
25250
25251         test_mkdir $DIR/$tdir
25252         touch $DIR/$tdir/f
25253         cnt=$(ls -1 $DIR/$tdir | wc -l)
25254         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25255
25256         FID=$(lfs path2fid $DIR/$tdir/f)
25257         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25258         # rmfid should fail
25259         cnt=$(ls -1 $DIR/$tdir | wc -l)
25260         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25261
25262         chmod a+rw $DIR/$tdir
25263         ls -la $DIR/$tdir
25264         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25265         # rmfid should fail
25266         cnt=$(ls -1 $DIR/$tdir | wc -l)
25267         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25268
25269         rm -f $DIR/$tdir/f
25270         $RUNAS touch $DIR/$tdir/f
25271         FID=$(lfs path2fid $DIR/$tdir/f)
25272         echo "rmfid as root"
25273         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25274         cnt=$(ls -1 $DIR/$tdir | wc -l)
25275         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25276
25277         rm -f $DIR/$tdir/f
25278         $RUNAS touch $DIR/$tdir/f
25279         cnt=$(ls -1 $DIR/$tdir | wc -l)
25280         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25281         FID=$(lfs path2fid $DIR/$tdir/f)
25282         # rmfid w/o user_fid2path mount option should fail
25283         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25284         cnt=$(ls -1 $DIR/$tdir | wc -l)
25285         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25286
25287         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25288         stack_trap "rmdir $tmpdir"
25289         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25290                 error "failed to mount client'"
25291         stack_trap "umount_client $tmpdir"
25292
25293         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25294         # rmfid should succeed
25295         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25296         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25297
25298         # rmfid shouldn't allow to remove files due to dir's permission
25299         chmod a+rwx $tmpdir/$tdir
25300         touch $tmpdir/$tdir/f
25301         ls -la $tmpdir/$tdir
25302         FID=$(lfs path2fid $tmpdir/$tdir/f)
25303         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25304         return 0
25305 }
25306 run_test 421f "rmfid checks permissions"
25307
25308 test_421g() {
25309         local cnt
25310         local FIDS
25311
25312         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25313         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25314                 skip "Need MDS version at least 2.12.54"
25315
25316         mkdir -p $DIR/$tdir
25317         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25318         createmany -o $DIR/$tdir/striped_dir/f 512
25319         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25320         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25321
25322         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25323                 sed "s/[/][^:]*://g")
25324
25325         rm -f $DIR/$tdir/striped_dir/f1*
25326         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25327         removed=$((512 - cnt))
25328
25329         # few files have been just removed, so we expect
25330         # rmfid to fail on their fids
25331         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25332         [ $removed != $errors ] && error "$errors != $removed"
25333
25334         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25335         rm -rf $DIR/$tdir
25336         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25337 }
25338 run_test 421g "rmfid to return errors properly"
25339
25340 test_422() {
25341         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25342         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25343         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25344         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25345         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25346
25347         local amc=$(at_max_get client)
25348         local amo=$(at_max_get mds1)
25349         local timeout=`lctl get_param -n timeout`
25350
25351         at_max_set 0 client
25352         at_max_set 0 mds1
25353
25354 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25355         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25356                         fail_val=$(((2*timeout + 10)*1000))
25357         touch $DIR/$tdir/d3/file &
25358         sleep 2
25359 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25360         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25361                         fail_val=$((2*timeout + 5))
25362         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25363         local pid=$!
25364         sleep 1
25365         kill -9 $pid
25366         sleep $((2 * timeout))
25367         echo kill $pid
25368         kill -9 $pid
25369         lctl mark touch
25370         touch $DIR/$tdir/d2/file3
25371         touch $DIR/$tdir/d2/file4
25372         touch $DIR/$tdir/d2/file5
25373
25374         wait
25375         at_max_set $amc client
25376         at_max_set $amo mds1
25377
25378         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25379         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25380                 error "Watchdog is always throttled"
25381 }
25382 run_test 422 "kill a process with RPC in progress"
25383
25384 stat_test() {
25385     df -h $MOUNT &
25386     df -h $MOUNT &
25387     df -h $MOUNT &
25388     df -h $MOUNT &
25389     df -h $MOUNT &
25390     df -h $MOUNT &
25391 }
25392
25393 test_423() {
25394     local _stats
25395     # ensure statfs cache is expired
25396     sleep 2;
25397
25398     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25399     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25400
25401     return 0
25402 }
25403 run_test 423 "statfs should return a right data"
25404
25405 test_424() {
25406 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25407         $LCTL set_param fail_loc=0x80000522
25408         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25409         rm -f $DIR/$tfile
25410 }
25411 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25412
25413 test_425() {
25414         test_mkdir -c -1 $DIR/$tdir
25415         $LFS setstripe -c -1 $DIR/$tdir
25416
25417         lru_resize_disable "" 100
25418         stack_trap "lru_resize_enable" EXIT
25419
25420         sleep 5
25421
25422         for i in $(seq $((MDSCOUNT * 125))); do
25423                 local t=$DIR/$tdir/$tfile_$i
25424
25425                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25426                         error_noexit "Create file $t"
25427         done
25428         stack_trap "rm -rf $DIR/$tdir" EXIT
25429
25430         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25431                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25432                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25433
25434                 [ $lock_count -le $lru_size ] ||
25435                         error "osc lock count $lock_count > lru size $lru_size"
25436         done
25437
25438         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25439                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25440                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25441
25442                 [ $lock_count -le $lru_size ] ||
25443                         error "mdc lock count $lock_count > lru size $lru_size"
25444         done
25445 }
25446 run_test 425 "lock count should not exceed lru size"
25447
25448 test_426() {
25449         splice-test -r $DIR/$tfile
25450         splice-test -rd $DIR/$tfile
25451         splice-test $DIR/$tfile
25452         splice-test -d $DIR/$tfile
25453 }
25454 run_test 426 "splice test on Lustre"
25455
25456 test_427() {
25457         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25458         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25459                 skip "Need MDS version at least 2.12.4"
25460         local log
25461
25462         mkdir $DIR/$tdir
25463         mkdir $DIR/$tdir/1
25464         mkdir $DIR/$tdir/2
25465         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25466         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25467
25468         $LFS getdirstripe $DIR/$tdir/1/dir
25469
25470         #first setfattr for creating updatelog
25471         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25472
25473 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25474         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25475         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25476         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25477
25478         sleep 2
25479         fail mds2
25480         wait_recovery_complete mds2 $((2*TIMEOUT))
25481
25482         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25483         echo $log | grep "get update log failed" &&
25484                 error "update log corruption is detected" || true
25485 }
25486 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25487
25488 test_428() {
25489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25490         local cache_limit=$CACHE_MAX
25491
25492         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25493         $LCTL set_param -n llite.*.max_cached_mb=64
25494
25495         mkdir $DIR/$tdir
25496         $LFS setstripe -c 1 $DIR/$tdir
25497         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25498         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25499         #test write
25500         for f in $(seq 4); do
25501                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25502         done
25503         wait
25504
25505         cancel_lru_locks osc
25506         # Test read
25507         for f in $(seq 4); do
25508                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25509         done
25510         wait
25511 }
25512 run_test 428 "large block size IO should not hang"
25513
25514 test_429() { # LU-7915 / LU-10948
25515         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25516         local testfile=$DIR/$tfile
25517         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25518         local new_flag=1
25519         local first_rpc
25520         local second_rpc
25521         local third_rpc
25522
25523         $LCTL get_param $ll_opencache_threshold_count ||
25524                 skip "client does not have opencache parameter"
25525
25526         set_opencache $new_flag
25527         stack_trap "restore_opencache"
25528         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25529                 error "enable opencache failed"
25530         touch $testfile
25531         # drop MDC DLM locks
25532         cancel_lru_locks mdc
25533         # clear MDC RPC stats counters
25534         $LCTL set_param $mdc_rpcstats=clear
25535
25536         # According to the current implementation, we need to run 3 times
25537         # open & close file to verify if opencache is enabled correctly.
25538         # 1st, RPCs are sent for lookup/open and open handle is released on
25539         #      close finally.
25540         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25541         #      so open handle won't be released thereafter.
25542         # 3rd, No RPC is sent out.
25543         $MULTIOP $testfile oc || error "multiop failed"
25544         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25545         echo "1st: $first_rpc RPCs in flight"
25546
25547         $MULTIOP $testfile oc || error "multiop failed"
25548         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25549         echo "2nd: $second_rpc RPCs in flight"
25550
25551         $MULTIOP $testfile oc || error "multiop failed"
25552         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25553         echo "3rd: $third_rpc RPCs in flight"
25554
25555         #verify no MDC RPC is sent
25556         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25557 }
25558 run_test 429 "verify if opencache flag on client side does work"
25559
25560 lseek_test_430() {
25561         local offset
25562         local file=$1
25563
25564         # data at [200K, 400K)
25565         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25566                 error "256K->512K dd fails"
25567         # data at [2M, 3M)
25568         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25569                 error "2M->3M dd fails"
25570         # data at [4M, 5M)
25571         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25572                 error "4M->5M dd fails"
25573         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25574         # start at first component hole #1
25575         printf "Seeking hole from 1000 ... "
25576         offset=$(lseek_test -l 1000 $file)
25577         echo $offset
25578         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25579         printf "Seeking data from 1000 ... "
25580         offset=$(lseek_test -d 1000 $file)
25581         echo $offset
25582         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25583
25584         # start at first component data block
25585         printf "Seeking hole from 300000 ... "
25586         offset=$(lseek_test -l 300000 $file)
25587         echo $offset
25588         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25589         printf "Seeking data from 300000 ... "
25590         offset=$(lseek_test -d 300000 $file)
25591         echo $offset
25592         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25593
25594         # start at the first component but beyond end of object size
25595         printf "Seeking hole from 1000000 ... "
25596         offset=$(lseek_test -l 1000000 $file)
25597         echo $offset
25598         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25599         printf "Seeking data from 1000000 ... "
25600         offset=$(lseek_test -d 1000000 $file)
25601         echo $offset
25602         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25603
25604         # start at second component stripe 2 (empty file)
25605         printf "Seeking hole from 1500000 ... "
25606         offset=$(lseek_test -l 1500000 $file)
25607         echo $offset
25608         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25609         printf "Seeking data from 1500000 ... "
25610         offset=$(lseek_test -d 1500000 $file)
25611         echo $offset
25612         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25613
25614         # start at second component stripe 1 (all data)
25615         printf "Seeking hole from 3000000 ... "
25616         offset=$(lseek_test -l 3000000 $file)
25617         echo $offset
25618         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25619         printf "Seeking data from 3000000 ... "
25620         offset=$(lseek_test -d 3000000 $file)
25621         echo $offset
25622         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25623
25624         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25625                 error "2nd dd fails"
25626         echo "Add data block at 640K...1280K"
25627
25628         # start at before new data block, in hole
25629         printf "Seeking hole from 600000 ... "
25630         offset=$(lseek_test -l 600000 $file)
25631         echo $offset
25632         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25633         printf "Seeking data from 600000 ... "
25634         offset=$(lseek_test -d 600000 $file)
25635         echo $offset
25636         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25637
25638         # start at the first component new data block
25639         printf "Seeking hole from 1000000 ... "
25640         offset=$(lseek_test -l 1000000 $file)
25641         echo $offset
25642         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25643         printf "Seeking data from 1000000 ... "
25644         offset=$(lseek_test -d 1000000 $file)
25645         echo $offset
25646         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25647
25648         # start at second component stripe 2, new data
25649         printf "Seeking hole from 1200000 ... "
25650         offset=$(lseek_test -l 1200000 $file)
25651         echo $offset
25652         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25653         printf "Seeking data from 1200000 ... "
25654         offset=$(lseek_test -d 1200000 $file)
25655         echo $offset
25656         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25657
25658         # start beyond file end
25659         printf "Using offset > filesize ... "
25660         lseek_test -l 4000000 $file && error "lseek should fail"
25661         printf "Using offset > filesize ... "
25662         lseek_test -d 4000000 $file && error "lseek should fail"
25663
25664         printf "Done\n\n"
25665 }
25666
25667 test_430a() {
25668         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25669                 skip "MDT does not support SEEK_HOLE"
25670
25671         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25672                 skip "OST does not support SEEK_HOLE"
25673
25674         local file=$DIR/$tdir/$tfile
25675
25676         mkdir -p $DIR/$tdir
25677
25678         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25679         # OST stripe #1 will have continuous data at [1M, 3M)
25680         # OST stripe #2 is empty
25681         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25682         lseek_test_430 $file
25683         rm $file
25684         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25685         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25686         lseek_test_430 $file
25687         rm $file
25688         $LFS setstripe -c2 -S 512K $file
25689         echo "Two stripes, stripe size 512K"
25690         lseek_test_430 $file
25691         rm $file
25692         # FLR with stale mirror
25693         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25694                        -N -c2 -S 1M $file
25695         echo "Mirrored file:"
25696         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25697         echo "Plain 2 stripes 1M"
25698         lseek_test_430 $file
25699         rm $file
25700 }
25701 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25702
25703 test_430b() {
25704         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25705                 skip "OST does not support SEEK_HOLE"
25706
25707         local offset
25708         local file=$DIR/$tdir/$tfile
25709
25710         mkdir -p $DIR/$tdir
25711         # Empty layout lseek should fail
25712         $MCREATE $file
25713         # seek from 0
25714         printf "Seeking hole from 0 ... "
25715         lseek_test -l 0 $file && error "lseek should fail"
25716         printf "Seeking data from 0 ... "
25717         lseek_test -d 0 $file && error "lseek should fail"
25718         rm $file
25719
25720         # 1M-hole file
25721         $LFS setstripe -E 1M -c2 -E eof $file
25722         $TRUNCATE $file 1048576
25723         printf "Seeking hole from 1000000 ... "
25724         offset=$(lseek_test -l 1000000 $file)
25725         echo $offset
25726         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25727         printf "Seeking data from 1000000 ... "
25728         lseek_test -d 1000000 $file && error "lseek should fail"
25729         rm $file
25730
25731         # full component followed by non-inited one
25732         $LFS setstripe -E 1M -c2 -E eof $file
25733         dd if=/dev/urandom of=$file bs=1M count=1
25734         printf "Seeking hole from 1000000 ... "
25735         offset=$(lseek_test -l 1000000 $file)
25736         echo $offset
25737         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25738         printf "Seeking hole from 1048576 ... "
25739         lseek_test -l 1048576 $file && error "lseek should fail"
25740         # init second component and truncate back
25741         echo "123" >> $file
25742         $TRUNCATE $file 1048576
25743         printf "Seeking hole from 1000000 ... "
25744         offset=$(lseek_test -l 1000000 $file)
25745         echo $offset
25746         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25747         printf "Seeking hole from 1048576 ... "
25748         lseek_test -l 1048576 $file && error "lseek should fail"
25749         # boundary checks for big values
25750         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25751         offset=$(lseek_test -d 0 $file.10g)
25752         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25753         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25754         offset=$(lseek_test -d 0 $file.100g)
25755         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25756         return 0
25757 }
25758 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25759
25760 test_430c() {
25761         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25762                 skip "OST does not support SEEK_HOLE"
25763
25764         local file=$DIR/$tdir/$tfile
25765         local start
25766
25767         mkdir -p $DIR/$tdir
25768         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25769
25770         # cp version 8.33+ prefers lseek over fiemap
25771         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25772                 start=$SECONDS
25773                 time cp $file /dev/null
25774                 (( SECONDS - start < 5 )) ||
25775                         error "cp: too long runtime $((SECONDS - start))"
25776
25777         fi
25778         # tar version 1.29+ supports SEEK_HOLE/DATA
25779         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25780                 start=$SECONDS
25781                 time tar cS $file - | cat > /dev/null
25782                 (( SECONDS - start < 5 )) ||
25783                         error "tar: too long runtime $((SECONDS - start))"
25784         fi
25785 }
25786 run_test 430c "lseek: external tools check"
25787
25788 test_431() { # LU-14187
25789         local file=$DIR/$tdir/$tfile
25790
25791         mkdir -p $DIR/$tdir
25792         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25793         dd if=/dev/urandom of=$file bs=4k count=1
25794         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25795         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25796         #define OBD_FAIL_OST_RESTART_IO 0x251
25797         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25798         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25799         cp $file $file.0
25800         cancel_lru_locks
25801         sync_all_data
25802         echo 3 > /proc/sys/vm/drop_caches
25803         diff  $file $file.0 || error "data diff"
25804 }
25805 run_test 431 "Restart transaction for IO"
25806
25807 cleanup_test_432() {
25808         do_facet mgs $LCTL nodemap_activate 0
25809         wait_nm_sync active
25810 }
25811
25812 test_432() {
25813         local tmpdir=$TMP/dir432
25814
25815         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
25816                 skip "Need MDS version at least 2.14.52"
25817
25818         stack_trap cleanup_test_432 EXIT
25819         mkdir $DIR/$tdir
25820         mkdir $tmpdir
25821
25822         do_facet mgs $LCTL nodemap_activate 1
25823         wait_nm_sync active
25824         do_facet mgs $LCTL nodemap_modify --name default \
25825                 --property admin --value 1
25826         do_facet mgs $LCTL nodemap_modify --name default \
25827                 --property trusted --value 1
25828         cancel_lru_locks mdc
25829         wait_nm_sync default admin_nodemap
25830         wait_nm_sync default trusted_nodemap
25831
25832         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
25833                grep -ci "Operation not permitted") -ne 0 ]; then
25834                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
25835         fi
25836 }
25837 run_test 432 "mv dir from outside Lustre"
25838
25839 prep_801() {
25840         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25841         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25842                 skip "Need server version at least 2.9.55"
25843
25844         start_full_debug_logging
25845 }
25846
25847 post_801() {
25848         stop_full_debug_logging
25849 }
25850
25851 barrier_stat() {
25852         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25853                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25854                            awk '/The barrier for/ { print $7 }')
25855                 echo $st
25856         else
25857                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25858                 echo \'$st\'
25859         fi
25860 }
25861
25862 barrier_expired() {
25863         local expired
25864
25865         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25866                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25867                           awk '/will be expired/ { print $7 }')
25868         else
25869                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25870         fi
25871
25872         echo $expired
25873 }
25874
25875 test_801a() {
25876         prep_801
25877
25878         echo "Start barrier_freeze at: $(date)"
25879         #define OBD_FAIL_BARRIER_DELAY          0x2202
25880         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25881         # Do not reduce barrier time - See LU-11873
25882         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25883
25884         sleep 2
25885         local b_status=$(barrier_stat)
25886         echo "Got barrier status at: $(date)"
25887         [ "$b_status" = "'freezing_p1'" ] ||
25888                 error "(1) unexpected barrier status $b_status"
25889
25890         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25891         wait
25892         b_status=$(barrier_stat)
25893         [ "$b_status" = "'frozen'" ] ||
25894                 error "(2) unexpected barrier status $b_status"
25895
25896         local expired=$(barrier_expired)
25897         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25898         sleep $((expired + 3))
25899
25900         b_status=$(barrier_stat)
25901         [ "$b_status" = "'expired'" ] ||
25902                 error "(3) unexpected barrier status $b_status"
25903
25904         # Do not reduce barrier time - See LU-11873
25905         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25906                 error "(4) fail to freeze barrier"
25907
25908         b_status=$(barrier_stat)
25909         [ "$b_status" = "'frozen'" ] ||
25910                 error "(5) unexpected barrier status $b_status"
25911
25912         echo "Start barrier_thaw at: $(date)"
25913         #define OBD_FAIL_BARRIER_DELAY          0x2202
25914         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25915         do_facet mgs $LCTL barrier_thaw $FSNAME &
25916
25917         sleep 2
25918         b_status=$(barrier_stat)
25919         echo "Got barrier status at: $(date)"
25920         [ "$b_status" = "'thawing'" ] ||
25921                 error "(6) unexpected barrier status $b_status"
25922
25923         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25924         wait
25925         b_status=$(barrier_stat)
25926         [ "$b_status" = "'thawed'" ] ||
25927                 error "(7) unexpected barrier status $b_status"
25928
25929         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25930         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25931         do_facet mgs $LCTL barrier_freeze $FSNAME
25932
25933         b_status=$(barrier_stat)
25934         [ "$b_status" = "'failed'" ] ||
25935                 error "(8) unexpected barrier status $b_status"
25936
25937         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25938         do_facet mgs $LCTL barrier_thaw $FSNAME
25939
25940         post_801
25941 }
25942 run_test 801a "write barrier user interfaces and stat machine"
25943
25944 test_801b() {
25945         prep_801
25946
25947         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25948         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25949         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25950         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25951         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25952
25953         cancel_lru_locks mdc
25954
25955         # 180 seconds should be long enough
25956         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25957
25958         local b_status=$(barrier_stat)
25959         [ "$b_status" = "'frozen'" ] ||
25960                 error "(6) unexpected barrier status $b_status"
25961
25962         mkdir $DIR/$tdir/d0/d10 &
25963         mkdir_pid=$!
25964
25965         touch $DIR/$tdir/d1/f13 &
25966         touch_pid=$!
25967
25968         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25969         ln_pid=$!
25970
25971         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25972         mv_pid=$!
25973
25974         rm -f $DIR/$tdir/d4/f12 &
25975         rm_pid=$!
25976
25977         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25978
25979         # To guarantee taht the 'stat' is not blocked
25980         b_status=$(barrier_stat)
25981         [ "$b_status" = "'frozen'" ] ||
25982                 error "(8) unexpected barrier status $b_status"
25983
25984         # let above commands to run at background
25985         sleep 5
25986
25987         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25988         ps -p $touch_pid || error "(10) touch should be blocked"
25989         ps -p $ln_pid || error "(11) link should be blocked"
25990         ps -p $mv_pid || error "(12) rename should be blocked"
25991         ps -p $rm_pid || error "(13) unlink should be blocked"
25992
25993         b_status=$(barrier_stat)
25994         [ "$b_status" = "'frozen'" ] ||
25995                 error "(14) unexpected barrier status $b_status"
25996
25997         do_facet mgs $LCTL barrier_thaw $FSNAME
25998         b_status=$(barrier_stat)
25999         [ "$b_status" = "'thawed'" ] ||
26000                 error "(15) unexpected barrier status $b_status"
26001
26002         wait $mkdir_pid || error "(16) mkdir should succeed"
26003         wait $touch_pid || error "(17) touch should succeed"
26004         wait $ln_pid || error "(18) link should succeed"
26005         wait $mv_pid || error "(19) rename should succeed"
26006         wait $rm_pid || error "(20) unlink should succeed"
26007
26008         post_801
26009 }
26010 run_test 801b "modification will be blocked by write barrier"
26011
26012 test_801c() {
26013         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26014
26015         prep_801
26016
26017         stop mds2 || error "(1) Fail to stop mds2"
26018
26019         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26020
26021         local b_status=$(barrier_stat)
26022         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26023                 do_facet mgs $LCTL barrier_thaw $FSNAME
26024                 error "(2) unexpected barrier status $b_status"
26025         }
26026
26027         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26028                 error "(3) Fail to rescan barrier bitmap"
26029
26030         # Do not reduce barrier time - See LU-11873
26031         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26032
26033         b_status=$(barrier_stat)
26034         [ "$b_status" = "'frozen'" ] ||
26035                 error "(4) unexpected barrier status $b_status"
26036
26037         do_facet mgs $LCTL barrier_thaw $FSNAME
26038         b_status=$(barrier_stat)
26039         [ "$b_status" = "'thawed'" ] ||
26040                 error "(5) unexpected barrier status $b_status"
26041
26042         local devname=$(mdsdevname 2)
26043
26044         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26045
26046         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26047                 error "(7) Fail to rescan barrier bitmap"
26048
26049         post_801
26050 }
26051 run_test 801c "rescan barrier bitmap"
26052
26053 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26054 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26055 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26056 saved_MOUNT_OPTS=$MOUNT_OPTS
26057
26058 cleanup_802a() {
26059         trap 0
26060
26061         stopall
26062         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26063         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26064         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26065         MOUNT_OPTS=$saved_MOUNT_OPTS
26066         setupall
26067 }
26068
26069 test_802a() {
26070         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26071         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26072         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26073                 skip "Need server version at least 2.9.55"
26074
26075         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26076
26077         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26078
26079         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26080                 error "(2) Fail to copy"
26081
26082         trap cleanup_802a EXIT
26083
26084         # sync by force before remount as readonly
26085         sync; sync_all_data; sleep 3; sync_all_data
26086
26087         stopall
26088
26089         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26090         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26091         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26092
26093         echo "Mount the server as read only"
26094         setupall server_only || error "(3) Fail to start servers"
26095
26096         echo "Mount client without ro should fail"
26097         mount_client $MOUNT &&
26098                 error "(4) Mount client without 'ro' should fail"
26099
26100         echo "Mount client with ro should succeed"
26101         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26102         mount_client $MOUNT ||
26103                 error "(5) Mount client with 'ro' should succeed"
26104
26105         echo "Modify should be refused"
26106         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26107
26108         echo "Read should be allowed"
26109         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26110                 error "(7) Read should succeed under ro mode"
26111
26112         cleanup_802a
26113 }
26114 run_test 802a "simulate readonly device"
26115
26116 test_802b() {
26117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26118         remote_mds_nodsh && skip "remote MDS with nodsh"
26119
26120         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26121                 skip "readonly option not available"
26122
26123         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26124
26125         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26126                 error "(2) Fail to copy"
26127
26128         # write back all cached data before setting MDT to readonly
26129         cancel_lru_locks
26130         sync_all_data
26131
26132         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26133         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26134
26135         echo "Modify should be refused"
26136         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26137
26138         echo "Read should be allowed"
26139         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26140                 error "(7) Read should succeed under ro mode"
26141
26142         # disable readonly
26143         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26144 }
26145 run_test 802b "be able to set MDTs to readonly"
26146
26147 test_803a() {
26148         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26149         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26150                 skip "MDS needs to be newer than 2.10.54"
26151
26152         mkdir_on_mdt0 $DIR/$tdir
26153         # Create some objects on all MDTs to trigger related logs objects
26154         for idx in $(seq $MDSCOUNT); do
26155                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26156                         $DIR/$tdir/dir${idx} ||
26157                         error "Fail to create $DIR/$tdir/dir${idx}"
26158         done
26159
26160         sync; sleep 3
26161         wait_delete_completed # ensure old test cleanups are finished
26162         echo "before create:"
26163         $LFS df -i $MOUNT
26164         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26165
26166         for i in {1..10}; do
26167                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26168                         error "Fail to create $DIR/$tdir/foo$i"
26169         done
26170
26171         sync; sleep 3
26172         echo "after create:"
26173         $LFS df -i $MOUNT
26174         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26175
26176         # allow for an llog to be cleaned up during the test
26177         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26178                 error "before ($before_used) + 10 > after ($after_used)"
26179
26180         for i in {1..10}; do
26181                 rm -rf $DIR/$tdir/foo$i ||
26182                         error "Fail to remove $DIR/$tdir/foo$i"
26183         done
26184
26185         sleep 3 # avoid MDT return cached statfs
26186         wait_delete_completed
26187         echo "after unlink:"
26188         $LFS df -i $MOUNT
26189         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26190
26191         # allow for an llog to be created during the test
26192         [ $after_used -le $((before_used + 1)) ] ||
26193                 error "after ($after_used) > before ($before_used) + 1"
26194 }
26195 run_test 803a "verify agent object for remote object"
26196
26197 test_803b() {
26198         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26199         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26200                 skip "MDS needs to be newer than 2.13.56"
26201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26202
26203         for i in $(seq 0 $((MDSCOUNT - 1))); do
26204                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26205         done
26206
26207         local before=0
26208         local after=0
26209
26210         local tmp
26211
26212         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26213         for i in $(seq 0 $((MDSCOUNT - 1))); do
26214                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26215                         awk '/getattr/ { print $2 }')
26216                 before=$((before + tmp))
26217         done
26218         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26219         for i in $(seq 0 $((MDSCOUNT - 1))); do
26220                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26221                         awk '/getattr/ { print $2 }')
26222                 after=$((after + tmp))
26223         done
26224
26225         [ $before -eq $after ] || error "getattr count $before != $after"
26226 }
26227 run_test 803b "remote object can getattr from cache"
26228
26229 test_804() {
26230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26231         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26232                 skip "MDS needs to be newer than 2.10.54"
26233         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26234
26235         mkdir -p $DIR/$tdir
26236         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26237                 error "Fail to create $DIR/$tdir/dir0"
26238
26239         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26240         local dev=$(mdsdevname 2)
26241
26242         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26243                 grep ${fid} || error "NOT found agent entry for dir0"
26244
26245         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26246                 error "Fail to create $DIR/$tdir/dir1"
26247
26248         touch $DIR/$tdir/dir1/foo0 ||
26249                 error "Fail to create $DIR/$tdir/dir1/foo0"
26250         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26251         local rc=0
26252
26253         for idx in $(seq $MDSCOUNT); do
26254                 dev=$(mdsdevname $idx)
26255                 do_facet mds${idx} \
26256                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26257                         grep ${fid} && rc=$idx
26258         done
26259
26260         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26261                 error "Fail to rename foo0 to foo1"
26262         if [ $rc -eq 0 ]; then
26263                 for idx in $(seq $MDSCOUNT); do
26264                         dev=$(mdsdevname $idx)
26265                         do_facet mds${idx} \
26266                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26267                         grep ${fid} && rc=$idx
26268                 done
26269         fi
26270
26271         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26272                 error "Fail to rename foo1 to foo2"
26273         if [ $rc -eq 0 ]; then
26274                 for idx in $(seq $MDSCOUNT); do
26275                         dev=$(mdsdevname $idx)
26276                         do_facet mds${idx} \
26277                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26278                         grep ${fid} && rc=$idx
26279                 done
26280         fi
26281
26282         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26283
26284         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26285                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26286         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26287                 error "Fail to rename foo2 to foo0"
26288         unlink $DIR/$tdir/dir1/foo0 ||
26289                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26290         rm -rf $DIR/$tdir/dir0 ||
26291                 error "Fail to rm $DIR/$tdir/dir0"
26292
26293         for idx in $(seq $MDSCOUNT); do
26294                 dev=$(mdsdevname $idx)
26295                 rc=0
26296
26297                 stop mds${idx}
26298                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26299                         rc=$?
26300                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26301                         error "mount mds$idx failed"
26302                 df $MOUNT > /dev/null 2>&1
26303
26304                 # e2fsck should not return error
26305                 [ $rc -eq 0 ] ||
26306                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26307         done
26308 }
26309 run_test 804 "verify agent entry for remote entry"
26310
26311 cleanup_805() {
26312         do_facet $SINGLEMDS zfs set quota=$old $fsset
26313         unlinkmany $DIR/$tdir/f- 1000000
26314         trap 0
26315 }
26316
26317 test_805() {
26318         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26319         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26320         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26321                 skip "netfree not implemented before 0.7"
26322         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26323                 skip "Need MDS version at least 2.10.57"
26324
26325         local fsset
26326         local freekb
26327         local usedkb
26328         local old
26329         local quota
26330         local pref="osd-zfs.$FSNAME-MDT0000."
26331
26332         # limit available space on MDS dataset to meet nospace issue
26333         # quickly. then ZFS 0.7.2 can use reserved space if asked
26334         # properly (using netfree flag in osd_declare_destroy()
26335         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26336         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26337                 gawk '{print $3}')
26338         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26339         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26340         let "usedkb=usedkb-freekb"
26341         let "freekb=freekb/2"
26342         if let "freekb > 5000"; then
26343                 let "freekb=5000"
26344         fi
26345         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26346         trap cleanup_805 EXIT
26347         mkdir_on_mdt0 $DIR/$tdir
26348         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26349                 error "Can't set PFL layout"
26350         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26351         rm -rf $DIR/$tdir || error "not able to remove"
26352         do_facet $SINGLEMDS zfs set quota=$old $fsset
26353         trap 0
26354 }
26355 run_test 805 "ZFS can remove from full fs"
26356
26357 # Size-on-MDS test
26358 check_lsom_data()
26359 {
26360         local file=$1
26361         local expect=$(stat -c %s $file)
26362
26363         check_lsom_size $1 $expect
26364
26365         local blocks=$($LFS getsom -b $file)
26366         expect=$(stat -c %b $file)
26367         [[ $blocks == $expect ]] ||
26368                 error "$file expected blocks: $expect, got: $blocks"
26369 }
26370
26371 check_lsom_size()
26372 {
26373         local size
26374         local expect=$2
26375
26376         cancel_lru_locks mdc
26377
26378         size=$($LFS getsom -s $1)
26379         [[ $size == $expect ]] ||
26380                 error "$file expected size: $expect, got: $size"
26381 }
26382
26383 test_806() {
26384         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26385                 skip "Need MDS version at least 2.11.52"
26386
26387         local bs=1048576
26388
26389         touch $DIR/$tfile || error "touch $tfile failed"
26390
26391         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26392         save_lustre_params client "llite.*.xattr_cache" > $save
26393         lctl set_param llite.*.xattr_cache=0
26394         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26395
26396         # single-threaded write
26397         echo "Test SOM for single-threaded write"
26398         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26399                 error "write $tfile failed"
26400         check_lsom_size $DIR/$tfile $bs
26401
26402         local num=32
26403         local size=$(($num * $bs))
26404         local offset=0
26405         local i
26406
26407         echo "Test SOM for single client multi-threaded($num) write"
26408         $TRUNCATE $DIR/$tfile 0
26409         for ((i = 0; i < $num; i++)); do
26410                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26411                 local pids[$i]=$!
26412                 offset=$((offset + $bs))
26413         done
26414         for (( i=0; i < $num; i++ )); do
26415                 wait ${pids[$i]}
26416         done
26417         check_lsom_size $DIR/$tfile $size
26418
26419         $TRUNCATE $DIR/$tfile 0
26420         for ((i = 0; i < $num; i++)); do
26421                 offset=$((offset - $bs))
26422                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26423                 local pids[$i]=$!
26424         done
26425         for (( i=0; i < $num; i++ )); do
26426                 wait ${pids[$i]}
26427         done
26428         check_lsom_size $DIR/$tfile $size
26429
26430         # multi-client writes
26431         num=$(get_node_count ${CLIENTS//,/ })
26432         size=$(($num * $bs))
26433         offset=0
26434         i=0
26435
26436         echo "Test SOM for multi-client ($num) writes"
26437         $TRUNCATE $DIR/$tfile 0
26438         for client in ${CLIENTS//,/ }; do
26439                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26440                 local pids[$i]=$!
26441                 i=$((i + 1))
26442                 offset=$((offset + $bs))
26443         done
26444         for (( i=0; i < $num; i++ )); do
26445                 wait ${pids[$i]}
26446         done
26447         check_lsom_size $DIR/$tfile $offset
26448
26449         i=0
26450         $TRUNCATE $DIR/$tfile 0
26451         for client in ${CLIENTS//,/ }; do
26452                 offset=$((offset - $bs))
26453                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26454                 local pids[$i]=$!
26455                 i=$((i + 1))
26456         done
26457         for (( i=0; i < $num; i++ )); do
26458                 wait ${pids[$i]}
26459         done
26460         check_lsom_size $DIR/$tfile $size
26461
26462         # verify truncate
26463         echo "Test SOM for truncate"
26464         $TRUNCATE $DIR/$tfile 1048576
26465         check_lsom_size $DIR/$tfile 1048576
26466         $TRUNCATE $DIR/$tfile 1234
26467         check_lsom_size $DIR/$tfile 1234
26468
26469         # verify SOM blocks count
26470         echo "Verify SOM block count"
26471         $TRUNCATE $DIR/$tfile 0
26472         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26473                 error "failed to write file $tfile"
26474         check_lsom_data $DIR/$tfile
26475 }
26476 run_test 806 "Verify Lazy Size on MDS"
26477
26478 test_807() {
26479         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26480         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26481                 skip "Need MDS version at least 2.11.52"
26482
26483         # Registration step
26484         changelog_register || error "changelog_register failed"
26485         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26486         changelog_users $SINGLEMDS | grep -q $cl_user ||
26487                 error "User $cl_user not found in changelog_users"
26488
26489         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26490         save_lustre_params client "llite.*.xattr_cache" > $save
26491         lctl set_param llite.*.xattr_cache=0
26492         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26493
26494         rm -rf $DIR/$tdir || error "rm $tdir failed"
26495         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26496         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26497         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26498         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26499                 error "truncate $tdir/trunc failed"
26500
26501         local bs=1048576
26502         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26503                 error "write $tfile failed"
26504
26505         # multi-client wirtes
26506         local num=$(get_node_count ${CLIENTS//,/ })
26507         local offset=0
26508         local i=0
26509
26510         echo "Test SOM for multi-client ($num) writes"
26511         touch $DIR/$tfile || error "touch $tfile failed"
26512         $TRUNCATE $DIR/$tfile 0
26513         for client in ${CLIENTS//,/ }; do
26514                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26515                 local pids[$i]=$!
26516                 i=$((i + 1))
26517                 offset=$((offset + $bs))
26518         done
26519         for (( i=0; i < $num; i++ )); do
26520                 wait ${pids[$i]}
26521         done
26522
26523         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26524         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26525         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26526         check_lsom_data $DIR/$tdir/trunc
26527         check_lsom_data $DIR/$tdir/single_dd
26528         check_lsom_data $DIR/$tfile
26529
26530         rm -rf $DIR/$tdir
26531         # Deregistration step
26532         changelog_deregister || error "changelog_deregister failed"
26533 }
26534 run_test 807 "verify LSOM syncing tool"
26535
26536 check_som_nologged()
26537 {
26538         local lines=$($LFS changelog $FSNAME-MDT0000 |
26539                 grep 'x=trusted.som' | wc -l)
26540         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26541 }
26542
26543 test_808() {
26544         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26545                 skip "Need MDS version at least 2.11.55"
26546
26547         # Registration step
26548         changelog_register || error "changelog_register failed"
26549
26550         touch $DIR/$tfile || error "touch $tfile failed"
26551         check_som_nologged
26552
26553         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26554                 error "write $tfile failed"
26555         check_som_nologged
26556
26557         $TRUNCATE $DIR/$tfile 1234
26558         check_som_nologged
26559
26560         $TRUNCATE $DIR/$tfile 1048576
26561         check_som_nologged
26562
26563         # Deregistration step
26564         changelog_deregister || error "changelog_deregister failed"
26565 }
26566 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26567
26568 check_som_nodata()
26569 {
26570         $LFS getsom $1
26571         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26572 }
26573
26574 test_809() {
26575         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26576                 skip "Need MDS version at least 2.11.56"
26577
26578         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26579                 error "failed to create DoM-only file $DIR/$tfile"
26580         touch $DIR/$tfile || error "touch $tfile failed"
26581         check_som_nodata $DIR/$tfile
26582
26583         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26584                 error "write $tfile failed"
26585         check_som_nodata $DIR/$tfile
26586
26587         $TRUNCATE $DIR/$tfile 1234
26588         check_som_nodata $DIR/$tfile
26589
26590         $TRUNCATE $DIR/$tfile 4097
26591         check_som_nodata $DIR/$file
26592 }
26593 run_test 809 "Verify no SOM xattr store for DoM-only files"
26594
26595 test_810() {
26596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26597         $GSS && skip_env "could not run with gss"
26598         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26599                 skip "OST < 2.12.58 doesn't align checksum"
26600
26601         set_checksums 1
26602         stack_trap "set_checksums $ORIG_CSUM" EXIT
26603         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26604
26605         local csum
26606         local before
26607         local after
26608         for csum in $CKSUM_TYPES; do
26609                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26610                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26611                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26612                         eval set -- $i
26613                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26614                         before=$(md5sum $DIR/$tfile)
26615                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26616                         after=$(md5sum $DIR/$tfile)
26617                         [ "$before" == "$after" ] ||
26618                                 error "$csum: $before != $after bs=$1 seek=$2"
26619                 done
26620         done
26621 }
26622 run_test 810 "partial page writes on ZFS (LU-11663)"
26623
26624 test_812a() {
26625         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26626                 skip "OST < 2.12.51 doesn't support this fail_loc"
26627
26628         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26629         # ensure ost1 is connected
26630         stat $DIR/$tfile >/dev/null || error "can't stat"
26631         wait_osc_import_state client ost1 FULL
26632         # no locks, no reqs to let the connection idle
26633         cancel_lru_locks osc
26634
26635         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26636 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26637         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26638         wait_osc_import_state client ost1 CONNECTING
26639         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26640
26641         stat $DIR/$tfile >/dev/null || error "can't stat file"
26642 }
26643 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26644
26645 test_812b() { # LU-12378
26646         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26647                 skip "OST < 2.12.51 doesn't support this fail_loc"
26648
26649         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26650         # ensure ost1 is connected
26651         stat $DIR/$tfile >/dev/null || error "can't stat"
26652         wait_osc_import_state client ost1 FULL
26653         # no locks, no reqs to let the connection idle
26654         cancel_lru_locks osc
26655
26656         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26657 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26658         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26659         wait_osc_import_state client ost1 CONNECTING
26660         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26661
26662         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26663         wait_osc_import_state client ost1 IDLE
26664 }
26665 run_test 812b "do not drop no resend request for idle connect"
26666
26667 test_812c() {
26668         local old
26669
26670         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26671
26672         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26673         $LFS getstripe $DIR/$tfile
26674         $LCTL set_param osc.*.idle_timeout=10
26675         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26676         # ensure ost1 is connected
26677         stat $DIR/$tfile >/dev/null || error "can't stat"
26678         wait_osc_import_state client ost1 FULL
26679         # no locks, no reqs to let the connection idle
26680         cancel_lru_locks osc
26681
26682 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26683         $LCTL set_param fail_loc=0x80000533
26684         sleep 15
26685         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26686 }
26687 run_test 812c "idle import vs lock enqueue race"
26688
26689 test_813() {
26690         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26691         [ -z "$file_heat_sav" ] && skip "no file heat support"
26692
26693         local readsample
26694         local writesample
26695         local readbyte
26696         local writebyte
26697         local readsample1
26698         local writesample1
26699         local readbyte1
26700         local writebyte1
26701
26702         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26703         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26704
26705         $LCTL set_param -n llite.*.file_heat=1
26706         echo "Turn on file heat"
26707         echo "Period second: $period_second, Decay percentage: $decay_pct"
26708
26709         echo "QQQQ" > $DIR/$tfile
26710         echo "QQQQ" > $DIR/$tfile
26711         echo "QQQQ" > $DIR/$tfile
26712         cat $DIR/$tfile > /dev/null
26713         cat $DIR/$tfile > /dev/null
26714         cat $DIR/$tfile > /dev/null
26715         cat $DIR/$tfile > /dev/null
26716
26717         local out=$($LFS heat_get $DIR/$tfile)
26718
26719         $LFS heat_get $DIR/$tfile
26720         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26721         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26722         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26723         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26724
26725         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26726         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26727         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26728         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26729
26730         sleep $((period_second + 3))
26731         echo "Sleep $((period_second + 3)) seconds..."
26732         # The recursion formula to calculate the heat of the file f is as
26733         # follow:
26734         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26735         # Where Hi is the heat value in the period between time points i*I and
26736         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26737         # to the weight of Ci.
26738         out=$($LFS heat_get $DIR/$tfile)
26739         $LFS heat_get $DIR/$tfile
26740         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26741         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26742         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26743         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26744
26745         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26746                 error "read sample ($readsample) is wrong"
26747         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26748                 error "write sample ($writesample) is wrong"
26749         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26750                 error "read bytes ($readbyte) is wrong"
26751         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26752                 error "write bytes ($writebyte) is wrong"
26753
26754         echo "QQQQ" > $DIR/$tfile
26755         echo "QQQQ" > $DIR/$tfile
26756         echo "QQQQ" > $DIR/$tfile
26757         cat $DIR/$tfile > /dev/null
26758         cat $DIR/$tfile > /dev/null
26759         cat $DIR/$tfile > /dev/null
26760         cat $DIR/$tfile > /dev/null
26761
26762         sleep $((period_second + 3))
26763         echo "Sleep $((period_second + 3)) seconds..."
26764
26765         out=$($LFS heat_get $DIR/$tfile)
26766         $LFS heat_get $DIR/$tfile
26767         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26768         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26769         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26770         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26771
26772         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26773                 4 * $decay_pct) / 100") -eq 1 ] ||
26774                 error "read sample ($readsample1) is wrong"
26775         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26776                 3 * $decay_pct) / 100") -eq 1 ] ||
26777                 error "write sample ($writesample1) is wrong"
26778         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26779                 20 * $decay_pct) / 100") -eq 1 ] ||
26780                 error "read bytes ($readbyte1) is wrong"
26781         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26782                 15 * $decay_pct) / 100") -eq 1 ] ||
26783                 error "write bytes ($writebyte1) is wrong"
26784
26785         echo "Turn off file heat for the file $DIR/$tfile"
26786         $LFS heat_set -o $DIR/$tfile
26787
26788         echo "QQQQ" > $DIR/$tfile
26789         echo "QQQQ" > $DIR/$tfile
26790         echo "QQQQ" > $DIR/$tfile
26791         cat $DIR/$tfile > /dev/null
26792         cat $DIR/$tfile > /dev/null
26793         cat $DIR/$tfile > /dev/null
26794         cat $DIR/$tfile > /dev/null
26795
26796         out=$($LFS heat_get $DIR/$tfile)
26797         $LFS heat_get $DIR/$tfile
26798         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26799         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26800         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26801         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26802
26803         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26804         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26805         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26806         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26807
26808         echo "Trun on file heat for the file $DIR/$tfile"
26809         $LFS heat_set -O $DIR/$tfile
26810
26811         echo "QQQQ" > $DIR/$tfile
26812         echo "QQQQ" > $DIR/$tfile
26813         echo "QQQQ" > $DIR/$tfile
26814         cat $DIR/$tfile > /dev/null
26815         cat $DIR/$tfile > /dev/null
26816         cat $DIR/$tfile > /dev/null
26817         cat $DIR/$tfile > /dev/null
26818
26819         out=$($LFS heat_get $DIR/$tfile)
26820         $LFS heat_get $DIR/$tfile
26821         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26822         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26823         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26824         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26825
26826         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26827         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26828         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26829         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26830
26831         $LFS heat_set -c $DIR/$tfile
26832         $LCTL set_param -n llite.*.file_heat=0
26833         echo "Turn off file heat support for the Lustre filesystem"
26834
26835         echo "QQQQ" > $DIR/$tfile
26836         echo "QQQQ" > $DIR/$tfile
26837         echo "QQQQ" > $DIR/$tfile
26838         cat $DIR/$tfile > /dev/null
26839         cat $DIR/$tfile > /dev/null
26840         cat $DIR/$tfile > /dev/null
26841         cat $DIR/$tfile > /dev/null
26842
26843         out=$($LFS heat_get $DIR/$tfile)
26844         $LFS heat_get $DIR/$tfile
26845         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26846         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26847         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26848         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26849
26850         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26851         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26852         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26853         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26854
26855         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26856         rm -f $DIR/$tfile
26857 }
26858 run_test 813 "File heat verfication"
26859
26860 test_814()
26861 {
26862         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26863         echo -n y >> $DIR/$tfile
26864         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26865         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26866 }
26867 run_test 814 "sparse cp works as expected (LU-12361)"
26868
26869 test_815()
26870 {
26871         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26872         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26873 }
26874 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26875
26876 test_816() {
26877         local ost1_imp=$(get_osc_import_name client ost1)
26878         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26879                          cut -d'.' -f2)
26880
26881         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26882         # ensure ost1 is connected
26883
26884         stat $DIR/$tfile >/dev/null || error "can't stat"
26885         wait_osc_import_state client ost1 FULL
26886         # no locks, no reqs to let the connection idle
26887         cancel_lru_locks osc
26888         lru_resize_disable osc
26889         local before
26890         local now
26891         before=$($LCTL get_param -n \
26892                  ldlm.namespaces.$imp_name.lru_size)
26893
26894         wait_osc_import_state client ost1 IDLE
26895         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26896         now=$($LCTL get_param -n \
26897               ldlm.namespaces.$imp_name.lru_size)
26898         [ $before == $now ] || error "lru_size changed $before != $now"
26899 }
26900 run_test 816 "do not reset lru_resize on idle reconnect"
26901
26902 cleanup_817() {
26903         umount $tmpdir
26904         exportfs -u localhost:$DIR/nfsexp
26905         rm -rf $DIR/nfsexp
26906 }
26907
26908 test_817() {
26909         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26910
26911         mkdir -p $DIR/nfsexp
26912         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26913                 error "failed to export nfs"
26914
26915         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26916         stack_trap cleanup_817 EXIT
26917
26918         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26919                 error "failed to mount nfs to $tmpdir"
26920
26921         cp /bin/true $tmpdir
26922         $DIR/nfsexp/true || error "failed to execute 'true' command"
26923 }
26924 run_test 817 "nfsd won't cache write lock for exec file"
26925
26926 test_818() {
26927         mkdir $DIR/$tdir
26928         $LFS setstripe -c1 -i0 $DIR/$tfile
26929         $LFS setstripe -c1 -i1 $DIR/$tfile
26930         stop $SINGLEMDS
26931         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26932         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26933         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26934                 error "start $SINGLEMDS failed"
26935         rm -rf $DIR/$tdir
26936 }
26937 run_test 818 "unlink with failed llog"
26938
26939 test_819a() {
26940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26941         cancel_lru_locks osc
26942         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26943         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26944         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26945         rm -f $TDIR/$tfile
26946 }
26947 run_test 819a "too big niobuf in read"
26948
26949 test_819b() {
26950         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26951         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26952         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26953         cancel_lru_locks osc
26954         sleep 1
26955         rm -f $TDIR/$tfile
26956 }
26957 run_test 819b "too big niobuf in write"
26958
26959
26960 function test_820_start_ost() {
26961         sleep 5
26962
26963         for num in $(seq $OSTCOUNT); do
26964                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26965         done
26966 }
26967
26968 test_820() {
26969         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26970
26971         mkdir $DIR/$tdir
26972         umount_client $MOUNT || error "umount failed"
26973         for num in $(seq $OSTCOUNT); do
26974                 stop ost$num
26975         done
26976
26977         # mount client with no active OSTs
26978         # so that the client can't initialize max LOV EA size
26979         # from OSC notifications
26980         mount_client $MOUNT || error "mount failed"
26981         # delay OST starting to keep this 0 max EA size for a while
26982         test_820_start_ost &
26983
26984         # create a directory on MDS2
26985         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26986                 error "Failed to create directory"
26987         # open intent should update default EA size
26988         # see mdc_update_max_ea_from_body()
26989         # notice this is the very first RPC to MDS2
26990         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26991         ret=$?
26992         echo $out
26993         # With SSK, this situation can lead to -EPERM being returned.
26994         # In that case, simply retry.
26995         if [ $ret -ne 0 ] && $SHARED_KEY; then
26996                 if echo "$out" | grep -q "not permitted"; then
26997                         cp /etc/services $DIR/$tdir/mds2
26998                         ret=$?
26999                 fi
27000         fi
27001         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27002 }
27003 run_test 820 "update max EA from open intent"
27004
27005 test_822() {
27006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27007
27008         save_lustre_params mds1 \
27009                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27010         do_facet $SINGLEMDS "$LCTL set_param -n \
27011                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27012         do_facet $SINGLEMDS "$LCTL set_param -n \
27013                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27014
27015         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27016         local maxage=$(do_facet mds1 $LCTL get_param -n \
27017                        osp.$FSNAME-OST0000*MDT0000.maxage)
27018         sleep $((maxage + 1))
27019
27020         #define OBD_FAIL_NET_ERROR_RPC          0x532
27021         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27022
27023         stack_trap "restore_lustre_params < $p; rm $p"
27024
27025         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27026                       osp.$FSNAME-OST0000*MDT0000.create_count")
27027         for i in $(seq 1 $count); do
27028                 touch $DIR/$tfile.${i} || error "touch failed"
27029         done
27030 }
27031 run_test 822 "test precreate failure"
27032
27033 #
27034 # tests that do cleanup/setup should be run at the end
27035 #
27036
27037 test_900() {
27038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27039         local ls
27040
27041         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27042         $LCTL set_param fail_loc=0x903
27043
27044         cancel_lru_locks MGC
27045
27046         FAIL_ON_ERROR=true cleanup
27047         FAIL_ON_ERROR=true setup
27048 }
27049 run_test 900 "umount should not race with any mgc requeue thread"
27050
27051 # LUS-6253/LU-11185
27052 test_901() {
27053         local oldc
27054         local newc
27055         local olds
27056         local news
27057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27058
27059         # some get_param have a bug to handle dot in param name
27060         cancel_lru_locks MGC
27061         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27062         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27063         umount_client $MOUNT || error "umount failed"
27064         mount_client $MOUNT || error "mount failed"
27065         cancel_lru_locks MGC
27066         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27067         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27068
27069         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27070         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27071
27072         return 0
27073 }
27074 run_test 901 "don't leak a mgc lock on client umount"
27075
27076 # LU-13377
27077 test_902() {
27078         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27079                 skip "client does not have LU-13377 fix"
27080         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27081         $LCTL set_param fail_loc=0x1415
27082         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27083         cancel_lru_locks osc
27084         rm -f $DIR/$tfile
27085 }
27086 run_test 902 "test short write doesn't hang lustre"
27087
27088 complete $SECONDS
27089 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27090 check_and_cleanup_lustre
27091 if [ "$I_MOUNTED" != "yes" ]; then
27092         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27093 fi
27094 exit_status