Whamcloud - gitweb
58f74627b1c8621eae32e8225118fff6062e9283
[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 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         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
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         test_mkdir $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 test_27Q() {
3323         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3324         stack_trap "rm -f $TMP/$tfile*"
3325
3326         test_mkdir $DIR/$tdir-1
3327         test_mkdir $DIR/$tdir-2
3328
3329         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3330         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3333         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3334
3335         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3336         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3337
3338         # Create some bad symlinks and ensure that we don't loop
3339         # forever or something. These should return ELOOP (40) and
3340         # ENOENT (2) but I don't want to test for that because there's
3341         # always some weirdo architecture that needs to ruin
3342         # everything by defining these error numbers differently.
3343
3344         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3345         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3346
3347         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3348         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3349
3350         return 0
3351 }
3352 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3353
3354 # createtest also checks that device nodes are created and
3355 # then visible correctly (#2091)
3356 test_28() { # bug 2091
3357         test_mkdir $DIR/d28
3358         $CREATETEST $DIR/d28/ct || error "createtest failed"
3359 }
3360 run_test 28 "create/mknod/mkdir with bad file types ============"
3361
3362 test_29() {
3363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3364
3365         sync; sleep 1; sync # flush out any dirty pages from previous tests
3366         cancel_lru_locks
3367         test_mkdir $DIR/d29
3368         touch $DIR/d29/foo
3369         log 'first d29'
3370         ls -l $DIR/d29
3371
3372         declare -i LOCKCOUNTORIG=0
3373         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3374                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3375         done
3376         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3377
3378         declare -i LOCKUNUSEDCOUNTORIG=0
3379         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3380                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3381         done
3382
3383         log 'second d29'
3384         ls -l $DIR/d29
3385         log 'done'
3386
3387         declare -i LOCKCOUNTCURRENT=0
3388         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3389                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3390         done
3391
3392         declare -i LOCKUNUSEDCOUNTCURRENT=0
3393         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3394                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3395         done
3396
3397         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3398                 $LCTL set_param -n ldlm.dump_namespaces ""
3399                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3400                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3401                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3402                 return 2
3403         fi
3404         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3405                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3406                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3407                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3408                 return 3
3409         fi
3410 }
3411 run_test 29 "IT_GETATTR regression  ============================"
3412
3413 test_30a() { # was test_30
3414         cp $(which ls) $DIR || cp /bin/ls $DIR
3415         $DIR/ls / || error "Can't execute binary from lustre"
3416         rm $DIR/ls
3417 }
3418 run_test 30a "execute binary from Lustre (execve) =============="
3419
3420 test_30b() {
3421         cp `which ls` $DIR || cp /bin/ls $DIR
3422         chmod go+rx $DIR/ls
3423         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3424         rm $DIR/ls
3425 }
3426 run_test 30b "execute binary from Lustre as non-root ==========="
3427
3428 test_30c() { # b=22376
3429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3430
3431         cp $(which ls) $DIR || cp /bin/ls $DIR
3432         chmod a-rw $DIR/ls
3433         cancel_lru_locks mdc
3434         cancel_lru_locks osc
3435         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3436         rm -f $DIR/ls
3437 }
3438 run_test 30c "execute binary from Lustre without read perms ===="
3439
3440 test_30d() {
3441         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3442
3443         for i in {1..10}; do
3444                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3445                 local PID=$!
3446                 sleep 1
3447                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3448                 wait $PID || error "executing dd from Lustre failed"
3449                 rm -f $DIR/$tfile
3450         done
3451
3452         rm -f $DIR/dd
3453 }
3454 run_test 30d "execute binary from Lustre while clear locks"
3455
3456 test_31a() {
3457         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3458         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3459 }
3460 run_test 31a "open-unlink file =================================="
3461
3462 test_31b() {
3463         touch $DIR/f31 || error "touch $DIR/f31 failed"
3464         ln $DIR/f31 $DIR/f31b || error "ln failed"
3465         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3466         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3467 }
3468 run_test 31b "unlink file with multiple links while open ======="
3469
3470 test_31c() {
3471         touch $DIR/f31 || error "touch $DIR/f31 failed"
3472         ln $DIR/f31 $DIR/f31c || error "ln failed"
3473         multiop_bg_pause $DIR/f31 O_uc ||
3474                 error "multiop_bg_pause for $DIR/f31 failed"
3475         MULTIPID=$!
3476         $MULTIOP $DIR/f31c Ouc
3477         kill -USR1 $MULTIPID
3478         wait $MULTIPID
3479 }
3480 run_test 31c "open-unlink file with multiple links ============="
3481
3482 test_31d() {
3483         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3484         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3485 }
3486 run_test 31d "remove of open directory ========================="
3487
3488 test_31e() { # bug 2904
3489         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3490 }
3491 run_test 31e "remove of open non-empty directory ==============="
3492
3493 test_31f() { # bug 4554
3494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3495
3496         set -vx
3497         test_mkdir $DIR/d31f
3498         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3499         cp /etc/hosts $DIR/d31f
3500         ls -l $DIR/d31f
3501         $LFS getstripe $DIR/d31f/hosts
3502         multiop_bg_pause $DIR/d31f D_c || return 1
3503         MULTIPID=$!
3504
3505         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3506         test_mkdir $DIR/d31f
3507         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3508         cp /etc/hosts $DIR/d31f
3509         ls -l $DIR/d31f
3510         $LFS getstripe $DIR/d31f/hosts
3511         multiop_bg_pause $DIR/d31f D_c || return 1
3512         MULTIPID2=$!
3513
3514         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3515         wait $MULTIPID || error "first opendir $MULTIPID failed"
3516
3517         sleep 6
3518
3519         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3520         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3521         set +vx
3522 }
3523 run_test 31f "remove of open directory with open-unlink file ==="
3524
3525 test_31g() {
3526         echo "-- cross directory link --"
3527         test_mkdir -c1 $DIR/${tdir}ga
3528         test_mkdir -c1 $DIR/${tdir}gb
3529         touch $DIR/${tdir}ga/f
3530         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3531         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3532         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3533         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3534         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3535 }
3536 run_test 31g "cross directory link==============="
3537
3538 test_31h() {
3539         echo "-- cross directory link --"
3540         test_mkdir -c1 $DIR/${tdir}
3541         test_mkdir -c1 $DIR/${tdir}/dir
3542         touch $DIR/${tdir}/f
3543         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3544         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3545         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3546         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3547         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3548 }
3549 run_test 31h "cross directory link under child==============="
3550
3551 test_31i() {
3552         echo "-- cross directory link --"
3553         test_mkdir -c1 $DIR/$tdir
3554         test_mkdir -c1 $DIR/$tdir/dir
3555         touch $DIR/$tdir/dir/f
3556         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3557         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3558         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3559         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3560         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3561 }
3562 run_test 31i "cross directory link under parent==============="
3563
3564 test_31j() {
3565         test_mkdir -c1 -p $DIR/$tdir
3566         test_mkdir -c1 -p $DIR/$tdir/dir1
3567         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3568         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3569         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3571         return 0
3572 }
3573 run_test 31j "link for directory==============="
3574
3575 test_31k() {
3576         test_mkdir -c1 -p $DIR/$tdir
3577         touch $DIR/$tdir/s
3578         touch $DIR/$tdir/exist
3579         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3580         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3581         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3582         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3583         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3584         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3586         return 0
3587 }
3588 run_test 31k "link to file: the same, non-existing, dir==============="
3589
3590 test_31m() {
3591         mkdir $DIR/d31m
3592         touch $DIR/d31m/s
3593         mkdir $DIR/d31m2
3594         touch $DIR/d31m2/exist
3595         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3596         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3597         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3598         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3599         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3601         return 0
3602 }
3603 run_test 31m "link to file: the same, non-existing, dir==============="
3604
3605 test_31n() {
3606         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3607         nlink=$(stat --format=%h $DIR/$tfile)
3608         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3609         local fd=$(free_fd)
3610         local cmd="exec $fd<$DIR/$tfile"
3611         eval $cmd
3612         cmd="exec $fd<&-"
3613         trap "eval $cmd" EXIT
3614         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3615         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3616         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3617         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3618         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3619         eval $cmd
3620 }
3621 run_test 31n "check link count of unlinked file"
3622
3623 link_one() {
3624         local tempfile=$(mktemp $1_XXXXXX)
3625         mlink $tempfile $1 2> /dev/null &&
3626                 echo "$BASHPID: link $tempfile to $1 succeeded"
3627         munlink $tempfile
3628 }
3629
3630 test_31o() { # LU-2901
3631         test_mkdir $DIR/$tdir
3632         for LOOP in $(seq 100); do
3633                 rm -f $DIR/$tdir/$tfile*
3634                 for THREAD in $(seq 8); do
3635                         link_one $DIR/$tdir/$tfile.$LOOP &
3636                 done
3637                 wait
3638                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3639                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3640                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3641                         break || true
3642         done
3643 }
3644 run_test 31o "duplicate hard links with same filename"
3645
3646 test_31p() {
3647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3648
3649         test_mkdir $DIR/$tdir
3650         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3651         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3652
3653         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3654                 error "open unlink test1 failed"
3655         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3656                 error "open unlink test2 failed"
3657
3658         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3659                 error "test1 still exists"
3660         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3661                 error "test2 still exists"
3662 }
3663 run_test 31p "remove of open striped directory"
3664
3665 test_31q() {
3666         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3667
3668         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3669         index=$($LFS getdirstripe -i $DIR/$tdir)
3670         [ $index -eq 3 ] || error "first stripe index $index != 3"
3671         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3672         [ $index -eq 1 ] || error "second stripe index $index != 1"
3673
3674         # when "-c <stripe_count>" is set, the number of MDTs specified after
3675         # "-i" should equal to the stripe count
3676         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3677 }
3678 run_test 31q "create striped directory on specific MDTs"
3679
3680 cleanup_test32_mount() {
3681         local rc=0
3682         trap 0
3683         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3684         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3685         losetup -d $loopdev || true
3686         rm -rf $DIR/$tdir
3687         return $rc
3688 }
3689
3690 test_32a() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692
3693         echo "== more mountpoints and symlinks ================="
3694         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3695         trap cleanup_test32_mount EXIT
3696         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3697         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3698                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3699         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3700                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3701         cleanup_test32_mount
3702 }
3703 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3704
3705 test_32b() {
3706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3707
3708         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3709         trap cleanup_test32_mount EXIT
3710         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3711         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3712                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3713         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3714                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3715         cleanup_test32_mount
3716 }
3717 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3718
3719 test_32c() {
3720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3721
3722         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3723         trap cleanup_test32_mount EXIT
3724         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3725         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3726                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3727         test_mkdir -p $DIR/$tdir/d2/test_dir
3728         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3729                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3730         cleanup_test32_mount
3731 }
3732 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3733
3734 test_32d() {
3735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3736
3737         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3738         trap cleanup_test32_mount EXIT
3739         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3740         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3741                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3742         test_mkdir -p $DIR/$tdir/d2/test_dir
3743         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3744                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3745         cleanup_test32_mount
3746 }
3747 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3748
3749 test_32e() {
3750         rm -fr $DIR/$tdir
3751         test_mkdir -p $DIR/$tdir/tmp
3752         local tmp_dir=$DIR/$tdir/tmp
3753         ln -s $DIR/$tdir $tmp_dir/symlink11
3754         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3755         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3756         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3757 }
3758 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3759
3760 test_32f() {
3761         rm -fr $DIR/$tdir
3762         test_mkdir -p $DIR/$tdir/tmp
3763         local tmp_dir=$DIR/$tdir/tmp
3764         ln -s $DIR/$tdir $tmp_dir/symlink11
3765         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3766         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3767         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3768 }
3769 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3770
3771 test_32g() {
3772         local tmp_dir=$DIR/$tdir/tmp
3773         test_mkdir -p $tmp_dir
3774         test_mkdir $DIR/${tdir}2
3775         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3776         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3777         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3778         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3779         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3780         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3781 }
3782 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3783
3784 test_32h() {
3785         rm -fr $DIR/$tdir $DIR/${tdir}2
3786         tmp_dir=$DIR/$tdir/tmp
3787         test_mkdir -p $tmp_dir
3788         test_mkdir $DIR/${tdir}2
3789         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3790         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3791         ls $tmp_dir/symlink12 || error "listing symlink12"
3792         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3793 }
3794 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3795
3796 test_32i() {
3797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3798
3799         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3800         trap cleanup_test32_mount EXIT
3801         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3802         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3803                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3804         touch $DIR/$tdir/test_file
3805         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3806                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3807         cleanup_test32_mount
3808 }
3809 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3810
3811 test_32j() {
3812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3813
3814         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3815         trap cleanup_test32_mount EXIT
3816         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3817         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3818                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3819         touch $DIR/$tdir/test_file
3820         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3825
3826 test_32k() {
3827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3828
3829         rm -fr $DIR/$tdir
3830         trap cleanup_test32_mount EXIT
3831         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3832         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3833                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3834         test_mkdir -p $DIR/$tdir/d2
3835         touch $DIR/$tdir/d2/test_file || error "touch failed"
3836         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3837                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3838         cleanup_test32_mount
3839 }
3840 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3841
3842 test_32l() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2
3851         touch $DIR/$tdir/d2/test_file || error "touch failed"
3852         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3853                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3854         cleanup_test32_mount
3855 }
3856 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3857
3858 test_32m() {
3859         rm -fr $DIR/d32m
3860         test_mkdir -p $DIR/d32m/tmp
3861         TMP_DIR=$DIR/d32m/tmp
3862         ln -s $DIR $TMP_DIR/symlink11
3863         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3864         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3865                 error "symlink11 not a link"
3866         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3867                 error "symlink01 not a link"
3868 }
3869 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3870
3871 test_32n() {
3872         rm -fr $DIR/d32n
3873         test_mkdir -p $DIR/d32n/tmp
3874         TMP_DIR=$DIR/d32n/tmp
3875         ln -s $DIR $TMP_DIR/symlink11
3876         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3877         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3878         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3879 }
3880 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3881
3882 test_32o() {
3883         touch $DIR/$tfile
3884         test_mkdir -p $DIR/d32o/tmp
3885         TMP_DIR=$DIR/d32o/tmp
3886         ln -s $DIR/$tfile $TMP_DIR/symlink12
3887         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3888         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3889                 error "symlink12 not a link"
3890         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3891         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3892                 error "$DIR/d32o/tmp/symlink12 not file type"
3893         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3894                 error "$DIR/d32o/symlink02 not file type"
3895 }
3896 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3897
3898 test_32p() {
3899         log 32p_1
3900         rm -fr $DIR/d32p
3901         log 32p_2
3902         rm -f $DIR/$tfile
3903         log 32p_3
3904         touch $DIR/$tfile
3905         log 32p_4
3906         test_mkdir -p $DIR/d32p/tmp
3907         log 32p_5
3908         TMP_DIR=$DIR/d32p/tmp
3909         log 32p_6
3910         ln -s $DIR/$tfile $TMP_DIR/symlink12
3911         log 32p_7
3912         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3913         log 32p_8
3914         cat $DIR/d32p/tmp/symlink12 ||
3915                 error "Can't open $DIR/d32p/tmp/symlink12"
3916         log 32p_9
3917         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3918         log 32p_10
3919 }
3920 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3921
3922 test_32q() {
3923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3924
3925         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3926         trap cleanup_test32_mount EXIT
3927         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3928         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3929         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3930                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3931         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3932         cleanup_test32_mount
3933 }
3934 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3935
3936 test_32r() {
3937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3938
3939         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3940         trap cleanup_test32_mount EXIT
3941         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3942         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3943         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3944                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3945         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3946         cleanup_test32_mount
3947 }
3948 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3949
3950 test_33aa() {
3951         rm -f $DIR/$tfile
3952         touch $DIR/$tfile
3953         chmod 444 $DIR/$tfile
3954         chown $RUNAS_ID $DIR/$tfile
3955         log 33_1
3956         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3957         log 33_2
3958 }
3959 run_test 33aa "write file with mode 444 (should return error)"
3960
3961 test_33a() {
3962         rm -fr $DIR/$tdir
3963         test_mkdir $DIR/$tdir
3964         chown $RUNAS_ID $DIR/$tdir
3965         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3966                 error "$RUNAS create $tdir/$tfile failed"
3967         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3968                 error "open RDWR" || true
3969 }
3970 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3971
3972 test_33b() {
3973         rm -fr $DIR/$tdir
3974         test_mkdir $DIR/$tdir
3975         chown $RUNAS_ID $DIR/$tdir
3976         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3977 }
3978 run_test 33b "test open file with malformed flags (No panic)"
3979
3980 test_33c() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982         remote_ost_nodsh && skip "remote OST with nodsh"
3983
3984         local ostnum
3985         local ostname
3986         local write_bytes
3987         local all_zeros
3988
3989         all_zeros=true
3990         test_mkdir $DIR/$tdir
3991         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3992
3993         sync
3994         for ostnum in $(seq $OSTCOUNT); do
3995                 # test-framework's OST numbering is one-based, while Lustre's
3996                 # is zero-based
3997                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3998                 # check if at least some write_bytes stats are counted
3999                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4000                               obdfilter.$ostname.stats |
4001                               awk '/^write_bytes/ {print $7}' )
4002                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4003                 if (( ${write_bytes:-0} > 0 )); then
4004                         all_zeros=false
4005                         break
4006                 fi
4007         done
4008
4009         $all_zeros || return 0
4010
4011         # Write four bytes
4012         echo foo > $DIR/$tdir/bar
4013         # Really write them
4014         sync
4015
4016         # Total up write_bytes after writing.  We'd better find non-zeros.
4017         for ostnum in $(seq $OSTCOUNT); do
4018                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4019                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4020                               obdfilter/$ostname/stats |
4021                               awk '/^write_bytes/ {print $7}' )
4022                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4023                 if (( ${write_bytes:-0} > 0 )); then
4024                         all_zeros=false
4025                         break
4026                 fi
4027         done
4028
4029         if $all_zeros; then
4030                 for ostnum in $(seq $OSTCOUNT); do
4031                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4032                         echo "Check write_bytes is in obdfilter.*.stats:"
4033                         do_facet ost$ostnum lctl get_param -n \
4034                                 obdfilter.$ostname.stats
4035                 done
4036                 error "OST not keeping write_bytes stats (b=22312)"
4037         fi
4038 }
4039 run_test 33c "test write_bytes stats"
4040
4041 test_33d() {
4042         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4044
4045         local MDTIDX=1
4046         local remote_dir=$DIR/$tdir/remote_dir
4047
4048         test_mkdir $DIR/$tdir
4049         $LFS mkdir -i $MDTIDX $remote_dir ||
4050                 error "create remote directory failed"
4051
4052         touch $remote_dir/$tfile
4053         chmod 444 $remote_dir/$tfile
4054         chown $RUNAS_ID $remote_dir/$tfile
4055
4056         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4057
4058         chown $RUNAS_ID $remote_dir
4059         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4060                                         error "create" || true
4061         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4062                                     error "open RDWR" || true
4063         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4064 }
4065 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4066
4067 test_33e() {
4068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4069
4070         mkdir $DIR/$tdir
4071
4072         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4073         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4074         mkdir $DIR/$tdir/local_dir
4075
4076         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4077         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4078         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4079
4080         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4081                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4082
4083         rmdir $DIR/$tdir/* || error "rmdir failed"
4084
4085         umask 777
4086         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4087         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4088         mkdir $DIR/$tdir/local_dir
4089
4090         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4091         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4092         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4093
4094         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4095                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4096
4097         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4098
4099         umask 000
4100         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4101         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4102         mkdir $DIR/$tdir/local_dir
4103
4104         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4105         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4106         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4107
4108         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4109                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4110 }
4111 run_test 33e "mkdir and striped directory should have same mode"
4112
4113 cleanup_33f() {
4114         trap 0
4115         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4116 }
4117
4118 test_33f() {
4119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4120         remote_mds_nodsh && skip "remote MDS with nodsh"
4121
4122         mkdir $DIR/$tdir
4123         chmod go+rwx $DIR/$tdir
4124         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4125         trap cleanup_33f EXIT
4126
4127         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4128                 error "cannot create striped directory"
4129
4130         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4131                 error "cannot create files in striped directory"
4132
4133         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4134                 error "cannot remove files in striped directory"
4135
4136         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4137                 error "cannot remove striped directory"
4138
4139         cleanup_33f
4140 }
4141 run_test 33f "nonroot user can create, access, and remove a striped directory"
4142
4143 test_33g() {
4144         mkdir -p $DIR/$tdir/dir2
4145
4146         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4147         echo $err
4148         [[ $err =~ "exists" ]] || error "Not exists error"
4149 }
4150 run_test 33g "nonroot user create already existing root created file"
4151
4152 test_33h() {
4153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4154         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4155                 skip "Need MDS version at least 2.13.50"
4156
4157         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4158                 error "mkdir $tdir failed"
4159         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4160
4161         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4162         local index2
4163
4164         for fname in $DIR/$tdir/$tfile.bak \
4165                      $DIR/$tdir/$tfile.SAV \
4166                      $DIR/$tdir/$tfile.orig \
4167                      $DIR/$tdir/$tfile~; do
4168                 touch $fname  || error "touch $fname failed"
4169                 index2=$($LFS getstripe -m $fname)
4170                 [ $index -eq $index2 ] ||
4171                         error "$fname MDT index mismatch $index != $index2"
4172         done
4173
4174         local failed=0
4175         for i in {1..250}; do
4176                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4177                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4178                         touch $fname  || error "touch $fname failed"
4179                         index2=$($LFS getstripe -m $fname)
4180                         if [[ $index != $index2 ]]; then
4181                                 failed=$((failed + 1))
4182                                 echo "$fname MDT index mismatch $index != $index2"
4183                         fi
4184                 done
4185         done
4186         echo "$failed MDT index mismatches"
4187         (( failed < 20 )) || error "MDT index mismatch $failed times"
4188
4189 }
4190 run_test 33h "temp file is located on the same MDT as target"
4191
4192 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4193 test_34a() {
4194         rm -f $DIR/f34
4195         $MCREATE $DIR/f34 || error "mcreate failed"
4196         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4197                 error "getstripe failed"
4198         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4200                 error "getstripe failed"
4201         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4202                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4203 }
4204 run_test 34a "truncate file that has not been opened ==========="
4205
4206 test_34b() {
4207         [ ! -f $DIR/f34 ] && test_34a
4208         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4209                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4210         $OPENFILE -f O_RDONLY $DIR/f34
4211         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4212                 error "getstripe failed"
4213         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4214                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4215 }
4216 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4217
4218 test_34c() {
4219         [ ! -f $DIR/f34 ] && test_34a
4220         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4221                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4222         $OPENFILE -f O_RDWR $DIR/f34
4223         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4224                 error "$LFS getstripe failed"
4225         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4226                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4227 }
4228 run_test 34c "O_RDWR opening file-with-size works =============="
4229
4230 test_34d() {
4231         [ ! -f $DIR/f34 ] && test_34a
4232         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4233                 error "dd failed"
4234         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4235                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4236         rm $DIR/f34
4237 }
4238 run_test 34d "write to sparse file ============================="
4239
4240 test_34e() {
4241         rm -f $DIR/f34e
4242         $MCREATE $DIR/f34e || error "mcreate failed"
4243         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4244         $CHECKSTAT -s 1000 $DIR/f34e ||
4245                 error "Size of $DIR/f34e not equal to 1000 bytes"
4246         $OPENFILE -f O_RDWR $DIR/f34e
4247         $CHECKSTAT -s 1000 $DIR/f34e ||
4248                 error "Size of $DIR/f34e not equal to 1000 bytes"
4249 }
4250 run_test 34e "create objects, some with size and some without =="
4251
4252 test_34f() { # bug 6242, 6243
4253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4254
4255         SIZE34F=48000
4256         rm -f $DIR/f34f
4257         $MCREATE $DIR/f34f || error "mcreate failed"
4258         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4259         dd if=$DIR/f34f of=$TMP/f34f
4260         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4261         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4262         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4263         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4264         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4265 }
4266 run_test 34f "read from a file with no objects until EOF ======="
4267
4268 test_34g() {
4269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4270
4271         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4272                 error "dd failed"
4273         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4274         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4275                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4276         cancel_lru_locks osc
4277         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4278                 error "wrong size after lock cancel"
4279
4280         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4281         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4282                 error "expanding truncate failed"
4283         cancel_lru_locks osc
4284         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4285                 error "wrong expanded size after lock cancel"
4286 }
4287 run_test 34g "truncate long file ==============================="
4288
4289 test_34h() {
4290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4291
4292         local gid=10
4293         local sz=1000
4294
4295         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4296         sync # Flush the cache so that multiop below does not block on cache
4297              # flush when getting the group lock
4298         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4299         MULTIPID=$!
4300
4301         # Since just timed wait is not good enough, let's do a sync write
4302         # that way we are sure enough time for a roundtrip + processing
4303         # passed + 2 seconds of extra margin.
4304         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4305         rm $DIR/${tfile}-1
4306         sleep 2
4307
4308         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4309                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4310                 kill -9 $MULTIPID
4311         fi
4312         wait $MULTIPID
4313         local nsz=`stat -c %s $DIR/$tfile`
4314         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4315 }
4316 run_test 34h "ftruncate file under grouplock should not block"
4317
4318 test_35a() {
4319         cp /bin/sh $DIR/f35a
4320         chmod 444 $DIR/f35a
4321         chown $RUNAS_ID $DIR/f35a
4322         $RUNAS $DIR/f35a && error || true
4323         rm $DIR/f35a
4324 }
4325 run_test 35a "exec file with mode 444 (should return and not leak)"
4326
4327 test_36a() {
4328         rm -f $DIR/f36
4329         utime $DIR/f36 || error "utime failed for MDS"
4330 }
4331 run_test 36a "MDS utime check (mknod, utime)"
4332
4333 test_36b() {
4334         echo "" > $DIR/f36
4335         utime $DIR/f36 || error "utime failed for OST"
4336 }
4337 run_test 36b "OST utime check (open, utime)"
4338
4339 test_36c() {
4340         rm -f $DIR/d36/f36
4341         test_mkdir $DIR/d36
4342         chown $RUNAS_ID $DIR/d36
4343         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4344 }
4345 run_test 36c "non-root MDS utime check (mknod, utime)"
4346
4347 test_36d() {
4348         [ ! -d $DIR/d36 ] && test_36c
4349         echo "" > $DIR/d36/f36
4350         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4351 }
4352 run_test 36d "non-root OST utime check (open, utime)"
4353
4354 test_36e() {
4355         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4356
4357         test_mkdir $DIR/$tdir
4358         touch $DIR/$tdir/$tfile
4359         $RUNAS utime $DIR/$tdir/$tfile &&
4360                 error "utime worked, expected failure" || true
4361 }
4362 run_test 36e "utime on non-owned file (should return error)"
4363
4364 subr_36fh() {
4365         local fl="$1"
4366         local LANG_SAVE=$LANG
4367         local LC_LANG_SAVE=$LC_LANG
4368         export LANG=C LC_LANG=C # for date language
4369
4370         DATESTR="Dec 20  2000"
4371         test_mkdir $DIR/$tdir
4372         lctl set_param fail_loc=$fl
4373         date; date +%s
4374         cp /etc/hosts $DIR/$tdir/$tfile
4375         sync & # write RPC generated with "current" inode timestamp, but delayed
4376         sleep 1
4377         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4378         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4379         cancel_lru_locks $OSC
4380         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4381         date; date +%s
4382         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4383                 echo "BEFORE: $LS_BEFORE" && \
4384                 echo "AFTER : $LS_AFTER" && \
4385                 echo "WANT  : $DATESTR" && \
4386                 error "$DIR/$tdir/$tfile timestamps changed" || true
4387
4388         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4389 }
4390
4391 test_36f() {
4392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4393
4394         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4395         subr_36fh "0x80000214"
4396 }
4397 run_test 36f "utime on file racing with OST BRW write =========="
4398
4399 test_36g() {
4400         remote_ost_nodsh && skip "remote OST with nodsh"
4401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4402         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4403                 skip "Need MDS version at least 2.12.51"
4404
4405         local fmd_max_age
4406         local fmd
4407         local facet="ost1"
4408         local tgt="obdfilter"
4409
4410         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4411
4412         test_mkdir $DIR/$tdir
4413         fmd_max_age=$(do_facet $facet \
4414                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4415                 head -n 1")
4416
4417         echo "FMD max age: ${fmd_max_age}s"
4418         touch $DIR/$tdir/$tfile
4419         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4420                 gawk '{cnt=cnt+$1}  END{print cnt}')
4421         echo "FMD before: $fmd"
4422         [[ $fmd == 0 ]] &&
4423                 error "FMD wasn't create by touch"
4424         sleep $((fmd_max_age + 12))
4425         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4426                 gawk '{cnt=cnt+$1}  END{print cnt}')
4427         echo "FMD after: $fmd"
4428         [[ $fmd == 0 ]] ||
4429                 error "FMD wasn't expired by ping"
4430 }
4431 run_test 36g "FMD cache expiry ====================="
4432
4433 test_36h() {
4434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4435
4436         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4437         subr_36fh "0x80000227"
4438 }
4439 run_test 36h "utime on file racing with OST BRW write =========="
4440
4441 test_36i() {
4442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4443
4444         test_mkdir $DIR/$tdir
4445         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4446
4447         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4448         local new_mtime=$((mtime + 200))
4449
4450         #change Modify time of striped dir
4451         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4452                         error "change mtime failed"
4453
4454         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4455
4456         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4457 }
4458 run_test 36i "change mtime on striped directory"
4459
4460 # test_37 - duplicate with tests 32q 32r
4461
4462 test_38() {
4463         local file=$DIR/$tfile
4464         touch $file
4465         openfile -f O_DIRECTORY $file
4466         local RC=$?
4467         local ENOTDIR=20
4468         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4469         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4470 }
4471 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4472
4473 test_39a() { # was test_39
4474         touch $DIR/$tfile
4475         touch $DIR/${tfile}2
4476 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4477 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4479         sleep 2
4480         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4481         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4482                 echo "mtime"
4483                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4484                 echo "atime"
4485                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4486                 echo "ctime"
4487                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4488                 error "O_TRUNC didn't change timestamps"
4489         fi
4490 }
4491 run_test 39a "mtime changed on create"
4492
4493 test_39b() {
4494         test_mkdir -c1 $DIR/$tdir
4495         cp -p /etc/passwd $DIR/$tdir/fopen
4496         cp -p /etc/passwd $DIR/$tdir/flink
4497         cp -p /etc/passwd $DIR/$tdir/funlink
4498         cp -p /etc/passwd $DIR/$tdir/frename
4499         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4500
4501         sleep 1
4502         echo "aaaaaa" >> $DIR/$tdir/fopen
4503         echo "aaaaaa" >> $DIR/$tdir/flink
4504         echo "aaaaaa" >> $DIR/$tdir/funlink
4505         echo "aaaaaa" >> $DIR/$tdir/frename
4506
4507         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4508         local link_new=`stat -c %Y $DIR/$tdir/flink`
4509         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4510         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4511
4512         cat $DIR/$tdir/fopen > /dev/null
4513         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4514         rm -f $DIR/$tdir/funlink2
4515         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4516
4517         for (( i=0; i < 2; i++ )) ; do
4518                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4519                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4520                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4521                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4522
4523                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4524                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4525                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4526                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4527
4528                 cancel_lru_locks $OSC
4529                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4530         done
4531 }
4532 run_test 39b "mtime change on open, link, unlink, rename  ======"
4533
4534 # this should be set to past
4535 TEST_39_MTIME=`date -d "1 year ago" +%s`
4536
4537 # bug 11063
4538 test_39c() {
4539         touch $DIR1/$tfile
4540         sleep 2
4541         local mtime0=`stat -c %Y $DIR1/$tfile`
4542
4543         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4544         local mtime1=`stat -c %Y $DIR1/$tfile`
4545         [ "$mtime1" = $TEST_39_MTIME ] || \
4546                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4547
4548         local d1=`date +%s`
4549         echo hello >> $DIR1/$tfile
4550         local d2=`date +%s`
4551         local mtime2=`stat -c %Y $DIR1/$tfile`
4552         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4553                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4554
4555         mv $DIR1/$tfile $DIR1/$tfile-1
4556
4557         for (( i=0; i < 2; i++ )) ; do
4558                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4559                 [ "$mtime2" = "$mtime3" ] || \
4560                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4561
4562                 cancel_lru_locks $OSC
4563                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4564         done
4565 }
4566 run_test 39c "mtime change on rename ==========================="
4567
4568 # bug 21114
4569 test_39d() {
4570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4571
4572         touch $DIR1/$tfile
4573         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4574
4575         for (( i=0; i < 2; i++ )) ; do
4576                 local mtime=`stat -c %Y $DIR1/$tfile`
4577                 [ $mtime = $TEST_39_MTIME ] || \
4578                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4579
4580                 cancel_lru_locks $OSC
4581                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4582         done
4583 }
4584 run_test 39d "create, utime, stat =============================="
4585
4586 # bug 21114
4587 test_39e() {
4588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4589
4590         touch $DIR1/$tfile
4591         local mtime1=`stat -c %Y $DIR1/$tfile`
4592
4593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4594
4595         for (( i=0; i < 2; i++ )) ; do
4596                 local mtime2=`stat -c %Y $DIR1/$tfile`
4597                 [ $mtime2 = $TEST_39_MTIME ] || \
4598                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4599
4600                 cancel_lru_locks $OSC
4601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4602         done
4603 }
4604 run_test 39e "create, stat, utime, stat ========================"
4605
4606 # bug 21114
4607 test_39f() {
4608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4609
4610         touch $DIR1/$tfile
4611         mtime1=`stat -c %Y $DIR1/$tfile`
4612
4613         sleep 2
4614         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4615
4616         for (( i=0; i < 2; i++ )) ; do
4617                 local mtime2=`stat -c %Y $DIR1/$tfile`
4618                 [ $mtime2 = $TEST_39_MTIME ] || \
4619                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4620
4621                 cancel_lru_locks $OSC
4622                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4623         done
4624 }
4625 run_test 39f "create, stat, sleep, utime, stat ================="
4626
4627 # bug 11063
4628 test_39g() {
4629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4630
4631         echo hello >> $DIR1/$tfile
4632         local mtime1=`stat -c %Y $DIR1/$tfile`
4633
4634         sleep 2
4635         chmod o+r $DIR1/$tfile
4636
4637         for (( i=0; i < 2; i++ )) ; do
4638                 local mtime2=`stat -c %Y $DIR1/$tfile`
4639                 [ "$mtime1" = "$mtime2" ] || \
4640                         error "lost mtime: $mtime2, should be $mtime1"
4641
4642                 cancel_lru_locks $OSC
4643                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4644         done
4645 }
4646 run_test 39g "write, chmod, stat ==============================="
4647
4648 # bug 11063
4649 test_39h() {
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651
4652         touch $DIR1/$tfile
4653         sleep 1
4654
4655         local d1=`date`
4656         echo hello >> $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4660         local d2=`date`
4661         if [ "$d1" != "$d2" ]; then
4662                 echo "write and touch not within one second"
4663         else
4664                 for (( i=0; i < 2; i++ )) ; do
4665                         local mtime2=`stat -c %Y $DIR1/$tfile`
4666                         [ "$mtime2" = $TEST_39_MTIME ] || \
4667                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4668
4669                         cancel_lru_locks $OSC
4670                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4671                 done
4672         fi
4673 }
4674 run_test 39h "write, utime within one second, stat ============="
4675
4676 test_39i() {
4677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4678
4679         touch $DIR1/$tfile
4680         sleep 1
4681
4682         echo hello >> $DIR1/$tfile
4683         local mtime1=`stat -c %Y $DIR1/$tfile`
4684
4685         mv $DIR1/$tfile $DIR1/$tfile-1
4686
4687         for (( i=0; i < 2; i++ )) ; do
4688                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4689
4690                 [ "$mtime1" = "$mtime2" ] || \
4691                         error "lost mtime: $mtime2, should be $mtime1"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39i "write, rename, stat =============================="
4698
4699 test_39j() {
4700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4701
4702         start_full_debug_logging
4703         touch $DIR1/$tfile
4704         sleep 1
4705
4706         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4707         lctl set_param fail_loc=0x80000412
4708         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4709                 error "multiop failed"
4710         local multipid=$!
4711         local mtime1=`stat -c %Y $DIR1/$tfile`
4712
4713         mv $DIR1/$tfile $DIR1/$tfile-1
4714
4715         kill -USR1 $multipid
4716         wait $multipid || error "multiop close failed"
4717
4718         for (( i=0; i < 2; i++ )) ; do
4719                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4720                 [ "$mtime1" = "$mtime2" ] ||
4721                         error "mtime is lost on close: $mtime2, " \
4722                               "should be $mtime1"
4723
4724                 cancel_lru_locks
4725                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4726         done
4727         lctl set_param fail_loc=0
4728         stop_full_debug_logging
4729 }
4730 run_test 39j "write, rename, close, stat ======================="
4731
4732 test_39k() {
4733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4734
4735         touch $DIR1/$tfile
4736         sleep 1
4737
4738         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4739         local multipid=$!
4740         local mtime1=`stat -c %Y $DIR1/$tfile`
4741
4742         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4743
4744         kill -USR1 $multipid
4745         wait $multipid || error "multiop close failed"
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local mtime2=`stat -c %Y $DIR1/$tfile`
4749
4750                 [ "$mtime2" = $TEST_39_MTIME ] || \
4751                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4752
4753                 cancel_lru_locks
4754                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4755         done
4756 }
4757 run_test 39k "write, utime, close, stat ========================"
4758
4759 # this should be set to future
4760 TEST_39_ATIME=`date -d "1 year" +%s`
4761
4762 test_39l() {
4763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4764         remote_mds_nodsh && skip "remote MDS with nodsh"
4765
4766         local atime_diff=$(do_facet $SINGLEMDS \
4767                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4768         rm -rf $DIR/$tdir
4769         mkdir -p $DIR/$tdir
4770
4771         # test setting directory atime to future
4772         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4773         local atime=$(stat -c %X $DIR/$tdir)
4774         [ "$atime" = $TEST_39_ATIME ] ||
4775                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4776
4777         # test setting directory atime from future to now
4778         local now=$(date +%s)
4779         touch -a -d @$now $DIR/$tdir
4780
4781         atime=$(stat -c %X $DIR/$tdir)
4782         [ "$atime" -eq "$now"  ] ||
4783                 error "atime is not updated from future: $atime, $now"
4784
4785         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4786         sleep 3
4787
4788         # test setting directory atime when now > dir atime + atime_diff
4789         local d1=$(date +%s)
4790         ls $DIR/$tdir
4791         local d2=$(date +%s)
4792         cancel_lru_locks mdc
4793         atime=$(stat -c %X $DIR/$tdir)
4794         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4795                 error "atime is not updated  : $atime, should be $d2"
4796
4797         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4798         sleep 3
4799
4800         # test not setting directory atime when now < dir atime + atime_diff
4801         ls $DIR/$tdir
4802         cancel_lru_locks mdc
4803         atime=$(stat -c %X $DIR/$tdir)
4804         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4805                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4806
4807         do_facet $SINGLEMDS \
4808                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4809 }
4810 run_test 39l "directory atime update ==========================="
4811
4812 test_39m() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814
4815         touch $DIR1/$tfile
4816         sleep 2
4817         local far_past_mtime=$(date -d "May 29 1953" +%s)
4818         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4819
4820         touch -m -d @$far_past_mtime $DIR1/$tfile
4821         touch -a -d @$far_past_atime $DIR1/$tfile
4822
4823         for (( i=0; i < 2; i++ )) ; do
4824                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4825                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4826                         error "atime or mtime set incorrectly"
4827
4828                 cancel_lru_locks $OSC
4829                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4830         done
4831 }
4832 run_test 39m "test atime and mtime before 1970"
4833
4834 test_39n() { # LU-3832
4835         remote_mds_nodsh && skip "remote MDS with nodsh"
4836
4837         local atime_diff=$(do_facet $SINGLEMDS \
4838                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4839         local atime0
4840         local atime1
4841         local atime2
4842
4843         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4844
4845         rm -rf $DIR/$tfile
4846         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4847         atime0=$(stat -c %X $DIR/$tfile)
4848
4849         sleep 5
4850         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4851         atime1=$(stat -c %X $DIR/$tfile)
4852
4853         sleep 5
4854         cancel_lru_locks mdc
4855         cancel_lru_locks osc
4856         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4857         atime2=$(stat -c %X $DIR/$tfile)
4858
4859         do_facet $SINGLEMDS \
4860                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4861
4862         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4863         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4864 }
4865 run_test 39n "check that O_NOATIME is honored"
4866
4867 test_39o() {
4868         TESTDIR=$DIR/$tdir/$tfile
4869         [ -e $TESTDIR ] && rm -rf $TESTDIR
4870         mkdir -p $TESTDIR
4871         cd $TESTDIR
4872         links1=2
4873         ls
4874         mkdir a b
4875         ls
4876         links2=$(stat -c %h .)
4877         [ $(($links1 + 2)) != $links2 ] &&
4878                 error "wrong links count $(($links1 + 2)) != $links2"
4879         rmdir b
4880         links3=$(stat -c %h .)
4881         [ $(($links1 + 1)) != $links3 ] &&
4882                 error "wrong links count $links1 != $links3"
4883         return 0
4884 }
4885 run_test 39o "directory cached attributes updated after create"
4886
4887 test_39p() {
4888         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4889
4890         local MDTIDX=1
4891         TESTDIR=$DIR/$tdir/$tdir
4892         [ -e $TESTDIR ] && rm -rf $TESTDIR
4893         test_mkdir -p $TESTDIR
4894         cd $TESTDIR
4895         links1=2
4896         ls
4897         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4899         ls
4900         links2=$(stat -c %h .)
4901         [ $(($links1 + 2)) != $links2 ] &&
4902                 error "wrong links count $(($links1 + 2)) != $links2"
4903         rmdir remote_dir2
4904         links3=$(stat -c %h .)
4905         [ $(($links1 + 1)) != $links3 ] &&
4906                 error "wrong links count $links1 != $links3"
4907         return 0
4908 }
4909 run_test 39p "remote directory cached attributes updated after create ========"
4910
4911 test_39r() {
4912         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4913                 skip "no atime update on old OST"
4914         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4915                 skip_env "ldiskfs only test"
4916         fi
4917
4918         local saved_adiff
4919         saved_adiff=$(do_facet ost1 \
4920                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4921         stack_trap "do_facet ost1 \
4922                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4923
4924         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4925
4926         $LFS setstripe -i 0 $DIR/$tfile
4927         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4928                 error "can't write initial file"
4929         cancel_lru_locks osc
4930
4931         # exceed atime_diff and access file
4932         sleep 6
4933         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4934                 error "can't udpate atime"
4935
4936         local atime_cli=$(stat -c %X $DIR/$tfile)
4937         echo "client atime: $atime_cli"
4938         # allow atime update to be written to device
4939         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4940         sleep 5
4941
4942         local ostdev=$(ostdevname 1)
4943         local fid=($(lfs getstripe -y $DIR/$tfile |
4944                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4945         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4946         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4947
4948         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4949         local atime_ost=$(do_facet ost1 "$cmd" |&
4950                           awk -F'[: ]' '/atime:/ { print $4 }')
4951         (( atime_cli == atime_ost )) ||
4952                 error "atime on client $atime_cli != ost $atime_ost"
4953 }
4954 run_test 39r "lazy atime update on OST"
4955
4956 test_39q() { # LU-8041
4957         local testdir=$DIR/$tdir
4958         mkdir -p $testdir
4959         multiop_bg_pause $testdir D_c || error "multiop failed"
4960         local multipid=$!
4961         cancel_lru_locks mdc
4962         kill -USR1 $multipid
4963         local atime=$(stat -c %X $testdir)
4964         [ "$atime" -ne 0 ] || error "atime is zero"
4965 }
4966 run_test 39q "close won't zero out atime"
4967
4968 test_40() {
4969         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4970         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4971                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4972         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4973                 error "$tfile is not 4096 bytes in size"
4974 }
4975 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4976
4977 test_41() {
4978         # bug 1553
4979         small_write $DIR/f41 18
4980 }
4981 run_test 41 "test small file write + fstat ====================="
4982
4983 count_ost_writes() {
4984         lctl get_param -n ${OSC}.*.stats |
4985                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4986                         END { printf("%0.0f", writes) }'
4987 }
4988
4989 # decent default
4990 WRITEBACK_SAVE=500
4991 DIRTY_RATIO_SAVE=40
4992 MAX_DIRTY_RATIO=50
4993 BG_DIRTY_RATIO_SAVE=10
4994 MAX_BG_DIRTY_RATIO=25
4995
4996 start_writeback() {
4997         trap 0
4998         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4999         # dirty_ratio, dirty_background_ratio
5000         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5001                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5002                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5003                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5004         else
5005                 # if file not here, we are a 2.4 kernel
5006                 kill -CONT `pidof kupdated`
5007         fi
5008 }
5009
5010 stop_writeback() {
5011         # setup the trap first, so someone cannot exit the test at the
5012         # exact wrong time and mess up a machine
5013         trap start_writeback EXIT
5014         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5015         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5016                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5017                 sysctl -w vm.dirty_writeback_centisecs=0
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 # save and increase /proc/sys/vm/dirty_ratio
5020                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5021                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5022                 # save and increase /proc/sys/vm/dirty_background_ratio
5023                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5024                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5025         else
5026                 # if file not here, we are a 2.4 kernel
5027                 kill -STOP `pidof kupdated`
5028         fi
5029 }
5030
5031 # ensure that all stripes have some grant before we test client-side cache
5032 setup_test42() {
5033         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5034                 dd if=/dev/zero of=$i bs=4k count=1
5035                 rm $i
5036         done
5037 }
5038
5039 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5040 # file truncation, and file removal.
5041 test_42a() {
5042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5043
5044         setup_test42
5045         cancel_lru_locks $OSC
5046         stop_writeback
5047         sync; sleep 1; sync # just to be safe
5048         BEFOREWRITES=`count_ost_writes`
5049         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5050         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5051         AFTERWRITES=`count_ost_writes`
5052         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5053                 error "$BEFOREWRITES < $AFTERWRITES"
5054         start_writeback
5055 }
5056 run_test 42a "ensure that we don't flush on close"
5057
5058 test_42b() {
5059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5060
5061         setup_test42
5062         cancel_lru_locks $OSC
5063         stop_writeback
5064         sync
5065         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5066         BEFOREWRITES=$(count_ost_writes)
5067         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5068         AFTERWRITES=$(count_ost_writes)
5069         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5070                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5071         fi
5072         BEFOREWRITES=$(count_ost_writes)
5073         sync || error "sync: $?"
5074         AFTERWRITES=$(count_ost_writes)
5075         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5076                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5077         fi
5078         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5079         start_writeback
5080         return 0
5081 }
5082 run_test 42b "test destroy of file with cached dirty data ======"
5083
5084 # if these tests just want to test the effect of truncation,
5085 # they have to be very careful.  consider:
5086 # - the first open gets a {0,EOF}PR lock
5087 # - the first write conflicts and gets a {0, count-1}PW
5088 # - the rest of the writes are under {count,EOF}PW
5089 # - the open for truncate tries to match a {0,EOF}PR
5090 #   for the filesize and cancels the PWs.
5091 # any number of fixes (don't get {0,EOF} on open, match
5092 # composite locks, do smarter file size management) fix
5093 # this, but for now we want these tests to verify that
5094 # the cancellation with truncate intent works, so we
5095 # start the file with a full-file pw lock to match against
5096 # until the truncate.
5097 trunc_test() {
5098         test=$1
5099         file=$DIR/$test
5100         offset=$2
5101         cancel_lru_locks $OSC
5102         stop_writeback
5103         # prime the file with 0,EOF PW to match
5104         touch $file
5105         $TRUNCATE $file 0
5106         sync; sync
5107         # now the real test..
5108         dd if=/dev/zero of=$file bs=1024 count=100
5109         BEFOREWRITES=`count_ost_writes`
5110         $TRUNCATE $file $offset
5111         cancel_lru_locks $OSC
5112         AFTERWRITES=`count_ost_writes`
5113         start_writeback
5114 }
5115
5116 test_42c() {
5117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5118
5119         trunc_test 42c 1024
5120         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5121                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5122         rm $file
5123 }
5124 run_test 42c "test partial truncate of file with cached dirty data"
5125
5126 test_42d() {
5127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5128
5129         trunc_test 42d 0
5130         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5131                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5132         rm $file
5133 }
5134 run_test 42d "test complete truncate of file with cached dirty data"
5135
5136 test_42e() { # bug22074
5137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5138
5139         local TDIR=$DIR/${tdir}e
5140         local pages=16 # hardcoded 16 pages, don't change it.
5141         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5142         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5143         local max_dirty_mb
5144         local warmup_files
5145
5146         test_mkdir $DIR/${tdir}e
5147         $LFS setstripe -c 1 $TDIR
5148         createmany -o $TDIR/f $files
5149
5150         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5151
5152         # we assume that with $OSTCOUNT files, at least one of them will
5153         # be allocated on OST0.
5154         warmup_files=$((OSTCOUNT * max_dirty_mb))
5155         createmany -o $TDIR/w $warmup_files
5156
5157         # write a large amount of data into one file and sync, to get good
5158         # avail_grant number from OST.
5159         for ((i=0; i<$warmup_files; i++)); do
5160                 idx=$($LFS getstripe -i $TDIR/w$i)
5161                 [ $idx -ne 0 ] && continue
5162                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5163                 break
5164         done
5165         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5166         sync
5167         $LCTL get_param $proc_osc0/cur_dirty_bytes
5168         $LCTL get_param $proc_osc0/cur_grant_bytes
5169
5170         # create as much dirty pages as we can while not to trigger the actual
5171         # RPCs directly. but depends on the env, VFS may trigger flush during this
5172         # period, hopefully we are good.
5173         for ((i=0; i<$warmup_files; i++)); do
5174                 idx=$($LFS getstripe -i $TDIR/w$i)
5175                 [ $idx -ne 0 ] && continue
5176                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5177         done
5178         $LCTL get_param $proc_osc0/cur_dirty_bytes
5179         $LCTL get_param $proc_osc0/cur_grant_bytes
5180
5181         # perform the real test
5182         $LCTL set_param $proc_osc0/rpc_stats 0
5183         for ((;i<$files; i++)); do
5184                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5185                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5186         done
5187         sync
5188         $LCTL get_param $proc_osc0/rpc_stats
5189
5190         local percent=0
5191         local have_ppr=false
5192         $LCTL get_param $proc_osc0/rpc_stats |
5193                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5194                         # skip lines until we are at the RPC histogram data
5195                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5196                         $have_ppr || continue
5197
5198                         # we only want the percent stat for < 16 pages
5199                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5200
5201                         percent=$((percent + WPCT))
5202                         if [[ $percent -gt 15 ]]; then
5203                                 error "less than 16-pages write RPCs" \
5204                                       "$percent% > 15%"
5205                                 break
5206                         fi
5207                 done
5208         rm -rf $TDIR
5209 }
5210 run_test 42e "verify sub-RPC writes are not done synchronously"
5211
5212 test_43A() { # was test_43
5213         test_mkdir $DIR/$tdir
5214         cp -p /bin/ls $DIR/$tdir/$tfile
5215         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5216         pid=$!
5217         # give multiop a chance to open
5218         sleep 1
5219
5220         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5221         kill -USR1 $pid
5222         # Wait for multiop to exit
5223         wait $pid
5224 }
5225 run_test 43A "execution of file opened for write should return -ETXTBSY"
5226
5227 test_43a() {
5228         test_mkdir $DIR/$tdir
5229         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5230         $DIR/$tdir/sleep 60 &
5231         SLEEP_PID=$!
5232         # Make sure exec of $tdir/sleep wins race with truncate
5233         sleep 1
5234         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5235         kill $SLEEP_PID
5236 }
5237 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5238
5239 test_43b() {
5240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5241
5242         test_mkdir $DIR/$tdir
5243         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5244         $DIR/$tdir/sleep 60 &
5245         SLEEP_PID=$!
5246         # Make sure exec of $tdir/sleep wins race with truncate
5247         sleep 1
5248         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5249         kill $SLEEP_PID
5250 }
5251 run_test 43b "truncate of file being executed should return -ETXTBSY"
5252
5253 test_43c() {
5254         local testdir="$DIR/$tdir"
5255         test_mkdir $testdir
5256         cp $SHELL $testdir/
5257         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5258                 ( cd $testdir && md5sum -c )
5259 }
5260 run_test 43c "md5sum of copy into lustre"
5261
5262 test_44A() { # was test_44
5263         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5264
5265         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5266         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5267 }
5268 run_test 44A "zero length read from a sparse stripe"
5269
5270 test_44a() {
5271         local nstripe=$($LFS getstripe -c -d $DIR)
5272         [ -z "$nstripe" ] && skip "can't get stripe info"
5273         [[ $nstripe -gt $OSTCOUNT ]] &&
5274                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5275
5276         local stride=$($LFS getstripe -S -d $DIR)
5277         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5278                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5279         fi
5280
5281         OFFSETS="0 $((stride/2)) $((stride-1))"
5282         for offset in $OFFSETS; do
5283                 for i in $(seq 0 $((nstripe-1))); do
5284                         local GLOBALOFFSETS=""
5285                         # size in Bytes
5286                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5287                         local myfn=$DIR/d44a-$size
5288                         echo "--------writing $myfn at $size"
5289                         ll_sparseness_write $myfn $size ||
5290                                 error "ll_sparseness_write"
5291                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5292                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5293                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5294
5295                         for j in $(seq 0 $((nstripe-1))); do
5296                                 # size in Bytes
5297                                 size=$((((j + $nstripe )*$stride + $offset)))
5298                                 ll_sparseness_write $myfn $size ||
5299                                         error "ll_sparseness_write"
5300                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5301                         done
5302                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5303                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5304                         rm -f $myfn
5305                 done
5306         done
5307 }
5308 run_test 44a "test sparse pwrite ==============================="
5309
5310 dirty_osc_total() {
5311         tot=0
5312         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5313                 tot=$(($tot + $d))
5314         done
5315         echo $tot
5316 }
5317 do_dirty_record() {
5318         before=`dirty_osc_total`
5319         echo executing "\"$*\""
5320         eval $*
5321         after=`dirty_osc_total`
5322         echo before $before, after $after
5323 }
5324 test_45() {
5325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5326
5327         f="$DIR/f45"
5328         # Obtain grants from OST if it supports it
5329         echo blah > ${f}_grant
5330         stop_writeback
5331         sync
5332         do_dirty_record "echo blah > $f"
5333         [[ $before -eq $after ]] && error "write wasn't cached"
5334         do_dirty_record "> $f"
5335         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5336         do_dirty_record "echo blah > $f"
5337         [[ $before -eq $after ]] && error "write wasn't cached"
5338         do_dirty_record "sync"
5339         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5340         do_dirty_record "echo blah > $f"
5341         [[ $before -eq $after ]] && error "write wasn't cached"
5342         do_dirty_record "cancel_lru_locks osc"
5343         [[ $before -gt $after ]] ||
5344                 error "lock cancellation didn't lower dirty count"
5345         start_writeback
5346 }
5347 run_test 45 "osc io page accounting ============================"
5348
5349 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5350 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5351 # objects offset and an assert hit when an rpc was built with 1023's mapped
5352 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5353 test_46() {
5354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5355
5356         f="$DIR/f46"
5357         stop_writeback
5358         sync
5359         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5360         sync
5361         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5363         sync
5364         start_writeback
5365 }
5366 run_test 46 "dirtying a previously written page ================"
5367
5368 # test_47 is removed "Device nodes check" is moved to test_28
5369
5370 test_48a() { # bug 2399
5371         [ "$mds1_FSTYPE" = "zfs" ] &&
5372         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5373                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5374
5375         test_mkdir $DIR/$tdir
5376         cd $DIR/$tdir
5377         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5378         test_mkdir $DIR/$tdir
5379         touch foo || error "'touch foo' failed after recreating cwd"
5380         test_mkdir bar
5381         touch .foo || error "'touch .foo' failed after recreating cwd"
5382         test_mkdir .bar
5383         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5384         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5385         cd . || error "'cd .' failed after recreating cwd"
5386         mkdir . && error "'mkdir .' worked after recreating cwd"
5387         rmdir . && error "'rmdir .' worked after recreating cwd"
5388         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5389         cd .. || error "'cd ..' failed after recreating cwd"
5390 }
5391 run_test 48a "Access renamed working dir (should return errors)="
5392
5393 test_48b() { # bug 2399
5394         rm -rf $DIR/$tdir
5395         test_mkdir $DIR/$tdir
5396         cd $DIR/$tdir
5397         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5398         touch foo && error "'touch foo' worked after removing cwd"
5399         mkdir foo && error "'mkdir foo' worked after removing cwd"
5400         touch .foo && error "'touch .foo' worked after removing cwd"
5401         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5402         ls . > /dev/null && error "'ls .' worked after removing cwd"
5403         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5404         mkdir . && error "'mkdir .' worked after removing cwd"
5405         rmdir . && error "'rmdir .' worked after removing cwd"
5406         ln -s . foo && error "'ln -s .' worked after removing cwd"
5407         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5408 }
5409 run_test 48b "Access removed working dir (should return errors)="
5410
5411 test_48c() { # bug 2350
5412         #lctl set_param debug=-1
5413         #set -vx
5414         rm -rf $DIR/$tdir
5415         test_mkdir -p $DIR/$tdir/dir
5416         cd $DIR/$tdir/dir
5417         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5418         $TRACE touch foo && error "touch foo worked after removing cwd"
5419         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5420         touch .foo && error "touch .foo worked after removing cwd"
5421         mkdir .foo && error "mkdir .foo worked after removing cwd"
5422         $TRACE ls . && error "'ls .' worked after removing cwd"
5423         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5424         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5425         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5426         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5427         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5428 }
5429 run_test 48c "Access removed working subdir (should return errors)"
5430
5431 test_48d() { # bug 2350
5432         #lctl set_param debug=-1
5433         #set -vx
5434         rm -rf $DIR/$tdir
5435         test_mkdir -p $DIR/$tdir/dir
5436         cd $DIR/$tdir/dir
5437         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5438         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5439         $TRACE touch foo && error "'touch foo' worked after removing parent"
5440         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5441         touch .foo && error "'touch .foo' worked after removing parent"
5442         mkdir .foo && error "mkdir .foo worked after removing parent"
5443         $TRACE ls . && error "'ls .' worked after removing parent"
5444         $TRACE ls .. && error "'ls ..' worked after removing parent"
5445         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5446         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5447         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5448         true
5449 }
5450 run_test 48d "Access removed parent subdir (should return errors)"
5451
5452 test_48e() { # bug 4134
5453         #lctl set_param debug=-1
5454         #set -vx
5455         rm -rf $DIR/$tdir
5456         test_mkdir -p $DIR/$tdir/dir
5457         cd $DIR/$tdir/dir
5458         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5459         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5460         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5461         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5462         # On a buggy kernel addition of "touch foo" after cd .. will
5463         # produce kernel oops in lookup_hash_it
5464         touch ../foo && error "'cd ..' worked after recreate parent"
5465         cd $DIR
5466         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5467 }
5468 run_test 48e "Access to recreated parent subdir (should return errors)"
5469
5470 test_48f() {
5471         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5472                 skip "need MDS >= 2.13.55"
5473         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5474         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5475                 skip "needs different host for mdt1 mdt2"
5476         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5477
5478         $LFS mkdir -i0 $DIR/$tdir
5479         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5480
5481         for d in sub1 sub2 sub3; do
5482                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5483                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5484                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5485         done
5486
5487         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5488 }
5489 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5490
5491 test_49() { # LU-1030
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493         remote_ost_nodsh && skip "remote OST with nodsh"
5494
5495         # get ost1 size - $FSNAME-OST0000
5496         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5497                 awk '{ print $4 }')
5498         # write 800M at maximum
5499         [[ $ost1_size -lt 2 ]] && ost1_size=2
5500         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5501
5502         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5503         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5504         local dd_pid=$!
5505
5506         # change max_pages_per_rpc while writing the file
5507         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5508         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5509         # loop until dd process exits
5510         while ps ax -opid | grep -wq $dd_pid; do
5511                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5512                 sleep $((RANDOM % 5 + 1))
5513         done
5514         # restore original max_pages_per_rpc
5515         $LCTL set_param $osc1_mppc=$orig_mppc
5516         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5517 }
5518 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5519
5520 test_50() {
5521         # bug 1485
5522         test_mkdir $DIR/$tdir
5523         cd $DIR/$tdir
5524         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5525 }
5526 run_test 50 "special situations: /proc symlinks  ==============="
5527
5528 test_51a() {    # was test_51
5529         # bug 1516 - create an empty entry right after ".." then split dir
5530         test_mkdir -c1 $DIR/$tdir
5531         touch $DIR/$tdir/foo
5532         $MCREATE $DIR/$tdir/bar
5533         rm $DIR/$tdir/foo
5534         createmany -m $DIR/$tdir/longfile 201
5535         FNUM=202
5536         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5537                 $MCREATE $DIR/$tdir/longfile$FNUM
5538                 FNUM=$(($FNUM + 1))
5539                 echo -n "+"
5540         done
5541         echo
5542         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5543 }
5544 run_test 51a "special situations: split htree with empty entry =="
5545
5546 cleanup_print_lfs_df () {
5547         trap 0
5548         $LFS df
5549         $LFS df -i
5550 }
5551
5552 test_51b() {
5553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5554
5555         local dir=$DIR/$tdir
5556         local nrdirs=$((65536 + 100))
5557
5558         # cleanup the directory
5559         rm -fr $dir
5560
5561         test_mkdir -c1 $dir
5562
5563         $LFS df
5564         $LFS df -i
5565         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5566         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5567         [[ $numfree -lt $nrdirs ]] &&
5568                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5569
5570         # need to check free space for the directories as well
5571         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5572         numfree=$(( blkfree / $(fs_inode_ksize) ))
5573         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5574
5575         trap cleanup_print_lfs_df EXIT
5576
5577         # create files
5578         createmany -d $dir/d $nrdirs || {
5579                 unlinkmany $dir/d $nrdirs
5580                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5581         }
5582
5583         # really created :
5584         nrdirs=$(ls -U $dir | wc -l)
5585
5586         # unlink all but 100 subdirectories, then check it still works
5587         local left=100
5588         local delete=$((nrdirs - left))
5589
5590         $LFS df
5591         $LFS df -i
5592
5593         # for ldiskfs the nlink count should be 1, but this is OSD specific
5594         # and so this is listed for informational purposes only
5595         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5596         unlinkmany -d $dir/d $delete ||
5597                 error "unlink of first $delete subdirs failed"
5598
5599         echo "nlink between: $(stat -c %h $dir)"
5600         local found=$(ls -U $dir | wc -l)
5601         [ $found -ne $left ] &&
5602                 error "can't find subdirs: found only $found, expected $left"
5603
5604         unlinkmany -d $dir/d $delete $left ||
5605                 error "unlink of second $left subdirs failed"
5606         # regardless of whether the backing filesystem tracks nlink accurately
5607         # or not, the nlink count shouldn't be more than "." and ".." here
5608         local after=$(stat -c %h $dir)
5609         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5610                 echo "nlink after: $after"
5611
5612         cleanup_print_lfs_df
5613 }
5614 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5615
5616 test_51d() {
5617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5618         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5619
5620         test_mkdir $DIR/$tdir
5621         createmany -o $DIR/$tdir/t- 1000
5622         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5623         for N in $(seq 0 $((OSTCOUNT - 1))); do
5624                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5625                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5626                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5627                         '($1 == '$N') { objs += 1 } \
5628                         END { printf("%0.0f", objs) }')
5629                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5630         done
5631         unlinkmany $DIR/$tdir/t- 1000
5632
5633         NLAST=0
5634         for N in $(seq 1 $((OSTCOUNT - 1))); do
5635                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5636                         error "OST $N has less objects vs OST $NLAST" \
5637                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5638                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5639                         error "OST $N has less objects vs OST $NLAST" \
5640                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5641
5642                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5643                         error "OST $N has less #0 objects vs OST $NLAST" \
5644                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5645                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5646                         error "OST $N has less #0 objects vs OST $NLAST" \
5647                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5648                 NLAST=$N
5649         done
5650         rm -f $TMP/$tfile
5651 }
5652 run_test 51d "check object distribution"
5653
5654 test_51e() {
5655         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5656                 skip_env "ldiskfs only test"
5657         fi
5658
5659         test_mkdir -c1 $DIR/$tdir
5660         test_mkdir -c1 $DIR/$tdir/d0
5661
5662         touch $DIR/$tdir/d0/foo
5663         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5664                 error "file exceed 65000 nlink limit!"
5665         unlinkmany $DIR/$tdir/d0/f- 65001
5666         return 0
5667 }
5668 run_test 51e "check file nlink limit"
5669
5670 test_51f() {
5671         test_mkdir $DIR/$tdir
5672
5673         local max=100000
5674         local ulimit_old=$(ulimit -n)
5675         local spare=20 # number of spare fd's for scripts/libraries, etc.
5676         local mdt=$($LFS getstripe -m $DIR/$tdir)
5677         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5678
5679         echo "MDT$mdt numfree=$numfree, max=$max"
5680         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5681         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5682                 while ! ulimit -n $((numfree + spare)); do
5683                         numfree=$((numfree * 3 / 4))
5684                 done
5685                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5686         else
5687                 echo "left ulimit at $ulimit_old"
5688         fi
5689
5690         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5691                 unlinkmany $DIR/$tdir/f $numfree
5692                 error "create+open $numfree files in $DIR/$tdir failed"
5693         }
5694         ulimit -n $ulimit_old
5695
5696         # if createmany exits at 120s there will be fewer than $numfree files
5697         unlinkmany $DIR/$tdir/f $numfree || true
5698 }
5699 run_test 51f "check many open files limit"
5700
5701 test_52a() {
5702         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5703         test_mkdir $DIR/$tdir
5704         touch $DIR/$tdir/foo
5705         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5706         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5707         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5708         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5709         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5710                                         error "link worked"
5711         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5712         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5713         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5714                                                      error "lsattr"
5715         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5716         cp -r $DIR/$tdir $TMP/
5717         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5718 }
5719 run_test 52a "append-only flag test (should return errors)"
5720
5721 test_52b() {
5722         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5723         test_mkdir $DIR/$tdir
5724         touch $DIR/$tdir/foo
5725         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5726         cat test > $DIR/$tdir/foo && error "cat test worked"
5727         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5728         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5729         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5730                                         error "link worked"
5731         echo foo >> $DIR/$tdir/foo && error "echo worked"
5732         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5733         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5734         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5735         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5736                                                         error "lsattr"
5737         chattr -i $DIR/$tdir/foo || error "chattr failed"
5738
5739         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5740 }
5741 run_test 52b "immutable flag test (should return errors) ======="
5742
5743 test_53() {
5744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5745         remote_mds_nodsh && skip "remote MDS with nodsh"
5746         remote_ost_nodsh && skip "remote OST with nodsh"
5747
5748         local param
5749         local param_seq
5750         local ostname
5751         local mds_last
5752         local mds_last_seq
5753         local ost_last
5754         local ost_last_seq
5755         local ost_last_id
5756         local ostnum
5757         local node
5758         local found=false
5759         local support_last_seq=true
5760
5761         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5762                 support_last_seq=false
5763
5764         # only test MDT0000
5765         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5766         local value
5767         for value in $(do_facet $SINGLEMDS \
5768                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5769                 param=$(echo ${value[0]} | cut -d "=" -f1)
5770                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5771
5772                 if $support_last_seq; then
5773                         param_seq=$(echo $param |
5774                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5775                         mds_last_seq=$(do_facet $SINGLEMDS \
5776                                        $LCTL get_param -n $param_seq)
5777                 fi
5778                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5779
5780                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5781                 node=$(facet_active_host ost$((ostnum+1)))
5782                 param="obdfilter.$ostname.last_id"
5783                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5784                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5785                         ost_last_id=$ost_last
5786
5787                         if $support_last_seq; then
5788                                 ost_last_id=$(echo $ost_last |
5789                                               awk -F':' '{print $2}' |
5790                                               sed -e "s/^0x//g")
5791                                 ost_last_seq=$(echo $ost_last |
5792                                                awk -F':' '{print $1}')
5793                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5794                         fi
5795
5796                         if [[ $ost_last_id != $mds_last ]]; then
5797                                 error "$ost_last_id != $mds_last"
5798                         else
5799                                 found=true
5800                                 break
5801                         fi
5802                 done
5803         done
5804         $found || error "can not match last_seq/last_id for $mdtosc"
5805         return 0
5806 }
5807 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5808
5809 test_54a() {
5810         perl -MSocket -e ';' || skip "no Socket perl module installed"
5811
5812         $SOCKETSERVER $DIR/socket ||
5813                 error "$SOCKETSERVER $DIR/socket failed: $?"
5814         $SOCKETCLIENT $DIR/socket ||
5815                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5816         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5817 }
5818 run_test 54a "unix domain socket test =========================="
5819
5820 test_54b() {
5821         f="$DIR/f54b"
5822         mknod $f c 1 3
5823         chmod 0666 $f
5824         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5825 }
5826 run_test 54b "char device works in lustre ======================"
5827
5828 find_loop_dev() {
5829         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5830         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5831         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5832
5833         for i in $(seq 3 7); do
5834                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5835                 LOOPDEV=$LOOPBASE$i
5836                 LOOPNUM=$i
5837                 break
5838         done
5839 }
5840
5841 cleanup_54c() {
5842         local rc=0
5843         loopdev="$DIR/loop54c"
5844
5845         trap 0
5846         $UMOUNT $DIR/$tdir || rc=$?
5847         losetup -d $loopdev || true
5848         losetup -d $LOOPDEV || true
5849         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5850         return $rc
5851 }
5852
5853 test_54c() {
5854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5855
5856         loopdev="$DIR/loop54c"
5857
5858         find_loop_dev
5859         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5860         trap cleanup_54c EXIT
5861         mknod $loopdev b 7 $LOOPNUM
5862         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5863         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5864         losetup $loopdev $DIR/$tfile ||
5865                 error "can't set up $loopdev for $DIR/$tfile"
5866         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5867         test_mkdir $DIR/$tdir
5868         mount -t ext2 $loopdev $DIR/$tdir ||
5869                 error "error mounting $loopdev on $DIR/$tdir"
5870         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5871                 error "dd write"
5872         df $DIR/$tdir
5873         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5874                 error "dd read"
5875         cleanup_54c
5876 }
5877 run_test 54c "block device works in lustre ====================="
5878
5879 test_54d() {
5880         f="$DIR/f54d"
5881         string="aaaaaa"
5882         mknod $f p
5883         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5884 }
5885 run_test 54d "fifo device works in lustre ======================"
5886
5887 test_54e() {
5888         f="$DIR/f54e"
5889         string="aaaaaa"
5890         cp -aL /dev/console $f
5891         echo $string > $f || error "echo $string to $f failed"
5892 }
5893 run_test 54e "console/tty device works in lustre ======================"
5894
5895 test_56a() {
5896         local numfiles=3
5897         local numdirs=2
5898         local dir=$DIR/$tdir
5899
5900         rm -rf $dir
5901         test_mkdir -p $dir/dir
5902         for i in $(seq $numfiles); do
5903                 touch $dir/file$i
5904                 touch $dir/dir/file$i
5905         done
5906
5907         local numcomp=$($LFS getstripe --component-count $dir)
5908
5909         [[ $numcomp == 0 ]] && numcomp=1
5910
5911         # test lfs getstripe with --recursive
5912         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5913
5914         [[ $filenum -eq $((numfiles * 2)) ]] ||
5915                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5916         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5917         [[ $filenum -eq $numfiles ]] ||
5918                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5919         echo "$LFS getstripe showed obdidx or l_ost_idx"
5920
5921         # test lfs getstripe with file instead of dir
5922         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5923         [[ $filenum -eq 1 ]] ||
5924                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5925         echo "$LFS getstripe file1 passed"
5926
5927         #test lfs getstripe with --verbose
5928         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5929         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5930                 error "$LFS getstripe --verbose $dir: "\
5931                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5932         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5933                 error "$LFS getstripe $dir: showed lmm_magic"
5934
5935         #test lfs getstripe with -v prints lmm_fid
5936         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5937         local countfids=$((numdirs + numfiles * numcomp))
5938         [[ $filenum -eq $countfids ]] ||
5939                 error "$LFS getstripe -v $dir: "\
5940                       "got $filenum want $countfids lmm_fid"
5941         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5942                 error "$LFS getstripe $dir: showed lmm_fid by default"
5943         echo "$LFS getstripe --verbose passed"
5944
5945         #check for FID information
5946         local fid1=$($LFS getstripe --fid $dir/file1)
5947         local fid2=$($LFS getstripe --verbose $dir/file1 |
5948                      awk '/lmm_fid: / { print $2; exit; }')
5949         local fid3=$($LFS path2fid $dir/file1)
5950
5951         [ "$fid1" != "$fid2" ] &&
5952                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5953         [ "$fid1" != "$fid3" ] &&
5954                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5955         echo "$LFS getstripe --fid passed"
5956
5957         #test lfs getstripe with --obd
5958         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5959                 error "$LFS getstripe --obd wrong_uuid: should return error"
5960
5961         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5962
5963         local ostidx=1
5964         local obduuid=$(ostuuid_from_index $ostidx)
5965         local found=$($LFS getstripe -r --obd $obduuid $dir |
5966                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5967
5968         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5969         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5970                 ((filenum--))
5971         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5972                 ((filenum--))
5973
5974         [[ $found -eq $filenum ]] ||
5975                 error "$LFS getstripe --obd: found $found expect $filenum"
5976         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5977                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5978                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5979                 error "$LFS getstripe --obd: should not show file on other obd"
5980         echo "$LFS getstripe --obd passed"
5981 }
5982 run_test 56a "check $LFS getstripe"
5983
5984 test_56b() {
5985         local dir=$DIR/$tdir
5986         local numdirs=3
5987
5988         test_mkdir $dir
5989         for i in $(seq $numdirs); do
5990                 test_mkdir $dir/dir$i
5991         done
5992
5993         # test lfs getdirstripe default mode is non-recursion, which is
5994         # different from lfs getstripe
5995         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5996
5997         [[ $dircnt -eq 1 ]] ||
5998                 error "$LFS getdirstripe: found $dircnt, not 1"
5999         dircnt=$($LFS getdirstripe --recursive $dir |
6000                 grep -c lmv_stripe_count)
6001         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6002                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6003 }
6004 run_test 56b "check $LFS getdirstripe"
6005
6006 test_56c() {
6007         remote_ost_nodsh && skip "remote OST with nodsh"
6008
6009         local ost_idx=0
6010         local ost_name=$(ostname_from_index $ost_idx)
6011         local old_status=$(ost_dev_status $ost_idx)
6012         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6013
6014         [[ -z "$old_status" ]] ||
6015                 skip_env "OST $ost_name is in $old_status status"
6016
6017         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6018         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6019                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6020         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6021                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6022                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6023         fi
6024
6025         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6026                 error "$LFS df -v showing inactive devices"
6027         sleep_maxage
6028
6029         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6030
6031         [[ "$new_status" =~ "D" ]] ||
6032                 error "$ost_name status is '$new_status', missing 'D'"
6033         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6034                 [[ "$new_status" =~ "N" ]] ||
6035                         error "$ost_name status is '$new_status', missing 'N'"
6036         fi
6037         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6038                 [[ "$new_status" =~ "f" ]] ||
6039                         error "$ost_name status is '$new_status', missing 'f'"
6040         fi
6041
6042         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6043         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6044                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6045         [[ -z "$p" ]] && restore_lustre_params < $p || true
6046         sleep_maxage
6047
6048         new_status=$(ost_dev_status $ost_idx)
6049         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6050                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6051         # can't check 'f' as devices may actually be on flash
6052 }
6053 run_test 56c "check 'lfs df' showing device status"
6054
6055 test_56d() {
6056         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6057         local osts=$($LFS df -v $MOUNT | grep -c OST)
6058
6059         $LFS df $MOUNT
6060
6061         (( mdts == MDSCOUNT )) ||
6062                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6063         (( osts == OSTCOUNT )) ||
6064                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6065 }
6066 run_test 56d "'lfs df -v' prints only configured devices"
6067
6068 NUMFILES=3
6069 NUMDIRS=3
6070 setup_56() {
6071         local local_tdir="$1"
6072         local local_numfiles="$2"
6073         local local_numdirs="$3"
6074         local dir_params="$4"
6075         local dir_stripe_params="$5"
6076
6077         if [ ! -d "$local_tdir" ] ; then
6078                 test_mkdir -p $dir_stripe_params $local_tdir
6079                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6080                 for i in $(seq $local_numfiles) ; do
6081                         touch $local_tdir/file$i
6082                 done
6083                 for i in $(seq $local_numdirs) ; do
6084                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6085                         for j in $(seq $local_numfiles) ; do
6086                                 touch $local_tdir/dir$i/file$j
6087                         done
6088                 done
6089         fi
6090 }
6091
6092 setup_56_special() {
6093         local local_tdir=$1
6094         local local_numfiles=$2
6095         local local_numdirs=$3
6096
6097         setup_56 $local_tdir $local_numfiles $local_numdirs
6098
6099         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6100                 for i in $(seq $local_numfiles) ; do
6101                         mknod $local_tdir/loop${i}b b 7 $i
6102                         mknod $local_tdir/null${i}c c 1 3
6103                         ln -s $local_tdir/file1 $local_tdir/link${i}
6104                 done
6105                 for i in $(seq $local_numdirs) ; do
6106                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6107                         mknod $local_tdir/dir$i/null${i}c c 1 3
6108                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6109                 done
6110         fi
6111 }
6112
6113 test_56g() {
6114         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6115         local expected=$(($NUMDIRS + 2))
6116
6117         setup_56 $dir $NUMFILES $NUMDIRS
6118
6119         # test lfs find with -name
6120         for i in $(seq $NUMFILES) ; do
6121                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6122
6123                 [ $nums -eq $expected ] ||
6124                         error "lfs find -name '*$i' $dir wrong: "\
6125                               "found $nums, expected $expected"
6126         done
6127 }
6128 run_test 56g "check lfs find -name"
6129
6130 test_56h() {
6131         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6132         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6133
6134         setup_56 $dir $NUMFILES $NUMDIRS
6135
6136         # test lfs find with ! -name
6137         for i in $(seq $NUMFILES) ; do
6138                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6139
6140                 [ $nums -eq $expected ] ||
6141                         error "lfs find ! -name '*$i' $dir wrong: "\
6142                               "found $nums, expected $expected"
6143         done
6144 }
6145 run_test 56h "check lfs find ! -name"
6146
6147 test_56i() {
6148         local dir=$DIR/$tdir
6149
6150         test_mkdir $dir
6151
6152         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6153         local out=$($cmd)
6154
6155         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6156 }
6157 run_test 56i "check 'lfs find -ost UUID' skips directories"
6158
6159 test_56j() {
6160         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6161
6162         setup_56_special $dir $NUMFILES $NUMDIRS
6163
6164         local expected=$((NUMDIRS + 1))
6165         local cmd="$LFS find -type d $dir"
6166         local nums=$($cmd | wc -l)
6167
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170 }
6171 run_test 56j "check lfs find -type d"
6172
6173 test_56k() {
6174         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6175
6176         setup_56_special $dir $NUMFILES $NUMDIRS
6177
6178         local expected=$(((NUMDIRS + 1) * NUMFILES))
6179         local cmd="$LFS find -type f $dir"
6180         local nums=$($cmd | wc -l)
6181
6182         [ $nums -eq $expected ] ||
6183                 error "'$cmd' wrong: found $nums, expected $expected"
6184 }
6185 run_test 56k "check lfs find -type f"
6186
6187 test_56l() {
6188         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6189
6190         setup_56_special $dir $NUMFILES $NUMDIRS
6191
6192         local expected=$((NUMDIRS + NUMFILES))
6193         local cmd="$LFS find -type b $dir"
6194         local nums=$($cmd | wc -l)
6195
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198 }
6199 run_test 56l "check lfs find -type b"
6200
6201 test_56m() {
6202         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6203
6204         setup_56_special $dir $NUMFILES $NUMDIRS
6205
6206         local expected=$((NUMDIRS + NUMFILES))
6207         local cmd="$LFS find -type c $dir"
6208         local nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211 }
6212 run_test 56m "check lfs find -type c"
6213
6214 test_56n() {
6215         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6216         setup_56_special $dir $NUMFILES $NUMDIRS
6217
6218         local expected=$((NUMDIRS + NUMFILES))
6219         local cmd="$LFS find -type l $dir"
6220         local nums=$($cmd | wc -l)
6221
6222         [ $nums -eq $expected ] ||
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224 }
6225 run_test 56n "check lfs find -type l"
6226
6227 test_56o() {
6228         local dir=$DIR/$tdir
6229
6230         setup_56 $dir $NUMFILES $NUMDIRS
6231         utime $dir/file1 > /dev/null || error "utime (1)"
6232         utime $dir/file2 > /dev/null || error "utime (2)"
6233         utime $dir/dir1 > /dev/null || error "utime (3)"
6234         utime $dir/dir2 > /dev/null || error "utime (4)"
6235         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6236         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6237
6238         local expected=4
6239         local nums=$($LFS find -mtime +0 $dir | wc -l)
6240
6241         [ $nums -eq $expected ] ||
6242                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6243
6244         expected=12
6245         cmd="$LFS find -mtime 0 $dir"
6246         nums=$($cmd | wc -l)
6247         [ $nums -eq $expected ] ||
6248                 error "'$cmd' wrong: found $nums, expected $expected"
6249 }
6250 run_test 56o "check lfs find -mtime for old files"
6251
6252 test_56ob() {
6253         local dir=$DIR/$tdir
6254         local expected=1
6255         local count=0
6256
6257         # just to make sure there is something that won't be found
6258         test_mkdir $dir
6259         touch $dir/$tfile.now
6260
6261         for age in year week day hour min; do
6262                 count=$((count + 1))
6263
6264                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6265                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6266                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6267
6268                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6269                 local nums=$($cmd | wc -l)
6270                 [ $nums -eq $expected ] ||
6271                         error "'$cmd' wrong: found $nums, expected $expected"
6272
6273                 cmd="$LFS find $dir -atime $count${age:0:1}"
6274                 nums=$($cmd | wc -l)
6275                 [ $nums -eq $expected ] ||
6276                         error "'$cmd' wrong: found $nums, expected $expected"
6277         done
6278
6279         sleep 2
6280         cmd="$LFS find $dir -ctime +1s -type f"
6281         nums=$($cmd | wc -l)
6282         (( $nums == $count * 2 + 1)) ||
6283                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6284 }
6285 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6286
6287 test_newerXY_base() {
6288         local x=$1
6289         local y=$2
6290         local dir=$DIR/$tdir
6291         local ref
6292         local negref
6293
6294         if [ $y == "t" ]; then
6295                 if [ $x == "b" ]; then
6296                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6297                 else
6298                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6299                 fi
6300         else
6301                 ref=$DIR/$tfile.newer.$x$y
6302                 touch $ref || error "touch $ref failed"
6303         fi
6304
6305         echo "before = $ref"
6306         sleep 2
6307         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6308         sleep 2
6309         if [ $y == "t" ]; then
6310                 if [ $x == "b" ]; then
6311                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6312                 else
6313                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6314                 fi
6315         else
6316                 negref=$DIR/$tfile.negnewer.$x$y
6317                 touch $negref || error "touch $negref failed"
6318         fi
6319
6320         echo "after = $negref"
6321         local cmd="$LFS find $dir -newer$x$y $ref"
6322         local nums=$(eval $cmd | wc -l)
6323         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6324
6325         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6326                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6327
6328         cmd="$LFS find $dir ! -newer$x$y $negref"
6329         nums=$(eval $cmd | wc -l)
6330         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6331                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6332
6333         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6334         nums=$(eval $cmd | wc -l)
6335         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6336                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6337
6338         rm -rf $DIR/*
6339 }
6340
6341 test_56oc() {
6342         test_newerXY_base "a" "a"
6343         test_newerXY_base "a" "m"
6344         test_newerXY_base "a" "c"
6345         test_newerXY_base "m" "a"
6346         test_newerXY_base "m" "m"
6347         test_newerXY_base "m" "c"
6348         test_newerXY_base "c" "a"
6349         test_newerXY_base "c" "m"
6350         test_newerXY_base "c" "c"
6351
6352         [[ -n "$sles_version" ]] &&
6353                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6354
6355         test_newerXY_base "a" "t"
6356         test_newerXY_base "m" "t"
6357         test_newerXY_base "c" "t"
6358
6359         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6360            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6361                 ! btime_supported && echo "btime unsupported" && return 0
6362
6363         test_newerXY_base "b" "b"
6364         test_newerXY_base "b" "t"
6365 }
6366 run_test 56oc "check lfs find -newerXY work"
6367
6368 btime_supported() {
6369         local dir=$DIR/$tdir
6370         local rc
6371
6372         mkdir -p $dir
6373         touch $dir/$tfile
6374         $LFS find $dir -btime -1d -type f
6375         rc=$?
6376         rm -rf $dir
6377         return $rc
6378 }
6379
6380 test_56od() {
6381         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6382                 ! btime_supported && skip "btime unsupported on MDS"
6383
6384         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6385                 ! btime_supported && skip "btime unsupported on clients"
6386
6387         local dir=$DIR/$tdir
6388         local ref=$DIR/$tfile.ref
6389         local negref=$DIR/$tfile.negref
6390
6391         mkdir $dir || error "mkdir $dir failed"
6392         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6393         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6394         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6395         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6396         touch $ref || error "touch $ref failed"
6397         # sleep 3 seconds at least
6398         sleep 3
6399
6400         local before=$(do_facet mds1 date +%s)
6401         local skew=$(($(date +%s) - before + 1))
6402
6403         if (( skew < 0 && skew > -5 )); then
6404                 sleep $((0 - skew + 1))
6405                 skew=0
6406         fi
6407
6408         # Set the dir stripe params to limit files all on MDT0,
6409         # otherwise we need to calc the max clock skew between
6410         # the client and MDTs.
6411         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6412         sleep 2
6413         touch $negref || error "touch $negref failed"
6414
6415         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6416         local nums=$($cmd | wc -l)
6417         local expected=$(((NUMFILES + 1) * NUMDIRS))
6418
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6423         nums=$($cmd | wc -l)
6424         expected=$((NUMFILES + 1))
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427
6428         [ $skew -lt 0 ] && return
6429
6430         local after=$(do_facet mds1 date +%s)
6431         local age=$((after - before + 1 + skew))
6432
6433         cmd="$LFS find $dir -btime -${age}s -type f"
6434         nums=$($cmd | wc -l)
6435         expected=$(((NUMFILES + 1) * NUMDIRS))
6436
6437         echo "Clock skew between client and server: $skew, age:$age"
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         expected=$(($NUMDIRS + 1))
6442         cmd="$LFS find $dir -btime -${age}s -type d"
6443         nums=$($cmd | wc -l)
6444         [ $nums -eq $expected ] ||
6445                 error "'$cmd' wrong: found $nums, expected $expected"
6446         rm -f $ref $negref || error "Failed to remove $ref $negref"
6447 }
6448 run_test 56od "check lfs find -btime with units"
6449
6450 test_56p() {
6451         [ $RUNAS_ID -eq $UID ] &&
6452                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6453
6454         local dir=$DIR/$tdir
6455
6456         setup_56 $dir $NUMFILES $NUMDIRS
6457         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6458
6459         local expected=$NUMFILES
6460         local cmd="$LFS find -uid $RUNAS_ID $dir"
6461         local nums=$($cmd | wc -l)
6462
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465
6466         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6467         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471 }
6472 run_test 56p "check lfs find -uid and ! -uid"
6473
6474 test_56q() {
6475         [ $RUNAS_ID -eq $UID ] &&
6476                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6477
6478         local dir=$DIR/$tdir
6479
6480         setup_56 $dir $NUMFILES $NUMDIRS
6481         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6482
6483         local expected=$NUMFILES
6484         local cmd="$LFS find -gid $RUNAS_GID $dir"
6485         local nums=$($cmd | wc -l)
6486
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6491         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495 }
6496 run_test 56q "check lfs find -gid and ! -gid"
6497
6498 test_56r() {
6499         local dir=$DIR/$tdir
6500
6501         setup_56 $dir $NUMFILES $NUMDIRS
6502
6503         local expected=12
6504         local cmd="$LFS find -size 0 -type f -lazy $dir"
6505         local nums=$($cmd | wc -l)
6506
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509         cmd="$LFS find -size 0 -type f $dir"
6510         nums=$($cmd | wc -l)
6511         [ $nums -eq $expected ] ||
6512                 error "'$cmd' wrong: found $nums, expected $expected"
6513
6514         expected=0
6515         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6516         nums=$($cmd | wc -l)
6517         [ $nums -eq $expected ] ||
6518                 error "'$cmd' wrong: found $nums, expected $expected"
6519         cmd="$LFS find ! -size 0 -type f $dir"
6520         nums=$($cmd | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523
6524         echo "test" > $dir/$tfile
6525         echo "test2" > $dir/$tfile.2 && sync
6526         expected=1
6527         cmd="$LFS find -size 5 -type f -lazy $dir"
6528         nums=$($cmd | wc -l)
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531         cmd="$LFS find -size 5 -type f $dir"
6532         nums=$($cmd | wc -l)
6533         [ $nums -eq $expected ] ||
6534                 error "'$cmd' wrong: found $nums, expected $expected"
6535
6536         expected=1
6537         cmd="$LFS find -size +5 -type f -lazy $dir"
6538         nums=$($cmd | wc -l)
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541         cmd="$LFS find -size +5 -type f $dir"
6542         nums=$($cmd | wc -l)
6543         [ $nums -eq $expected ] ||
6544                 error "'$cmd' wrong: found $nums, expected $expected"
6545
6546         expected=2
6547         cmd="$LFS find -size +0 -type f -lazy $dir"
6548         nums=$($cmd | wc -l)
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551         cmd="$LFS find -size +0 -type f $dir"
6552         nums=$($cmd | wc -l)
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555
6556         expected=2
6557         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6558         nums=$($cmd | wc -l)
6559         [ $nums -eq $expected ] ||
6560                 error "'$cmd' wrong: found $nums, expected $expected"
6561         cmd="$LFS find ! -size -5 -type f $dir"
6562         nums=$($cmd | wc -l)
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565
6566         expected=12
6567         cmd="$LFS find -size -5 -type f -lazy $dir"
6568         nums=$($cmd | wc -l)
6569         [ $nums -eq $expected ] ||
6570                 error "'$cmd' wrong: found $nums, expected $expected"
6571         cmd="$LFS find -size -5 -type f $dir"
6572         nums=$($cmd | wc -l)
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575 }
6576 run_test 56r "check lfs find -size works"
6577
6578 test_56ra_sub() {
6579         local expected=$1
6580         local glimpses=$2
6581         local cmd="$3"
6582
6583         cancel_lru_locks $OSC
6584
6585         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6586         local nums=$($cmd | wc -l)
6587
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590
6591         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6592
6593         if (( rpcs_before + glimpses != rpcs_after )); then
6594                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6595                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6596
6597                 if [[ $glimpses == 0 ]]; then
6598                         error "'$cmd' should not send glimpse RPCs to OST"
6599                 else
6600                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6601                 fi
6602         fi
6603 }
6604
6605 test_56ra() {
6606         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6607                 skip "MDS < 2.12.58 doesn't return LSOM data"
6608         local dir=$DIR/$tdir
6609         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6610
6611         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6612
6613         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6614         $LCTL set_param -n llite.*.statahead_agl=0
6615         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6616
6617         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6618         # open and close all files to ensure LSOM is updated
6619         cancel_lru_locks $OSC
6620         find $dir -type f | xargs cat > /dev/null
6621
6622         #   expect_found  glimpse_rpcs  command_to_run
6623         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6624         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6625         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6626         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6627
6628         echo "test" > $dir/$tfile
6629         echo "test2" > $dir/$tfile.2 && sync
6630         cancel_lru_locks $OSC
6631         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6632
6633         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6634         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6635         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6636         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6637
6638         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6639         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6640         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6641         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6642         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6643         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6644 }
6645 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6646
6647 test_56rb() {
6648         local dir=$DIR/$tdir
6649         local tmp=$TMP/$tfile.log
6650         local mdt_idx;
6651
6652         test_mkdir -p $dir || error "failed to mkdir $dir"
6653         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6654                 error "failed to setstripe $dir/$tfile"
6655         mdt_idx=$($LFS getdirstripe -i $dir)
6656         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6657
6658         stack_trap "rm -f $tmp" EXIT
6659         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6660         ! grep -q obd_uuid $tmp ||
6661                 error "failed to find --size +100K --ost 0 $dir"
6662         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6663         ! grep -q obd_uuid $tmp ||
6664                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6665 }
6666 run_test 56rb "check lfs find --size --ost/--mdt works"
6667
6668 test_56s() { # LU-611 #LU-9369
6669         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6670
6671         local dir=$DIR/$tdir
6672         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6673
6674         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6675         for i in $(seq $NUMDIRS); do
6676                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6677         done
6678
6679         local expected=$NUMDIRS
6680         local cmd="$LFS find -c $OSTCOUNT $dir"
6681         local nums=$($cmd | wc -l)
6682
6683         [ $nums -eq $expected ] || {
6684                 $LFS getstripe -R $dir
6685                 error "'$cmd' wrong: found $nums, expected $expected"
6686         }
6687
6688         expected=$((NUMDIRS + onestripe))
6689         cmd="$LFS find -stripe-count +0 -type f $dir"
6690         nums=$($cmd | wc -l)
6691         [ $nums -eq $expected ] || {
6692                 $LFS getstripe -R $dir
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694         }
6695
6696         expected=$onestripe
6697         cmd="$LFS find -stripe-count 1 -type f $dir"
6698         nums=$($cmd | wc -l)
6699         [ $nums -eq $expected ] || {
6700                 $LFS getstripe -R $dir
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         }
6703
6704         cmd="$LFS find -stripe-count -2 -type f $dir"
6705         nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] || {
6707                 $LFS getstripe -R $dir
6708                 error "'$cmd' wrong: found $nums, expected $expected"
6709         }
6710
6711         expected=0
6712         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] || {
6715                 $LFS getstripe -R $dir
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717         }
6718 }
6719 run_test 56s "check lfs find -stripe-count works"
6720
6721 test_56t() { # LU-611 #LU-9369
6722         local dir=$DIR/$tdir
6723
6724         setup_56 $dir 0 $NUMDIRS
6725         for i in $(seq $NUMDIRS); do
6726                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6727         done
6728
6729         local expected=$NUMDIRS
6730         local cmd="$LFS find -S 8M $dir"
6731         local nums=$($cmd | wc -l)
6732
6733         [ $nums -eq $expected ] || {
6734                 $LFS getstripe -R $dir
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736         }
6737         rm -rf $dir
6738
6739         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6740
6741         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6742
6743         expected=$(((NUMDIRS + 1) * NUMFILES))
6744         cmd="$LFS find -stripe-size 512k -type f $dir"
6745         nums=$($cmd | wc -l)
6746         [ $nums -eq $expected ] ||
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748
6749         cmd="$LFS find -stripe-size +320k -type f $dir"
6750         nums=$($cmd | wc -l)
6751         [ $nums -eq $expected ] ||
6752                 error "'$cmd' wrong: found $nums, expected $expected"
6753
6754         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6755         cmd="$LFS find -stripe-size +200k -type f $dir"
6756         nums=$($cmd | wc -l)
6757         [ $nums -eq $expected ] ||
6758                 error "'$cmd' wrong: found $nums, expected $expected"
6759
6760         cmd="$LFS find -stripe-size -640k -type f $dir"
6761         nums=$($cmd | wc -l)
6762         [ $nums -eq $expected ] ||
6763                 error "'$cmd' wrong: found $nums, expected $expected"
6764
6765         expected=4
6766         cmd="$LFS find -stripe-size 256k -type f $dir"
6767         nums=$($cmd | wc -l)
6768         [ $nums -eq $expected ] ||
6769                 error "'$cmd' wrong: found $nums, expected $expected"
6770
6771         cmd="$LFS find -stripe-size -320k -type f $dir"
6772         nums=$($cmd | wc -l)
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         expected=0
6777         cmd="$LFS find -stripe-size 1024k -type f $dir"
6778         nums=$($cmd | wc -l)
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781 }
6782 run_test 56t "check lfs find -stripe-size works"
6783
6784 test_56u() { # LU-611
6785         local dir=$DIR/$tdir
6786
6787         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6788
6789         if [[ $OSTCOUNT -gt 1 ]]; then
6790                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6791                 onestripe=4
6792         else
6793                 onestripe=0
6794         fi
6795
6796         local expected=$(((NUMDIRS + 1) * NUMFILES))
6797         local cmd="$LFS find -stripe-index 0 -type f $dir"
6798         local nums=$($cmd | wc -l)
6799
6800         [ $nums -eq $expected ] ||
6801                 error "'$cmd' wrong: found $nums, expected $expected"
6802
6803         expected=$onestripe
6804         cmd="$LFS find -stripe-index 1 -type f $dir"
6805         nums=$($cmd | wc -l)
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808
6809         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6810         nums=$($cmd | wc -l)
6811         [ $nums -eq $expected ] ||
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813
6814         expected=0
6815         # This should produce an error and not return any files
6816         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6817         nums=$($cmd 2>/dev/null | wc -l)
6818         [ $nums -eq $expected ] ||
6819                 error "'$cmd' wrong: found $nums, expected $expected"
6820
6821         if [[ $OSTCOUNT -gt 1 ]]; then
6822                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6823                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6824                 nums=$($cmd | wc -l)
6825                 [ $nums -eq $expected ] ||
6826                         error "'$cmd' wrong: found $nums, expected $expected"
6827         fi
6828 }
6829 run_test 56u "check lfs find -stripe-index works"
6830
6831 test_56v() {
6832         local mdt_idx=0
6833         local dir=$DIR/$tdir
6834
6835         setup_56 $dir $NUMFILES $NUMDIRS
6836
6837         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6838         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6839
6840         for file in $($LFS find -m $UUID $dir); do
6841                 file_midx=$($LFS getstripe -m $file)
6842                 [ $file_midx -eq $mdt_idx ] ||
6843                         error "lfs find -m $UUID != getstripe -m $file_midx"
6844         done
6845 }
6846 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6847
6848 test_56w() {
6849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6851
6852         local dir=$DIR/$tdir
6853
6854         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6855
6856         local stripe_size=$($LFS getstripe -S -d $dir) ||
6857                 error "$LFS getstripe -S -d $dir failed"
6858         stripe_size=${stripe_size%% *}
6859
6860         local file_size=$((stripe_size * OSTCOUNT))
6861         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6862         local required_space=$((file_num * file_size))
6863         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6864                            head -n1)
6865         [[ $free_space -le $((required_space / 1024)) ]] &&
6866                 skip_env "need $required_space, have $free_space kbytes"
6867
6868         local dd_bs=65536
6869         local dd_count=$((file_size / dd_bs))
6870
6871         # write data into the files
6872         local i
6873         local j
6874         local file
6875
6876         for i in $(seq $NUMFILES); do
6877                 file=$dir/file$i
6878                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6879                         error "write data into $file failed"
6880         done
6881         for i in $(seq $NUMDIRS); do
6882                 for j in $(seq $NUMFILES); do
6883                         file=$dir/dir$i/file$j
6884                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6885                                 error "write data into $file failed"
6886                 done
6887         done
6888
6889         # $LFS_MIGRATE will fail if hard link migration is unsupported
6890         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6891                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6892                         error "creating links to $dir/dir1/file1 failed"
6893         fi
6894
6895         local expected=-1
6896
6897         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6898
6899         # lfs_migrate file
6900         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6901
6902         echo "$cmd"
6903         eval $cmd || error "$cmd failed"
6904
6905         check_stripe_count $dir/file1 $expected
6906
6907         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6908         then
6909                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6910                 # OST 1 if it is on OST 0. This file is small enough to
6911                 # be on only one stripe.
6912                 file=$dir/migr_1_ost
6913                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6914                         error "write data into $file failed"
6915                 local obdidx=$($LFS getstripe -i $file)
6916                 local oldmd5=$(md5sum $file)
6917                 local newobdidx=0
6918
6919                 [[ $obdidx -eq 0 ]] && newobdidx=1
6920                 cmd="$LFS migrate -i $newobdidx $file"
6921                 echo $cmd
6922                 eval $cmd || error "$cmd failed"
6923
6924                 local realobdix=$($LFS getstripe -i $file)
6925                 local newmd5=$(md5sum $file)
6926
6927                 [[ $newobdidx -ne $realobdix ]] &&
6928                         error "new OST is different (was=$obdidx, "\
6929                               "wanted=$newobdidx, got=$realobdix)"
6930                 [[ "$oldmd5" != "$newmd5" ]] &&
6931                         error "md5sum differ: $oldmd5, $newmd5"
6932         fi
6933
6934         # lfs_migrate dir
6935         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6936         echo "$cmd"
6937         eval $cmd || error "$cmd failed"
6938
6939         for j in $(seq $NUMFILES); do
6940                 check_stripe_count $dir/dir1/file$j $expected
6941         done
6942
6943         # lfs_migrate works with lfs find
6944         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6945              $LFS_MIGRATE -y -c $expected"
6946         echo "$cmd"
6947         eval $cmd || error "$cmd failed"
6948
6949         for i in $(seq 2 $NUMFILES); do
6950                 check_stripe_count $dir/file$i $expected
6951         done
6952         for i in $(seq 2 $NUMDIRS); do
6953                 for j in $(seq $NUMFILES); do
6954                 check_stripe_count $dir/dir$i/file$j $expected
6955                 done
6956         done
6957 }
6958 run_test 56w "check lfs_migrate -c stripe_count works"
6959
6960 test_56wb() {
6961         local file1=$DIR/$tdir/file1
6962         local create_pool=false
6963         local initial_pool=$($LFS getstripe -p $DIR)
6964         local pool_list=()
6965         local pool=""
6966
6967         echo -n "Creating test dir..."
6968         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6969         echo "done."
6970
6971         echo -n "Creating test file..."
6972         touch $file1 || error "cannot create file"
6973         echo "done."
6974
6975         echo -n "Detecting existing pools..."
6976         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6977
6978         if [ ${#pool_list[@]} -gt 0 ]; then
6979                 echo "${pool_list[@]}"
6980                 for thispool in "${pool_list[@]}"; do
6981                         if [[ -z "$initial_pool" ||
6982                               "$initial_pool" != "$thispool" ]]; then
6983                                 pool="$thispool"
6984                                 echo "Using existing pool '$pool'"
6985                                 break
6986                         fi
6987                 done
6988         else
6989                 echo "none detected."
6990         fi
6991         if [ -z "$pool" ]; then
6992                 pool=${POOL:-testpool}
6993                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6994                 echo -n "Creating pool '$pool'..."
6995                 create_pool=true
6996                 pool_add $pool &> /dev/null ||
6997                         error "pool_add failed"
6998                 echo "done."
6999
7000                 echo -n "Adding target to pool..."
7001                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7002                         error "pool_add_targets failed"
7003                 echo "done."
7004         fi
7005
7006         echo -n "Setting pool using -p option..."
7007         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7008                 error "migrate failed rc = $?"
7009         echo "done."
7010
7011         echo -n "Verifying test file is in pool after migrating..."
7012         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7013                 error "file was not migrated to pool $pool"
7014         echo "done."
7015
7016         echo -n "Removing test file from pool '$pool'..."
7017         # "lfs migrate $file" won't remove the file from the pool
7018         # until some striping information is changed.
7019         $LFS migrate -c 1 $file1 &> /dev/null ||
7020                 error "cannot remove from pool"
7021         [ "$($LFS getstripe -p $file1)" ] &&
7022                 error "pool still set"
7023         echo "done."
7024
7025         echo -n "Setting pool using --pool option..."
7026         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7027                 error "migrate failed rc = $?"
7028         echo "done."
7029
7030         # Clean up
7031         rm -f $file1
7032         if $create_pool; then
7033                 destroy_test_pools 2> /dev/null ||
7034                         error "destroy test pools failed"
7035         fi
7036 }
7037 run_test 56wb "check lfs_migrate pool support"
7038
7039 test_56wc() {
7040         local file1="$DIR/$tdir/file1"
7041         local parent_ssize
7042         local parent_scount
7043         local cur_ssize
7044         local cur_scount
7045         local orig_ssize
7046
7047         echo -n "Creating test dir..."
7048         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7049         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7050                 error "cannot set stripe by '-S 1M -c 1'"
7051         echo "done"
7052
7053         echo -n "Setting initial stripe for test file..."
7054         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7055                 error "cannot set stripe"
7056         cur_ssize=$($LFS getstripe -S "$file1")
7057         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7058         echo "done."
7059
7060         # File currently set to -S 512K -c 1
7061
7062         # Ensure -c and -S options are rejected when -R is set
7063         echo -n "Verifying incompatible options are detected..."
7064         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7065                 error "incompatible -c and -R options not detected"
7066         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7067                 error "incompatible -S and -R options not detected"
7068         echo "done."
7069
7070         # Ensure unrecognized options are passed through to 'lfs migrate'
7071         echo -n "Verifying -S option is passed through to lfs migrate..."
7072         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7073                 error "migration failed"
7074         cur_ssize=$($LFS getstripe -S "$file1")
7075         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7076         echo "done."
7077
7078         # File currently set to -S 1M -c 1
7079
7080         # Ensure long options are supported
7081         echo -n "Verifying long options supported..."
7082         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7083                 error "long option without argument not supported"
7084         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7085                 error "long option with argument not supported"
7086         cur_ssize=$($LFS getstripe -S "$file1")
7087         [ $cur_ssize -eq 524288 ] ||
7088                 error "migrate --stripe-size $cur_ssize != 524288"
7089         echo "done."
7090
7091         # File currently set to -S 512K -c 1
7092
7093         if [ "$OSTCOUNT" -gt 1 ]; then
7094                 echo -n "Verifying explicit stripe count can be set..."
7095                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7096                         error "migrate failed"
7097                 cur_scount=$($LFS getstripe -c "$file1")
7098                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7099                 echo "done."
7100         fi
7101
7102         # File currently set to -S 512K -c 1 or -S 512K -c 2
7103
7104         # Ensure parent striping is used if -R is set, and no stripe
7105         # count or size is specified
7106         echo -n "Setting stripe for parent directory..."
7107         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7108                 error "cannot set stripe '-S 2M -c 1'"
7109         echo "done."
7110
7111         echo -n "Verifying restripe option uses parent stripe settings..."
7112         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7113         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7114         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7115                 error "migrate failed"
7116         cur_ssize=$($LFS getstripe -S "$file1")
7117         [ $cur_ssize -eq $parent_ssize ] ||
7118                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7119         cur_scount=$($LFS getstripe -c "$file1")
7120         [ $cur_scount -eq $parent_scount ] ||
7121                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7122         echo "done."
7123
7124         # File currently set to -S 1M -c 1
7125
7126         # Ensure striping is preserved if -R is not set, and no stripe
7127         # count or size is specified
7128         echo -n "Verifying striping size preserved when not specified..."
7129         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7130         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7131                 error "cannot set stripe on parent directory"
7132         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7133                 error "migrate failed"
7134         cur_ssize=$($LFS getstripe -S "$file1")
7135         [ $cur_ssize -eq $orig_ssize ] ||
7136                 error "migrate by default $cur_ssize != $orig_ssize"
7137         echo "done."
7138
7139         # Ensure file name properly detected when final option has no argument
7140         echo -n "Verifying file name properly detected..."
7141         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7142                 error "file name interpreted as option argument"
7143         echo "done."
7144
7145         # Clean up
7146         rm -f "$file1"
7147 }
7148 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7149
7150 test_56wd() {
7151         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7152
7153         local file1=$DIR/$tdir/file1
7154
7155         echo -n "Creating test dir..."
7156         test_mkdir $DIR/$tdir || error "cannot create dir"
7157         echo "done."
7158
7159         echo -n "Creating test file..."
7160         touch $file1
7161         echo "done."
7162
7163         # Ensure 'lfs migrate' will fail by using a non-existent option,
7164         # and make sure rsync is not called to recover
7165         echo -n "Make sure --no-rsync option works..."
7166         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7167                 grep -q 'refusing to fall back to rsync' ||
7168                 error "rsync was called with --no-rsync set"
7169         echo "done."
7170
7171         # Ensure rsync is called without trying 'lfs migrate' first
7172         echo -n "Make sure --rsync option works..."
7173         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7174                 grep -q 'falling back to rsync' &&
7175                 error "lfs migrate was called with --rsync set"
7176         echo "done."
7177
7178         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7179         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7180                 grep -q 'at the same time' ||
7181                 error "--rsync and --no-rsync accepted concurrently"
7182         echo "done."
7183
7184         # Clean up
7185         rm -f $file1
7186 }
7187 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7188
7189 test_56we() {
7190         local td=$DIR/$tdir
7191         local tf=$td/$tfile
7192
7193         test_mkdir $td || error "cannot create $td"
7194         touch $tf || error "cannot touch $tf"
7195
7196         echo -n "Make sure --non-direct|-D works..."
7197         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7198                 grep -q "lfs migrate --non-direct" ||
7199                 error "--non-direct option cannot work correctly"
7200         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7201                 grep -q "lfs migrate -D" ||
7202                 error "-D option cannot work correctly"
7203         echo "done."
7204 }
7205 run_test 56we "check lfs_migrate --non-direct|-D support"
7206
7207 test_56x() {
7208         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7209         check_swap_layouts_support
7210
7211         local dir=$DIR/$tdir
7212         local ref1=/etc/passwd
7213         local file1=$dir/file1
7214
7215         test_mkdir $dir || error "creating dir $dir"
7216         $LFS setstripe -c 2 $file1
7217         cp $ref1 $file1
7218         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7219         stripe=$($LFS getstripe -c $file1)
7220         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7221         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7222
7223         # clean up
7224         rm -f $file1
7225 }
7226 run_test 56x "lfs migration support"
7227
7228 test_56xa() {
7229         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7230         check_swap_layouts_support
7231
7232         local dir=$DIR/$tdir/$testnum
7233
7234         test_mkdir -p $dir
7235
7236         local ref1=/etc/passwd
7237         local file1=$dir/file1
7238
7239         $LFS setstripe -c 2 $file1
7240         cp $ref1 $file1
7241         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7242
7243         local stripe=$($LFS getstripe -c $file1)
7244
7245         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7246         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7247
7248         # clean up
7249         rm -f $file1
7250 }
7251 run_test 56xa "lfs migration --block support"
7252
7253 check_migrate_links() {
7254         local dir="$1"
7255         local file1="$dir/file1"
7256         local begin="$2"
7257         local count="$3"
7258         local runas="$4"
7259         local total_count=$(($begin + $count - 1))
7260         local symlink_count=10
7261         local uniq_count=10
7262
7263         if [ ! -f "$file1" ]; then
7264                 echo -n "creating initial file..."
7265                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7266                         error "cannot setstripe initial file"
7267                 echo "done"
7268
7269                 echo -n "creating symlinks..."
7270                 for s in $(seq 1 $symlink_count); do
7271                         ln -s "$file1" "$dir/slink$s" ||
7272                                 error "cannot create symlinks"
7273                 done
7274                 echo "done"
7275
7276                 echo -n "creating nonlinked files..."
7277                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7278                         error "cannot create nonlinked files"
7279                 echo "done"
7280         fi
7281
7282         # create hard links
7283         if [ ! -f "$dir/file$total_count" ]; then
7284                 echo -n "creating hard links $begin:$total_count..."
7285                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7286                         /dev/null || error "cannot create hard links"
7287                 echo "done"
7288         fi
7289
7290         echo -n "checking number of hard links listed in xattrs..."
7291         local fid=$($LFS getstripe -F "$file1")
7292         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7293
7294         echo "${#paths[*]}"
7295         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7296                         skip "hard link list has unexpected size, skipping test"
7297         fi
7298         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7299                         error "link names should exceed xattrs size"
7300         fi
7301
7302         echo -n "migrating files..."
7303         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7304         local rc=$?
7305         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7306         echo "done"
7307
7308         # make sure all links have been properly migrated
7309         echo -n "verifying files..."
7310         fid=$($LFS getstripe -F "$file1") ||
7311                 error "cannot get fid for file $file1"
7312         for i in $(seq 2 $total_count); do
7313                 local fid2=$($LFS getstripe -F $dir/file$i)
7314
7315                 [ "$fid2" == "$fid" ] ||
7316                         error "migrated hard link has mismatched FID"
7317         done
7318
7319         # make sure hard links were properly detected, and migration was
7320         # performed only once for the entire link set; nonlinked files should
7321         # also be migrated
7322         local actual=$(grep -c 'done' <<< "$migrate_out")
7323         local expected=$(($uniq_count + 1))
7324
7325         [ "$actual" -eq  "$expected" ] ||
7326                 error "hard links individually migrated ($actual != $expected)"
7327
7328         # make sure the correct number of hard links are present
7329         local hardlinks=$(stat -c '%h' "$file1")
7330
7331         [ $hardlinks -eq $total_count ] ||
7332                 error "num hard links $hardlinks != $total_count"
7333         echo "done"
7334
7335         return 0
7336 }
7337
7338 test_56xb() {
7339         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7340                 skip "Need MDS version at least 2.10.55"
7341
7342         local dir="$DIR/$tdir"
7343
7344         test_mkdir "$dir" || error "cannot create dir $dir"
7345
7346         echo "testing lfs migrate mode when all links fit within xattrs"
7347         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7348
7349         echo "testing rsync mode when all links fit within xattrs"
7350         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7351
7352         echo "testing lfs migrate mode when all links do not fit within xattrs"
7353         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7354
7355         echo "testing rsync mode when all links do not fit within xattrs"
7356         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7357
7358         chown -R $RUNAS_ID $dir
7359         echo "testing non-root lfs migrate mode when not all links are in xattr"
7360         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7361
7362         # clean up
7363         rm -rf $dir
7364 }
7365 run_test 56xb "lfs migration hard link support"
7366
7367 test_56xc() {
7368         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7369
7370         local dir="$DIR/$tdir"
7371
7372         test_mkdir "$dir" || error "cannot create dir $dir"
7373
7374         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7375         echo -n "Setting initial stripe for 20MB test file..."
7376         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7377                 error "cannot setstripe 20MB file"
7378         echo "done"
7379         echo -n "Sizing 20MB test file..."
7380         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7381         echo "done"
7382         echo -n "Verifying small file autostripe count is 1..."
7383         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7384                 error "cannot migrate 20MB file"
7385         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7386                 error "cannot get stripe for $dir/20mb"
7387         [ $stripe_count -eq 1 ] ||
7388                 error "unexpected stripe count $stripe_count for 20MB file"
7389         rm -f "$dir/20mb"
7390         echo "done"
7391
7392         # Test 2: File is small enough to fit within the available space on
7393         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7394         # have at least an additional 1KB for each desired stripe for test 3
7395         echo -n "Setting stripe for 1GB test file..."
7396         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7397         echo "done"
7398         echo -n "Sizing 1GB test file..."
7399         # File size is 1GB + 3KB
7400         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7401         echo "done"
7402
7403         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7404         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7405         if (( avail > 524288 * OSTCOUNT )); then
7406                 echo -n "Migrating 1GB file..."
7407                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7408                         error "cannot migrate 1GB file"
7409                 echo "done"
7410                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7411                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7412                         error "cannot getstripe for 1GB file"
7413                 [ $stripe_count -eq 2 ] ||
7414                         error "unexpected stripe count $stripe_count != 2"
7415                 echo "done"
7416         fi
7417
7418         # Test 3: File is too large to fit within the available space on
7419         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7420         if [ $OSTCOUNT -ge 3 ]; then
7421                 # The required available space is calculated as
7422                 # file size (1GB + 3KB) / OST count (3).
7423                 local kb_per_ost=349526
7424
7425                 echo -n "Migrating 1GB file with limit..."
7426                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7427                         error "cannot migrate 1GB file with limit"
7428                 echo "done"
7429
7430                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7431                 echo -n "Verifying 1GB autostripe count with limited space..."
7432                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7433                         error "unexpected stripe count $stripe_count (min 3)"
7434                 echo "done"
7435         fi
7436
7437         # clean up
7438         rm -rf $dir
7439 }
7440 run_test 56xc "lfs migration autostripe"
7441
7442 test_56xd() {
7443         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7444
7445         local dir=$DIR/$tdir
7446         local f_mgrt=$dir/$tfile.mgrt
7447         local f_yaml=$dir/$tfile.yaml
7448         local f_copy=$dir/$tfile.copy
7449         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7450         local layout_copy="-c 2 -S 2M -i 1"
7451         local yamlfile=$dir/yamlfile
7452         local layout_before;
7453         local layout_after;
7454
7455         test_mkdir "$dir" || error "cannot create dir $dir"
7456         $LFS setstripe $layout_yaml $f_yaml ||
7457                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7458         $LFS getstripe --yaml $f_yaml > $yamlfile
7459         $LFS setstripe $layout_copy $f_copy ||
7460                 error "cannot setstripe $f_copy with layout $layout_copy"
7461         touch $f_mgrt
7462         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7463
7464         # 1. test option --yaml
7465         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7466                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7467         layout_before=$(get_layout_param $f_yaml)
7468         layout_after=$(get_layout_param $f_mgrt)
7469         [ "$layout_after" == "$layout_before" ] ||
7470                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7471
7472         # 2. test option --copy
7473         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7474                 error "cannot migrate $f_mgrt with --copy $f_copy"
7475         layout_before=$(get_layout_param $f_copy)
7476         layout_after=$(get_layout_param $f_mgrt)
7477         [ "$layout_after" == "$layout_before" ] ||
7478                 error "lfs_migrate --copy: $layout_after != $layout_before"
7479 }
7480 run_test 56xd "check lfs_migrate --yaml and --copy support"
7481
7482 test_56xe() {
7483         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7484
7485         local dir=$DIR/$tdir
7486         local f_comp=$dir/$tfile
7487         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7488         local layout_before=""
7489         local layout_after=""
7490
7491         test_mkdir "$dir" || error "cannot create dir $dir"
7492         $LFS setstripe $layout $f_comp ||
7493                 error "cannot setstripe $f_comp with layout $layout"
7494         layout_before=$(get_layout_param $f_comp)
7495         dd if=/dev/zero of=$f_comp bs=1M count=4
7496
7497         # 1. migrate a comp layout file by lfs_migrate
7498         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7499         layout_after=$(get_layout_param $f_comp)
7500         [ "$layout_before" == "$layout_after" ] ||
7501                 error "lfs_migrate: $layout_before != $layout_after"
7502
7503         # 2. migrate a comp layout file by lfs migrate
7504         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7505         layout_after=$(get_layout_param $f_comp)
7506         [ "$layout_before" == "$layout_after" ] ||
7507                 error "lfs migrate: $layout_before != $layout_after"
7508 }
7509 run_test 56xe "migrate a composite layout file"
7510
7511 test_56xf() {
7512         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7513
7514         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7515                 skip "Need server version at least 2.13.53"
7516
7517         local dir=$DIR/$tdir
7518         local f_comp=$dir/$tfile
7519         local layout="-E 1M -c1 -E -1 -c2"
7520         local fid_before=""
7521         local fid_after=""
7522
7523         test_mkdir "$dir" || error "cannot create dir $dir"
7524         $LFS setstripe $layout $f_comp ||
7525                 error "cannot setstripe $f_comp with layout $layout"
7526         fid_before=$($LFS getstripe --fid $f_comp)
7527         dd if=/dev/zero of=$f_comp bs=1M count=4
7528
7529         # 1. migrate a comp layout file to a comp layout
7530         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7531         fid_after=$($LFS getstripe --fid $f_comp)
7532         [ "$fid_before" == "$fid_after" ] ||
7533                 error "comp-to-comp migrate: $fid_before != $fid_after"
7534
7535         # 2. migrate a comp layout file to a plain layout
7536         $LFS migrate -c2 $f_comp ||
7537                 error "cannot migrate $f_comp by lfs migrate"
7538         fid_after=$($LFS getstripe --fid $f_comp)
7539         [ "$fid_before" == "$fid_after" ] ||
7540                 error "comp-to-plain migrate: $fid_before != $fid_after"
7541
7542         # 3. migrate a plain layout file to a comp layout
7543         $LFS migrate $layout $f_comp ||
7544                 error "cannot migrate $f_comp by lfs migrate"
7545         fid_after=$($LFS getstripe --fid $f_comp)
7546         [ "$fid_before" == "$fid_after" ] ||
7547                 error "plain-to-comp migrate: $fid_before != $fid_after"
7548 }
7549 run_test 56xf "FID is not lost during migration of a composite layout file"
7550
7551 test_56y() {
7552         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7553                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7554
7555         local res=""
7556         local dir=$DIR/$tdir
7557         local f1=$dir/file1
7558         local f2=$dir/file2
7559
7560         test_mkdir -p $dir || error "creating dir $dir"
7561         touch $f1 || error "creating std file $f1"
7562         $MULTIOP $f2 H2c || error "creating released file $f2"
7563
7564         # a directory can be raid0, so ask only for files
7565         res=$($LFS find $dir -L raid0 -type f | wc -l)
7566         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7567
7568         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7569         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7570
7571         # only files can be released, so no need to force file search
7572         res=$($LFS find $dir -L released)
7573         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7574
7575         res=$($LFS find $dir -type f \! -L released)
7576         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7577 }
7578 run_test 56y "lfs find -L raid0|released"
7579
7580 test_56z() { # LU-4824
7581         # This checks to make sure 'lfs find' continues after errors
7582         # There are two classes of errors that should be caught:
7583         # - If multiple paths are provided, all should be searched even if one
7584         #   errors out
7585         # - If errors are encountered during the search, it should not terminate
7586         #   early
7587         local dir=$DIR/$tdir
7588         local i
7589
7590         test_mkdir $dir
7591         for i in d{0..9}; do
7592                 test_mkdir $dir/$i
7593                 touch $dir/$i/$tfile
7594         done
7595         $LFS find $DIR/non_existent_dir $dir &&
7596                 error "$LFS find did not return an error"
7597         # Make a directory unsearchable. This should NOT be the last entry in
7598         # directory order.  Arbitrarily pick the 6th entry
7599         chmod 700 $($LFS find $dir -type d | sed '6!d')
7600
7601         $RUNAS $LFS find $DIR/non_existent $dir
7602         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7603
7604         # The user should be able to see 10 directories and 9 files
7605         (( count == 19 )) ||
7606                 error "$LFS find found $count != 19 entries after error"
7607 }
7608 run_test 56z "lfs find should continue after an error"
7609
7610 test_56aa() { # LU-5937
7611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7612
7613         local dir=$DIR/$tdir
7614
7615         mkdir $dir
7616         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7617
7618         createmany -o $dir/striped_dir/${tfile}- 1024
7619         local dirs=$($LFS find --size +8k $dir/)
7620
7621         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7622 }
7623 run_test 56aa "lfs find --size under striped dir"
7624
7625 test_56ab() { # LU-10705
7626         test_mkdir $DIR/$tdir
7627         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7628         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7629         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7630         # Flush writes to ensure valid blocks.  Need to be more thorough for
7631         # ZFS, since blocks are not allocated/returned to client immediately.
7632         sync_all_data
7633         wait_zfs_commit ost1 2
7634         cancel_lru_locks osc
7635         ls -ls $DIR/$tdir
7636
7637         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7638
7639         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7640
7641         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7642         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7643
7644         rm -f $DIR/$tdir/$tfile.[123]
7645 }
7646 run_test 56ab "lfs find --blocks"
7647
7648 # LU-11188
7649 test_56aca() {
7650         local dir="$DIR/$tdir"
7651         local perms=(001 002 003 004 005 006 007
7652                      010 020 030 040 050 060 070
7653                      100 200 300 400 500 600 700
7654                      111 222 333 444 555 666 777)
7655         local perm_minus=(8 8 4 8 4 4 2
7656                           8 8 4 8 4 4 2
7657                           8 8 4 8 4 4 2
7658                           4 4 2 4 2 2 1)
7659         local perm_slash=(8  8 12  8 12 12 14
7660                           8  8 12  8 12 12 14
7661                           8  8 12  8 12 12 14
7662                          16 16 24 16 24 24 28)
7663
7664         test_mkdir "$dir"
7665         for perm in ${perms[*]}; do
7666                 touch "$dir/$tfile.$perm"
7667                 chmod $perm "$dir/$tfile.$perm"
7668         done
7669
7670         for ((i = 0; i < ${#perms[*]}; i++)); do
7671                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7672                 (( $num == 1 )) ||
7673                         error "lfs find -perm ${perms[i]}:"\
7674                               "$num != 1"
7675
7676                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7677                 (( $num == ${perm_minus[i]} )) ||
7678                         error "lfs find -perm -${perms[i]}:"\
7679                               "$num != ${perm_minus[i]}"
7680
7681                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7682                 (( $num == ${perm_slash[i]} )) ||
7683                         error "lfs find -perm /${perms[i]}:"\
7684                               "$num != ${perm_slash[i]}"
7685         done
7686 }
7687 run_test 56aca "check lfs find -perm with octal representation"
7688
7689 test_56acb() {
7690         local dir=$DIR/$tdir
7691         # p is the permission of write and execute for user, group and other
7692         # without the umask. It is used to test +wx.
7693         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7694         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7695         local symbolic=(+t  a+t u+t g+t o+t
7696                         g+s u+s o+s +s o+sr
7697                         o=r,ug+o,u+w
7698                         u+ g+ o+ a+ ugo+
7699                         u- g- o- a- ugo-
7700                         u= g= o= a= ugo=
7701                         o=r,ug+o,u+w u=r,a+u,u+w
7702                         g=r,ugo=g,u+w u+x,+X +X
7703                         u+x,u+X u+X u+x,g+X o+r,+X
7704                         u+x,go+X +wx +rwx)
7705
7706         test_mkdir $dir
7707         for perm in ${perms[*]}; do
7708                 touch "$dir/$tfile.$perm"
7709                 chmod $perm "$dir/$tfile.$perm"
7710         done
7711
7712         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7713                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7714
7715                 (( $num == 1 )) ||
7716                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7717         done
7718 }
7719 run_test 56acb "check lfs find -perm with symbolic representation"
7720
7721 test_56acc() {
7722         local dir=$DIR/$tdir
7723         local tests="17777 787 789 abcd
7724                 ug=uu ug=a ug=gu uo=ou urw
7725                 u+xg+x a=r,u+x,"
7726
7727         test_mkdir $dir
7728         for err in $tests; do
7729                 if $LFS find $dir -perm $err 2>/dev/null; then
7730                         error "lfs find -perm $err: parsing should have failed"
7731                 fi
7732         done
7733 }
7734 run_test 56acc "check parsing error for lfs find -perm"
7735
7736 test_56ba() {
7737         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7738                 skip "Need MDS version at least 2.10.50"
7739
7740         # Create composite files with one component
7741         local dir=$DIR/$tdir
7742
7743         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7744         # Create composite files with three components
7745         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7746         # Create non-composite files
7747         createmany -o $dir/${tfile}- 10
7748
7749         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7750
7751         [[ $nfiles == 10 ]] ||
7752                 error "lfs find -E 1M found $nfiles != 10 files"
7753
7754         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7755         [[ $nfiles == 25 ]] ||
7756                 error "lfs find ! -E 1M found $nfiles != 25 files"
7757
7758         # All files have a component that starts at 0
7759         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7760         [[ $nfiles == 35 ]] ||
7761                 error "lfs find --component-start 0 - $nfiles != 35 files"
7762
7763         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7764         [[ $nfiles == 15 ]] ||
7765                 error "lfs find --component-start 2M - $nfiles != 15 files"
7766
7767         # All files created here have a componenet that does not starts at 2M
7768         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7769         [[ $nfiles == 35 ]] ||
7770                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7771
7772         # Find files with a specified number of components
7773         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7774         [[ $nfiles == 15 ]] ||
7775                 error "lfs find --component-count 3 - $nfiles != 15 files"
7776
7777         # Remember non-composite files have a component count of zero
7778         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7779         [[ $nfiles == 10 ]] ||
7780                 error "lfs find --component-count 0 - $nfiles != 10 files"
7781
7782         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7783         [[ $nfiles == 20 ]] ||
7784                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7785
7786         # All files have a flag called "init"
7787         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7788         [[ $nfiles == 35 ]] ||
7789                 error "lfs find --component-flags init - $nfiles != 35 files"
7790
7791         # Multi-component files will have a component not initialized
7792         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7793         [[ $nfiles == 15 ]] ||
7794                 error "lfs find !--component-flags init - $nfiles != 15 files"
7795
7796         rm -rf $dir
7797
7798 }
7799 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7800
7801 test_56ca() {
7802         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7803                 skip "Need MDS version at least 2.10.57"
7804
7805         local td=$DIR/$tdir
7806         local tf=$td/$tfile
7807         local dir
7808         local nfiles
7809         local cmd
7810         local i
7811         local j
7812
7813         # create mirrored directories and mirrored files
7814         mkdir $td || error "mkdir $td failed"
7815         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7816         createmany -o $tf- 10 || error "create $tf- failed"
7817
7818         for i in $(seq 2); do
7819                 dir=$td/dir$i
7820                 mkdir $dir || error "mkdir $dir failed"
7821                 $LFS mirror create -N$((3 + i)) $dir ||
7822                         error "create mirrored dir $dir failed"
7823                 createmany -o $dir/$tfile- 10 ||
7824                         error "create $dir/$tfile- failed"
7825         done
7826
7827         # change the states of some mirrored files
7828         echo foo > $tf-6
7829         for i in $(seq 2); do
7830                 dir=$td/dir$i
7831                 for j in $(seq 4 9); do
7832                         echo foo > $dir/$tfile-$j
7833                 done
7834         done
7835
7836         # find mirrored files with specific mirror count
7837         cmd="$LFS find --mirror-count 3 --type f $td"
7838         nfiles=$($cmd | wc -l)
7839         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7840
7841         cmd="$LFS find ! --mirror-count 3 --type f $td"
7842         nfiles=$($cmd | wc -l)
7843         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7844
7845         cmd="$LFS find --mirror-count +2 --type f $td"
7846         nfiles=$($cmd | wc -l)
7847         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7848
7849         cmd="$LFS find --mirror-count -6 --type f $td"
7850         nfiles=$($cmd | wc -l)
7851         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7852
7853         # find mirrored files with specific file state
7854         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7855         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7856
7857         cmd="$LFS find --mirror-state=ro --type f $td"
7858         nfiles=$($cmd | wc -l)
7859         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7860
7861         cmd="$LFS find ! --mirror-state=ro --type f $td"
7862         nfiles=$($cmd | wc -l)
7863         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7864
7865         cmd="$LFS find --mirror-state=wp --type f $td"
7866         nfiles=$($cmd | wc -l)
7867         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7868
7869         cmd="$LFS find ! --mirror-state=sp --type f $td"
7870         nfiles=$($cmd | wc -l)
7871         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7872 }
7873 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7874
7875 test_56da() { # LU-14179
7876         local path=$DIR/$tdir
7877
7878         test_mkdir $path
7879         cd $path
7880
7881         local longdir=$(str_repeat 'a' 255)
7882
7883         for i in {1..15}; do
7884                 path=$path/$longdir
7885                 test_mkdir $longdir
7886                 cd $longdir
7887         done
7888
7889         local len=${#path}
7890         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7891
7892         test_mkdir $lastdir
7893         cd $lastdir
7894         # PATH_MAX-1
7895         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7896
7897         # NAME_MAX
7898         touch $(str_repeat 'f' 255)
7899
7900         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7901                 error "lfs find reported an error"
7902
7903         rm -rf $DIR/$tdir
7904 }
7905 run_test 56da "test lfs find with long paths"
7906
7907 test_57a() {
7908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7909         # note test will not do anything if MDS is not local
7910         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7911                 skip_env "ldiskfs only test"
7912         fi
7913         remote_mds_nodsh && skip "remote MDS with nodsh"
7914
7915         local MNTDEV="osd*.*MDT*.mntdev"
7916         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7917         [ -z "$DEV" ] && error "can't access $MNTDEV"
7918         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7919                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7920                         error "can't access $DEV"
7921                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7922                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7923                 rm $TMP/t57a.dump
7924         done
7925 }
7926 run_test 57a "verify MDS filesystem created with large inodes =="
7927
7928 test_57b() {
7929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7930         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7931                 skip_env "ldiskfs only test"
7932         fi
7933         remote_mds_nodsh && skip "remote MDS with nodsh"
7934
7935         local dir=$DIR/$tdir
7936         local filecount=100
7937         local file1=$dir/f1
7938         local fileN=$dir/f$filecount
7939
7940         rm -rf $dir || error "removing $dir"
7941         test_mkdir -c1 $dir
7942         local mdtidx=$($LFS getstripe -m $dir)
7943         local mdtname=MDT$(printf %04x $mdtidx)
7944         local facet=mds$((mdtidx + 1))
7945
7946         echo "mcreating $filecount files"
7947         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7948
7949         # verify that files do not have EAs yet
7950         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7951                 error "$file1 has an EA"
7952         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7953                 error "$fileN has an EA"
7954
7955         sync
7956         sleep 1
7957         df $dir  #make sure we get new statfs data
7958         local mdsfree=$(do_facet $facet \
7959                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7960         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7961         local file
7962
7963         echo "opening files to create objects/EAs"
7964         for file in $(seq -f $dir/f%g 1 $filecount); do
7965                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7966                         error "opening $file"
7967         done
7968
7969         # verify that files have EAs now
7970         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7971         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7972
7973         sleep 1  #make sure we get new statfs data
7974         df $dir
7975         local mdsfree2=$(do_facet $facet \
7976                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7977         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7978
7979         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7980                 if [ "$mdsfree" != "$mdsfree2" ]; then
7981                         error "MDC before $mdcfree != after $mdcfree2"
7982                 else
7983                         echo "MDC before $mdcfree != after $mdcfree2"
7984                         echo "unable to confirm if MDS has large inodes"
7985                 fi
7986         fi
7987         rm -rf $dir
7988 }
7989 run_test 57b "default LOV EAs are stored inside large inodes ==="
7990
7991 test_58() {
7992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7993         [ -z "$(which wiretest 2>/dev/null)" ] &&
7994                         skip_env "could not find wiretest"
7995
7996         wiretest
7997 }
7998 run_test 58 "verify cross-platform wire constants =============="
7999
8000 test_59() {
8001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8002
8003         echo "touch 130 files"
8004         createmany -o $DIR/f59- 130
8005         echo "rm 130 files"
8006         unlinkmany $DIR/f59- 130
8007         sync
8008         # wait for commitment of removal
8009         wait_delete_completed
8010 }
8011 run_test 59 "verify cancellation of llog records async ========="
8012
8013 TEST60_HEAD="test_60 run $RANDOM"
8014 test_60a() {
8015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8016         remote_mgs_nodsh && skip "remote MGS with nodsh"
8017         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8018                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8019                         skip_env "missing subtest run-llog.sh"
8020
8021         log "$TEST60_HEAD - from kernel mode"
8022         do_facet mgs "$LCTL dk > /dev/null"
8023         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8024         do_facet mgs $LCTL dk > $TMP/$tfile
8025
8026         # LU-6388: test llog_reader
8027         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8028         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8029         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8030                         skip_env "missing llog_reader"
8031         local fstype=$(facet_fstype mgs)
8032         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8033                 skip_env "Only for ldiskfs or zfs type mgs"
8034
8035         local mntpt=$(facet_mntpt mgs)
8036         local mgsdev=$(mgsdevname 1)
8037         local fid_list
8038         local fid
8039         local rec_list
8040         local rec
8041         local rec_type
8042         local obj_file
8043         local path
8044         local seq
8045         local oid
8046         local pass=true
8047
8048         #get fid and record list
8049         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8050                 tail -n 4))
8051         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8052                 tail -n 4))
8053         #remount mgs as ldiskfs or zfs type
8054         stop mgs || error "stop mgs failed"
8055         mount_fstype mgs || error "remount mgs failed"
8056         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8057                 fid=${fid_list[i]}
8058                 rec=${rec_list[i]}
8059                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8060                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8061                 oid=$((16#$oid))
8062
8063                 case $fstype in
8064                         ldiskfs )
8065                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8066                         zfs )
8067                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8068                 esac
8069                 echo "obj_file is $obj_file"
8070                 do_facet mgs $llog_reader $obj_file
8071
8072                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8073                         awk '{ print $3 }' | sed -e "s/^type=//g")
8074                 if [ $rec_type != $rec ]; then
8075                         echo "FAILED test_60a wrong record type $rec_type," \
8076                               "should be $rec"
8077                         pass=false
8078                         break
8079                 fi
8080
8081                 #check obj path if record type is LLOG_LOGID_MAGIC
8082                 if [ "$rec" == "1064553b" ]; then
8083                         path=$(do_facet mgs $llog_reader $obj_file |
8084                                 grep "path=" | awk '{ print $NF }' |
8085                                 sed -e "s/^path=//g")
8086                         if [ $obj_file != $mntpt/$path ]; then
8087                                 echo "FAILED test_60a wrong obj path" \
8088                                       "$montpt/$path, should be $obj_file"
8089                                 pass=false
8090                                 break
8091                         fi
8092                 fi
8093         done
8094         rm -f $TMP/$tfile
8095         #restart mgs before "error", otherwise it will block the next test
8096         stop mgs || error "stop mgs failed"
8097         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8098         $pass || error "test failed, see FAILED test_60a messages for specifics"
8099 }
8100 run_test 60a "llog_test run from kernel module and test llog_reader"
8101
8102 test_60b() { # bug 6411
8103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8104
8105         dmesg > $DIR/$tfile
8106         LLOG_COUNT=$(do_facet mgs dmesg |
8107                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8108                           /llog_[a-z]*.c:[0-9]/ {
8109                                 if (marker)
8110                                         from_marker++
8111                                 from_begin++
8112                           }
8113                           END {
8114                                 if (marker)
8115                                         print from_marker
8116                                 else
8117                                         print from_begin
8118                           }")
8119
8120         [[ $LLOG_COUNT -gt 120 ]] &&
8121                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8122 }
8123 run_test 60b "limit repeated messages from CERROR/CWARN"
8124
8125 test_60c() {
8126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8127
8128         echo "create 5000 files"
8129         createmany -o $DIR/f60c- 5000
8130 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8131         lctl set_param fail_loc=0x80000137
8132         unlinkmany $DIR/f60c- 5000
8133         lctl set_param fail_loc=0
8134 }
8135 run_test 60c "unlink file when mds full"
8136
8137 test_60d() {
8138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8139
8140         SAVEPRINTK=$(lctl get_param -n printk)
8141         # verify "lctl mark" is even working"
8142         MESSAGE="test message ID $RANDOM $$"
8143         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8144         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8145
8146         lctl set_param printk=0 || error "set lnet.printk failed"
8147         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8148         MESSAGE="new test message ID $RANDOM $$"
8149         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8150         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8151         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8152
8153         lctl set_param -n printk="$SAVEPRINTK"
8154 }
8155 run_test 60d "test printk console message masking"
8156
8157 test_60e() {
8158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8159         remote_mds_nodsh && skip "remote MDS with nodsh"
8160
8161         touch $DIR/$tfile
8162 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8163         do_facet mds1 lctl set_param fail_loc=0x15b
8164         rm $DIR/$tfile
8165 }
8166 run_test 60e "no space while new llog is being created"
8167
8168 test_60f() {
8169         local old_path=$($LCTL get_param -n debug_path)
8170
8171         stack_trap "$LCTL set_param debug_path=$old_path"
8172         stack_trap "rm -f $TMP/$tfile*"
8173         rm -f $TMP/$tfile* 2> /dev/null
8174         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8175         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8176         test_mkdir $DIR/$tdir
8177         # retry in case the open is cached and not released
8178         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8179                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8180                 sleep 0.1
8181         done
8182         ls $TMP/$tfile*
8183         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8184 }
8185 run_test 60f "change debug_path works"
8186
8187 test_60g() {
8188         local pid
8189         local i
8190
8191         test_mkdir -c $MDSCOUNT $DIR/$tdir
8192
8193         (
8194                 local index=0
8195                 while true; do
8196                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8197                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8198                                 2>/dev/null
8199                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8200                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8201                         index=$((index + 1))
8202                 done
8203         ) &
8204
8205         pid=$!
8206
8207         for i in {0..100}; do
8208                 # define OBD_FAIL_OSD_TXN_START    0x19a
8209                 local index=$((i % MDSCOUNT + 1))
8210
8211                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8212                         > /dev/null
8213                 sleep 0.01
8214         done
8215
8216         kill -9 $pid
8217
8218         for i in $(seq $MDSCOUNT); do
8219                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8220         done
8221
8222         mkdir $DIR/$tdir/new || error "mkdir failed"
8223         rmdir $DIR/$tdir/new || error "rmdir failed"
8224
8225         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8226                 -t namespace
8227         for i in $(seq $MDSCOUNT); do
8228                 wait_update_facet mds$i "$LCTL get_param -n \
8229                         mdd.$(facet_svc mds$i).lfsck_namespace |
8230                         awk '/^status/ { print \\\$2 }'" "completed"
8231         done
8232
8233         ls -R $DIR/$tdir || error "ls failed"
8234         rm -rf $DIR/$tdir || error "rmdir failed"
8235 }
8236 run_test 60g "transaction abort won't cause MDT hung"
8237
8238 test_60h() {
8239         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8240                 skip "Need MDS version at least 2.12.52"
8241         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8242
8243         local f
8244
8245         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8246         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8247         for fail_loc in 0x80000188 0x80000189; do
8248                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8249                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8250                         error "mkdir $dir-$fail_loc failed"
8251                 for i in {0..10}; do
8252                         # create may fail on missing stripe
8253                         echo $i > $DIR/$tdir-$fail_loc/$i
8254                 done
8255                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8256                         error "getdirstripe $tdir-$fail_loc failed"
8257                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8258                         error "migrate $tdir-$fail_loc failed"
8259                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8260                         error "getdirstripe $tdir-$fail_loc failed"
8261                 pushd $DIR/$tdir-$fail_loc
8262                 for f in *; do
8263                         echo $f | cmp $f - || error "$f data mismatch"
8264                 done
8265                 popd
8266                 rm -rf $DIR/$tdir-$fail_loc
8267         done
8268 }
8269 run_test 60h "striped directory with missing stripes can be accessed"
8270
8271 function t60i_load() {
8272         mkdir $DIR/$tdir
8273         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8274         $LCTL set_param fail_loc=0x131c fail_val=1
8275         for ((i=0; i<5000; i++)); do
8276                 touch $DIR/$tdir/f$i
8277         done
8278 }
8279
8280 test_60i() {
8281         changelog_register || error "changelog_register failed"
8282         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8283         changelog_users $SINGLEMDS | grep -q $cl_user ||
8284                 error "User $cl_user not found in changelog_users"
8285         changelog_chmask "ALL"
8286         t60i_load &
8287         local PID=$!
8288         for((i=0; i<100; i++)); do
8289                 changelog_dump >/dev/null ||
8290                         error "can't read changelog"
8291         done
8292         kill $PID
8293         wait $PID
8294         changelog_deregister || error "changelog_deregister failed"
8295         $LCTL set_param fail_loc=0
8296 }
8297 run_test 60i "llog: new record vs reader race"
8298
8299 test_61a() {
8300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8301
8302         f="$DIR/f61"
8303         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8304         cancel_lru_locks osc
8305         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8306         sync
8307 }
8308 run_test 61a "mmap() writes don't make sync hang ================"
8309
8310 test_61b() {
8311         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8312 }
8313 run_test 61b "mmap() of unstriped file is successful"
8314
8315 # bug 2330 - insufficient obd_match error checking causes LBUG
8316 test_62() {
8317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8318
8319         f="$DIR/f62"
8320         echo foo > $f
8321         cancel_lru_locks osc
8322         lctl set_param fail_loc=0x405
8323         cat $f && error "cat succeeded, expect -EIO"
8324         lctl set_param fail_loc=0
8325 }
8326 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8327 # match every page all of the time.
8328 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8329
8330 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8331 # Though this test is irrelevant anymore, it helped to reveal some
8332 # other grant bugs (LU-4482), let's keep it.
8333 test_63a() {   # was test_63
8334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8335
8336         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8337
8338         for i in `seq 10` ; do
8339                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8340                 sleep 5
8341                 kill $!
8342                 sleep 1
8343         done
8344
8345         rm -f $DIR/f63 || true
8346 }
8347 run_test 63a "Verify oig_wait interruption does not crash ======="
8348
8349 # bug 2248 - async write errors didn't return to application on sync
8350 # bug 3677 - async write errors left page locked
8351 test_63b() {
8352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8353
8354         debugsave
8355         lctl set_param debug=-1
8356
8357         # ensure we have a grant to do async writes
8358         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8359         rm $DIR/$tfile
8360
8361         sync    # sync lest earlier test intercept the fail_loc
8362
8363         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8364         lctl set_param fail_loc=0x80000406
8365         $MULTIOP $DIR/$tfile Owy && \
8366                 error "sync didn't return ENOMEM"
8367         sync; sleep 2; sync     # do a real sync this time to flush page
8368         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8369                 error "locked page left in cache after async error" || true
8370         debugrestore
8371 }
8372 run_test 63b "async write errors should be returned to fsync ==="
8373
8374 test_64a () {
8375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8376
8377         lfs df $DIR
8378         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8379 }
8380 run_test 64a "verify filter grant calculations (in kernel) ====="
8381
8382 test_64b () {
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384
8385         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8386 }
8387 run_test 64b "check out-of-space detection on client"
8388
8389 test_64c() {
8390         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8391 }
8392 run_test 64c "verify grant shrink"
8393
8394 import_param() {
8395         local tgt=$1
8396         local param=$2
8397
8398         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8399 }
8400
8401 # this does exactly what osc_request.c:osc_announce_cached() does in
8402 # order to calculate max amount of grants to ask from server
8403 want_grant() {
8404         local tgt=$1
8405
8406         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8407         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8408
8409         ((rpc_in_flight++));
8410         nrpages=$((nrpages * rpc_in_flight))
8411
8412         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8413
8414         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8415
8416         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8417         local undirty=$((nrpages * PAGE_SIZE))
8418
8419         local max_extent_pages
8420         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8421         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8422         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8423         local grant_extent_tax
8424         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8425
8426         undirty=$((undirty + nrextents * grant_extent_tax))
8427
8428         echo $undirty
8429 }
8430
8431 # this is size of unit for grant allocation. It should be equal to
8432 # what tgt_grant.c:tgt_grant_chunk() calculates
8433 grant_chunk() {
8434         local tgt=$1
8435         local max_brw_size
8436         local grant_extent_tax
8437
8438         max_brw_size=$(import_param $tgt max_brw_size)
8439
8440         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8441
8442         echo $(((max_brw_size + grant_extent_tax) * 2))
8443 }
8444
8445 test_64d() {
8446         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8447                 skip "OST < 2.10.55 doesn't limit grants enough"
8448
8449         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8450
8451         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8452                 skip "no grant_param connect flag"
8453
8454         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8455
8456         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8457         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8458
8459
8460         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8461         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8462
8463         $LFS setstripe $DIR/$tfile -i 0 -c 1
8464         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8465         ddpid=$!
8466
8467         while kill -0 $ddpid; do
8468                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8469
8470                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8471                         kill $ddpid
8472                         error "cur_grant $cur_grant > $max_cur_granted"
8473                 fi
8474
8475                 sleep 1
8476         done
8477 }
8478 run_test 64d "check grant limit exceed"
8479
8480 check_grants() {
8481         local tgt=$1
8482         local expected=$2
8483         local msg=$3
8484         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8485
8486         ((cur_grants == expected)) ||
8487                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8488 }
8489
8490 round_up_p2() {
8491         echo $((($1 + $2 - 1) & ~($2 - 1)))
8492 }
8493
8494 test_64e() {
8495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8496         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8497                 skip "Need OSS version at least 2.11.56"
8498
8499         # Remount client to reset grant
8500         remount_client $MOUNT || error "failed to remount client"
8501         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8502
8503         local init_grants=$(import_param $osc_tgt initial_grant)
8504
8505         check_grants $osc_tgt $init_grants "init grants"
8506
8507         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8508         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8509         local gbs=$(import_param $osc_tgt grant_block_size)
8510
8511         # write random number of bytes from max_brw_size / 4 to max_brw_size
8512         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8513         # align for direct io
8514         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8515         # round to grant consumption unit
8516         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8517
8518         local grants=$((wb_round_up + extent_tax))
8519
8520         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8521
8522         # define OBD_FAIL_TGT_NO_GRANT 0x725
8523         # make the server not grant more back
8524         do_facet ost1 $LCTL set_param fail_loc=0x725
8525         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8526
8527         do_facet ost1 $LCTL set_param fail_loc=0
8528
8529         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8530
8531         rm -f $DIR/$tfile || error "rm failed"
8532
8533         # Remount client to reset grant
8534         remount_client $MOUNT || error "failed to remount client"
8535         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8536
8537         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8538
8539         # define OBD_FAIL_TGT_NO_GRANT 0x725
8540         # make the server not grant more back
8541         do_facet ost1 $LCTL set_param fail_loc=0x725
8542         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8543         do_facet ost1 $LCTL set_param fail_loc=0
8544
8545         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8546 }
8547 run_test 64e "check grant consumption (no grant allocation)"
8548
8549 test_64f() {
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551
8552         # Remount client to reset grant
8553         remount_client $MOUNT || error "failed to remount client"
8554         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8555
8556         local init_grants=$(import_param $osc_tgt initial_grant)
8557         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8558         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8559         local gbs=$(import_param $osc_tgt grant_block_size)
8560         local chunk=$(grant_chunk $osc_tgt)
8561
8562         # write random number of bytes from max_brw_size / 4 to max_brw_size
8563         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8564         # align for direct io
8565         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8566         # round to grant consumption unit
8567         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8568
8569         local grants=$((wb_round_up + extent_tax))
8570
8571         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8572         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8573                 error "error writing to $DIR/$tfile"
8574
8575         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8576                 "direct io with grant allocation"
8577
8578         rm -f $DIR/$tfile || error "rm failed"
8579
8580         # Remount client to reset grant
8581         remount_client $MOUNT || error "failed to remount client"
8582         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8583
8584         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8585
8586         local cmd="oO_WRONLY:w${write_bytes}_yc"
8587
8588         $MULTIOP $DIR/$tfile $cmd &
8589         MULTIPID=$!
8590         sleep 1
8591
8592         check_grants $osc_tgt $((init_grants - grants)) \
8593                 "buffered io, not write rpc"
8594
8595         kill -USR1 $MULTIPID
8596         wait
8597
8598         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8599                 "buffered io, one RPC"
8600 }
8601 run_test 64f "check grant consumption (with grant allocation)"
8602
8603 # bug 1414 - set/get directories' stripe info
8604 test_65a() {
8605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8606
8607         test_mkdir $DIR/$tdir
8608         touch $DIR/$tdir/f1
8609         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8610 }
8611 run_test 65a "directory with no stripe info"
8612
8613 test_65b() {
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         test_mkdir $DIR/$tdir
8617         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8618
8619         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8620                                                 error "setstripe"
8621         touch $DIR/$tdir/f2
8622         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8623 }
8624 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8625
8626 test_65c() {
8627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8628         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8629
8630         test_mkdir $DIR/$tdir
8631         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8632
8633         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8634                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8635         touch $DIR/$tdir/f3
8636         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8637 }
8638 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8639
8640 test_65d() {
8641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8642
8643         test_mkdir $DIR/$tdir
8644         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8645         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8646
8647         if [[ $STRIPECOUNT -le 0 ]]; then
8648                 sc=1
8649         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8650                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8651                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8652         else
8653                 sc=$(($STRIPECOUNT - 1))
8654         fi
8655         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8656         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8657         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8658                 error "lverify failed"
8659 }
8660 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8661
8662 test_65e() {
8663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8664
8665         test_mkdir $DIR/$tdir
8666
8667         $LFS setstripe $DIR/$tdir || error "setstripe"
8668         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8669                                         error "no stripe info failed"
8670         touch $DIR/$tdir/f6
8671         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8672 }
8673 run_test 65e "directory setstripe defaults"
8674
8675 test_65f() {
8676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8677
8678         test_mkdir $DIR/${tdir}f
8679         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8680                 error "setstripe succeeded" || true
8681 }
8682 run_test 65f "dir setstripe permission (should return error) ==="
8683
8684 test_65g() {
8685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8686
8687         test_mkdir $DIR/$tdir
8688         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8689
8690         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8691                 error "setstripe -S failed"
8692         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8693         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8694                 error "delete default stripe failed"
8695 }
8696 run_test 65g "directory setstripe -d"
8697
8698 test_65h() {
8699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8700
8701         test_mkdir $DIR/$tdir
8702         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8703
8704         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8705                 error "setstripe -S failed"
8706         test_mkdir $DIR/$tdir/dd1
8707         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8708                 error "stripe info inherit failed"
8709 }
8710 run_test 65h "directory stripe info inherit ===================="
8711
8712 test_65i() {
8713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8714
8715         save_layout_restore_at_exit $MOUNT
8716
8717         # bug6367: set non-default striping on root directory
8718         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8719
8720         # bug12836: getstripe on -1 default directory striping
8721         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8722
8723         # bug12836: getstripe -v on -1 default directory striping
8724         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8725
8726         # bug12836: new find on -1 default directory striping
8727         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8728 }
8729 run_test 65i "various tests to set root directory striping"
8730
8731 test_65j() { # bug6367
8732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8733
8734         sync; sleep 1
8735
8736         # if we aren't already remounting for each test, do so for this test
8737         if [ "$I_MOUNTED" = "yes" ]; then
8738                 cleanup || error "failed to unmount"
8739                 setup
8740         fi
8741
8742         save_layout_restore_at_exit $MOUNT
8743
8744         $LFS setstripe -d $MOUNT || error "setstripe failed"
8745 }
8746 run_test 65j "set default striping on root directory (bug 6367)="
8747
8748 cleanup_65k() {
8749         rm -rf $DIR/$tdir
8750         wait_delete_completed
8751         do_facet $SINGLEMDS "lctl set_param -n \
8752                 osp.$ost*MDT0000.max_create_count=$max_count"
8753         do_facet $SINGLEMDS "lctl set_param -n \
8754                 osp.$ost*MDT0000.create_count=$count"
8755         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8756         echo $INACTIVE_OSC "is Activate"
8757
8758         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8759 }
8760
8761 test_65k() { # bug11679
8762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8763         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8764         remote_mds_nodsh && skip "remote MDS with nodsh"
8765
8766         local disable_precreate=true
8767         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8768                 disable_precreate=false
8769
8770         echo "Check OST status: "
8771         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8772                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8773
8774         for OSC in $MDS_OSCS; do
8775                 echo $OSC "is active"
8776                 do_facet $SINGLEMDS lctl --device %$OSC activate
8777         done
8778
8779         for INACTIVE_OSC in $MDS_OSCS; do
8780                 local ost=$(osc_to_ost $INACTIVE_OSC)
8781                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8782                                lov.*md*.target_obd |
8783                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8784
8785                 mkdir -p $DIR/$tdir
8786                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8787                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8788
8789                 echo "Deactivate: " $INACTIVE_OSC
8790                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8791
8792                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8793                               osp.$ost*MDT0000.create_count")
8794                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8795                                   osp.$ost*MDT0000.max_create_count")
8796                 $disable_precreate &&
8797                         do_facet $SINGLEMDS "lctl set_param -n \
8798                                 osp.$ost*MDT0000.max_create_count=0"
8799
8800                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8801                         [ -f $DIR/$tdir/$idx ] && continue
8802                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8803                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8804                                 { cleanup_65k;
8805                                   error "setstripe $idx should succeed"; }
8806                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8807                 done
8808                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8809                 rmdir $DIR/$tdir
8810
8811                 do_facet $SINGLEMDS "lctl set_param -n \
8812                         osp.$ost*MDT0000.max_create_count=$max_count"
8813                 do_facet $SINGLEMDS "lctl set_param -n \
8814                         osp.$ost*MDT0000.create_count=$count"
8815                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8816                 echo $INACTIVE_OSC "is Activate"
8817
8818                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8819         done
8820 }
8821 run_test 65k "validate manual striping works properly with deactivated OSCs"
8822
8823 test_65l() { # bug 12836
8824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8825
8826         test_mkdir -p $DIR/$tdir/test_dir
8827         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8828         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8829 }
8830 run_test 65l "lfs find on -1 stripe dir ========================"
8831
8832 test_65m() {
8833         local layout=$(save_layout $MOUNT)
8834         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8835                 restore_layout $MOUNT $layout
8836                 error "setstripe should fail by non-root users"
8837         }
8838         true
8839 }
8840 run_test 65m "normal user can't set filesystem default stripe"
8841
8842 test_65n() {
8843         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8844         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8845                 skip "Need MDS version at least 2.12.50"
8846         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8847
8848         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8849         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8850         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8851
8852         save_layout_restore_at_exit $MOUNT
8853
8854         # new subdirectory under root directory should not inherit
8855         # the default layout from root
8856         local dir1=$MOUNT/$tdir-1
8857         mkdir $dir1 || error "mkdir $dir1 failed"
8858         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8859                 error "$dir1 shouldn't have LOV EA"
8860
8861         # delete the default layout on root directory
8862         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8863
8864         local dir2=$MOUNT/$tdir-2
8865         mkdir $dir2 || error "mkdir $dir2 failed"
8866         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8867                 error "$dir2 shouldn't have LOV EA"
8868
8869         # set a new striping pattern on root directory
8870         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8871         local new_def_stripe_size=$((def_stripe_size * 2))
8872         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8873                 error "set stripe size on $MOUNT failed"
8874
8875         # new file created in $dir2 should inherit the new stripe size from
8876         # the filesystem default
8877         local file2=$dir2/$tfile-2
8878         touch $file2 || error "touch $file2 failed"
8879
8880         local file2_stripe_size=$($LFS getstripe -S $file2)
8881         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8882         {
8883                 echo "file2_stripe_size: '$file2_stripe_size'"
8884                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8885                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8886         }
8887
8888         local dir3=$MOUNT/$tdir-3
8889         mkdir $dir3 || error "mkdir $dir3 failed"
8890         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8891         # the root layout, which is the actual default layout that will be used
8892         # when new files are created in $dir3.
8893         local dir3_layout=$(get_layout_param $dir3)
8894         local root_dir_layout=$(get_layout_param $MOUNT)
8895         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8896         {
8897                 echo "dir3_layout: '$dir3_layout'"
8898                 echo "root_dir_layout: '$root_dir_layout'"
8899                 error "$dir3 should show the default layout from $MOUNT"
8900         }
8901
8902         # set OST pool on root directory
8903         local pool=$TESTNAME
8904         pool_add $pool || error "add $pool failed"
8905         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8906                 error "add targets to $pool failed"
8907
8908         $LFS setstripe -p $pool $MOUNT ||
8909                 error "set OST pool on $MOUNT failed"
8910
8911         # new file created in $dir3 should inherit the pool from
8912         # the filesystem default
8913         local file3=$dir3/$tfile-3
8914         touch $file3 || error "touch $file3 failed"
8915
8916         local file3_pool=$($LFS getstripe -p $file3)
8917         [[ "$file3_pool" = "$pool" ]] ||
8918                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8919
8920         local dir4=$MOUNT/$tdir-4
8921         mkdir $dir4 || error "mkdir $dir4 failed"
8922         local dir4_layout=$(get_layout_param $dir4)
8923         root_dir_layout=$(get_layout_param $MOUNT)
8924         echo "$LFS getstripe -d $dir4"
8925         $LFS getstripe -d $dir4
8926         echo "$LFS getstripe -d $MOUNT"
8927         $LFS getstripe -d $MOUNT
8928         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8929         {
8930                 echo "dir4_layout: '$dir4_layout'"
8931                 echo "root_dir_layout: '$root_dir_layout'"
8932                 error "$dir4 should show the default layout from $MOUNT"
8933         }
8934
8935         # new file created in $dir4 should inherit the pool from
8936         # the filesystem default
8937         local file4=$dir4/$tfile-4
8938         touch $file4 || error "touch $file4 failed"
8939
8940         local file4_pool=$($LFS getstripe -p $file4)
8941         [[ "$file4_pool" = "$pool" ]] ||
8942                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8943
8944         # new subdirectory under non-root directory should inherit
8945         # the default layout from its parent directory
8946         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8947                 error "set directory layout on $dir4 failed"
8948
8949         local dir5=$dir4/$tdir-5
8950         mkdir $dir5 || error "mkdir $dir5 failed"
8951
8952         dir4_layout=$(get_layout_param $dir4)
8953         local dir5_layout=$(get_layout_param $dir5)
8954         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8955         {
8956                 echo "dir4_layout: '$dir4_layout'"
8957                 echo "dir5_layout: '$dir5_layout'"
8958                 error "$dir5 should inherit the default layout from $dir4"
8959         }
8960
8961         # though subdir under ROOT doesn't inherit default layout, but
8962         # its sub dir/file should be created with default layout.
8963         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8964         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8965                 skip "Need MDS version at least 2.12.59"
8966
8967         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8968         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8969         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8970
8971         if [ $default_lmv_hash == "none" ]; then
8972                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8973         else
8974                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8975                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8976         fi
8977
8978         $LFS setdirstripe -D -c 2 $MOUNT ||
8979                 error "setdirstripe -D -c 2 failed"
8980         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8981         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8982         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8983 }
8984 run_test 65n "don't inherit default layout from root for new subdirectories"
8985
8986 # bug 2543 - update blocks count on client
8987 test_66() {
8988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8989
8990         COUNT=${COUNT:-8}
8991         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8992         sync; sync_all_data; sync; sync_all_data
8993         cancel_lru_locks osc
8994         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8995         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8996 }
8997 run_test 66 "update inode blocks count on client ==============="
8998
8999 meminfo() {
9000         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9001 }
9002
9003 swap_used() {
9004         swapon -s | awk '($1 == "'$1'") { print $4 }'
9005 }
9006
9007 # bug5265, obdfilter oa2dentry return -ENOENT
9008 # #define OBD_FAIL_SRV_ENOENT 0x217
9009 test_69() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011         remote_ost_nodsh && skip "remote OST with nodsh"
9012
9013         f="$DIR/$tfile"
9014         $LFS setstripe -c 1 -i 0 $f
9015
9016         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9017
9018         do_facet ost1 lctl set_param fail_loc=0x217
9019         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9020         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9021
9022         do_facet ost1 lctl set_param fail_loc=0
9023         $DIRECTIO write $f 0 2 || error "write error"
9024
9025         cancel_lru_locks osc
9026         $DIRECTIO read $f 0 1 || error "read error"
9027
9028         do_facet ost1 lctl set_param fail_loc=0x217
9029         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9030
9031         do_facet ost1 lctl set_param fail_loc=0
9032         rm -f $f
9033 }
9034 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9035
9036 test_71() {
9037         test_mkdir $DIR/$tdir
9038         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9039         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9040 }
9041 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9042
9043 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9045         [ "$RUNAS_ID" = "$UID" ] &&
9046                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9047         # Check that testing environment is properly set up. Skip if not
9048         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9049                 skip_env "User $RUNAS_ID does not exist - skipping"
9050
9051         touch $DIR/$tfile
9052         chmod 777 $DIR/$tfile
9053         chmod ug+s $DIR/$tfile
9054         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9055                 error "$RUNAS dd $DIR/$tfile failed"
9056         # See if we are still setuid/sgid
9057         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9058                 error "S/gid is not dropped on write"
9059         # Now test that MDS is updated too
9060         cancel_lru_locks mdc
9061         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9062                 error "S/gid is not dropped on MDS"
9063         rm -f $DIR/$tfile
9064 }
9065 run_test 72a "Test that remove suid works properly (bug5695) ===="
9066
9067 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9068         local perm
9069
9070         [ "$RUNAS_ID" = "$UID" ] &&
9071                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9072         [ "$RUNAS_ID" -eq 0 ] &&
9073                 skip_env "RUNAS_ID = 0 -- skipping"
9074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9075         # Check that testing environment is properly set up. Skip if not
9076         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9077                 skip_env "User $RUNAS_ID does not exist - skipping"
9078
9079         touch $DIR/${tfile}-f{g,u}
9080         test_mkdir $DIR/${tfile}-dg
9081         test_mkdir $DIR/${tfile}-du
9082         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9083         chmod g+s $DIR/${tfile}-{f,d}g
9084         chmod u+s $DIR/${tfile}-{f,d}u
9085         for perm in 777 2777 4777; do
9086                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9087                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9088                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9089                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9090         done
9091         true
9092 }
9093 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9094
9095 # bug 3462 - multiple simultaneous MDC requests
9096 test_73() {
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098
9099         test_mkdir $DIR/d73-1
9100         test_mkdir $DIR/d73-2
9101         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9102         pid1=$!
9103
9104         lctl set_param fail_loc=0x80000129
9105         $MULTIOP $DIR/d73-1/f73-2 Oc &
9106         sleep 1
9107         lctl set_param fail_loc=0
9108
9109         $MULTIOP $DIR/d73-2/f73-3 Oc &
9110         pid3=$!
9111
9112         kill -USR1 $pid1
9113         wait $pid1 || return 1
9114
9115         sleep 25
9116
9117         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9118         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9119         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9120
9121         rm -rf $DIR/d73-*
9122 }
9123 run_test 73 "multiple MDC requests (should not deadlock)"
9124
9125 test_74a() { # bug 6149, 6184
9126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9127
9128         touch $DIR/f74a
9129         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9130         #
9131         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9132         # will spin in a tight reconnection loop
9133         $LCTL set_param fail_loc=0x8000030e
9134         # get any lock that won't be difficult - lookup works.
9135         ls $DIR/f74a
9136         $LCTL set_param fail_loc=0
9137         rm -f $DIR/f74a
9138         true
9139 }
9140 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9141
9142 test_74b() { # bug 13310
9143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9144
9145         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9146         #
9147         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9148         # will spin in a tight reconnection loop
9149         $LCTL set_param fail_loc=0x8000030e
9150         # get a "difficult" lock
9151         touch $DIR/f74b
9152         $LCTL set_param fail_loc=0
9153         rm -f $DIR/f74b
9154         true
9155 }
9156 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9157
9158 test_74c() {
9159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9160
9161         #define OBD_FAIL_LDLM_NEW_LOCK
9162         $LCTL set_param fail_loc=0x319
9163         touch $DIR/$tfile && error "touch successful"
9164         $LCTL set_param fail_loc=0
9165         true
9166 }
9167 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9168
9169 slab_lic=/sys/kernel/slab/lustre_inode_cache
9170 num_objects() {
9171         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9172         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9173                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9174 }
9175
9176 test_76a() { # Now for b=20433, added originally in b=1443
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178
9179         cancel_lru_locks osc
9180         # there may be some slab objects cached per core
9181         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9182         local before=$(num_objects)
9183         local count=$((512 * cpus))
9184         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9185         local margin=$((count / 10))
9186         if [[ -f $slab_lic/aliases ]]; then
9187                 local aliases=$(cat $slab_lic/aliases)
9188                 (( aliases > 0 )) && margin=$((margin * aliases))
9189         fi
9190
9191         echo "before slab objects: $before"
9192         for i in $(seq $count); do
9193                 touch $DIR/$tfile
9194                 rm -f $DIR/$tfile
9195         done
9196         cancel_lru_locks osc
9197         local after=$(num_objects)
9198         echo "created: $count, after slab objects: $after"
9199         # shared slab counts are not very accurate, allow significant margin
9200         # the main goal is that the cache growth is not permanently > $count
9201         while (( after > before + margin )); do
9202                 sleep 1
9203                 after=$(num_objects)
9204                 wait=$((wait + 1))
9205                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9206                 if (( wait > 60 )); then
9207                         error "inode slab grew from $before+$margin to $after"
9208                 fi
9209         done
9210 }
9211 run_test 76a "confirm clients recycle inodes properly ===="
9212
9213 test_76b() {
9214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9215         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9216
9217         local count=512
9218         local before=$(num_objects)
9219
9220         for i in $(seq $count); do
9221                 mkdir $DIR/$tdir
9222                 rmdir $DIR/$tdir
9223         done
9224
9225         local after=$(num_objects)
9226         local wait=0
9227
9228         while (( after > before )); do
9229                 sleep 1
9230                 after=$(num_objects)
9231                 wait=$((wait + 1))
9232                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9233                 if (( wait > 60 )); then
9234                         error "inode slab grew from $before to $after"
9235                 fi
9236         done
9237
9238         echo "slab objects before: $before, after: $after"
9239 }
9240 run_test 76b "confirm clients recycle directory inodes properly ===="
9241
9242 export ORIG_CSUM=""
9243 set_checksums()
9244 {
9245         # Note: in sptlrpc modes which enable its own bulk checksum, the
9246         # original crc32_le bulk checksum will be automatically disabled,
9247         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9248         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9249         # In this case set_checksums() will not be no-op, because sptlrpc
9250         # bulk checksum will be enabled all through the test.
9251
9252         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9253         lctl set_param -n osc.*.checksums $1
9254         return 0
9255 }
9256
9257 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9258                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9259 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9260                              tr -d [] | head -n1)}
9261 set_checksum_type()
9262 {
9263         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9264         rc=$?
9265         log "set checksum type to $1, rc = $rc"
9266         return $rc
9267 }
9268
9269 get_osc_checksum_type()
9270 {
9271         # arugment 1: OST name, like OST0000
9272         ost=$1
9273         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9274                         sed 's/.*\[\(.*\)\].*/\1/g')
9275         rc=$?
9276         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9277         echo $checksum_type
9278 }
9279
9280 F77_TMP=$TMP/f77-temp
9281 F77SZ=8
9282 setup_f77() {
9283         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9284                 error "error writing to $F77_TMP"
9285 }
9286
9287 test_77a() { # bug 10889
9288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9289         $GSS && skip_env "could not run with gss"
9290
9291         [ ! -f $F77_TMP ] && setup_f77
9292         set_checksums 1
9293         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9294         set_checksums 0
9295         rm -f $DIR/$tfile
9296 }
9297 run_test 77a "normal checksum read/write operation"
9298
9299 test_77b() { # bug 10889
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301         $GSS && skip_env "could not run with gss"
9302
9303         [ ! -f $F77_TMP ] && setup_f77
9304         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9305         $LCTL set_param fail_loc=0x80000409
9306         set_checksums 1
9307
9308         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9309                 error "dd error: $?"
9310         $LCTL set_param fail_loc=0
9311
9312         for algo in $CKSUM_TYPES; do
9313                 cancel_lru_locks osc
9314                 set_checksum_type $algo
9315                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9316                 $LCTL set_param fail_loc=0x80000408
9317                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9318                 $LCTL set_param fail_loc=0
9319         done
9320         set_checksums 0
9321         set_checksum_type $ORIG_CSUM_TYPE
9322         rm -f $DIR/$tfile
9323 }
9324 run_test 77b "checksum error on client write, read"
9325
9326 cleanup_77c() {
9327         trap 0
9328         set_checksums 0
9329         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9330         $check_ost &&
9331                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9332         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9333         $check_ost && [ -n "$ost_file_prefix" ] &&
9334                 do_facet ost1 rm -f ${ost_file_prefix}\*
9335 }
9336
9337 test_77c() {
9338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9339         $GSS && skip_env "could not run with gss"
9340         remote_ost_nodsh && skip "remote OST with nodsh"
9341
9342         local bad1
9343         local osc_file_prefix
9344         local osc_file
9345         local check_ost=false
9346         local ost_file_prefix
9347         local ost_file
9348         local orig_cksum
9349         local dump_cksum
9350         local fid
9351
9352         # ensure corruption will occur on first OSS/OST
9353         $LFS setstripe -i 0 $DIR/$tfile
9354
9355         [ ! -f $F77_TMP ] && setup_f77
9356         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9357                 error "dd write error: $?"
9358         fid=$($LFS path2fid $DIR/$tfile)
9359
9360         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9361         then
9362                 check_ost=true
9363                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9364                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9365         else
9366                 echo "OSS do not support bulk pages dump upon error"
9367         fi
9368
9369         osc_file_prefix=$($LCTL get_param -n debug_path)
9370         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9371
9372         trap cleanup_77c EXIT
9373
9374         set_checksums 1
9375         # enable bulk pages dump upon error on Client
9376         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9377         # enable bulk pages dump upon error on OSS
9378         $check_ost &&
9379                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9380
9381         # flush Client cache to allow next read to reach OSS
9382         cancel_lru_locks osc
9383
9384         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9385         $LCTL set_param fail_loc=0x80000408
9386         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9387         $LCTL set_param fail_loc=0
9388
9389         rm -f $DIR/$tfile
9390
9391         # check cksum dump on Client
9392         osc_file=$(ls ${osc_file_prefix}*)
9393         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9394         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9395         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9396         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9397         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9398                      cksum)
9399         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9400         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9401                 error "dump content does not match on Client"
9402
9403         $check_ost || skip "No need to check cksum dump on OSS"
9404
9405         # check cksum dump on OSS
9406         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9407         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9408         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9409         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9410         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9411                 error "dump content does not match on OSS"
9412
9413         cleanup_77c
9414 }
9415 run_test 77c "checksum error on client read with debug"
9416
9417 test_77d() { # bug 10889
9418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9419         $GSS && skip_env "could not run with gss"
9420
9421         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9422         $LCTL set_param fail_loc=0x80000409
9423         set_checksums 1
9424         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9425                 error "direct write: rc=$?"
9426         $LCTL set_param fail_loc=0
9427         set_checksums 0
9428
9429         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9430         $LCTL set_param fail_loc=0x80000408
9431         set_checksums 1
9432         cancel_lru_locks osc
9433         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9434                 error "direct read: rc=$?"
9435         $LCTL set_param fail_loc=0
9436         set_checksums 0
9437 }
9438 run_test 77d "checksum error on OST direct write, read"
9439
9440 test_77f() { # bug 10889
9441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9442         $GSS && skip_env "could not run with gss"
9443
9444         set_checksums 1
9445         for algo in $CKSUM_TYPES; do
9446                 cancel_lru_locks osc
9447                 set_checksum_type $algo
9448                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9449                 $LCTL set_param fail_loc=0x409
9450                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9451                         error "direct write succeeded"
9452                 $LCTL set_param fail_loc=0
9453         done
9454         set_checksum_type $ORIG_CSUM_TYPE
9455         set_checksums 0
9456 }
9457 run_test 77f "repeat checksum error on write (expect error)"
9458
9459 test_77g() { # bug 10889
9460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9461         $GSS && skip_env "could not run with gss"
9462         remote_ost_nodsh && skip "remote OST with nodsh"
9463
9464         [ ! -f $F77_TMP ] && setup_f77
9465
9466         local file=$DIR/$tfile
9467         stack_trap "rm -f $file" EXIT
9468
9469         $LFS setstripe -c 1 -i 0 $file
9470         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9471         do_facet ost1 lctl set_param fail_loc=0x8000021a
9472         set_checksums 1
9473         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9474                 error "write error: rc=$?"
9475         do_facet ost1 lctl set_param fail_loc=0
9476         set_checksums 0
9477
9478         cancel_lru_locks osc
9479         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9480         do_facet ost1 lctl set_param fail_loc=0x8000021b
9481         set_checksums 1
9482         cmp $F77_TMP $file || error "file compare failed"
9483         do_facet ost1 lctl set_param fail_loc=0
9484         set_checksums 0
9485 }
9486 run_test 77g "checksum error on OST write, read"
9487
9488 test_77k() { # LU-10906
9489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9490         $GSS && skip_env "could not run with gss"
9491
9492         local cksum_param="osc.$FSNAME*.checksums"
9493         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9494         local checksum
9495         local i
9496
9497         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9498         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9499         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9500
9501         for i in 0 1; do
9502                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9503                         error "failed to set checksum=$i on MGS"
9504                 wait_update $HOSTNAME "$get_checksum" $i
9505                 #remount
9506                 echo "remount client, checksum should be $i"
9507                 remount_client $MOUNT || error "failed to remount client"
9508                 checksum=$(eval $get_checksum)
9509                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9510         done
9511         # remove persistent param to avoid races with checksum mountopt below
9512         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9513                 error "failed to delete checksum on MGS"
9514
9515         for opt in "checksum" "nochecksum"; do
9516                 #remount with mount option
9517                 echo "remount client with option $opt, checksum should be $i"
9518                 umount_client $MOUNT || error "failed to umount client"
9519                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9520                         error "failed to mount client with option '$opt'"
9521                 checksum=$(eval $get_checksum)
9522                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9523                 i=$((i - 1))
9524         done
9525
9526         remount_client $MOUNT || error "failed to remount client"
9527 }
9528 run_test 77k "enable/disable checksum correctly"
9529
9530 test_77l() {
9531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9532         $GSS && skip_env "could not run with gss"
9533
9534         set_checksums 1
9535         stack_trap "set_checksums $ORIG_CSUM" EXIT
9536         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9537
9538         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9539
9540         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9541         for algo in $CKSUM_TYPES; do
9542                 set_checksum_type $algo || error "fail to set checksum type $algo"
9543                 osc_algo=$(get_osc_checksum_type OST0000)
9544                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9545
9546                 # no locks, no reqs to let the connection idle
9547                 cancel_lru_locks osc
9548                 lru_resize_disable osc
9549                 wait_osc_import_state client ost1 IDLE
9550
9551                 # ensure ost1 is connected
9552                 stat $DIR/$tfile >/dev/null || error "can't stat"
9553                 wait_osc_import_state client ost1 FULL
9554
9555                 osc_algo=$(get_osc_checksum_type OST0000)
9556                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9557         done
9558         return 0
9559 }
9560 run_test 77l "preferred checksum type is remembered after reconnected"
9561
9562 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9563 rm -f $F77_TMP
9564 unset F77_TMP
9565
9566 cleanup_test_78() {
9567         trap 0
9568         rm -f $DIR/$tfile
9569 }
9570
9571 test_78() { # bug 10901
9572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9573         remote_ost || skip_env "local OST"
9574
9575         NSEQ=5
9576         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9577         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9578         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9579         echo "MemTotal: $MEMTOTAL"
9580
9581         # reserve 256MB of memory for the kernel and other running processes,
9582         # and then take 1/2 of the remaining memory for the read/write buffers.
9583         if [ $MEMTOTAL -gt 512 ] ;then
9584                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9585         else
9586                 # for those poor memory-starved high-end clusters...
9587                 MEMTOTAL=$((MEMTOTAL / 2))
9588         fi
9589         echo "Mem to use for directio: $MEMTOTAL"
9590
9591         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9592         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9593         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9594         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9595                 head -n1)
9596         echo "Smallest OST: $SMALLESTOST"
9597         [[ $SMALLESTOST -lt 10240 ]] &&
9598                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9599
9600         trap cleanup_test_78 EXIT
9601
9602         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9603                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9604
9605         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9606         echo "File size: $F78SIZE"
9607         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9608         for i in $(seq 1 $NSEQ); do
9609                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9610                 echo directIO rdwr round $i of $NSEQ
9611                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9612         done
9613
9614         cleanup_test_78
9615 }
9616 run_test 78 "handle large O_DIRECT writes correctly ============"
9617
9618 test_79() { # bug 12743
9619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9620
9621         wait_delete_completed
9622
9623         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9624         BKFREE=$(calc_osc_kbytes kbytesfree)
9625         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9626
9627         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9628         DFTOTAL=`echo $STRING | cut -d, -f1`
9629         DFUSED=`echo $STRING  | cut -d, -f2`
9630         DFAVAIL=`echo $STRING | cut -d, -f3`
9631         DFFREE=$(($DFTOTAL - $DFUSED))
9632
9633         ALLOWANCE=$((64 * $OSTCOUNT))
9634
9635         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9636            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9637                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9638         fi
9639         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9640            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9641                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9642         fi
9643         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9644            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9645                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9646         fi
9647 }
9648 run_test 79 "df report consistency check ======================="
9649
9650 test_80() { # bug 10718
9651         remote_ost_nodsh && skip "remote OST with nodsh"
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         # relax strong synchronous semantics for slow backends like ZFS
9655         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9656                 local soc="obdfilter.*.sync_lock_cancel"
9657                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9658
9659                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9660                 if [ -z "$save" ]; then
9661                         soc="obdfilter.*.sync_on_lock_cancel"
9662                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9663                 fi
9664
9665                 if [ "$save" != "never" ]; then
9666                         local hosts=$(comma_list $(osts_nodes))
9667
9668                         do_nodes $hosts $LCTL set_param $soc=never
9669                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9670                 fi
9671         fi
9672
9673         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9674         sync; sleep 1; sync
9675         local before=$(date +%s)
9676         cancel_lru_locks osc
9677         local after=$(date +%s)
9678         local diff=$((after - before))
9679         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9680
9681         rm -f $DIR/$tfile
9682 }
9683 run_test 80 "Page eviction is equally fast at high offsets too"
9684
9685 test_81a() { # LU-456
9686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9687         remote_ost_nodsh && skip "remote OST with nodsh"
9688
9689         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9690         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9691         do_facet ost1 lctl set_param fail_loc=0x80000228
9692
9693         # write should trigger a retry and success
9694         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9695         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9696         RC=$?
9697         if [ $RC -ne 0 ] ; then
9698                 error "write should success, but failed for $RC"
9699         fi
9700 }
9701 run_test 81a "OST should retry write when get -ENOSPC ==============="
9702
9703 test_81b() { # LU-456
9704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9705         remote_ost_nodsh && skip "remote OST with nodsh"
9706
9707         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9708         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9709         do_facet ost1 lctl set_param fail_loc=0x228
9710
9711         # write should retry several times and return -ENOSPC finally
9712         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9713         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9714         RC=$?
9715         ENOSPC=28
9716         if [ $RC -ne $ENOSPC ] ; then
9717                 error "dd should fail for -ENOSPC, but succeed."
9718         fi
9719 }
9720 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9721
9722 test_99() {
9723         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9724
9725         test_mkdir $DIR/$tdir.cvsroot
9726         chown $RUNAS_ID $DIR/$tdir.cvsroot
9727
9728         cd $TMP
9729         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9730
9731         cd /etc/init.d
9732         # some versions of cvs import exit(1) when asked to import links or
9733         # files they can't read.  ignore those files.
9734         local toignore=$(find . -type l -printf '-I %f\n' -o \
9735                          ! -perm /4 -printf '-I %f\n')
9736         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9737                 $tdir.reposname vtag rtag
9738
9739         cd $DIR
9740         test_mkdir $DIR/$tdir.reposname
9741         chown $RUNAS_ID $DIR/$tdir.reposname
9742         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9743
9744         cd $DIR/$tdir.reposname
9745         $RUNAS touch foo99
9746         $RUNAS cvs add -m 'addmsg' foo99
9747         $RUNAS cvs update
9748         $RUNAS cvs commit -m 'nomsg' foo99
9749         rm -fr $DIR/$tdir.cvsroot
9750 }
9751 run_test 99 "cvs strange file/directory operations"
9752
9753 test_100() {
9754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9755         [[ "$NETTYPE" =~ tcp ]] ||
9756                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9757         remote_ost_nodsh && skip "remote OST with nodsh"
9758         remote_mds_nodsh && skip "remote MDS with nodsh"
9759         remote_servers ||
9760                 skip "useless for local single node setup"
9761
9762         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9763                 [ "$PROT" != "tcp" ] && continue
9764                 RPORT=$(echo $REMOTE | cut -d: -f2)
9765                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9766
9767                 rc=0
9768                 LPORT=`echo $LOCAL | cut -d: -f2`
9769                 if [ $LPORT -ge 1024 ]; then
9770                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9771                         netstat -tna
9772                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9773                 fi
9774         done
9775         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9776 }
9777 run_test 100 "check local port using privileged port ==========="
9778
9779 function get_named_value()
9780 {
9781     local tag=$1
9782
9783     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9784 }
9785
9786 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9787                    awk '/^max_cached_mb/ { print $2 }')
9788
9789 cleanup_101a() {
9790         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9791         trap 0
9792 }
9793
9794 test_101a() {
9795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9796
9797         local s
9798         local discard
9799         local nreads=10000
9800         local cache_limit=32
9801
9802         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9803         trap cleanup_101a EXIT
9804         $LCTL set_param -n llite.*.read_ahead_stats=0
9805         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9806
9807         #
9808         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9809         #
9810         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9811         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9812
9813         discard=0
9814         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9815                    get_named_value 'read.but.discarded'); do
9816                         discard=$(($discard + $s))
9817         done
9818         cleanup_101a
9819
9820         $LCTL get_param osc.*-osc*.rpc_stats
9821         $LCTL get_param llite.*.read_ahead_stats
9822
9823         # Discard is generally zero, but sometimes a few random reads line up
9824         # and trigger larger readahead, which is wasted & leads to discards.
9825         if [[ $(($discard)) -gt $nreads ]]; then
9826                 error "too many ($discard) discarded pages"
9827         fi
9828         rm -f $DIR/$tfile || true
9829 }
9830 run_test 101a "check read-ahead for random reads"
9831
9832 setup_test101bc() {
9833         test_mkdir $DIR/$tdir
9834         local ssize=$1
9835         local FILE_LENGTH=$2
9836         STRIPE_OFFSET=0
9837
9838         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9839
9840         local list=$(comma_list $(osts_nodes))
9841         set_osd_param $list '' read_cache_enable 0
9842         set_osd_param $list '' writethrough_cache_enable 0
9843
9844         trap cleanup_test101bc EXIT
9845         # prepare the read-ahead file
9846         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9847
9848         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9849                                 count=$FILE_SIZE_MB 2> /dev/null
9850
9851 }
9852
9853 cleanup_test101bc() {
9854         trap 0
9855         rm -rf $DIR/$tdir
9856         rm -f $DIR/$tfile
9857
9858         local list=$(comma_list $(osts_nodes))
9859         set_osd_param $list '' read_cache_enable 1
9860         set_osd_param $list '' writethrough_cache_enable 1
9861 }
9862
9863 calc_total() {
9864         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9865 }
9866
9867 ra_check_101() {
9868         local READ_SIZE=$1
9869         local STRIPE_SIZE=$2
9870         local FILE_LENGTH=$3
9871         local RA_INC=1048576
9872         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9873         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9874                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9875         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9876                   get_named_value 'read.but.discarded' | calc_total)
9877         if [[ $DISCARD -gt $discard_limit ]]; then
9878                 $LCTL get_param llite.*.read_ahead_stats
9879                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9880         else
9881                 echo "Read-ahead success for size ${READ_SIZE}"
9882         fi
9883 }
9884
9885 test_101b() {
9886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9888
9889         local STRIPE_SIZE=1048576
9890         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9891
9892         if [ $SLOW == "yes" ]; then
9893                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9894         else
9895                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9896         fi
9897
9898         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9899
9900         # prepare the read-ahead file
9901         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9902         cancel_lru_locks osc
9903         for BIDX in 2 4 8 16 32 64 128 256
9904         do
9905                 local BSIZE=$((BIDX*4096))
9906                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9907                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9908                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9909                 $LCTL set_param -n llite.*.read_ahead_stats=0
9910                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9911                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9912                 cancel_lru_locks osc
9913                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9914         done
9915         cleanup_test101bc
9916         true
9917 }
9918 run_test 101b "check stride-io mode read-ahead ================="
9919
9920 test_101c() {
9921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9922
9923         local STRIPE_SIZE=1048576
9924         local FILE_LENGTH=$((STRIPE_SIZE*100))
9925         local nreads=10000
9926         local rsize=65536
9927         local osc_rpc_stats
9928
9929         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9930
9931         cancel_lru_locks osc
9932         $LCTL set_param osc.*.rpc_stats=0
9933         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9934         $LCTL get_param osc.*.rpc_stats
9935         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9936                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9937                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9938                 local size
9939
9940                 if [ $lines -le 20 ]; then
9941                         echo "continue debug"
9942                         continue
9943                 fi
9944                 for size in 1 2 4 8; do
9945                         local rpc=$(echo "$stats" |
9946                                     awk '($1 == "'$size':") {print $2; exit; }')
9947                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9948                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9949                 done
9950                 echo "$osc_rpc_stats check passed!"
9951         done
9952         cleanup_test101bc
9953         true
9954 }
9955 run_test 101c "check stripe_size aligned read-ahead"
9956
9957 test_101d() {
9958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9959
9960         local file=$DIR/$tfile
9961         local sz_MB=${FILESIZE_101d:-80}
9962         local ra_MB=${READAHEAD_MB:-40}
9963
9964         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9965         [ $free_MB -lt $sz_MB ] &&
9966                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9967
9968         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9969         $LFS setstripe -c -1 $file || error "setstripe failed"
9970
9971         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9972         echo Cancel LRU locks on lustre client to flush the client cache
9973         cancel_lru_locks osc
9974
9975         echo Disable read-ahead
9976         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9977         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9978         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9979         $LCTL get_param -n llite.*.max_read_ahead_mb
9980
9981         echo "Reading the test file $file with read-ahead disabled"
9982         local sz_KB=$((sz_MB * 1024 / 4))
9983         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9984         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9985         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9986                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9987
9988         echo "Cancel LRU locks on lustre client to flush the client cache"
9989         cancel_lru_locks osc
9990         echo Enable read-ahead with ${ra_MB}MB
9991         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9992
9993         echo "Reading the test file $file with read-ahead enabled"
9994         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9995                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9996
9997         echo "read-ahead disabled time read $raOFF"
9998         echo "read-ahead enabled time read $raON"
9999
10000         rm -f $file
10001         wait_delete_completed
10002
10003         # use awk for this check instead of bash because it handles decimals
10004         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10005                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10006 }
10007 run_test 101d "file read with and without read-ahead enabled"
10008
10009 test_101e() {
10010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10011
10012         local file=$DIR/$tfile
10013         local size_KB=500  #KB
10014         local count=100
10015         local bsize=1024
10016
10017         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10018         local need_KB=$((count * size_KB))
10019         [[ $free_KB -le $need_KB ]] &&
10020                 skip_env "Need free space $need_KB, have $free_KB"
10021
10022         echo "Creating $count ${size_KB}K test files"
10023         for ((i = 0; i < $count; i++)); do
10024                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10025         done
10026
10027         echo "Cancel LRU locks on lustre client to flush the client cache"
10028         cancel_lru_locks $OSC
10029
10030         echo "Reset readahead stats"
10031         $LCTL set_param -n llite.*.read_ahead_stats=0
10032
10033         for ((i = 0; i < $count; i++)); do
10034                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10035         done
10036
10037         $LCTL get_param llite.*.max_cached_mb
10038         $LCTL get_param llite.*.read_ahead_stats
10039         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10040                      get_named_value 'misses' | calc_total)
10041
10042         for ((i = 0; i < $count; i++)); do
10043                 rm -rf $file.$i 2>/dev/null
10044         done
10045
10046         #10000 means 20% reads are missing in readahead
10047         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10048 }
10049 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10050
10051 test_101f() {
10052         which iozone || skip_env "no iozone installed"
10053
10054         local old_debug=$($LCTL get_param debug)
10055         old_debug=${old_debug#*=}
10056         $LCTL set_param debug="reada mmap"
10057
10058         # create a test file
10059         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10060
10061         echo Cancel LRU locks on lustre client to flush the client cache
10062         cancel_lru_locks osc
10063
10064         echo Reset readahead stats
10065         $LCTL set_param -n llite.*.read_ahead_stats=0
10066
10067         echo mmap read the file with small block size
10068         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10069                 > /dev/null 2>&1
10070
10071         echo checking missing pages
10072         $LCTL get_param llite.*.read_ahead_stats
10073         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10074                         get_named_value 'misses' | calc_total)
10075
10076         $LCTL set_param debug="$old_debug"
10077         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10078         rm -f $DIR/$tfile
10079 }
10080 run_test 101f "check mmap read performance"
10081
10082 test_101g_brw_size_test() {
10083         local mb=$1
10084         local pages=$((mb * 1048576 / PAGE_SIZE))
10085         local file=$DIR/$tfile
10086
10087         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10088                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10089         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10090                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10091                         return 2
10092         done
10093
10094         stack_trap "rm -f $file" EXIT
10095         $LCTL set_param -n osc.*.rpc_stats=0
10096
10097         # 10 RPCs should be enough for the test
10098         local count=10
10099         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10100                 { error "dd write ${mb} MB blocks failed"; return 3; }
10101         cancel_lru_locks osc
10102         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10103                 { error "dd write ${mb} MB blocks failed"; return 4; }
10104
10105         # calculate number of full-sized read and write RPCs
10106         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10107                 sed -n '/pages per rpc/,/^$/p' |
10108                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10109                 END { print reads,writes }'))
10110         # allow one extra full-sized read RPC for async readahead
10111         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10112                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10113         [[ ${rpcs[1]} == $count ]] ||
10114                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10115 }
10116
10117 test_101g() {
10118         remote_ost_nodsh && skip "remote OST with nodsh"
10119
10120         local rpcs
10121         local osts=$(get_facets OST)
10122         local list=$(comma_list $(osts_nodes))
10123         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10124         local brw_size="obdfilter.*.brw_size"
10125
10126         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10127
10128         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10129
10130         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10131                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10132                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10133            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10134                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10135                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10136
10137                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10138                         suffix="M"
10139
10140                 if [[ $orig_mb -lt 16 ]]; then
10141                         save_lustre_params $osts "$brw_size" > $p
10142                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10143                                 error "set 16MB RPC size failed"
10144
10145                         echo "remount client to enable new RPC size"
10146                         remount_client $MOUNT || error "remount_client failed"
10147                 fi
10148
10149                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10150                 # should be able to set brw_size=12, but no rpc_stats for that
10151                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10152         fi
10153
10154         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10155
10156         if [[ $orig_mb -lt 16 ]]; then
10157                 restore_lustre_params < $p
10158                 remount_client $MOUNT || error "remount_client restore failed"
10159         fi
10160
10161         rm -f $p $DIR/$tfile
10162 }
10163 run_test 101g "Big bulk(4/16 MiB) readahead"
10164
10165 test_101h() {
10166         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10167
10168         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10169                 error "dd 70M file failed"
10170         echo Cancel LRU locks on lustre client to flush the client cache
10171         cancel_lru_locks osc
10172
10173         echo "Reset readahead stats"
10174         $LCTL set_param -n llite.*.read_ahead_stats 0
10175
10176         echo "Read 10M of data but cross 64M bundary"
10177         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10178         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10179                      get_named_value 'misses' | calc_total)
10180         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10181         rm -f $p $DIR/$tfile
10182 }
10183 run_test 101h "Readahead should cover current read window"
10184
10185 test_101i() {
10186         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10187                 error "dd 10M file failed"
10188
10189         local max_per_file_mb=$($LCTL get_param -n \
10190                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10191         cancel_lru_locks osc
10192         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10193         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10194                 error "set max_read_ahead_per_file_mb to 1 failed"
10195
10196         echo "Reset readahead stats"
10197         $LCTL set_param llite.*.read_ahead_stats=0
10198
10199         dd if=$DIR/$tfile of=/dev/null bs=2M
10200
10201         $LCTL get_param llite.*.read_ahead_stats
10202         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10203                      awk '/misses/ { print $2 }')
10204         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10205         rm -f $DIR/$tfile
10206 }
10207 run_test 101i "allow current readahead to exceed reservation"
10208
10209 test_101j() {
10210         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10211                 error "setstripe $DIR/$tfile failed"
10212         local file_size=$((1048576 * 16))
10213         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10214         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10215
10216         echo Disable read-ahead
10217         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10218
10219         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10220         for blk in $PAGE_SIZE 1048576 $file_size; do
10221                 cancel_lru_locks osc
10222                 echo "Reset readahead stats"
10223                 $LCTL set_param -n llite.*.read_ahead_stats=0
10224                 local count=$(($file_size / $blk))
10225                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10226                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10227                              get_named_value 'failed.to.fast.read' | calc_total)
10228                 $LCTL get_param -n llite.*.read_ahead_stats
10229                 [ $miss -eq $count ] || error "expected $count got $miss"
10230         done
10231
10232         rm -f $p $DIR/$tfile
10233 }
10234 run_test 101j "A complete read block should be submitted when no RA"
10235
10236 setup_test102() {
10237         test_mkdir $DIR/$tdir
10238         chown $RUNAS_ID $DIR/$tdir
10239         STRIPE_SIZE=65536
10240         STRIPE_OFFSET=1
10241         STRIPE_COUNT=$OSTCOUNT
10242         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10243
10244         trap cleanup_test102 EXIT
10245         cd $DIR
10246         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10247         cd $DIR/$tdir
10248         for num in 1 2 3 4; do
10249                 for count in $(seq 1 $STRIPE_COUNT); do
10250                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10251                                 local size=`expr $STRIPE_SIZE \* $num`
10252                                 local file=file"$num-$idx-$count"
10253                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10254                         done
10255                 done
10256         done
10257
10258         cd $DIR
10259         $1 tar cf $TMP/f102.tar $tdir --xattrs
10260 }
10261
10262 cleanup_test102() {
10263         trap 0
10264         rm -f $TMP/f102.tar
10265         rm -rf $DIR/d0.sanity/d102
10266 }
10267
10268 test_102a() {
10269         [ "$UID" != 0 ] && skip "must run as root"
10270         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10271                 skip_env "must have user_xattr"
10272
10273         [ -z "$(which setfattr 2>/dev/null)" ] &&
10274                 skip_env "could not find setfattr"
10275
10276         local testfile=$DIR/$tfile
10277
10278         touch $testfile
10279         echo "set/get xattr..."
10280         setfattr -n trusted.name1 -v value1 $testfile ||
10281                 error "setfattr -n trusted.name1=value1 $testfile failed"
10282         getfattr -n trusted.name1 $testfile 2> /dev/null |
10283           grep "trusted.name1=.value1" ||
10284                 error "$testfile missing trusted.name1=value1"
10285
10286         setfattr -n user.author1 -v author1 $testfile ||
10287                 error "setfattr -n user.author1=author1 $testfile failed"
10288         getfattr -n user.author1 $testfile 2> /dev/null |
10289           grep "user.author1=.author1" ||
10290                 error "$testfile missing trusted.author1=author1"
10291
10292         echo "listxattr..."
10293         setfattr -n trusted.name2 -v value2 $testfile ||
10294                 error "$testfile unable to set trusted.name2"
10295         setfattr -n trusted.name3 -v value3 $testfile ||
10296                 error "$testfile unable to set trusted.name3"
10297         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10298             grep "trusted.name" | wc -l) -eq 3 ] ||
10299                 error "$testfile missing 3 trusted.name xattrs"
10300
10301         setfattr -n user.author2 -v author2 $testfile ||
10302                 error "$testfile unable to set user.author2"
10303         setfattr -n user.author3 -v author3 $testfile ||
10304                 error "$testfile unable to set user.author3"
10305         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10306             grep "user.author" | wc -l) -eq 3 ] ||
10307                 error "$testfile missing 3 user.author xattrs"
10308
10309         echo "remove xattr..."
10310         setfattr -x trusted.name1 $testfile ||
10311                 error "$testfile error deleting trusted.name1"
10312         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10313                 error "$testfile did not delete trusted.name1 xattr"
10314
10315         setfattr -x user.author1 $testfile ||
10316                 error "$testfile error deleting user.author1"
10317         echo "set lustre special xattr ..."
10318         $LFS setstripe -c1 $testfile
10319         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10320                 awk -F "=" '/trusted.lov/ { print $2 }' )
10321         setfattr -n "trusted.lov" -v $lovea $testfile ||
10322                 error "$testfile doesn't ignore setting trusted.lov again"
10323         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10324                 error "$testfile allow setting invalid trusted.lov"
10325         rm -f $testfile
10326 }
10327 run_test 102a "user xattr test =================================="
10328
10329 check_102b_layout() {
10330         local layout="$*"
10331         local testfile=$DIR/$tfile
10332
10333         echo "test layout '$layout'"
10334         $LFS setstripe $layout $testfile || error "setstripe failed"
10335         $LFS getstripe -y $testfile
10336
10337         echo "get/set/list trusted.lov xattr ..." # b=10930
10338         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10339         [[ "$value" =~ "trusted.lov" ]] ||
10340                 error "can't get trusted.lov from $testfile"
10341         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10342                 error "getstripe failed"
10343
10344         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10345
10346         value=$(cut -d= -f2 <<<$value)
10347         # LU-13168: truncated xattr should fail if short lov_user_md header
10348         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10349                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10350         for len in $lens; do
10351                 echo "setfattr $len $testfile.2"
10352                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10353                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10354         done
10355         local stripe_size=$($LFS getstripe -S $testfile.2)
10356         local stripe_count=$($LFS getstripe -c $testfile.2)
10357         [[ $stripe_size -eq 65536 ]] ||
10358                 error "stripe size $stripe_size != 65536"
10359         [[ $stripe_count -eq $stripe_count_orig ]] ||
10360                 error "stripe count $stripe_count != $stripe_count_orig"
10361         rm $testfile $testfile.2
10362 }
10363
10364 test_102b() {
10365         [ -z "$(which setfattr 2>/dev/null)" ] &&
10366                 skip_env "could not find setfattr"
10367         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10368
10369         # check plain layout
10370         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10371
10372         # and also check composite layout
10373         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10374
10375 }
10376 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10377
10378 test_102c() {
10379         [ -z "$(which setfattr 2>/dev/null)" ] &&
10380                 skip_env "could not find setfattr"
10381         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10382
10383         # b10930: get/set/list lustre.lov xattr
10384         echo "get/set/list lustre.lov xattr ..."
10385         test_mkdir $DIR/$tdir
10386         chown $RUNAS_ID $DIR/$tdir
10387         local testfile=$DIR/$tdir/$tfile
10388         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10389                 error "setstripe failed"
10390         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10391                 error "getstripe failed"
10392         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10393         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10394
10395         local testfile2=${testfile}2
10396         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10397                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10398
10399         $RUNAS $MCREATE $testfile2
10400         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10401         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10402         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10403         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10404         [ $stripe_count -eq $STRIPECOUNT ] ||
10405                 error "stripe count $stripe_count != $STRIPECOUNT"
10406 }
10407 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10408
10409 compare_stripe_info1() {
10410         local stripe_index_all_zero=true
10411
10412         for num in 1 2 3 4; do
10413                 for count in $(seq 1 $STRIPE_COUNT); do
10414                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10415                                 local size=$((STRIPE_SIZE * num))
10416                                 local file=file"$num-$offset-$count"
10417                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10418                                 [[ $stripe_size -ne $size ]] &&
10419                                     error "$file: size $stripe_size != $size"
10420                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10421                                 # allow fewer stripes to be created, ORI-601
10422                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10423                                     error "$file: count $stripe_count != $count"
10424                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10425                                 [[ $stripe_index -ne 0 ]] &&
10426                                         stripe_index_all_zero=false
10427                         done
10428                 done
10429         done
10430         $stripe_index_all_zero &&
10431                 error "all files are being extracted starting from OST index 0"
10432         return 0
10433 }
10434
10435 have_xattrs_include() {
10436         tar --help | grep -q xattrs-include &&
10437                 echo --xattrs-include="lustre.*"
10438 }
10439
10440 test_102d() {
10441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10443
10444         XINC=$(have_xattrs_include)
10445         setup_test102
10446         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10447         cd $DIR/$tdir/$tdir
10448         compare_stripe_info1
10449 }
10450 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10451
10452 test_102f() {
10453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10454         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10455
10456         XINC=$(have_xattrs_include)
10457         setup_test102
10458         test_mkdir $DIR/$tdir.restore
10459         cd $DIR
10460         tar cf - --xattrs $tdir | tar xf - \
10461                 -C $DIR/$tdir.restore --xattrs $XINC
10462         cd $DIR/$tdir.restore/$tdir
10463         compare_stripe_info1
10464 }
10465 run_test 102f "tar copy files, not keep osts"
10466
10467 grow_xattr() {
10468         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10469                 skip "must have user_xattr"
10470         [ -z "$(which setfattr 2>/dev/null)" ] &&
10471                 skip_env "could not find setfattr"
10472         [ -z "$(which getfattr 2>/dev/null)" ] &&
10473                 skip_env "could not find getfattr"
10474
10475         local xsize=${1:-1024}  # in bytes
10476         local file=$DIR/$tfile
10477         local value="$(generate_string $xsize)"
10478         local xbig=trusted.big
10479         local toobig=$2
10480
10481         touch $file
10482         log "save $xbig on $file"
10483         if [ -z "$toobig" ]
10484         then
10485                 setfattr -n $xbig -v $value $file ||
10486                         error "saving $xbig on $file failed"
10487         else
10488                 setfattr -n $xbig -v $value $file &&
10489                         error "saving $xbig on $file succeeded"
10490                 return 0
10491         fi
10492
10493         local orig=$(get_xattr_value $xbig $file)
10494         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10495
10496         local xsml=trusted.sml
10497         log "save $xsml on $file"
10498         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10499
10500         local new=$(get_xattr_value $xbig $file)
10501         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10502
10503         log "grow $xsml on $file"
10504         setfattr -n $xsml -v "$value" $file ||
10505                 error "growing $xsml on $file failed"
10506
10507         new=$(get_xattr_value $xbig $file)
10508         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10509         log "$xbig still valid after growing $xsml"
10510
10511         rm -f $file
10512 }
10513
10514 test_102h() { # bug 15777
10515         grow_xattr 1024
10516 }
10517 run_test 102h "grow xattr from inside inode to external block"
10518
10519 test_102ha() {
10520         large_xattr_enabled || skip_env "ea_inode feature disabled"
10521
10522         echo "setting xattr of max xattr size: $(max_xattr_size)"
10523         grow_xattr $(max_xattr_size)
10524
10525         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10526         echo "This should fail:"
10527         grow_xattr $(($(max_xattr_size) + 10)) 1
10528 }
10529 run_test 102ha "grow xattr from inside inode to external inode"
10530
10531 test_102i() { # bug 17038
10532         [ -z "$(which getfattr 2>/dev/null)" ] &&
10533                 skip "could not find getfattr"
10534
10535         touch $DIR/$tfile
10536         ln -s $DIR/$tfile $DIR/${tfile}link
10537         getfattr -n trusted.lov $DIR/$tfile ||
10538                 error "lgetxattr on $DIR/$tfile failed"
10539         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10540                 grep -i "no such attr" ||
10541                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10542         rm -f $DIR/$tfile $DIR/${tfile}link
10543 }
10544 run_test 102i "lgetxattr test on symbolic link ============"
10545
10546 test_102j() {
10547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10548         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10549
10550         XINC=$(have_xattrs_include)
10551         setup_test102 "$RUNAS"
10552         chown $RUNAS_ID $DIR/$tdir
10553         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10554         cd $DIR/$tdir/$tdir
10555         compare_stripe_info1 "$RUNAS"
10556 }
10557 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10558
10559 test_102k() {
10560         [ -z "$(which setfattr 2>/dev/null)" ] &&
10561                 skip "could not find setfattr"
10562
10563         touch $DIR/$tfile
10564         # b22187 just check that does not crash for regular file.
10565         setfattr -n trusted.lov $DIR/$tfile
10566         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10567         local test_kdir=$DIR/$tdir
10568         test_mkdir $test_kdir
10569         local default_size=$($LFS getstripe -S $test_kdir)
10570         local default_count=$($LFS getstripe -c $test_kdir)
10571         local default_offset=$($LFS getstripe -i $test_kdir)
10572         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10573                 error 'dir setstripe failed'
10574         setfattr -n trusted.lov $test_kdir
10575         local stripe_size=$($LFS getstripe -S $test_kdir)
10576         local stripe_count=$($LFS getstripe -c $test_kdir)
10577         local stripe_offset=$($LFS getstripe -i $test_kdir)
10578         [ $stripe_size -eq $default_size ] ||
10579                 error "stripe size $stripe_size != $default_size"
10580         [ $stripe_count -eq $default_count ] ||
10581                 error "stripe count $stripe_count != $default_count"
10582         [ $stripe_offset -eq $default_offset ] ||
10583                 error "stripe offset $stripe_offset != $default_offset"
10584         rm -rf $DIR/$tfile $test_kdir
10585 }
10586 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10587
10588 test_102l() {
10589         [ -z "$(which getfattr 2>/dev/null)" ] &&
10590                 skip "could not find getfattr"
10591
10592         # LU-532 trusted. xattr is invisible to non-root
10593         local testfile=$DIR/$tfile
10594
10595         touch $testfile
10596
10597         echo "listxattr as user..."
10598         chown $RUNAS_ID $testfile
10599         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10600             grep -q "trusted" &&
10601                 error "$testfile trusted xattrs are user visible"
10602
10603         return 0;
10604 }
10605 run_test 102l "listxattr size test =================================="
10606
10607 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10608         local path=$DIR/$tfile
10609         touch $path
10610
10611         listxattr_size_check $path || error "listattr_size_check $path failed"
10612 }
10613 run_test 102m "Ensure listxattr fails on small bufffer ========"
10614
10615 cleanup_test102
10616
10617 getxattr() { # getxattr path name
10618         # Return the base64 encoding of the value of xattr name on path.
10619         local path=$1
10620         local name=$2
10621
10622         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10623         # file: $path
10624         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10625         #
10626         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10627
10628         getfattr --absolute-names --encoding=base64 --name=$name $path |
10629                 awk -F= -v name=$name '$1 == name {
10630                         print substr($0, index($0, "=") + 1);
10631         }'
10632 }
10633
10634 test_102n() { # LU-4101 mdt: protect internal xattrs
10635         [ -z "$(which setfattr 2>/dev/null)" ] &&
10636                 skip "could not find setfattr"
10637         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10638         then
10639                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10640         fi
10641
10642         local file0=$DIR/$tfile.0
10643         local file1=$DIR/$tfile.1
10644         local xattr0=$TMP/$tfile.0
10645         local xattr1=$TMP/$tfile.1
10646         local namelist="lov lma lmv link fid version som hsm"
10647         local name
10648         local value
10649
10650         rm -rf $file0 $file1 $xattr0 $xattr1
10651         touch $file0 $file1
10652
10653         # Get 'before' xattrs of $file1.
10654         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10655
10656         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10657                 namelist+=" lfsck_namespace"
10658         for name in $namelist; do
10659                 # Try to copy xattr from $file0 to $file1.
10660                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10661
10662                 setfattr --name=trusted.$name --value="$value" $file1 ||
10663                         error "setxattr 'trusted.$name' failed"
10664
10665                 # Try to set a garbage xattr.
10666                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10667
10668                 if [[ x$name == "xlov" ]]; then
10669                         setfattr --name=trusted.lov --value="$value" $file1 &&
10670                         error "setxattr invalid 'trusted.lov' success"
10671                 else
10672                         setfattr --name=trusted.$name --value="$value" $file1 ||
10673                                 error "setxattr invalid 'trusted.$name' failed"
10674                 fi
10675
10676                 # Try to remove the xattr from $file1. We don't care if this
10677                 # appears to succeed or fail, we just don't want there to be
10678                 # any changes or crashes.
10679                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10680         done
10681
10682         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10683         then
10684                 name="lfsck_ns"
10685                 # Try to copy xattr from $file0 to $file1.
10686                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10687
10688                 setfattr --name=trusted.$name --value="$value" $file1 ||
10689                         error "setxattr 'trusted.$name' failed"
10690
10691                 # Try to set a garbage xattr.
10692                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10693
10694                 setfattr --name=trusted.$name --value="$value" $file1 ||
10695                         error "setxattr 'trusted.$name' failed"
10696
10697                 # Try to remove the xattr from $file1. We don't care if this
10698                 # appears to succeed or fail, we just don't want there to be
10699                 # any changes or crashes.
10700                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10701         fi
10702
10703         # Get 'after' xattrs of file1.
10704         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10705
10706         if ! diff $xattr0 $xattr1; then
10707                 error "before and after xattrs of '$file1' differ"
10708         fi
10709
10710         rm -rf $file0 $file1 $xattr0 $xattr1
10711
10712         return 0
10713 }
10714 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10715
10716 test_102p() { # LU-4703 setxattr did not check ownership
10717         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10718                 skip "MDS needs to be at least 2.5.56"
10719
10720         local testfile=$DIR/$tfile
10721
10722         touch $testfile
10723
10724         echo "setfacl as user..."
10725         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10726         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10727
10728         echo "setfattr as user..."
10729         setfacl -m "u:$RUNAS_ID:---" $testfile
10730         $RUNAS setfattr -x system.posix_acl_access $testfile
10731         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10732 }
10733 run_test 102p "check setxattr(2) correctly fails without permission"
10734
10735 test_102q() {
10736         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10737                 skip "MDS needs to be at least 2.6.92"
10738
10739         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10740 }
10741 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10742
10743 test_102r() {
10744         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10745                 skip "MDS needs to be at least 2.6.93"
10746
10747         touch $DIR/$tfile || error "touch"
10748         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10749         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10750         rm $DIR/$tfile || error "rm"
10751
10752         #normal directory
10753         mkdir -p $DIR/$tdir || error "mkdir"
10754         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10755         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10756         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10757                 error "$testfile error deleting user.author1"
10758         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10759                 grep "user.$(basename $tdir)" &&
10760                 error "$tdir did not delete user.$(basename $tdir)"
10761         rmdir $DIR/$tdir || error "rmdir"
10762
10763         #striped directory
10764         test_mkdir $DIR/$tdir
10765         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10766         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10767         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10768                 error "$testfile error deleting user.author1"
10769         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10770                 grep "user.$(basename $tdir)" &&
10771                 error "$tdir did not delete user.$(basename $tdir)"
10772         rmdir $DIR/$tdir || error "rm striped dir"
10773 }
10774 run_test 102r "set EAs with empty values"
10775
10776 test_102s() {
10777         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10778                 skip "MDS needs to be at least 2.11.52"
10779
10780         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10781
10782         save_lustre_params client "llite.*.xattr_cache" > $save
10783
10784         for cache in 0 1; do
10785                 lctl set_param llite.*.xattr_cache=$cache
10786
10787                 rm -f $DIR/$tfile
10788                 touch $DIR/$tfile || error "touch"
10789                 for prefix in lustre security system trusted user; do
10790                         # Note getxattr() may fail with 'Operation not
10791                         # supported' or 'No such attribute' depending
10792                         # on prefix and cache.
10793                         getfattr -n $prefix.n102s $DIR/$tfile &&
10794                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10795                 done
10796         done
10797
10798         restore_lustre_params < $save
10799 }
10800 run_test 102s "getting nonexistent xattrs should fail"
10801
10802 test_102t() {
10803         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10804                 skip "MDS needs to be at least 2.11.52"
10805
10806         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10807
10808         save_lustre_params client "llite.*.xattr_cache" > $save
10809
10810         for cache in 0 1; do
10811                 lctl set_param llite.*.xattr_cache=$cache
10812
10813                 for buf_size in 0 256; do
10814                         rm -f $DIR/$tfile
10815                         touch $DIR/$tfile || error "touch"
10816                         setfattr -n user.multiop $DIR/$tfile
10817                         $MULTIOP $DIR/$tfile oa$buf_size ||
10818                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10819                 done
10820         done
10821
10822         restore_lustre_params < $save
10823 }
10824 run_test 102t "zero length xattr values handled correctly"
10825
10826 run_acl_subtest()
10827 {
10828     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10829     return $?
10830 }
10831
10832 test_103a() {
10833         [ "$UID" != 0 ] && skip "must run as root"
10834         $GSS && skip_env "could not run under gss"
10835         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10836                 skip_env "must have acl enabled"
10837         [ -z "$(which setfacl 2>/dev/null)" ] &&
10838                 skip_env "could not find setfacl"
10839         remote_mds_nodsh && skip "remote MDS with nodsh"
10840
10841         gpasswd -a daemon bin                           # LU-5641
10842         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10843
10844         declare -a identity_old
10845
10846         for num in $(seq $MDSCOUNT); do
10847                 switch_identity $num true || identity_old[$num]=$?
10848         done
10849
10850         SAVE_UMASK=$(umask)
10851         umask 0022
10852         mkdir -p $DIR/$tdir
10853         cd $DIR/$tdir
10854
10855         echo "performing cp ..."
10856         run_acl_subtest cp || error "run_acl_subtest cp failed"
10857         echo "performing getfacl-noacl..."
10858         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10859         echo "performing misc..."
10860         run_acl_subtest misc || error  "misc test failed"
10861         echo "performing permissions..."
10862         run_acl_subtest permissions || error "permissions failed"
10863         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10864         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10865                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10866                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10867         then
10868                 echo "performing permissions xattr..."
10869                 run_acl_subtest permissions_xattr ||
10870                         error "permissions_xattr failed"
10871         fi
10872         echo "performing setfacl..."
10873         run_acl_subtest setfacl || error  "setfacl test failed"
10874
10875         # inheritance test got from HP
10876         echo "performing inheritance..."
10877         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10878         chmod +x make-tree || error "chmod +x failed"
10879         run_acl_subtest inheritance || error "inheritance test failed"
10880         rm -f make-tree
10881
10882         echo "LU-974 ignore umask when acl is enabled..."
10883         run_acl_subtest 974 || error "LU-974 umask test failed"
10884         if [ $MDSCOUNT -ge 2 ]; then
10885                 run_acl_subtest 974_remote ||
10886                         error "LU-974 umask test failed under remote dir"
10887         fi
10888
10889         echo "LU-2561 newly created file is same size as directory..."
10890         if [ "$mds1_FSTYPE" != "zfs" ]; then
10891                 run_acl_subtest 2561 || error "LU-2561 test failed"
10892         else
10893                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10894         fi
10895
10896         run_acl_subtest 4924 || error "LU-4924 test failed"
10897
10898         cd $SAVE_PWD
10899         umask $SAVE_UMASK
10900
10901         for num in $(seq $MDSCOUNT); do
10902                 if [ "${identity_old[$num]}" = 1 ]; then
10903                         switch_identity $num false || identity_old[$num]=$?
10904                 fi
10905         done
10906 }
10907 run_test 103a "acl test"
10908
10909 test_103b() {
10910         declare -a pids
10911         local U
10912
10913         for U in {0..511}; do
10914                 {
10915                 local O=$(printf "%04o" $U)
10916
10917                 umask $(printf "%04o" $((511 ^ $O)))
10918                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10919                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10920
10921                 (( $S == ($O & 0666) )) ||
10922                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10923
10924                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10925                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10926                 (( $S == ($O & 0666) )) ||
10927                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10928
10929                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10930                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10931                 (( $S == ($O & 0666) )) ||
10932                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10933                 rm -f $DIR/$tfile.[smp]$0
10934                 } &
10935                 local pid=$!
10936
10937                 # limit the concurrently running threads to 64. LU-11878
10938                 local idx=$((U % 64))
10939                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10940                 pids[idx]=$pid
10941         done
10942         wait
10943 }
10944 run_test 103b "umask lfs setstripe"
10945
10946 test_103c() {
10947         mkdir -p $DIR/$tdir
10948         cp -rp $DIR/$tdir $DIR/$tdir.bak
10949
10950         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10951                 error "$DIR/$tdir shouldn't contain default ACL"
10952         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10953                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10954         true
10955 }
10956 run_test 103c "'cp -rp' won't set empty acl"
10957
10958 test_103e() {
10959         local numacl
10960         local fileacl
10961         local saved_debug=$($LCTL get_param -n debug)
10962
10963         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10964                 skip "MDS needs to be at least 2.14.0"
10965
10966         large_xattr_enabled || skip_env "ea_inode feature disabled"
10967
10968         mkdir -p $DIR/$tdir
10969         # add big LOV EA to cause reply buffer overflow earlier
10970         $LFS setstripe -C 1000 $DIR/$tdir
10971         lctl set_param mdc.*-mdc*.stats=clear
10972
10973         $LCTL set_param debug=0
10974         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10975         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10976
10977         # add a large number of default ACLs (expect 8000+ for 2.13+)
10978         for U in {2..7000}; do
10979                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10980                         error "Able to add just $U default ACLs"
10981         done
10982         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10983         echo "$numacl default ACLs created"
10984
10985         stat $DIR/$tdir || error "Cannot stat directory"
10986         # check file creation
10987         touch $DIR/$tdir/$tfile ||
10988                 error "failed to create $tfile with $numacl default ACLs"
10989         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10990         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10991         echo "$fileacl ACLs were inherited"
10992         (( $fileacl == $numacl )) ||
10993                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10994         # check that new ACLs creation adds new ACLs to inherited ACLs
10995         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10996                 error "Cannot set new ACL"
10997         numacl=$((numacl + 1))
10998         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10999         (( $fileacl == $numacl )) ||
11000                 error "failed to add new ACL: $fileacl != $numacl as expected"
11001         # adds more ACLs to a file to reach their maximum at 8000+
11002         numacl=0
11003         for U in {20000..25000}; do
11004                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11005                 numacl=$((numacl + 1))
11006         done
11007         echo "Added $numacl more ACLs to the file"
11008         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11009         echo "Total $fileacl ACLs in file"
11010         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11011         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11012         rmdir $DIR/$tdir || error "Cannot remove directory"
11013 }
11014 run_test 103e "inheritance of big amount of default ACLs"
11015
11016 test_103f() {
11017         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11018                 skip "MDS needs to be at least 2.14.51"
11019
11020         large_xattr_enabled || skip_env "ea_inode feature disabled"
11021
11022         # enable changelog to consume more internal MDD buffers
11023         changelog_register
11024
11025         mkdir -p $DIR/$tdir
11026         # add big LOV EA
11027         $LFS setstripe -C 1000 $DIR/$tdir
11028         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11029         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11030         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11031         rmdir $DIR/$tdir || error "Cannot remove directory"
11032 }
11033 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11034
11035 test_104a() {
11036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11037
11038         touch $DIR/$tfile
11039         lfs df || error "lfs df failed"
11040         lfs df -ih || error "lfs df -ih failed"
11041         lfs df -h $DIR || error "lfs df -h $DIR failed"
11042         lfs df -i $DIR || error "lfs df -i $DIR failed"
11043         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11044         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11045
11046         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11047         lctl --device %$OSC deactivate
11048         lfs df || error "lfs df with deactivated OSC failed"
11049         lctl --device %$OSC activate
11050         # wait the osc back to normal
11051         wait_osc_import_ready client ost
11052
11053         lfs df || error "lfs df with reactivated OSC failed"
11054         rm -f $DIR/$tfile
11055 }
11056 run_test 104a "lfs df [-ih] [path] test ========================="
11057
11058 test_104b() {
11059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11060         [ $RUNAS_ID -eq $UID ] &&
11061                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11062
11063         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11064                         grep "Permission denied" | wc -l)))
11065         if [ $denied_cnt -ne 0 ]; then
11066                 error "lfs check servers test failed"
11067         fi
11068 }
11069 run_test 104b "$RUNAS lfs check servers test ===================="
11070
11071 #
11072 # Verify $1 is within range of $2.
11073 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11074 # $1 is <= 2% of $2. Else Fail.
11075 #
11076 value_in_range() {
11077         # Strip all units (M, G, T)
11078         actual=$(echo $1 | tr -d A-Z)
11079         expect=$(echo $2 | tr -d A-Z)
11080
11081         expect_lo=$(($expect * 98 / 100)) # 2% below
11082         expect_hi=$(($expect * 102 / 100)) # 2% above
11083
11084         # permit 2% drift above and below
11085         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11086 }
11087
11088 test_104c() {
11089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11090         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11091
11092         local ost_param="osd-zfs.$FSNAME-OST0000."
11093         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11094         local ofacets=$(get_facets OST)
11095         local mfacets=$(get_facets MDS)
11096         local saved_ost_blocks=
11097         local saved_mdt_blocks=
11098
11099         echo "Before recordsize change"
11100         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11101         df=($(df -h | grep "/mnt/lustre"$))
11102
11103         # For checking.
11104         echo "lfs output : ${lfs_df[*]}"
11105         echo "df  output : ${df[*]}"
11106
11107         for facet in ${ofacets//,/ }; do
11108                 if [ -z $saved_ost_blocks ]; then
11109                         saved_ost_blocks=$(do_facet $facet \
11110                                 lctl get_param -n $ost_param.blocksize)
11111                         echo "OST Blocksize: $saved_ost_blocks"
11112                 fi
11113                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11114                 do_facet $facet zfs set recordsize=32768 $ost
11115         done
11116
11117         # BS too small. Sufficient for functional testing.
11118         for facet in ${mfacets//,/ }; do
11119                 if [ -z $saved_mdt_blocks ]; then
11120                         saved_mdt_blocks=$(do_facet $facet \
11121                                 lctl get_param -n $mdt_param.blocksize)
11122                         echo "MDT Blocksize: $saved_mdt_blocks"
11123                 fi
11124                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11125                 do_facet $facet zfs set recordsize=32768 $mdt
11126         done
11127
11128         # Give new values chance to reflect change
11129         sleep 2
11130
11131         echo "After recordsize change"
11132         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11133         df_after=($(df -h | grep "/mnt/lustre"$))
11134
11135         # For checking.
11136         echo "lfs output : ${lfs_df_after[*]}"
11137         echo "df  output : ${df_after[*]}"
11138
11139         # Verify lfs df
11140         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11141                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11142         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11143                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11144         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11145                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11146
11147         # Verify df
11148         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11149                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11150         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11151                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11152         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11153                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11154
11155         # Restore MDT recordize back to original
11156         for facet in ${mfacets//,/ }; do
11157                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11158                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11159         done
11160
11161         # Restore OST recordize back to original
11162         for facet in ${ofacets//,/ }; do
11163                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11164                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11165         done
11166
11167         return 0
11168 }
11169 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11170
11171 test_105a() {
11172         # doesn't work on 2.4 kernels
11173         touch $DIR/$tfile
11174         if $(flock_is_enabled); then
11175                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11176         else
11177                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11178         fi
11179         rm -f $DIR/$tfile
11180 }
11181 run_test 105a "flock when mounted without -o flock test ========"
11182
11183 test_105b() {
11184         touch $DIR/$tfile
11185         if $(flock_is_enabled); then
11186                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11187         else
11188                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11189         fi
11190         rm -f $DIR/$tfile
11191 }
11192 run_test 105b "fcntl when mounted without -o flock test ========"
11193
11194 test_105c() {
11195         touch $DIR/$tfile
11196         if $(flock_is_enabled); then
11197                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11198         else
11199                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11200         fi
11201         rm -f $DIR/$tfile
11202 }
11203 run_test 105c "lockf when mounted without -o flock test"
11204
11205 test_105d() { # bug 15924
11206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11207
11208         test_mkdir $DIR/$tdir
11209         flock_is_enabled || skip_env "mount w/o flock enabled"
11210         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11211         $LCTL set_param fail_loc=0x80000315
11212         flocks_test 2 $DIR/$tdir
11213 }
11214 run_test 105d "flock race (should not freeze) ========"
11215
11216 test_105e() { # bug 22660 && 22040
11217         flock_is_enabled || skip_env "mount w/o flock enabled"
11218
11219         touch $DIR/$tfile
11220         flocks_test 3 $DIR/$tfile
11221 }
11222 run_test 105e "Two conflicting flocks from same process"
11223
11224 test_106() { #bug 10921
11225         test_mkdir $DIR/$tdir
11226         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11227         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11228 }
11229 run_test 106 "attempt exec of dir followed by chown of that dir"
11230
11231 test_107() {
11232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11233
11234         CDIR=`pwd`
11235         local file=core
11236
11237         cd $DIR
11238         rm -f $file
11239
11240         local save_pattern=$(sysctl -n kernel.core_pattern)
11241         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11242         sysctl -w kernel.core_pattern=$file
11243         sysctl -w kernel.core_uses_pid=0
11244
11245         ulimit -c unlimited
11246         sleep 60 &
11247         SLEEPPID=$!
11248
11249         sleep 1
11250
11251         kill -s 11 $SLEEPPID
11252         wait $SLEEPPID
11253         if [ -e $file ]; then
11254                 size=`stat -c%s $file`
11255                 [ $size -eq 0 ] && error "Fail to create core file $file"
11256         else
11257                 error "Fail to create core file $file"
11258         fi
11259         rm -f $file
11260         sysctl -w kernel.core_pattern=$save_pattern
11261         sysctl -w kernel.core_uses_pid=$save_uses_pid
11262         cd $CDIR
11263 }
11264 run_test 107 "Coredump on SIG"
11265
11266 test_110() {
11267         test_mkdir $DIR/$tdir
11268         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11269         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11270                 error "mkdir with 256 char should fail, but did not"
11271         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11272                 error "create with 255 char failed"
11273         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11274                 error "create with 256 char should fail, but did not"
11275
11276         ls -l $DIR/$tdir
11277         rm -rf $DIR/$tdir
11278 }
11279 run_test 110 "filename length checking"
11280
11281 #
11282 # Purpose: To verify dynamic thread (OSS) creation.
11283 #
11284 test_115() {
11285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11286         remote_ost_nodsh && skip "remote OST with nodsh"
11287
11288         # Lustre does not stop service threads once they are started.
11289         # Reset number of running threads to default.
11290         stopall
11291         setupall
11292
11293         local OSTIO_pre
11294         local save_params="$TMP/sanity-$TESTNAME.parameters"
11295
11296         # Get ll_ost_io count before I/O
11297         OSTIO_pre=$(do_facet ost1 \
11298                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11299         # Exit if lustre is not running (ll_ost_io not running).
11300         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11301
11302         echo "Starting with $OSTIO_pre threads"
11303         local thread_max=$((OSTIO_pre * 2))
11304         local rpc_in_flight=$((thread_max * 2))
11305         # Number of I/O Process proposed to be started.
11306         local nfiles
11307         local facets=$(get_facets OST)
11308
11309         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11310         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11311
11312         # Set in_flight to $rpc_in_flight
11313         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11314                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11315         nfiles=${rpc_in_flight}
11316         # Set ost thread_max to $thread_max
11317         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11318
11319         # 5 Minutes should be sufficient for max number of OSS
11320         # threads(thread_max) to be created.
11321         local timeout=300
11322
11323         # Start I/O.
11324         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11325         test_mkdir $DIR/$tdir
11326         for i in $(seq $nfiles); do
11327                 local file=$DIR/$tdir/${tfile}-$i
11328                 $LFS setstripe -c -1 -i 0 $file
11329                 ($WTL $file $timeout)&
11330         done
11331
11332         # I/O Started - Wait for thread_started to reach thread_max or report
11333         # error if thread_started is more than thread_max.
11334         echo "Waiting for thread_started to reach thread_max"
11335         local thread_started=0
11336         local end_time=$((SECONDS + timeout))
11337
11338         while [ $SECONDS -le $end_time ] ; do
11339                 echo -n "."
11340                 # Get ost i/o thread_started count.
11341                 thread_started=$(do_facet ost1 \
11342                         "$LCTL get_param \
11343                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11344                 # Break out if thread_started is equal/greater than thread_max
11345                 if [[ $thread_started -ge $thread_max ]]; then
11346                         echo ll_ost_io thread_started $thread_started, \
11347                                 equal/greater than thread_max $thread_max
11348                         break
11349                 fi
11350                 sleep 1
11351         done
11352
11353         # Cleanup - We have the numbers, Kill i/o jobs if running.
11354         jobcount=($(jobs -p))
11355         for i in $(seq 0 $((${#jobcount[@]}-1)))
11356         do
11357                 kill -9 ${jobcount[$i]}
11358                 if [ $? -ne 0 ] ; then
11359                         echo Warning: \
11360                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11361                 fi
11362         done
11363
11364         # Cleanup files left by WTL binary.
11365         for i in $(seq $nfiles); do
11366                 local file=$DIR/$tdir/${tfile}-$i
11367                 rm -rf $file
11368                 if [ $? -ne 0 ] ; then
11369                         echo "Warning: Failed to delete file $file"
11370                 fi
11371         done
11372
11373         restore_lustre_params <$save_params
11374         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11375
11376         # Error out if no new thread has started or Thread started is greater
11377         # than thread max.
11378         if [[ $thread_started -le $OSTIO_pre ||
11379                         $thread_started -gt $thread_max ]]; then
11380                 error "ll_ost_io: thread_started $thread_started" \
11381                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11382                       "No new thread started or thread started greater " \
11383                       "than thread_max."
11384         fi
11385 }
11386 run_test 115 "verify dynamic thread creation===================="
11387
11388 free_min_max () {
11389         wait_delete_completed
11390         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11391         echo "OST kbytes available: ${AVAIL[@]}"
11392         MAXV=${AVAIL[0]}
11393         MAXI=0
11394         MINV=${AVAIL[0]}
11395         MINI=0
11396         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11397                 #echo OST $i: ${AVAIL[i]}kb
11398                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11399                         MAXV=${AVAIL[i]}
11400                         MAXI=$i
11401                 fi
11402                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11403                         MINV=${AVAIL[i]}
11404                         MINI=$i
11405                 fi
11406         done
11407         echo "Min free space: OST $MINI: $MINV"
11408         echo "Max free space: OST $MAXI: $MAXV"
11409 }
11410
11411 test_116a() { # was previously test_116()
11412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11413         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11414         remote_mds_nodsh && skip "remote MDS with nodsh"
11415
11416         echo -n "Free space priority "
11417         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11418                 head -n1
11419         declare -a AVAIL
11420         free_min_max
11421
11422         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11423         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11424         trap simple_cleanup_common EXIT
11425
11426         # Check if we need to generate uneven OSTs
11427         test_mkdir -p $DIR/$tdir/OST${MINI}
11428         local FILL=$((MINV / 4))
11429         local DIFF=$((MAXV - MINV))
11430         local DIFF2=$((DIFF * 100 / MINV))
11431
11432         local threshold=$(do_facet $SINGLEMDS \
11433                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11434         threshold=${threshold%%%}
11435         echo -n "Check for uneven OSTs: "
11436         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11437
11438         if [[ $DIFF2 -gt $threshold ]]; then
11439                 echo "ok"
11440                 echo "Don't need to fill OST$MINI"
11441         else
11442                 # generate uneven OSTs. Write 2% over the QOS threshold value
11443                 echo "no"
11444                 DIFF=$((threshold - DIFF2 + 2))
11445                 DIFF2=$((MINV * DIFF / 100))
11446                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11447                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11448                         error "setstripe failed"
11449                 DIFF=$((DIFF2 / 2048))
11450                 i=0
11451                 while [ $i -lt $DIFF ]; do
11452                         i=$((i + 1))
11453                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11454                                 bs=2M count=1 2>/dev/null
11455                         echo -n .
11456                 done
11457                 echo .
11458                 sync
11459                 sleep_maxage
11460                 free_min_max
11461         fi
11462
11463         DIFF=$((MAXV - MINV))
11464         DIFF2=$((DIFF * 100 / MINV))
11465         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11466         if [ $DIFF2 -gt $threshold ]; then
11467                 echo "ok"
11468         else
11469                 echo "failed - QOS mode won't be used"
11470                 simple_cleanup_common
11471                 skip "QOS imbalance criteria not met"
11472         fi
11473
11474         MINI1=$MINI
11475         MINV1=$MINV
11476         MAXI1=$MAXI
11477         MAXV1=$MAXV
11478
11479         # now fill using QOS
11480         $LFS setstripe -c 1 $DIR/$tdir
11481         FILL=$((FILL / 200))
11482         if [ $FILL -gt 600 ]; then
11483                 FILL=600
11484         fi
11485         echo "writing $FILL files to QOS-assigned OSTs"
11486         i=0
11487         while [ $i -lt $FILL ]; do
11488                 i=$((i + 1))
11489                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11490                         count=1 2>/dev/null
11491                 echo -n .
11492         done
11493         echo "wrote $i 200k files"
11494         sync
11495         sleep_maxage
11496
11497         echo "Note: free space may not be updated, so measurements might be off"
11498         free_min_max
11499         DIFF2=$((MAXV - MINV))
11500         echo "free space delta: orig $DIFF final $DIFF2"
11501         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11502         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11503         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11504         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11505         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11506         if [[ $DIFF -gt 0 ]]; then
11507                 FILL=$((DIFF2 * 100 / DIFF - 100))
11508                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11509         fi
11510
11511         # Figure out which files were written where
11512         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11513                awk '/'$MINI1': / {print $2; exit}')
11514         echo $UUID
11515         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11516         echo "$MINC files created on smaller OST $MINI1"
11517         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11518                awk '/'$MAXI1': / {print $2; exit}')
11519         echo $UUID
11520         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11521         echo "$MAXC files created on larger OST $MAXI1"
11522         if [[ $MINC -gt 0 ]]; then
11523                 FILL=$((MAXC * 100 / MINC - 100))
11524                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11525         fi
11526         [[ $MAXC -gt $MINC ]] ||
11527                 error_ignore LU-9 "stripe QOS didn't balance free space"
11528         simple_cleanup_common
11529 }
11530 run_test 116a "stripe QOS: free space balance ==================="
11531
11532 test_116b() { # LU-2093
11533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11534         remote_mds_nodsh && skip "remote MDS with nodsh"
11535
11536 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11537         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11538                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11539         [ -z "$old_rr" ] && skip "no QOS"
11540         do_facet $SINGLEMDS lctl set_param \
11541                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11542         mkdir -p $DIR/$tdir
11543         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11544         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11545         do_facet $SINGLEMDS lctl set_param fail_loc=0
11546         rm -rf $DIR/$tdir
11547         do_facet $SINGLEMDS lctl set_param \
11548                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11549 }
11550 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11551
11552 test_117() # bug 10891
11553 {
11554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11555
11556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11557         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11558         lctl set_param fail_loc=0x21e
11559         > $DIR/$tfile || error "truncate failed"
11560         lctl set_param fail_loc=0
11561         echo "Truncate succeeded."
11562         rm -f $DIR/$tfile
11563 }
11564 run_test 117 "verify osd extend =========="
11565
11566 NO_SLOW_RESENDCOUNT=4
11567 export OLD_RESENDCOUNT=""
11568 set_resend_count () {
11569         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11570         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11571         lctl set_param -n $PROC_RESENDCOUNT $1
11572         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11573 }
11574
11575 # for reduce test_118* time (b=14842)
11576 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11577
11578 # Reset async IO behavior after error case
11579 reset_async() {
11580         FILE=$DIR/reset_async
11581
11582         # Ensure all OSCs are cleared
11583         $LFS setstripe -c -1 $FILE
11584         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11585         sync
11586         rm $FILE
11587 }
11588
11589 test_118a() #bug 11710
11590 {
11591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11592
11593         reset_async
11594
11595         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11596         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11597         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11598
11599         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11600                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11601                 return 1;
11602         fi
11603         rm -f $DIR/$tfile
11604 }
11605 run_test 118a "verify O_SYNC works =========="
11606
11607 test_118b()
11608 {
11609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11610         remote_ost_nodsh && skip "remote OST with nodsh"
11611
11612         reset_async
11613
11614         #define OBD_FAIL_SRV_ENOENT 0x217
11615         set_nodes_failloc "$(osts_nodes)" 0x217
11616         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11617         RC=$?
11618         set_nodes_failloc "$(osts_nodes)" 0
11619         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11620         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11621                     grep -c writeback)
11622
11623         if [[ $RC -eq 0 ]]; then
11624                 error "Must return error due to dropped pages, rc=$RC"
11625                 return 1;
11626         fi
11627
11628         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11629                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11630                 return 1;
11631         fi
11632
11633         echo "Dirty pages not leaked on ENOENT"
11634
11635         # Due to the above error the OSC will issue all RPCs syncronously
11636         # until a subsequent RPC completes successfully without error.
11637         $MULTIOP $DIR/$tfile Ow4096yc
11638         rm -f $DIR/$tfile
11639
11640         return 0
11641 }
11642 run_test 118b "Reclaim dirty pages on fatal error =========="
11643
11644 test_118c()
11645 {
11646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11647
11648         # for 118c, restore the original resend count, LU-1940
11649         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11650                                 set_resend_count $OLD_RESENDCOUNT
11651         remote_ost_nodsh && skip "remote OST with nodsh"
11652
11653         reset_async
11654
11655         #define OBD_FAIL_OST_EROFS               0x216
11656         set_nodes_failloc "$(osts_nodes)" 0x216
11657
11658         # multiop should block due to fsync until pages are written
11659         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11660         MULTIPID=$!
11661         sleep 1
11662
11663         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11664                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11665         fi
11666
11667         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11668                     grep -c writeback)
11669         if [[ $WRITEBACK -eq 0 ]]; then
11670                 error "No page in writeback, writeback=$WRITEBACK"
11671         fi
11672
11673         set_nodes_failloc "$(osts_nodes)" 0
11674         wait $MULTIPID
11675         RC=$?
11676         if [[ $RC -ne 0 ]]; then
11677                 error "Multiop fsync failed, rc=$RC"
11678         fi
11679
11680         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11681         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11682                     grep -c writeback)
11683         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11684                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11685         fi
11686
11687         rm -f $DIR/$tfile
11688         echo "Dirty pages flushed via fsync on EROFS"
11689         return 0
11690 }
11691 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11692
11693 # continue to use small resend count to reduce test_118* time (b=14842)
11694 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11695
11696 test_118d()
11697 {
11698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11699         remote_ost_nodsh && skip "remote OST with nodsh"
11700
11701         reset_async
11702
11703         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11704         set_nodes_failloc "$(osts_nodes)" 0x214
11705         # multiop should block due to fsync until pages are written
11706         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11707         MULTIPID=$!
11708         sleep 1
11709
11710         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11711                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11712         fi
11713
11714         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11715                     grep -c writeback)
11716         if [[ $WRITEBACK -eq 0 ]]; then
11717                 error "No page in writeback, writeback=$WRITEBACK"
11718         fi
11719
11720         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11721         set_nodes_failloc "$(osts_nodes)" 0
11722
11723         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11724         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11725                     grep -c writeback)
11726         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11727                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11728         fi
11729
11730         rm -f $DIR/$tfile
11731         echo "Dirty pages gaurenteed flushed via fsync"
11732         return 0
11733 }
11734 run_test 118d "Fsync validation inject a delay of the bulk =========="
11735
11736 test_118f() {
11737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11738
11739         reset_async
11740
11741         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11742         lctl set_param fail_loc=0x8000040a
11743
11744         # Should simulate EINVAL error which is fatal
11745         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11746         RC=$?
11747         if [[ $RC -eq 0 ]]; then
11748                 error "Must return error due to dropped pages, rc=$RC"
11749         fi
11750
11751         lctl set_param fail_loc=0x0
11752
11753         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11754         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11755         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11756                     grep -c writeback)
11757         if [[ $LOCKED -ne 0 ]]; then
11758                 error "Locked pages remain in cache, locked=$LOCKED"
11759         fi
11760
11761         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11762                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11763         fi
11764
11765         rm -f $DIR/$tfile
11766         echo "No pages locked after fsync"
11767
11768         reset_async
11769         return 0
11770 }
11771 run_test 118f "Simulate unrecoverable OSC side error =========="
11772
11773 test_118g() {
11774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11775
11776         reset_async
11777
11778         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11779         lctl set_param fail_loc=0x406
11780
11781         # simulate local -ENOMEM
11782         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11783         RC=$?
11784
11785         lctl set_param fail_loc=0
11786         if [[ $RC -eq 0 ]]; then
11787                 error "Must return error due to dropped pages, rc=$RC"
11788         fi
11789
11790         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11791         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11792         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11793                         grep -c writeback)
11794         if [[ $LOCKED -ne 0 ]]; then
11795                 error "Locked pages remain in cache, locked=$LOCKED"
11796         fi
11797
11798         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11799                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11800         fi
11801
11802         rm -f $DIR/$tfile
11803         echo "No pages locked after fsync"
11804
11805         reset_async
11806         return 0
11807 }
11808 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11809
11810 test_118h() {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812         remote_ost_nodsh && skip "remote OST with nodsh"
11813
11814         reset_async
11815
11816         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11817         set_nodes_failloc "$(osts_nodes)" 0x20e
11818         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11819         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11820         RC=$?
11821
11822         set_nodes_failloc "$(osts_nodes)" 0
11823         if [[ $RC -eq 0 ]]; then
11824                 error "Must return error due to dropped pages, rc=$RC"
11825         fi
11826
11827         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11828         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11829         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11830                     grep -c writeback)
11831         if [[ $LOCKED -ne 0 ]]; then
11832                 error "Locked pages remain in cache, locked=$LOCKED"
11833         fi
11834
11835         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11836                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11837         fi
11838
11839         rm -f $DIR/$tfile
11840         echo "No pages locked after fsync"
11841
11842         return 0
11843 }
11844 run_test 118h "Verify timeout in handling recoverables errors  =========="
11845
11846 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11847
11848 test_118i() {
11849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11850         remote_ost_nodsh && skip "remote OST with nodsh"
11851
11852         reset_async
11853
11854         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11855         set_nodes_failloc "$(osts_nodes)" 0x20e
11856
11857         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11858         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11859         PID=$!
11860         sleep 5
11861         set_nodes_failloc "$(osts_nodes)" 0
11862
11863         wait $PID
11864         RC=$?
11865         if [[ $RC -ne 0 ]]; then
11866                 error "got error, but should be not, rc=$RC"
11867         fi
11868
11869         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11870         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11871         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11872         if [[ $LOCKED -ne 0 ]]; then
11873                 error "Locked pages remain in cache, locked=$LOCKED"
11874         fi
11875
11876         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11877                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11878         fi
11879
11880         rm -f $DIR/$tfile
11881         echo "No pages locked after fsync"
11882
11883         return 0
11884 }
11885 run_test 118i "Fix error before timeout in recoverable error  =========="
11886
11887 [ "$SLOW" = "no" ] && set_resend_count 4
11888
11889 test_118j() {
11890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11891         remote_ost_nodsh && skip "remote OST with nodsh"
11892
11893         reset_async
11894
11895         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11896         set_nodes_failloc "$(osts_nodes)" 0x220
11897
11898         # return -EIO from OST
11899         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11900         RC=$?
11901         set_nodes_failloc "$(osts_nodes)" 0x0
11902         if [[ $RC -eq 0 ]]; then
11903                 error "Must return error due to dropped pages, rc=$RC"
11904         fi
11905
11906         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11907         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11908         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11909         if [[ $LOCKED -ne 0 ]]; then
11910                 error "Locked pages remain in cache, locked=$LOCKED"
11911         fi
11912
11913         # in recoverable error on OST we want resend and stay until it finished
11914         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11915                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11916         fi
11917
11918         rm -f $DIR/$tfile
11919         echo "No pages locked after fsync"
11920
11921         return 0
11922 }
11923 run_test 118j "Simulate unrecoverable OST side error =========="
11924
11925 test_118k()
11926 {
11927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11928         remote_ost_nodsh && skip "remote OSTs with nodsh"
11929
11930         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11931         set_nodes_failloc "$(osts_nodes)" 0x20e
11932         test_mkdir $DIR/$tdir
11933
11934         for ((i=0;i<10;i++)); do
11935                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11936                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11937                 SLEEPPID=$!
11938                 sleep 0.500s
11939                 kill $SLEEPPID
11940                 wait $SLEEPPID
11941         done
11942
11943         set_nodes_failloc "$(osts_nodes)" 0
11944         rm -rf $DIR/$tdir
11945 }
11946 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11947
11948 test_118l() # LU-646
11949 {
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951
11952         test_mkdir $DIR/$tdir
11953         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11954         rm -rf $DIR/$tdir
11955 }
11956 run_test 118l "fsync dir"
11957
11958 test_118m() # LU-3066
11959 {
11960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11961
11962         test_mkdir $DIR/$tdir
11963         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11964         rm -rf $DIR/$tdir
11965 }
11966 run_test 118m "fdatasync dir ========="
11967
11968 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11969
11970 test_118n()
11971 {
11972         local begin
11973         local end
11974
11975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11976         remote_ost_nodsh && skip "remote OSTs with nodsh"
11977
11978         # Sleep to avoid a cached response.
11979         #define OBD_STATFS_CACHE_SECONDS 1
11980         sleep 2
11981
11982         # Inject a 10 second delay in the OST_STATFS handler.
11983         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11984         set_nodes_failloc "$(osts_nodes)" 0x242
11985
11986         begin=$SECONDS
11987         stat --file-system $MOUNT > /dev/null
11988         end=$SECONDS
11989
11990         set_nodes_failloc "$(osts_nodes)" 0
11991
11992         if ((end - begin > 20)); then
11993             error "statfs took $((end - begin)) seconds, expected 10"
11994         fi
11995 }
11996 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11997
11998 test_119a() # bug 11737
11999 {
12000         BSIZE=$((512 * 1024))
12001         directio write $DIR/$tfile 0 1 $BSIZE
12002         # We ask to read two blocks, which is more than a file size.
12003         # directio will indicate an error when requested and actual
12004         # sizes aren't equeal (a normal situation in this case) and
12005         # print actual read amount.
12006         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12007         if [ "$NOB" != "$BSIZE" ]; then
12008                 error "read $NOB bytes instead of $BSIZE"
12009         fi
12010         rm -f $DIR/$tfile
12011 }
12012 run_test 119a "Short directIO read must return actual read amount"
12013
12014 test_119b() # bug 11737
12015 {
12016         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12017
12018         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12020         sync
12021         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12022                 error "direct read failed"
12023         rm -f $DIR/$tfile
12024 }
12025 run_test 119b "Sparse directIO read must return actual read amount"
12026
12027 test_119c() # bug 13099
12028 {
12029         BSIZE=1048576
12030         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12031         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12032         rm -f $DIR/$tfile
12033 }
12034 run_test 119c "Testing for direct read hitting hole"
12035
12036 test_119d() # bug 15950
12037 {
12038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12039
12040         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12041         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12042         BSIZE=1048576
12043         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12044         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12045         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12046         lctl set_param fail_loc=0x40d
12047         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12048         pid_dio=$!
12049         sleep 1
12050         cat $DIR/$tfile > /dev/null &
12051         lctl set_param fail_loc=0
12052         pid_reads=$!
12053         wait $pid_dio
12054         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12055         sleep 2
12056         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12057         error "the read rpcs have not completed in 2s"
12058         rm -f $DIR/$tfile
12059         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12060 }
12061 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12062
12063 test_120a() {
12064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12065         remote_mds_nodsh && skip "remote MDS with nodsh"
12066         test_mkdir -i0 -c1 $DIR/$tdir
12067         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12068                 skip_env "no early lock cancel on server"
12069
12070         lru_resize_disable mdc
12071         lru_resize_disable osc
12072         cancel_lru_locks mdc
12073         # asynchronous object destroy at MDT could cause bl ast to client
12074         cancel_lru_locks osc
12075
12076         stat $DIR/$tdir > /dev/null
12077         can1=$(do_facet mds1 \
12078                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12079                awk '/ldlm_cancel/ {print $2}')
12080         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12081                awk '/ldlm_bl_callback/ {print $2}')
12082         test_mkdir -i0 -c1 $DIR/$tdir/d1
12083         can2=$(do_facet mds1 \
12084                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12085                awk '/ldlm_cancel/ {print $2}')
12086         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12087                awk '/ldlm_bl_callback/ {print $2}')
12088         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12089         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12090         lru_resize_enable mdc
12091         lru_resize_enable osc
12092 }
12093 run_test 120a "Early Lock Cancel: mkdir test"
12094
12095 test_120b() {
12096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12097         remote_mds_nodsh && skip "remote MDS with nodsh"
12098         test_mkdir $DIR/$tdir
12099         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12100                 skip_env "no early lock cancel on server"
12101
12102         lru_resize_disable mdc
12103         lru_resize_disable osc
12104         cancel_lru_locks mdc
12105         stat $DIR/$tdir > /dev/null
12106         can1=$(do_facet $SINGLEMDS \
12107                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12108                awk '/ldlm_cancel/ {print $2}')
12109         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12110                awk '/ldlm_bl_callback/ {print $2}')
12111         touch $DIR/$tdir/f1
12112         can2=$(do_facet $SINGLEMDS \
12113                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12114                awk '/ldlm_cancel/ {print $2}')
12115         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12116                awk '/ldlm_bl_callback/ {print $2}')
12117         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12118         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12119         lru_resize_enable mdc
12120         lru_resize_enable osc
12121 }
12122 run_test 120b "Early Lock Cancel: create test"
12123
12124 test_120c() {
12125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12126         remote_mds_nodsh && skip "remote MDS with nodsh"
12127         test_mkdir -i0 -c1 $DIR/$tdir
12128         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12129                 skip "no early lock cancel on server"
12130
12131         lru_resize_disable mdc
12132         lru_resize_disable osc
12133         test_mkdir -i0 -c1 $DIR/$tdir/d1
12134         test_mkdir -i0 -c1 $DIR/$tdir/d2
12135         touch $DIR/$tdir/d1/f1
12136         cancel_lru_locks mdc
12137         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12138         can1=$(do_facet mds1 \
12139                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12140                awk '/ldlm_cancel/ {print $2}')
12141         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12142                awk '/ldlm_bl_callback/ {print $2}')
12143         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12144         can2=$(do_facet mds1 \
12145                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12146                awk '/ldlm_cancel/ {print $2}')
12147         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12148                awk '/ldlm_bl_callback/ {print $2}')
12149         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12150         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12151         lru_resize_enable mdc
12152         lru_resize_enable osc
12153 }
12154 run_test 120c "Early Lock Cancel: link test"
12155
12156 test_120d() {
12157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12158         remote_mds_nodsh && skip "remote MDS with nodsh"
12159         test_mkdir -i0 -c1 $DIR/$tdir
12160         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12161                 skip_env "no early lock cancel on server"
12162
12163         lru_resize_disable mdc
12164         lru_resize_disable osc
12165         touch $DIR/$tdir
12166         cancel_lru_locks mdc
12167         stat $DIR/$tdir > /dev/null
12168         can1=$(do_facet mds1 \
12169                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12170                awk '/ldlm_cancel/ {print $2}')
12171         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12172                awk '/ldlm_bl_callback/ {print $2}')
12173         chmod a+x $DIR/$tdir
12174         can2=$(do_facet mds1 \
12175                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12176                awk '/ldlm_cancel/ {print $2}')
12177         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12178                awk '/ldlm_bl_callback/ {print $2}')
12179         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12180         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12181         lru_resize_enable mdc
12182         lru_resize_enable osc
12183 }
12184 run_test 120d "Early Lock Cancel: setattr test"
12185
12186 test_120e() {
12187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12188         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12189                 skip_env "no early lock cancel on server"
12190         remote_mds_nodsh && skip "remote MDS with nodsh"
12191
12192         local dlmtrace_set=false
12193
12194         test_mkdir -i0 -c1 $DIR/$tdir
12195         lru_resize_disable mdc
12196         lru_resize_disable osc
12197         ! $LCTL get_param debug | grep -q dlmtrace &&
12198                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12199         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12200         cancel_lru_locks mdc
12201         cancel_lru_locks osc
12202         dd if=$DIR/$tdir/f1 of=/dev/null
12203         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12204         # XXX client can not do early lock cancel of OST lock
12205         # during unlink (LU-4206), so cancel osc lock now.
12206         sleep 2
12207         cancel_lru_locks osc
12208         can1=$(do_facet mds1 \
12209                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12210                awk '/ldlm_cancel/ {print $2}')
12211         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12212                awk '/ldlm_bl_callback/ {print $2}')
12213         unlink $DIR/$tdir/f1
12214         sleep 5
12215         can2=$(do_facet mds1 \
12216                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12217                awk '/ldlm_cancel/ {print $2}')
12218         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12219                awk '/ldlm_bl_callback/ {print $2}')
12220         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12221                 $LCTL dk $TMP/cancel.debug.txt
12222         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12223                 $LCTL dk $TMP/blocking.debug.txt
12224         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12225         lru_resize_enable mdc
12226         lru_resize_enable osc
12227 }
12228 run_test 120e "Early Lock Cancel: unlink test"
12229
12230 test_120f() {
12231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12232         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12233                 skip_env "no early lock cancel on server"
12234         remote_mds_nodsh && skip "remote MDS with nodsh"
12235
12236         test_mkdir -i0 -c1 $DIR/$tdir
12237         lru_resize_disable mdc
12238         lru_resize_disable osc
12239         test_mkdir -i0 -c1 $DIR/$tdir/d1
12240         test_mkdir -i0 -c1 $DIR/$tdir/d2
12241         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12242         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12243         cancel_lru_locks mdc
12244         cancel_lru_locks osc
12245         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12246         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12247         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12248         # XXX client can not do early lock cancel of OST lock
12249         # during rename (LU-4206), so cancel osc lock now.
12250         sleep 2
12251         cancel_lru_locks osc
12252         can1=$(do_facet mds1 \
12253                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12254                awk '/ldlm_cancel/ {print $2}')
12255         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12256                awk '/ldlm_bl_callback/ {print $2}')
12257         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12258         sleep 5
12259         can2=$(do_facet mds1 \
12260                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12261                awk '/ldlm_cancel/ {print $2}')
12262         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12263                awk '/ldlm_bl_callback/ {print $2}')
12264         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12265         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12266         lru_resize_enable mdc
12267         lru_resize_enable osc
12268 }
12269 run_test 120f "Early Lock Cancel: rename test"
12270
12271 test_120g() {
12272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12273         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12274                 skip_env "no early lock cancel on server"
12275         remote_mds_nodsh && skip "remote MDS with nodsh"
12276
12277         lru_resize_disable mdc
12278         lru_resize_disable osc
12279         count=10000
12280         echo create $count files
12281         test_mkdir $DIR/$tdir
12282         cancel_lru_locks mdc
12283         cancel_lru_locks osc
12284         t0=$(date +%s)
12285
12286         can0=$(do_facet $SINGLEMDS \
12287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12288                awk '/ldlm_cancel/ {print $2}')
12289         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12290                awk '/ldlm_bl_callback/ {print $2}')
12291         createmany -o $DIR/$tdir/f $count
12292         sync
12293         can1=$(do_facet $SINGLEMDS \
12294                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12295                awk '/ldlm_cancel/ {print $2}')
12296         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12297                awk '/ldlm_bl_callback/ {print $2}')
12298         t1=$(date +%s)
12299         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12300         echo rm $count files
12301         rm -r $DIR/$tdir
12302         sync
12303         can2=$(do_facet $SINGLEMDS \
12304                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12305                awk '/ldlm_cancel/ {print $2}')
12306         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12307                awk '/ldlm_bl_callback/ {print $2}')
12308         t2=$(date +%s)
12309         echo total: $count removes in $((t2-t1))
12310         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12311         sleep 2
12312         # wait for commitment of removal
12313         lru_resize_enable mdc
12314         lru_resize_enable osc
12315 }
12316 run_test 120g "Early Lock Cancel: performance test"
12317
12318 test_121() { #bug #10589
12319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12320
12321         rm -rf $DIR/$tfile
12322         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12323 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12324         lctl set_param fail_loc=0x310
12325         cancel_lru_locks osc > /dev/null
12326         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12327         lctl set_param fail_loc=0
12328         [[ $reads -eq $writes ]] ||
12329                 error "read $reads blocks, must be $writes blocks"
12330 }
12331 run_test 121 "read cancel race ========="
12332
12333 test_123a_base() { # was test 123, statahead(bug 11401)
12334         local lsx="$1"
12335
12336         SLOWOK=0
12337         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12338                 log "testing UP system. Performance may be lower than expected."
12339                 SLOWOK=1
12340         fi
12341
12342         rm -rf $DIR/$tdir
12343         test_mkdir $DIR/$tdir
12344         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12345         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12346         MULT=10
12347         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12348                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12349
12350                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12351                 lctl set_param -n llite.*.statahead_max 0
12352                 lctl get_param llite.*.statahead_max
12353                 cancel_lru_locks mdc
12354                 cancel_lru_locks osc
12355                 stime=$(date +%s)
12356                 time $lsx $DIR/$tdir | wc -l
12357                 etime=$(date +%s)
12358                 delta=$((etime - stime))
12359                 log "$lsx $i files without statahead: $delta sec"
12360                 lctl set_param llite.*.statahead_max=$max
12361
12362                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12363                         grep "statahead wrong:" | awk '{print $3}')
12364                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12365                 cancel_lru_locks mdc
12366                 cancel_lru_locks osc
12367                 stime=$(date +%s)
12368                 time $lsx $DIR/$tdir | wc -l
12369                 etime=$(date +%s)
12370                 delta_sa=$((etime - stime))
12371                 log "$lsx $i files with statahead: $delta_sa sec"
12372                 lctl get_param -n llite.*.statahead_stats
12373                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12374                         grep "statahead wrong:" | awk '{print $3}')
12375
12376                 [[ $swrong -lt $ewrong ]] &&
12377                         log "statahead was stopped, maybe too many locks held!"
12378                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12379
12380                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12381                         max=$(lctl get_param -n llite.*.statahead_max |
12382                                 head -n 1)
12383                         lctl set_param -n llite.*.statahead_max 0
12384                         lctl get_param llite.*.statahead_max
12385                         cancel_lru_locks mdc
12386                         cancel_lru_locks osc
12387                         stime=$(date +%s)
12388                         time $lsx $DIR/$tdir | wc -l
12389                         etime=$(date +%s)
12390                         delta=$((etime - stime))
12391                         log "$lsx $i files again without statahead: $delta sec"
12392                         lctl set_param llite.*.statahead_max=$max
12393                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12394                                 if [  $SLOWOK -eq 0 ]; then
12395                                         error "$lsx $i files is slower with statahead!"
12396                                 else
12397                                         log "$lsx $i files is slower with statahead!"
12398                                 fi
12399                                 break
12400                         fi
12401                 fi
12402
12403                 [ $delta -gt 20 ] && break
12404                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12405                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12406         done
12407         log "$lsx done"
12408
12409         stime=$(date +%s)
12410         rm -r $DIR/$tdir
12411         sync
12412         etime=$(date +%s)
12413         delta=$((etime - stime))
12414         log "rm -r $DIR/$tdir/: $delta seconds"
12415         log "rm done"
12416         lctl get_param -n llite.*.statahead_stats
12417 }
12418
12419 test_123aa() {
12420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12421
12422         test_123a_base "ls -l"
12423 }
12424 run_test 123aa "verify statahead work"
12425
12426 test_123ab() {
12427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12428
12429         statx_supported || skip_env "Test must be statx() syscall supported"
12430
12431         test_123a_base "$STATX -l"
12432 }
12433 run_test 123ab "verify statahead work by using statx"
12434
12435 test_123ac() {
12436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12437
12438         statx_supported || skip_env "Test must be statx() syscall supported"
12439
12440         local rpcs_before
12441         local rpcs_after
12442         local agl_before
12443         local agl_after
12444
12445         cancel_lru_locks $OSC
12446         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12447         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12448                 awk '/agl.total:/ {print $3}')
12449         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12450         test_123a_base "$STATX --cached=always -D"
12451         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12452                 awk '/agl.total:/ {print $3}')
12453         [ $agl_before -eq $agl_after ] ||
12454                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12455         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12456         [ $rpcs_after -eq $rpcs_before ] ||
12457                 error "$STATX should not send glimpse RPCs to $OSC"
12458 }
12459 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12460
12461 test_123b () { # statahead(bug 15027)
12462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12463
12464         test_mkdir $DIR/$tdir
12465         createmany -o $DIR/$tdir/$tfile-%d 1000
12466
12467         cancel_lru_locks mdc
12468         cancel_lru_locks osc
12469
12470 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12471         lctl set_param fail_loc=0x80000803
12472         ls -lR $DIR/$tdir > /dev/null
12473         log "ls done"
12474         lctl set_param fail_loc=0x0
12475         lctl get_param -n llite.*.statahead_stats
12476         rm -r $DIR/$tdir
12477         sync
12478
12479 }
12480 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12481
12482 test_123c() {
12483         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12484
12485         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12486         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12487         touch $DIR/$tdir.1/{1..3}
12488         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12489
12490         remount_client $MOUNT
12491
12492         $MULTIOP $DIR/$tdir.0 Q
12493
12494         # let statahead to complete
12495         ls -l $DIR/$tdir.0 > /dev/null
12496
12497         testid=$(echo $TESTNAME | tr '_' ' ')
12498         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12499                 error "statahead warning" || true
12500 }
12501 run_test 123c "Can not initialize inode warning on DNE statahead"
12502
12503 test_124a() {
12504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12505         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12506                 skip_env "no lru resize on server"
12507
12508         local NR=2000
12509
12510         test_mkdir $DIR/$tdir
12511
12512         log "create $NR files at $DIR/$tdir"
12513         createmany -o $DIR/$tdir/f $NR ||
12514                 error "failed to create $NR files in $DIR/$tdir"
12515
12516         cancel_lru_locks mdc
12517         ls -l $DIR/$tdir > /dev/null
12518
12519         local NSDIR=""
12520         local LRU_SIZE=0
12521         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12522                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12523                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12524                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12525                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12526                         log "NSDIR=$NSDIR"
12527                         log "NS=$(basename $NSDIR)"
12528                         break
12529                 fi
12530         done
12531
12532         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12533                 skip "Not enough cached locks created!"
12534         fi
12535         log "LRU=$LRU_SIZE"
12536
12537         local SLEEP=30
12538
12539         # We know that lru resize allows one client to hold $LIMIT locks
12540         # for 10h. After that locks begin to be killed by client.
12541         local MAX_HRS=10
12542         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12543         log "LIMIT=$LIMIT"
12544         if [ $LIMIT -lt $LRU_SIZE ]; then
12545                 skip "Limit is too small $LIMIT"
12546         fi
12547
12548         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12549         # killing locks. Some time was spent for creating locks. This means
12550         # that up to the moment of sleep finish we must have killed some of
12551         # them (10-100 locks). This depends on how fast ther were created.
12552         # Many of them were touched in almost the same moment and thus will
12553         # be killed in groups.
12554         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12555
12556         # Use $LRU_SIZE_B here to take into account real number of locks
12557         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12558         local LRU_SIZE_B=$LRU_SIZE
12559         log "LVF=$LVF"
12560         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12561         log "OLD_LVF=$OLD_LVF"
12562         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12563
12564         # Let's make sure that we really have some margin. Client checks
12565         # cached locks every 10 sec.
12566         SLEEP=$((SLEEP+20))
12567         log "Sleep ${SLEEP} sec"
12568         local SEC=0
12569         while ((SEC<$SLEEP)); do
12570                 echo -n "..."
12571                 sleep 5
12572                 SEC=$((SEC+5))
12573                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12574                 echo -n "$LRU_SIZE"
12575         done
12576         echo ""
12577         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12578         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12579
12580         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12581                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12582                 unlinkmany $DIR/$tdir/f $NR
12583                 return
12584         }
12585
12586         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12587         log "unlink $NR files at $DIR/$tdir"
12588         unlinkmany $DIR/$tdir/f $NR
12589 }
12590 run_test 124a "lru resize ======================================="
12591
12592 get_max_pool_limit()
12593 {
12594         local limit=$($LCTL get_param \
12595                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12596         local max=0
12597         for l in $limit; do
12598                 if [[ $l -gt $max ]]; then
12599                         max=$l
12600                 fi
12601         done
12602         echo $max
12603 }
12604
12605 test_124b() {
12606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12607         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12608                 skip_env "no lru resize on server"
12609
12610         LIMIT=$(get_max_pool_limit)
12611
12612         NR=$(($(default_lru_size)*20))
12613         if [[ $NR -gt $LIMIT ]]; then
12614                 log "Limit lock number by $LIMIT locks"
12615                 NR=$LIMIT
12616         fi
12617
12618         IFree=$(mdsrate_inodes_available)
12619         if [ $IFree -lt $NR ]; then
12620                 log "Limit lock number by $IFree inodes"
12621                 NR=$IFree
12622         fi
12623
12624         lru_resize_disable mdc
12625         test_mkdir -p $DIR/$tdir/disable_lru_resize
12626
12627         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12628         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12629         cancel_lru_locks mdc
12630         stime=`date +%s`
12631         PID=""
12632         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12633         PID="$PID $!"
12634         sleep 2
12635         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12636         PID="$PID $!"
12637         sleep 2
12638         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12639         PID="$PID $!"
12640         wait $PID
12641         etime=`date +%s`
12642         nolruresize_delta=$((etime-stime))
12643         log "ls -la time: $nolruresize_delta seconds"
12644         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12645         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12646
12647         lru_resize_enable mdc
12648         test_mkdir -p $DIR/$tdir/enable_lru_resize
12649
12650         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12651         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12652         cancel_lru_locks mdc
12653         stime=`date +%s`
12654         PID=""
12655         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12656         PID="$PID $!"
12657         sleep 2
12658         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12659         PID="$PID $!"
12660         sleep 2
12661         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12662         PID="$PID $!"
12663         wait $PID
12664         etime=`date +%s`
12665         lruresize_delta=$((etime-stime))
12666         log "ls -la time: $lruresize_delta seconds"
12667         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12668
12669         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12670                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12671         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12672                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12673         else
12674                 log "lru resize performs the same with no lru resize"
12675         fi
12676         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12677 }
12678 run_test 124b "lru resize (performance test) ======================="
12679
12680 test_124c() {
12681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12682         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12683                 skip_env "no lru resize on server"
12684
12685         # cache ununsed locks on client
12686         local nr=100
12687         cancel_lru_locks mdc
12688         test_mkdir $DIR/$tdir
12689         createmany -o $DIR/$tdir/f $nr ||
12690                 error "failed to create $nr files in $DIR/$tdir"
12691         ls -l $DIR/$tdir > /dev/null
12692
12693         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12694         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12695         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12696         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12697         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12698
12699         # set lru_max_age to 1 sec
12700         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12701         echo "sleep $((recalc_p * 2)) seconds..."
12702         sleep $((recalc_p * 2))
12703
12704         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12705         # restore lru_max_age
12706         $LCTL set_param -n $nsdir.lru_max_age $max_age
12707         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12708         unlinkmany $DIR/$tdir/f $nr
12709 }
12710 run_test 124c "LRUR cancel very aged locks"
12711
12712 test_124d() {
12713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12714         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12715                 skip_env "no lru resize on server"
12716
12717         # cache ununsed locks on client
12718         local nr=100
12719
12720         lru_resize_disable mdc
12721         stack_trap "lru_resize_enable mdc" EXIT
12722
12723         cancel_lru_locks mdc
12724
12725         # asynchronous object destroy at MDT could cause bl ast to client
12726         test_mkdir $DIR/$tdir
12727         createmany -o $DIR/$tdir/f $nr ||
12728                 error "failed to create $nr files in $DIR/$tdir"
12729         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12730
12731         ls -l $DIR/$tdir > /dev/null
12732
12733         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12734         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12735         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12736         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12737
12738         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12739
12740         # set lru_max_age to 1 sec
12741         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12742         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12743
12744         echo "sleep $((recalc_p * 2)) seconds..."
12745         sleep $((recalc_p * 2))
12746
12747         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12748
12749         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12750 }
12751 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12752
12753 test_125() { # 13358
12754         $LCTL get_param -n llite.*.client_type | grep -q local ||
12755                 skip "must run as local client"
12756         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12757                 skip_env "must have acl enabled"
12758         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12759
12760         test_mkdir $DIR/$tdir
12761         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12762         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12763         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12764 }
12765 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12766
12767 test_126() { # bug 12829/13455
12768         $GSS && skip_env "must run as gss disabled"
12769         $LCTL get_param -n llite.*.client_type | grep -q local ||
12770                 skip "must run as local client"
12771         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12772
12773         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12774         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12775         rm -f $DIR/$tfile
12776         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12777 }
12778 run_test 126 "check that the fsgid provided by the client is taken into account"
12779
12780 test_127a() { # bug 15521
12781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12782         local name count samp unit min max sum sumsq
12783
12784         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12785         echo "stats before reset"
12786         $LCTL get_param osc.*.stats
12787         $LCTL set_param osc.*.stats=0
12788         local fsize=$((2048 * 1024))
12789
12790         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12791         cancel_lru_locks osc
12792         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12793
12794         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12795         stack_trap "rm -f $TMP/$tfile.tmp"
12796         while read name count samp unit min max sum sumsq; do
12797                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12798                 [ ! $min ] && error "Missing min value for $name proc entry"
12799                 eval $name=$count || error "Wrong proc format"
12800
12801                 case $name in
12802                 read_bytes|write_bytes)
12803                         [[ "$unit" =~ "bytes" ]] ||
12804                                 error "unit is not 'bytes': $unit"
12805                         (( $min >= 4096 )) || error "min is too small: $min"
12806                         (( $min <= $fsize )) || error "min is too big: $min"
12807                         (( $max >= 4096 )) || error "max is too small: $max"
12808                         (( $max <= $fsize )) || error "max is too big: $max"
12809                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12810                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12811                                 error "sumsquare is too small: $sumsq"
12812                         (( $sumsq <= $fsize * $fsize )) ||
12813                                 error "sumsquare is too big: $sumsq"
12814                         ;;
12815                 ost_read|ost_write)
12816                         [[ "$unit" =~ "usec" ]] ||
12817                                 error "unit is not 'usec': $unit"
12818                         ;;
12819                 *)      ;;
12820                 esac
12821         done < $DIR/$tfile.tmp
12822
12823         #check that we actually got some stats
12824         [ "$read_bytes" ] || error "Missing read_bytes stats"
12825         [ "$write_bytes" ] || error "Missing write_bytes stats"
12826         [ "$read_bytes" != 0 ] || error "no read done"
12827         [ "$write_bytes" != 0 ] || error "no write done"
12828 }
12829 run_test 127a "verify the client stats are sane"
12830
12831 test_127b() { # bug LU-333
12832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12833         local name count samp unit min max sum sumsq
12834
12835         echo "stats before reset"
12836         $LCTL get_param llite.*.stats
12837         $LCTL set_param llite.*.stats=0
12838
12839         # perform 2 reads and writes so MAX is different from SUM.
12840         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12841         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12842         cancel_lru_locks osc
12843         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12844         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12845
12846         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12847         stack_trap "rm -f $TMP/$tfile.tmp"
12848         while read name count samp unit min max sum sumsq; do
12849                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12850                 eval $name=$count || error "Wrong proc format"
12851
12852                 case $name in
12853                 read_bytes|write_bytes)
12854                         [[ "$unit" =~ "bytes" ]] ||
12855                                 error "unit is not 'bytes': $unit"
12856                         (( $count == 2 )) || error "count is not 2: $count"
12857                         (( $min == $PAGE_SIZE )) ||
12858                                 error "min is not $PAGE_SIZE: $min"
12859                         (( $max == $PAGE_SIZE )) ||
12860                                 error "max is not $PAGE_SIZE: $max"
12861                         (( $sum == $PAGE_SIZE * 2 )) ||
12862                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12863                         ;;
12864                 read|write)
12865                         [[ "$unit" =~ "usec" ]] ||
12866                                 error "unit is not 'usec': $unit"
12867                         ;;
12868                 *)      ;;
12869                 esac
12870         done < $TMP/$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 127b "verify the llite client stats are sane"
12879
12880 test_127c() { # LU-12394
12881         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12882         local size
12883         local bsize
12884         local reads
12885         local writes
12886         local count
12887
12888         $LCTL set_param llite.*.extents_stats=1
12889         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12890
12891         # Use two stripes so there is enough space in default config
12892         $LFS setstripe -c 2 $DIR/$tfile
12893
12894         # Extent stats start at 0-4K and go in power of two buckets
12895         # LL_HIST_START = 12 --> 2^12 = 4K
12896         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12897         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12898         # small configs
12899         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12900                 do
12901                 # Write and read, 2x each, second time at a non-zero offset
12902                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12903                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12904                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12905                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12906                 rm -f $DIR/$tfile
12907         done
12908
12909         $LCTL get_param llite.*.extents_stats
12910
12911         count=2
12912         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12913                 do
12914                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12915                                 grep -m 1 $bsize)
12916                 reads=$(echo $bucket | awk '{print $5}')
12917                 writes=$(echo $bucket | awk '{print $9}')
12918                 [ "$reads" -eq $count ] ||
12919                         error "$reads reads in < $bsize bucket, expect $count"
12920                 [ "$writes" -eq $count ] ||
12921                         error "$writes writes in < $bsize bucket, expect $count"
12922         done
12923
12924         # Test mmap write and read
12925         $LCTL set_param llite.*.extents_stats=c
12926         size=512
12927         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12928         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12929         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12930
12931         $LCTL get_param llite.*.extents_stats
12932
12933         count=$(((size*1024) / PAGE_SIZE))
12934
12935         bsize=$((2 * PAGE_SIZE / 1024))K
12936
12937         bucket=$($LCTL get_param -n llite.*.extents_stats |
12938                         grep -m 1 $bsize)
12939         reads=$(echo $bucket | awk '{print $5}')
12940         writes=$(echo $bucket | awk '{print $9}')
12941         # mmap writes fault in the page first, creating an additonal read
12942         [ "$reads" -eq $((2 * count)) ] ||
12943                 error "$reads reads in < $bsize bucket, expect $count"
12944         [ "$writes" -eq $count ] ||
12945                 error "$writes writes in < $bsize bucket, expect $count"
12946 }
12947 run_test 127c "test llite extent stats with regular & mmap i/o"
12948
12949 test_128() { # bug 15212
12950         touch $DIR/$tfile
12951         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12952                 find $DIR/$tfile
12953                 find $DIR/$tfile
12954         EOF
12955
12956         result=$(grep error $TMP/$tfile.log)
12957         rm -f $DIR/$tfile $TMP/$tfile.log
12958         [ -z "$result" ] ||
12959                 error "consecutive find's under interactive lfs failed"
12960 }
12961 run_test 128 "interactive lfs for 2 consecutive find's"
12962
12963 set_dir_limits () {
12964         local mntdev
12965         local canondev
12966         local node
12967
12968         local ldproc=/proc/fs/ldiskfs
12969         local facets=$(get_facets MDS)
12970
12971         for facet in ${facets//,/ }; do
12972                 canondev=$(ldiskfs_canon \
12973                            *.$(convert_facet2label $facet).mntdev $facet)
12974                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12975                         ldproc=/sys/fs/ldiskfs
12976                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12977                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12978         done
12979 }
12980
12981 check_mds_dmesg() {
12982         local facets=$(get_facets MDS)
12983         for facet in ${facets//,/ }; do
12984                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12985         done
12986         return 1
12987 }
12988
12989 test_129() {
12990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12991         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12992                 skip "Need MDS version with at least 2.5.56"
12993         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12994                 skip_env "ldiskfs only test"
12995         fi
12996         remote_mds_nodsh && skip "remote MDS with nodsh"
12997
12998         local ENOSPC=28
12999         local has_warning=false
13000
13001         rm -rf $DIR/$tdir
13002         mkdir -p $DIR/$tdir
13003
13004         # block size of mds1
13005         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13006         set_dir_limits $maxsize $((maxsize * 6 / 8))
13007         stack_trap "set_dir_limits 0 0"
13008         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13009         local dirsize=$(stat -c%s "$DIR/$tdir")
13010         local nfiles=0
13011         while (( $dirsize <= $maxsize )); do
13012                 $MCREATE $DIR/$tdir/file_base_$nfiles
13013                 rc=$?
13014                 # check two errors:
13015                 # ENOSPC for ext4 max_dir_size, which has been used since
13016                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13017                 if (( rc == ENOSPC )); then
13018                         set_dir_limits 0 0
13019                         echo "rc=$rc returned as expected after $nfiles files"
13020
13021                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13022                                 error "create failed w/o dir size limit"
13023
13024                         # messages may be rate limited if test is run repeatedly
13025                         check_mds_dmesg '"is approaching max"' ||
13026                                 echo "warning message should be output"
13027                         check_mds_dmesg '"has reached max"' ||
13028                                 echo "reached message should be output"
13029
13030                         dirsize=$(stat -c%s "$DIR/$tdir")
13031
13032                         [[ $dirsize -ge $maxsize ]] && return 0
13033                         error "dirsize $dirsize < $maxsize after $nfiles files"
13034                 elif (( rc != 0 )); then
13035                         break
13036                 fi
13037                 nfiles=$((nfiles + 1))
13038                 dirsize=$(stat -c%s "$DIR/$tdir")
13039         done
13040
13041         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13042 }
13043 run_test 129 "test directory size limit ========================"
13044
13045 OLDIFS="$IFS"
13046 cleanup_130() {
13047         trap 0
13048         IFS="$OLDIFS"
13049 }
13050
13051 test_130a() {
13052         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13053         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13054
13055         trap cleanup_130 EXIT RETURN
13056
13057         local fm_file=$DIR/$tfile
13058         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13059         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13060                 error "dd failed for $fm_file"
13061
13062         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13063         filefrag -ves $fm_file
13064         RC=$?
13065         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13066                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13067         [ $RC != 0 ] && error "filefrag $fm_file failed"
13068
13069         filefrag_op=$(filefrag -ve -k $fm_file |
13070                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13071         lun=$($LFS getstripe -i $fm_file)
13072
13073         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13074         IFS=$'\n'
13075         tot_len=0
13076         for line in $filefrag_op
13077         do
13078                 frag_lun=`echo $line | cut -d: -f5`
13079                 ext_len=`echo $line | cut -d: -f4`
13080                 if (( $frag_lun != $lun )); then
13081                         cleanup_130
13082                         error "FIEMAP on 1-stripe file($fm_file) failed"
13083                         return
13084                 fi
13085                 (( tot_len += ext_len ))
13086         done
13087
13088         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13089                 cleanup_130
13090                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13091                 return
13092         fi
13093
13094         cleanup_130
13095
13096         echo "FIEMAP on single striped file succeeded"
13097 }
13098 run_test 130a "FIEMAP (1-stripe file)"
13099
13100 test_130b() {
13101         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13102
13103         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13104         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13105
13106         trap cleanup_130 EXIT RETURN
13107
13108         local fm_file=$DIR/$tfile
13109         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13110                         error "setstripe on $fm_file"
13111         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13112                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13113
13114         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13115                 error "dd failed on $fm_file"
13116
13117         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13118         filefrag_op=$(filefrag -ve -k $fm_file |
13119                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13120
13121         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13122                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13123
13124         IFS=$'\n'
13125         tot_len=0
13126         num_luns=1
13127         for line in $filefrag_op
13128         do
13129                 frag_lun=$(echo $line | cut -d: -f5 |
13130                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13131                 ext_len=$(echo $line | cut -d: -f4)
13132                 if (( $frag_lun != $last_lun )); then
13133                         if (( tot_len != 1024 )); then
13134                                 cleanup_130
13135                                 error "FIEMAP on $fm_file failed; returned " \
13136                                 "len $tot_len for OST $last_lun instead of 1024"
13137                                 return
13138                         else
13139                                 (( num_luns += 1 ))
13140                                 tot_len=0
13141                         fi
13142                 fi
13143                 (( tot_len += ext_len ))
13144                 last_lun=$frag_lun
13145         done
13146         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13147                 cleanup_130
13148                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13149                         "luns or wrong len for OST $last_lun"
13150                 return
13151         fi
13152
13153         cleanup_130
13154
13155         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13156 }
13157 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13158
13159 test_130c() {
13160         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13161
13162         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13163         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13164
13165         trap cleanup_130 EXIT RETURN
13166
13167         local fm_file=$DIR/$tfile
13168         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13169         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13170                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13171
13172         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13173                         error "dd failed on $fm_file"
13174
13175         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13176         filefrag_op=$(filefrag -ve -k $fm_file |
13177                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13178
13179         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13180                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13181
13182         IFS=$'\n'
13183         tot_len=0
13184         num_luns=1
13185         for line in $filefrag_op
13186         do
13187                 frag_lun=$(echo $line | cut -d: -f5 |
13188                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13189                 ext_len=$(echo $line | cut -d: -f4)
13190                 if (( $frag_lun != $last_lun )); then
13191                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13192                         if (( logical != 512 )); then
13193                                 cleanup_130
13194                                 error "FIEMAP on $fm_file failed; returned " \
13195                                 "logical start for lun $logical instead of 512"
13196                                 return
13197                         fi
13198                         if (( tot_len != 512 )); then
13199                                 cleanup_130
13200                                 error "FIEMAP on $fm_file failed; returned " \
13201                                 "len $tot_len for OST $last_lun instead of 1024"
13202                                 return
13203                         else
13204                                 (( num_luns += 1 ))
13205                                 tot_len=0
13206                         fi
13207                 fi
13208                 (( tot_len += ext_len ))
13209                 last_lun=$frag_lun
13210         done
13211         if (( num_luns != 2 || tot_len != 512 )); then
13212                 cleanup_130
13213                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13214                         "luns or wrong len for OST $last_lun"
13215                 return
13216         fi
13217
13218         cleanup_130
13219
13220         echo "FIEMAP on 2-stripe file with hole succeeded"
13221 }
13222 run_test 130c "FIEMAP (2-stripe file with hole)"
13223
13224 test_130d() {
13225         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13226
13227         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13228         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13229
13230         trap cleanup_130 EXIT RETURN
13231
13232         local fm_file=$DIR/$tfile
13233         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13234                         error "setstripe on $fm_file"
13235         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13236                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13237
13238         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13239         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13240                 error "dd failed on $fm_file"
13241
13242         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13243         filefrag_op=$(filefrag -ve -k $fm_file |
13244                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13245
13246         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13247                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13248
13249         IFS=$'\n'
13250         tot_len=0
13251         num_luns=1
13252         for line in $filefrag_op
13253         do
13254                 frag_lun=$(echo $line | cut -d: -f5 |
13255                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13256                 ext_len=$(echo $line | cut -d: -f4)
13257                 if (( $frag_lun != $last_lun )); then
13258                         if (( tot_len != 1024 )); then
13259                                 cleanup_130
13260                                 error "FIEMAP on $fm_file failed; returned " \
13261                                 "len $tot_len for OST $last_lun instead of 1024"
13262                                 return
13263                         else
13264                                 (( num_luns += 1 ))
13265                                 tot_len=0
13266                         fi
13267                 fi
13268                 (( tot_len += ext_len ))
13269                 last_lun=$frag_lun
13270         done
13271         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13272                 cleanup_130
13273                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13274                         "luns or wrong len for OST $last_lun"
13275                 return
13276         fi
13277
13278         cleanup_130
13279
13280         echo "FIEMAP on N-stripe file succeeded"
13281 }
13282 run_test 130d "FIEMAP (N-stripe file)"
13283
13284 test_130e() {
13285         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13286
13287         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13288         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13289
13290         trap cleanup_130 EXIT RETURN
13291
13292         local fm_file=$DIR/$tfile
13293         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13294
13295         NUM_BLKS=512
13296         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13297         for ((i = 0; i < $NUM_BLKS; i++)); do
13298                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13299                         conv=notrunc > /dev/null 2>&1
13300         done
13301
13302         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13303         filefrag_op=$(filefrag -ve -k $fm_file |
13304                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13305
13306         last_lun=$(echo $filefrag_op | cut -d: -f5)
13307
13308         IFS=$'\n'
13309         tot_len=0
13310         num_luns=1
13311         for line in $filefrag_op; do
13312                 frag_lun=$(echo $line | cut -d: -f5)
13313                 ext_len=$(echo $line | cut -d: -f4)
13314                 if [[ "$frag_lun" != "$last_lun" ]]; then
13315                         if (( tot_len != $EXPECTED_LEN )); then
13316                                 cleanup_130
13317                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13318                         else
13319                                 (( num_luns += 1 ))
13320                                 tot_len=0
13321                         fi
13322                 fi
13323                 (( tot_len += ext_len ))
13324                 last_lun=$frag_lun
13325         done
13326         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13327                 cleanup_130
13328                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13329         fi
13330
13331         echo "FIEMAP with continuation calls succeeded"
13332 }
13333 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13334
13335 test_130f() {
13336         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13337         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13338
13339         local fm_file=$DIR/$tfile
13340         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13341                 error "multiop create with lov_delay_create on $fm_file"
13342
13343         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13344         filefrag_extents=$(filefrag -vek $fm_file |
13345                            awk '/extents? found/ { print $2 }')
13346         if [[ "$filefrag_extents" != "0" ]]; then
13347                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13348         fi
13349
13350         rm -f $fm_file
13351 }
13352 run_test 130f "FIEMAP (unstriped file)"
13353
13354 test_130g() {
13355         local file=$DIR/$tfile
13356         local nr=$((OSTCOUNT * 100))
13357
13358         $LFS setstripe -C $nr $file ||
13359                 error "failed to setstripe -C $nr $file"
13360
13361         dd if=/dev/zero of=$file count=$nr bs=1M
13362         sync
13363         nr=$($LFS getstripe -c $file)
13364
13365         local extents=$(filefrag -v $file |
13366                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13367
13368         echo "filefrag list $extents extents in file with stripecount $nr"
13369         if (( extents < nr )); then
13370                 $LFS getstripe $file
13371                 filefrag -v $file
13372                 error "filefrag printed $extents < $nr extents"
13373         fi
13374
13375         rm -f $file
13376 }
13377 run_test 130g "FIEMAP (overstripe file)"
13378
13379 # Test for writev/readv
13380 test_131a() {
13381         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13382                 error "writev test failed"
13383         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13384                 error "readv failed"
13385         rm -f $DIR/$tfile
13386 }
13387 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13388
13389 test_131b() {
13390         local fsize=$((524288 + 1048576 + 1572864))
13391         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13392                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13393                         error "append writev test failed"
13394
13395         ((fsize += 1572864 + 1048576))
13396         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13397                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13398                         error "append writev test failed"
13399         rm -f $DIR/$tfile
13400 }
13401 run_test 131b "test append writev"
13402
13403 test_131c() {
13404         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13405         error "NOT PASS"
13406 }
13407 run_test 131c "test read/write on file w/o objects"
13408
13409 test_131d() {
13410         rwv -f $DIR/$tfile -w -n 1 1572864
13411         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13412         if [ "$NOB" != 1572864 ]; then
13413                 error "Short read filed: read $NOB bytes instead of 1572864"
13414         fi
13415         rm -f $DIR/$tfile
13416 }
13417 run_test 131d "test short read"
13418
13419 test_131e() {
13420         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13421         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13422         error "read hitting hole failed"
13423         rm -f $DIR/$tfile
13424 }
13425 run_test 131e "test read hitting hole"
13426
13427 check_stats() {
13428         local facet=$1
13429         local op=$2
13430         local want=${3:-0}
13431         local res
13432
13433         case $facet in
13434         mds*) res=$(do_facet $facet \
13435                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13436                  ;;
13437         ost*) res=$(do_facet $facet \
13438                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13439                  ;;
13440         *) error "Wrong facet '$facet'" ;;
13441         esac
13442         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13443         # if the argument $3 is zero, it means any stat increment is ok.
13444         if [[ $want -gt 0 ]]; then
13445                 local count=$(echo $res | awk '{ print $2 }')
13446                 [[ $count -ne $want ]] &&
13447                         error "The $op counter on $facet is $count, not $want"
13448         fi
13449 }
13450
13451 test_133a() {
13452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13453         remote_ost_nodsh && skip "remote OST with nodsh"
13454         remote_mds_nodsh && skip "remote MDS with nodsh"
13455         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13456                 skip_env "MDS doesn't support rename stats"
13457
13458         local testdir=$DIR/${tdir}/stats_testdir
13459
13460         mkdir -p $DIR/${tdir}
13461
13462         # clear stats.
13463         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13464         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13465
13466         # verify mdt stats first.
13467         mkdir ${testdir} || error "mkdir failed"
13468         check_stats $SINGLEMDS "mkdir" 1
13469         touch ${testdir}/${tfile} || error "touch failed"
13470         check_stats $SINGLEMDS "open" 1
13471         check_stats $SINGLEMDS "close" 1
13472         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13473                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13474                 check_stats $SINGLEMDS "mknod" 2
13475         }
13476         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13477         check_stats $SINGLEMDS "unlink" 1
13478         rm -f ${testdir}/${tfile} || error "file remove failed"
13479         check_stats $SINGLEMDS "unlink" 2
13480
13481         # remove working dir and check mdt stats again.
13482         rmdir ${testdir} || error "rmdir failed"
13483         check_stats $SINGLEMDS "rmdir" 1
13484
13485         local testdir1=$DIR/${tdir}/stats_testdir1
13486         mkdir -p ${testdir}
13487         mkdir -p ${testdir1}
13488         touch ${testdir1}/test1
13489         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13490         check_stats $SINGLEMDS "crossdir_rename" 1
13491
13492         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13493         check_stats $SINGLEMDS "samedir_rename" 1
13494
13495         rm -rf $DIR/${tdir}
13496 }
13497 run_test 133a "Verifying MDT stats ========================================"
13498
13499 test_133b() {
13500         local res
13501
13502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13503         remote_ost_nodsh && skip "remote OST with nodsh"
13504         remote_mds_nodsh && skip "remote MDS with nodsh"
13505
13506         local testdir=$DIR/${tdir}/stats_testdir
13507
13508         mkdir -p ${testdir} || error "mkdir failed"
13509         touch ${testdir}/${tfile} || error "touch failed"
13510         cancel_lru_locks mdc
13511
13512         # clear stats.
13513         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13514         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13515
13516         # extra mdt stats verification.
13517         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13518         check_stats $SINGLEMDS "setattr" 1
13519         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13520         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13521         then            # LU-1740
13522                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13523                 check_stats $SINGLEMDS "getattr" 1
13524         fi
13525         rm -rf $DIR/${tdir}
13526
13527         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13528         # so the check below is not reliable
13529         [ $MDSCOUNT -eq 1 ] || return 0
13530
13531         # Sleep to avoid a cached response.
13532         #define OBD_STATFS_CACHE_SECONDS 1
13533         sleep 2
13534         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13535         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13536         $LFS df || error "lfs failed"
13537         check_stats $SINGLEMDS "statfs" 1
13538
13539         # check aggregated statfs (LU-10018)
13540         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13541                 return 0
13542         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13543                 return 0
13544         sleep 2
13545         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13546         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13547         df $DIR
13548         check_stats $SINGLEMDS "statfs" 1
13549
13550         # We want to check that the client didn't send OST_STATFS to
13551         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13552         # extra care is needed here.
13553         if remote_mds; then
13554                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13555                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13556
13557                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13558                 [ "$res" ] && error "OST got STATFS"
13559         fi
13560
13561         return 0
13562 }
13563 run_test 133b "Verifying extra MDT stats =================================="
13564
13565 test_133c() {
13566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13567         remote_ost_nodsh && skip "remote OST with nodsh"
13568         remote_mds_nodsh && skip "remote MDS with nodsh"
13569
13570         local testdir=$DIR/$tdir/stats_testdir
13571
13572         test_mkdir -p $testdir
13573
13574         # verify obdfilter stats.
13575         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13576         sync
13577         cancel_lru_locks osc
13578         wait_delete_completed
13579
13580         # clear stats.
13581         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13582         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13583
13584         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13585                 error "dd failed"
13586         sync
13587         cancel_lru_locks osc
13588         check_stats ost1 "write" 1
13589
13590         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13591         check_stats ost1 "read" 1
13592
13593         > $testdir/$tfile || error "truncate failed"
13594         check_stats ost1 "punch" 1
13595
13596         rm -f $testdir/$tfile || error "file remove failed"
13597         wait_delete_completed
13598         check_stats ost1 "destroy" 1
13599
13600         rm -rf $DIR/$tdir
13601 }
13602 run_test 133c "Verifying OST stats ========================================"
13603
13604 order_2() {
13605         local value=$1
13606         local orig=$value
13607         local order=1
13608
13609         while [ $value -ge 2 ]; do
13610                 order=$((order*2))
13611                 value=$((value/2))
13612         done
13613
13614         if [ $orig -gt $order ]; then
13615                 order=$((order*2))
13616         fi
13617         echo $order
13618 }
13619
13620 size_in_KMGT() {
13621     local value=$1
13622     local size=('K' 'M' 'G' 'T');
13623     local i=0
13624     local size_string=$value
13625
13626     while [ $value -ge 1024 ]; do
13627         if [ $i -gt 3 ]; then
13628             #T is the biggest unit we get here, if that is bigger,
13629             #just return XXXT
13630             size_string=${value}T
13631             break
13632         fi
13633         value=$((value >> 10))
13634         if [ $value -lt 1024 ]; then
13635             size_string=${value}${size[$i]}
13636             break
13637         fi
13638         i=$((i + 1))
13639     done
13640
13641     echo $size_string
13642 }
13643
13644 get_rename_size() {
13645         local size=$1
13646         local context=${2:-.}
13647         local sample=$(do_facet $SINGLEMDS $LCTL \
13648                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13649                 grep -A1 $context |
13650                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13651         echo $sample
13652 }
13653
13654 test_133d() {
13655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13656         remote_ost_nodsh && skip "remote OST with nodsh"
13657         remote_mds_nodsh && skip "remote MDS with nodsh"
13658         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13659                 skip_env "MDS doesn't support rename stats"
13660
13661         local testdir1=$DIR/${tdir}/stats_testdir1
13662         local testdir2=$DIR/${tdir}/stats_testdir2
13663         mkdir -p $DIR/${tdir}
13664
13665         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13666
13667         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13668         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13669
13670         createmany -o $testdir1/test 512 || error "createmany failed"
13671
13672         # check samedir rename size
13673         mv ${testdir1}/test0 ${testdir1}/test_0
13674
13675         local testdir1_size=$(ls -l $DIR/${tdir} |
13676                 awk '/stats_testdir1/ {print $5}')
13677         local testdir2_size=$(ls -l $DIR/${tdir} |
13678                 awk '/stats_testdir2/ {print $5}')
13679
13680         testdir1_size=$(order_2 $testdir1_size)
13681         testdir2_size=$(order_2 $testdir2_size)
13682
13683         testdir1_size=$(size_in_KMGT $testdir1_size)
13684         testdir2_size=$(size_in_KMGT $testdir2_size)
13685
13686         echo "source rename dir size: ${testdir1_size}"
13687         echo "target rename dir size: ${testdir2_size}"
13688
13689         local cmd="do_facet $SINGLEMDS $LCTL "
13690         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13691
13692         eval $cmd || error "$cmd failed"
13693         local samedir=$($cmd | grep 'same_dir')
13694         local same_sample=$(get_rename_size $testdir1_size)
13695         [ -z "$samedir" ] && error "samedir_rename_size count error"
13696         [[ $same_sample -eq 1 ]] ||
13697                 error "samedir_rename_size error $same_sample"
13698         echo "Check same dir rename stats success"
13699
13700         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13701
13702         # check crossdir rename size
13703         mv ${testdir1}/test_0 ${testdir2}/test_0
13704
13705         testdir1_size=$(ls -l $DIR/${tdir} |
13706                 awk '/stats_testdir1/ {print $5}')
13707         testdir2_size=$(ls -l $DIR/${tdir} |
13708                 awk '/stats_testdir2/ {print $5}')
13709
13710         testdir1_size=$(order_2 $testdir1_size)
13711         testdir2_size=$(order_2 $testdir2_size)
13712
13713         testdir1_size=$(size_in_KMGT $testdir1_size)
13714         testdir2_size=$(size_in_KMGT $testdir2_size)
13715
13716         echo "source rename dir size: ${testdir1_size}"
13717         echo "target rename dir size: ${testdir2_size}"
13718
13719         eval $cmd || error "$cmd failed"
13720         local crossdir=$($cmd | grep 'crossdir')
13721         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13722         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13723         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13724         [[ $src_sample -eq 1 ]] ||
13725                 error "crossdir_rename_size error $src_sample"
13726         [[ $tgt_sample -eq 1 ]] ||
13727                 error "crossdir_rename_size error $tgt_sample"
13728         echo "Check cross dir rename stats success"
13729         rm -rf $DIR/${tdir}
13730 }
13731 run_test 133d "Verifying rename_stats ========================================"
13732
13733 test_133e() {
13734         remote_mds_nodsh && skip "remote MDS with nodsh"
13735         remote_ost_nodsh && skip "remote OST with nodsh"
13736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13737
13738         local testdir=$DIR/${tdir}/stats_testdir
13739         local ctr f0 f1 bs=32768 count=42 sum
13740
13741         mkdir -p ${testdir} || error "mkdir failed"
13742
13743         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13744
13745         for ctr in {write,read}_bytes; do
13746                 sync
13747                 cancel_lru_locks osc
13748
13749                 do_facet ost1 $LCTL set_param -n \
13750                         "obdfilter.*.exports.clear=clear"
13751
13752                 if [ $ctr = write_bytes ]; then
13753                         f0=/dev/zero
13754                         f1=${testdir}/${tfile}
13755                 else
13756                         f0=${testdir}/${tfile}
13757                         f1=/dev/null
13758                 fi
13759
13760                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13761                         error "dd failed"
13762                 sync
13763                 cancel_lru_locks osc
13764
13765                 sum=$(do_facet ost1 $LCTL get_param \
13766                         "obdfilter.*.exports.*.stats" |
13767                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13768                                 $1 == ctr { sum += $7 }
13769                                 END { printf("%0.0f", sum) }')
13770
13771                 if ((sum != bs * count)); then
13772                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13773                 fi
13774         done
13775
13776         rm -rf $DIR/${tdir}
13777 }
13778 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13779
13780 test_133f() {
13781         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13782                 skip "too old lustre for get_param -R ($facet_ver)"
13783
13784         # verifying readability.
13785         $LCTL get_param -R '*' &> /dev/null
13786
13787         # Verifing writability with badarea_io.
13788         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13789                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13790                 error "client badarea_io failed"
13791
13792         # remount the FS in case writes/reads /proc break the FS
13793         cleanup || error "failed to unmount"
13794         setup || error "failed to setup"
13795 }
13796 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13797
13798 test_133g() {
13799         remote_mds_nodsh && skip "remote MDS with nodsh"
13800         remote_ost_nodsh && skip "remote OST with nodsh"
13801
13802         local facet
13803         for facet in mds1 ost1; do
13804                 local facet_ver=$(lustre_version_code $facet)
13805                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13806                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13807                 else
13808                         log "$facet: too old lustre for get_param -R"
13809                 fi
13810                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13811                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13812                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13813                                 xargs badarea_io" ||
13814                                         error "$facet badarea_io failed"
13815                 else
13816                         skip_noexit "$facet: too old lustre for get_param -R"
13817                 fi
13818         done
13819
13820         # remount the FS in case writes/reads /proc break the FS
13821         cleanup || error "failed to unmount"
13822         setup || error "failed to setup"
13823 }
13824 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13825
13826 test_133h() {
13827         remote_mds_nodsh && skip "remote MDS with nodsh"
13828         remote_ost_nodsh && skip "remote OST with nodsh"
13829         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13830                 skip "Need MDS version at least 2.9.54"
13831
13832         local facet
13833         for facet in client mds1 ost1; do
13834                 # Get the list of files that are missing the terminating newline
13835                 local plist=$(do_facet $facet
13836                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13837                 local ent
13838                 for ent in $plist; do
13839                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13840                                 awk -v FS='\v' -v RS='\v\v' \
13841                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13842                                         print FILENAME}'" 2>/dev/null)
13843                         [ -z $missing ] || {
13844                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13845                                 error "file does not end with newline: $facet-$ent"
13846                         }
13847                 done
13848         done
13849 }
13850 run_test 133h "Proc files should end with newlines"
13851
13852 test_134a() {
13853         remote_mds_nodsh && skip "remote MDS with nodsh"
13854         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13855                 skip "Need MDS version at least 2.7.54"
13856
13857         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13858         cancel_lru_locks mdc
13859
13860         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13861         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13862         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13863
13864         local nr=1000
13865         createmany -o $DIR/$tdir/f $nr ||
13866                 error "failed to create $nr files in $DIR/$tdir"
13867         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13868
13869         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13870         do_facet mds1 $LCTL set_param fail_loc=0x327
13871         do_facet mds1 $LCTL set_param fail_val=500
13872         touch $DIR/$tdir/m
13873
13874         echo "sleep 10 seconds ..."
13875         sleep 10
13876         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13877
13878         do_facet mds1 $LCTL set_param fail_loc=0
13879         do_facet mds1 $LCTL set_param fail_val=0
13880         [ $lck_cnt -lt $unused ] ||
13881                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13882
13883         rm $DIR/$tdir/m
13884         unlinkmany $DIR/$tdir/f $nr
13885 }
13886 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13887
13888 test_134b() {
13889         remote_mds_nodsh && skip "remote MDS with nodsh"
13890         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13891                 skip "Need MDS version at least 2.7.54"
13892
13893         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13894         cancel_lru_locks mdc
13895
13896         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13897                         ldlm.lock_reclaim_threshold_mb)
13898         # disable reclaim temporarily
13899         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13900
13901         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13902         do_facet mds1 $LCTL set_param fail_loc=0x328
13903         do_facet mds1 $LCTL set_param fail_val=500
13904
13905         $LCTL set_param debug=+trace
13906
13907         local nr=600
13908         createmany -o $DIR/$tdir/f $nr &
13909         local create_pid=$!
13910
13911         echo "Sleep $TIMEOUT seconds ..."
13912         sleep $TIMEOUT
13913         if ! ps -p $create_pid  > /dev/null 2>&1; then
13914                 do_facet mds1 $LCTL set_param fail_loc=0
13915                 do_facet mds1 $LCTL set_param fail_val=0
13916                 do_facet mds1 $LCTL set_param \
13917                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13918                 error "createmany finished incorrectly!"
13919         fi
13920         do_facet mds1 $LCTL set_param fail_loc=0
13921         do_facet mds1 $LCTL set_param fail_val=0
13922         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13923         wait $create_pid || return 1
13924
13925         unlinkmany $DIR/$tdir/f $nr
13926 }
13927 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13928
13929 test_135() {
13930         remote_mds_nodsh && skip "remote MDS with nodsh"
13931         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13932                 skip "Need MDS version at least 2.13.50"
13933         local fname
13934
13935         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13936
13937 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13938         #set only one record at plain llog
13939         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13940
13941         #fill already existed plain llog each 64767
13942         #wrapping whole catalog
13943         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13944
13945         createmany -o $DIR/$tdir/$tfile_ 64700
13946         for (( i = 0; i < 64700; i = i + 2 ))
13947         do
13948                 rm $DIR/$tdir/$tfile_$i &
13949                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13950                 local pid=$!
13951                 wait $pid
13952         done
13953
13954         #waiting osp synchronization
13955         wait_delete_completed
13956 }
13957 run_test 135 "Race catalog processing"
13958
13959 test_136() {
13960         remote_mds_nodsh && skip "remote MDS with nodsh"
13961         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13962                 skip "Need MDS version at least 2.13.50"
13963         local fname
13964
13965         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13966         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13967         #set only one record at plain llog
13968 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13969         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13970
13971         #fill already existed 2 plain llogs each 64767
13972         #wrapping whole catalog
13973         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13974         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13975         wait_delete_completed
13976
13977         createmany -o $DIR/$tdir/$tfile_ 10
13978         sleep 25
13979
13980         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13981         for (( i = 0; i < 10; i = i + 3 ))
13982         do
13983                 rm $DIR/$tdir/$tfile_$i &
13984                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13985                 local pid=$!
13986                 wait $pid
13987                 sleep 7
13988                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13989         done
13990
13991         #waiting osp synchronization
13992         wait_delete_completed
13993 }
13994 run_test 136 "Race catalog processing 2"
13995
13996 test_140() { #bug-17379
13997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13998
13999         test_mkdir $DIR/$tdir
14000         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14001         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14002
14003         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14004         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14005         local i=0
14006         while i=$((i + 1)); do
14007                 test_mkdir $i
14008                 cd $i || error "Changing to $i"
14009                 ln -s ../stat stat || error "Creating stat symlink"
14010                 # Read the symlink until ELOOP present,
14011                 # not LBUGing the system is considered success,
14012                 # we didn't overrun the stack.
14013                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14014                 if [ $ret -ne 0 ]; then
14015                         if [ $ret -eq 40 ]; then
14016                                 break  # -ELOOP
14017                         else
14018                                 error "Open stat symlink"
14019                                         return
14020                         fi
14021                 fi
14022         done
14023         i=$((i - 1))
14024         echo "The symlink depth = $i"
14025         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14026                 error "Invalid symlink depth"
14027
14028         # Test recursive symlink
14029         ln -s symlink_self symlink_self
14030         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14031         echo "open symlink_self returns $ret"
14032         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14033 }
14034 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14035
14036 test_150a() {
14037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14038
14039         local TF="$TMP/$tfile"
14040
14041         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14042         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14043         cp $TF $DIR/$tfile
14044         cancel_lru_locks $OSC
14045         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14046         remount_client $MOUNT
14047         df -P $MOUNT
14048         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14049
14050         $TRUNCATE $TF 6000
14051         $TRUNCATE $DIR/$tfile 6000
14052         cancel_lru_locks $OSC
14053         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14054
14055         echo "12345" >>$TF
14056         echo "12345" >>$DIR/$tfile
14057         cancel_lru_locks $OSC
14058         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14059
14060         echo "12345" >>$TF
14061         echo "12345" >>$DIR/$tfile
14062         cancel_lru_locks $OSC
14063         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14064 }
14065 run_test 150a "truncate/append tests"
14066
14067 test_150b() {
14068         check_set_fallocate_or_skip
14069
14070         touch $DIR/$tfile
14071         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14072         check_fallocate $DIR/$tfile || error "fallocate failed"
14073 }
14074 run_test 150b "Verify fallocate (prealloc) functionality"
14075
14076 test_150bb() {
14077         check_set_fallocate_or_skip
14078
14079         touch $DIR/$tfile
14080         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14081         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14082         > $DIR/$tfile
14083         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14084         # precomputed md5sum for 20MB of zeroes
14085         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14086         local sum=($(md5sum $DIR/$tfile))
14087
14088         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14089
14090         check_set_fallocate 1
14091
14092         > $DIR/$tfile
14093         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14094         sum=($(md5sum $DIR/$tfile))
14095
14096         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14097 }
14098 run_test 150bb "Verify fallocate modes both zero space"
14099
14100 test_150c() {
14101         check_set_fallocate_or_skip
14102
14103         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14104         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14105         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14106         sync; sync_all_data
14107         cancel_lru_locks $OSC
14108         sleep 5
14109         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14110         want=$((OSTCOUNT * 1048576))
14111
14112         # Must allocate all requested space, not more than 5% extra
14113         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14114                 error "bytes $bytes is not $want"
14115
14116         rm -f $DIR/$tfile
14117         # verify fallocate on PFL file
14118         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14119                 error "Create $DIR/$tfile failed"
14120         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14121                         error "fallocate failed"
14122         sync; sync_all_data
14123         cancel_lru_locks $OSC
14124         sleep 5
14125         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14126         local want=$((1024 * 1048576))
14127
14128         # Must allocate all requested space, not more than 5% extra
14129         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14130                 error "bytes $bytes is not $want"
14131 }
14132 run_test 150c "Verify fallocate Size and Blocks"
14133
14134 test_150d() {
14135         check_set_fallocate_or_skip
14136
14137         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14138         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14139         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14140         sync; sync_all_data
14141         cancel_lru_locks $OSC
14142         sleep 5
14143         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14144         local want=$((OSTCOUNT * 1048576))
14145
14146         # Must allocate all requested space, not more than 5% extra
14147         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14148                 error "bytes $bytes is not $want"
14149 }
14150 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14151
14152 test_150e() {
14153         check_set_fallocate_or_skip
14154
14155         echo "df before:"
14156         $LFS df
14157         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14158         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14159                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14160
14161         # Find OST with Minimum Size
14162         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14163                        sort -un | head -1)
14164
14165         # Get 100MB per OST of the available space to reduce run time
14166         # else 60% of the available space if we are running SLOW tests
14167         if [ $SLOW == "no" ]; then
14168                 local space=$((1024 * 100 * OSTCOUNT))
14169         else
14170                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14171         fi
14172
14173         fallocate -l${space}k $DIR/$tfile ||
14174                 error "fallocate ${space}k $DIR/$tfile failed"
14175         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14176
14177         # get size immediately after fallocate. This should be correctly
14178         # updated
14179         local size=$(stat -c '%s' $DIR/$tfile)
14180         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14181
14182         # Sleep for a while for statfs to get updated. And not pull from cache.
14183         sleep 2
14184
14185         echo "df after fallocate:"
14186         $LFS df
14187
14188         (( size / 1024 == space )) || error "size $size != requested $space"
14189         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14190                 error "used $used < space $space"
14191
14192         rm $DIR/$tfile || error "rm failed"
14193         sync
14194         wait_delete_completed
14195
14196         echo "df after unlink:"
14197         $LFS df
14198 }
14199 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14200
14201 test_150f() {
14202         local size
14203         local blocks
14204         local want_size_before=20480 # in bytes
14205         local want_blocks_before=40 # 512 sized blocks
14206         local want_blocks_after=24  # 512 sized blocks
14207         local length=$(((want_blocks_before - want_blocks_after) * 512))
14208
14209         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14210                 skip "need at least 2.14.0 for fallocate punch"
14211
14212         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14213                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14214         fi
14215
14216         check_set_fallocate_or_skip
14217         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14218
14219         echo "Verify fallocate punch: Range within the file range"
14220         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14221                 error "dd failed for bs 4096 and count 5"
14222
14223         # Call fallocate with punch range which is within the file range
14224         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14225                 error "fallocate failed: offset 4096 and length $length"
14226         # client must see changes immediately after fallocate
14227         size=$(stat -c '%s' $DIR/$tfile)
14228         blocks=$(stat -c '%b' $DIR/$tfile)
14229
14230         # Verify punch worked.
14231         (( blocks == want_blocks_after )) ||
14232                 error "punch failed: blocks $blocks != $want_blocks_after"
14233
14234         (( size == want_size_before )) ||
14235                 error "punch failed: size $size != $want_size_before"
14236
14237         # Verify there is hole in file
14238         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14239         # precomputed md5sum
14240         local expect="4a9a834a2db02452929c0a348273b4aa"
14241
14242         cksum=($(md5sum $DIR/$tfile))
14243         [[ "${cksum[0]}" == "$expect" ]] ||
14244                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14245
14246         # Start second sub-case for fallocate punch.
14247         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14248         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14249                 error "dd failed for bs 4096 and count 5"
14250
14251         # Punch range less than block size will have no change in block count
14252         want_blocks_after=40  # 512 sized blocks
14253
14254         # Punch overlaps two blocks and less than blocksize
14255         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14256                 error "fallocate failed: offset 4000 length 3000"
14257         size=$(stat -c '%s' $DIR/$tfile)
14258         blocks=$(stat -c '%b' $DIR/$tfile)
14259
14260         # Verify punch worked.
14261         (( blocks == want_blocks_after )) ||
14262                 error "punch failed: blocks $blocks != $want_blocks_after"
14263
14264         (( size == want_size_before )) ||
14265                 error "punch failed: size $size != $want_size_before"
14266
14267         # Verify if range is really zero'ed out. We expect Zeros.
14268         # precomputed md5sum
14269         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14270         cksum=($(md5sum $DIR/$tfile))
14271         [[ "${cksum[0]}" == "$expect" ]] ||
14272                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14273 }
14274 run_test 150f "Verify fallocate punch functionality"
14275
14276 test_150g() {
14277         local space
14278         local size
14279         local blocks
14280         local blocks_after
14281         local size_after
14282         local BS=4096 # Block size in bytes
14283
14284         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14285                 skip "need at least 2.14.0 for fallocate punch"
14286
14287         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14288                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14289         fi
14290
14291         check_set_fallocate_or_skip
14292         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14293
14294         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14295                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14296
14297         # Get 100MB per OST of the available space to reduce run time
14298         # else 60% of the available space if we are running SLOW tests
14299         if [ $SLOW == "no" ]; then
14300                 space=$((1024 * 100 * OSTCOUNT))
14301         else
14302                 # Find OST with Minimum Size
14303                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14304                         sort -un | head -1)
14305                 echo "min size OST: $space"
14306                 space=$(((space * 60)/100 * OSTCOUNT))
14307         fi
14308         # space in 1k units, round to 4k blocks
14309         local blkcount=$((space * 1024 / $BS))
14310
14311         echo "Verify fallocate punch: Very large Range"
14312         fallocate -l${space}k $DIR/$tfile ||
14313                 error "fallocate ${space}k $DIR/$tfile failed"
14314         # write 1M at the end, start and in the middle
14315         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14316                 error "dd failed: bs $BS count 256"
14317         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14318                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14319         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14320                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14321
14322         # Gather stats.
14323         size=$(stat -c '%s' $DIR/$tfile)
14324
14325         # gather punch length.
14326         local punch_size=$((size - (BS * 2)))
14327
14328         echo "punch_size = $punch_size"
14329         echo "size - punch_size: $((size - punch_size))"
14330         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14331
14332         # Call fallocate to punch all except 2 blocks. We leave the
14333         # first and the last block
14334         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14335         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14336                 error "fallocate failed: offset $BS length $punch_size"
14337
14338         size_after=$(stat -c '%s' $DIR/$tfile)
14339         blocks_after=$(stat -c '%b' $DIR/$tfile)
14340
14341         # Verify punch worked.
14342         # Size should be kept
14343         (( size == size_after )) ||
14344                 error "punch failed: size $size != $size_after"
14345
14346         # two 4k data blocks to remain plus possible 1 extra extent block
14347         (( blocks_after <= ((BS / 512) * 3) )) ||
14348                 error "too many blocks remains: $blocks_after"
14349
14350         # Verify that file has hole between the first and the last blocks
14351         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14352         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14353
14354         echo "Hole at [$hole_start, $hole_end)"
14355         (( hole_start == BS )) ||
14356                 error "no hole at offset $BS after punch"
14357
14358         (( hole_end == BS + punch_size )) ||
14359                 error "data at offset $hole_end < $((BS + punch_size))"
14360 }
14361 run_test 150g "Verify fallocate punch on large range"
14362
14363 #LU-2902 roc_hit was not able to read all values from lproc
14364 function roc_hit_init() {
14365         local list=$(comma_list $(osts_nodes))
14366         local dir=$DIR/$tdir-check
14367         local file=$dir/$tfile
14368         local BEFORE
14369         local AFTER
14370         local idx
14371
14372         test_mkdir $dir
14373         #use setstripe to do a write to every ost
14374         for i in $(seq 0 $((OSTCOUNT-1))); do
14375                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14376                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14377                 idx=$(printf %04x $i)
14378                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14379                         awk '$1 == "cache_access" {sum += $7}
14380                                 END { printf("%0.0f", sum) }')
14381
14382                 cancel_lru_locks osc
14383                 cat $file >/dev/null
14384
14385                 AFTER=$(get_osd_param $list *OST*$idx stats |
14386                         awk '$1 == "cache_access" {sum += $7}
14387                                 END { printf("%0.0f", sum) }')
14388
14389                 echo BEFORE:$BEFORE AFTER:$AFTER
14390                 if ! let "AFTER - BEFORE == 4"; then
14391                         rm -rf $dir
14392                         error "roc_hit is not safe to use"
14393                 fi
14394                 rm $file
14395         done
14396
14397         rm -rf $dir
14398 }
14399
14400 function roc_hit() {
14401         local list=$(comma_list $(osts_nodes))
14402         echo $(get_osd_param $list '' stats |
14403                 awk '$1 == "cache_hit" {sum += $7}
14404                         END { printf("%0.0f", sum) }')
14405 }
14406
14407 function set_cache() {
14408         local on=1
14409
14410         if [ "$2" == "off" ]; then
14411                 on=0;
14412         fi
14413         local list=$(comma_list $(osts_nodes))
14414         set_osd_param $list '' $1_cache_enable $on
14415
14416         cancel_lru_locks osc
14417 }
14418
14419 test_151() {
14420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14421         remote_ost_nodsh && skip "remote OST with nodsh"
14422
14423         local CPAGES=3
14424         local list=$(comma_list $(osts_nodes))
14425
14426         # check whether obdfilter is cache capable at all
14427         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14428                 skip "not cache-capable obdfilter"
14429         fi
14430
14431         # check cache is enabled on all obdfilters
14432         if get_osd_param $list '' read_cache_enable | grep 0; then
14433                 skip "oss cache is disabled"
14434         fi
14435
14436         set_osd_param $list '' writethrough_cache_enable 1
14437
14438         # check write cache is enabled on all obdfilters
14439         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14440                 skip "oss write cache is NOT enabled"
14441         fi
14442
14443         roc_hit_init
14444
14445         #define OBD_FAIL_OBD_NO_LRU  0x609
14446         do_nodes $list $LCTL set_param fail_loc=0x609
14447
14448         # pages should be in the case right after write
14449         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14450                 error "dd failed"
14451
14452         local BEFORE=$(roc_hit)
14453         cancel_lru_locks osc
14454         cat $DIR/$tfile >/dev/null
14455         local AFTER=$(roc_hit)
14456
14457         do_nodes $list $LCTL set_param fail_loc=0
14458
14459         if ! let "AFTER - BEFORE == CPAGES"; then
14460                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14461         fi
14462
14463         cancel_lru_locks osc
14464         # invalidates OST cache
14465         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14466         set_osd_param $list '' read_cache_enable 0
14467         cat $DIR/$tfile >/dev/null
14468
14469         # now data shouldn't be found in the cache
14470         BEFORE=$(roc_hit)
14471         cancel_lru_locks osc
14472         cat $DIR/$tfile >/dev/null
14473         AFTER=$(roc_hit)
14474         if let "AFTER - BEFORE != 0"; then
14475                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14476         fi
14477
14478         set_osd_param $list '' read_cache_enable 1
14479         rm -f $DIR/$tfile
14480 }
14481 run_test 151 "test cache on oss and controls ==============================="
14482
14483 test_152() {
14484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14485
14486         local TF="$TMP/$tfile"
14487
14488         # simulate ENOMEM during write
14489 #define OBD_FAIL_OST_NOMEM      0x226
14490         lctl set_param fail_loc=0x80000226
14491         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14492         cp $TF $DIR/$tfile
14493         sync || error "sync failed"
14494         lctl set_param fail_loc=0
14495
14496         # discard client's cache
14497         cancel_lru_locks osc
14498
14499         # simulate ENOMEM during read
14500         lctl set_param fail_loc=0x80000226
14501         cmp $TF $DIR/$tfile || error "cmp failed"
14502         lctl set_param fail_loc=0
14503
14504         rm -f $TF
14505 }
14506 run_test 152 "test read/write with enomem ============================"
14507
14508 test_153() {
14509         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14510 }
14511 run_test 153 "test if fdatasync does not crash ======================="
14512
14513 dot_lustre_fid_permission_check() {
14514         local fid=$1
14515         local ffid=$MOUNT/.lustre/fid/$fid
14516         local test_dir=$2
14517
14518         echo "stat fid $fid"
14519         stat $ffid > /dev/null || error "stat $ffid failed."
14520         echo "touch fid $fid"
14521         touch $ffid || error "touch $ffid failed."
14522         echo "write to fid $fid"
14523         cat /etc/hosts > $ffid || error "write $ffid failed."
14524         echo "read fid $fid"
14525         diff /etc/hosts $ffid || error "read $ffid failed."
14526         echo "append write to fid $fid"
14527         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14528         echo "rename fid $fid"
14529         mv $ffid $test_dir/$tfile.1 &&
14530                 error "rename $ffid to $tfile.1 should fail."
14531         touch $test_dir/$tfile.1
14532         mv $test_dir/$tfile.1 $ffid &&
14533                 error "rename $tfile.1 to $ffid should fail."
14534         rm -f $test_dir/$tfile.1
14535         echo "truncate fid $fid"
14536         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14537         echo "link fid $fid"
14538         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14539         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14540                 echo "setfacl fid $fid"
14541                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14542                 echo "getfacl fid $fid"
14543                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14544         fi
14545         echo "unlink fid $fid"
14546         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14547         echo "mknod fid $fid"
14548         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14549
14550         fid=[0xf00000400:0x1:0x0]
14551         ffid=$MOUNT/.lustre/fid/$fid
14552
14553         echo "stat non-exist fid $fid"
14554         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14555         echo "write to non-exist fid $fid"
14556         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14557         echo "link new fid $fid"
14558         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14559
14560         mkdir -p $test_dir/$tdir
14561         touch $test_dir/$tdir/$tfile
14562         fid=$($LFS path2fid $test_dir/$tdir)
14563         rc=$?
14564         [ $rc -ne 0 ] &&
14565                 error "error: could not get fid for $test_dir/$dir/$tfile."
14566
14567         ffid=$MOUNT/.lustre/fid/$fid
14568
14569         echo "ls $fid"
14570         ls $ffid > /dev/null || error "ls $ffid failed."
14571         echo "touch $fid/$tfile.1"
14572         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14573
14574         echo "touch $MOUNT/.lustre/fid/$tfile"
14575         touch $MOUNT/.lustre/fid/$tfile && \
14576                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14577
14578         echo "setxattr to $MOUNT/.lustre/fid"
14579         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14580
14581         echo "listxattr for $MOUNT/.lustre/fid"
14582         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14583
14584         echo "delxattr from $MOUNT/.lustre/fid"
14585         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14586
14587         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14588         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14589                 error "touch invalid fid should fail."
14590
14591         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14592         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14593                 error "touch non-normal fid should fail."
14594
14595         echo "rename $tdir to $MOUNT/.lustre/fid"
14596         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14597                 error "rename to $MOUNT/.lustre/fid should fail."
14598
14599         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14600         then            # LU-3547
14601                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14602                 local new_obf_mode=777
14603
14604                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14605                 chmod $new_obf_mode $DIR/.lustre/fid ||
14606                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14607
14608                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14609                 [ $obf_mode -eq $new_obf_mode ] ||
14610                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14611
14612                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14613                 chmod $old_obf_mode $DIR/.lustre/fid ||
14614                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14615         fi
14616
14617         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14618         fid=$($LFS path2fid $test_dir/$tfile-2)
14619
14620         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14621         then # LU-5424
14622                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14623                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14624                         error "create lov data thru .lustre failed"
14625         fi
14626         echo "cp /etc/passwd $test_dir/$tfile-2"
14627         cp /etc/passwd $test_dir/$tfile-2 ||
14628                 error "copy to $test_dir/$tfile-2 failed."
14629         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14630         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14631                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14632
14633         rm -rf $test_dir/tfile.lnk
14634         rm -rf $test_dir/$tfile-2
14635 }
14636
14637 test_154A() {
14638         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14639                 skip "Need MDS version at least 2.4.1"
14640
14641         local tf=$DIR/$tfile
14642         touch $tf
14643
14644         local fid=$($LFS path2fid $tf)
14645         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14646
14647         # check that we get the same pathname back
14648         local rootpath
14649         local found
14650         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14651                 echo "$rootpath $fid"
14652                 found=$($LFS fid2path $rootpath "$fid")
14653                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14654                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14655         done
14656
14657         # check wrong root path format
14658         rootpath=$MOUNT"_wrong"
14659         found=$($LFS fid2path $rootpath "$fid")
14660         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14661 }
14662 run_test 154A "lfs path2fid and fid2path basic checks"
14663
14664 test_154B() {
14665         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14666                 skip "Need MDS version at least 2.4.1"
14667
14668         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14669         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14670         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14671         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14672
14673         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14674         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14675
14676         # check that we get the same pathname
14677         echo "PFID: $PFID, name: $name"
14678         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14679         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14680         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14681                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14682
14683         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14684 }
14685 run_test 154B "verify the ll_decode_linkea tool"
14686
14687 test_154a() {
14688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14689         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14690         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14691                 skip "Need MDS version at least 2.2.51"
14692         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14693
14694         cp /etc/hosts $DIR/$tfile
14695
14696         fid=$($LFS path2fid $DIR/$tfile)
14697         rc=$?
14698         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14699
14700         dot_lustre_fid_permission_check "$fid" $DIR ||
14701                 error "dot lustre permission check $fid failed"
14702
14703         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14704
14705         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14706
14707         touch $MOUNT/.lustre/file &&
14708                 error "creation is not allowed under .lustre"
14709
14710         mkdir $MOUNT/.lustre/dir &&
14711                 error "mkdir is not allowed under .lustre"
14712
14713         rm -rf $DIR/$tfile
14714 }
14715 run_test 154a "Open-by-FID"
14716
14717 test_154b() {
14718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14719         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14721         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14722                 skip "Need MDS version at least 2.2.51"
14723
14724         local remote_dir=$DIR/$tdir/remote_dir
14725         local MDTIDX=1
14726         local rc=0
14727
14728         mkdir -p $DIR/$tdir
14729         $LFS mkdir -i $MDTIDX $remote_dir ||
14730                 error "create remote directory failed"
14731
14732         cp /etc/hosts $remote_dir/$tfile
14733
14734         fid=$($LFS path2fid $remote_dir/$tfile)
14735         rc=$?
14736         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14737
14738         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14739                 error "dot lustre permission check $fid failed"
14740         rm -rf $DIR/$tdir
14741 }
14742 run_test 154b "Open-by-FID for remote directory"
14743
14744 test_154c() {
14745         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14746                 skip "Need MDS version at least 2.4.1"
14747
14748         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14749         local FID1=$($LFS path2fid $DIR/$tfile.1)
14750         local FID2=$($LFS path2fid $DIR/$tfile.2)
14751         local FID3=$($LFS path2fid $DIR/$tfile.3)
14752
14753         local N=1
14754         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14755                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14756                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14757                 local want=FID$N
14758                 [ "$FID" = "${!want}" ] ||
14759                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14760                 N=$((N + 1))
14761         done
14762
14763         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14764         do
14765                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14766                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14767                 N=$((N + 1))
14768         done
14769 }
14770 run_test 154c "lfs path2fid and fid2path multiple arguments"
14771
14772 test_154d() {
14773         remote_mds_nodsh && skip "remote MDS with nodsh"
14774         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14775                 skip "Need MDS version at least 2.5.53"
14776
14777         if remote_mds; then
14778                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14779         else
14780                 nid="0@lo"
14781         fi
14782         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14783         local fd
14784         local cmd
14785
14786         rm -f $DIR/$tfile
14787         touch $DIR/$tfile
14788
14789         local fid=$($LFS path2fid $DIR/$tfile)
14790         # Open the file
14791         fd=$(free_fd)
14792         cmd="exec $fd<$DIR/$tfile"
14793         eval $cmd
14794         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14795         echo "$fid_list" | grep "$fid"
14796         rc=$?
14797
14798         cmd="exec $fd>/dev/null"
14799         eval $cmd
14800         if [ $rc -ne 0 ]; then
14801                 error "FID $fid not found in open files list $fid_list"
14802         fi
14803 }
14804 run_test 154d "Verify open file fid"
14805
14806 test_154e()
14807 {
14808         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14809                 skip "Need MDS version at least 2.6.50"
14810
14811         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14812                 error ".lustre returned by readdir"
14813         fi
14814 }
14815 run_test 154e ".lustre is not returned by readdir"
14816
14817 test_154f() {
14818         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14819
14820         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14821         test_mkdir -p -c1 $DIR/$tdir/d
14822         # test dirs inherit from its stripe
14823         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14824         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14825         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14826         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14827         touch $DIR/f
14828
14829         # get fid of parents
14830         local FID0=$($LFS path2fid $DIR/$tdir/d)
14831         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14832         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14833         local FID3=$($LFS path2fid $DIR)
14834
14835         # check that path2fid --parents returns expected <parent_fid>/name
14836         # 1) test for a directory (single parent)
14837         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14838         [ "$parent" == "$FID0/foo1" ] ||
14839                 error "expected parent: $FID0/foo1, got: $parent"
14840
14841         # 2) test for a file with nlink > 1 (multiple parents)
14842         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14843         echo "$parent" | grep -F "$FID1/$tfile" ||
14844                 error "$FID1/$tfile not returned in parent list"
14845         echo "$parent" | grep -F "$FID2/link" ||
14846                 error "$FID2/link not returned in parent list"
14847
14848         # 3) get parent by fid
14849         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14850         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14851         echo "$parent" | grep -F "$FID1/$tfile" ||
14852                 error "$FID1/$tfile not returned in parent list (by fid)"
14853         echo "$parent" | grep -F "$FID2/link" ||
14854                 error "$FID2/link not returned in parent list (by fid)"
14855
14856         # 4) test for entry in root directory
14857         parent=$($LFS path2fid --parents $DIR/f)
14858         echo "$parent" | grep -F "$FID3/f" ||
14859                 error "$FID3/f not returned in parent list"
14860
14861         # 5) test it on root directory
14862         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14863                 error "$MOUNT should not have parents"
14864
14865         # enable xattr caching and check that linkea is correctly updated
14866         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14867         save_lustre_params client "llite.*.xattr_cache" > $save
14868         lctl set_param llite.*.xattr_cache 1
14869
14870         # 6.1) linkea update on rename
14871         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14872
14873         # get parents by fid
14874         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14875         # foo1 should no longer be returned in parent list
14876         echo "$parent" | grep -F "$FID1" &&
14877                 error "$FID1 should no longer be in parent list"
14878         # the new path should appear
14879         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14880                 error "$FID2/$tfile.moved is not in parent list"
14881
14882         # 6.2) linkea update on unlink
14883         rm -f $DIR/$tdir/d/foo2/link
14884         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14885         # foo2/link should no longer be returned in parent list
14886         echo "$parent" | grep -F "$FID2/link" &&
14887                 error "$FID2/link should no longer be in parent list"
14888         true
14889
14890         rm -f $DIR/f
14891         restore_lustre_params < $save
14892         rm -f $save
14893 }
14894 run_test 154f "get parent fids by reading link ea"
14895
14896 test_154g()
14897 {
14898         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14899         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14900            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14901                 skip "Need MDS version at least 2.6.92"
14902
14903         mkdir -p $DIR/$tdir
14904         llapi_fid_test -d $DIR/$tdir
14905 }
14906 run_test 154g "various llapi FID tests"
14907
14908 test_155_small_load() {
14909     local temp=$TMP/$tfile
14910     local file=$DIR/$tfile
14911
14912     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14913         error "dd of=$temp bs=6096 count=1 failed"
14914     cp $temp $file
14915     cancel_lru_locks $OSC
14916     cmp $temp $file || error "$temp $file differ"
14917
14918     $TRUNCATE $temp 6000
14919     $TRUNCATE $file 6000
14920     cmp $temp $file || error "$temp $file differ (truncate1)"
14921
14922     echo "12345" >>$temp
14923     echo "12345" >>$file
14924     cmp $temp $file || error "$temp $file differ (append1)"
14925
14926     echo "12345" >>$temp
14927     echo "12345" >>$file
14928     cmp $temp $file || error "$temp $file differ (append2)"
14929
14930     rm -f $temp $file
14931     true
14932 }
14933
14934 test_155_big_load() {
14935         remote_ost_nodsh && skip "remote OST with nodsh"
14936
14937         local temp=$TMP/$tfile
14938         local file=$DIR/$tfile
14939
14940         free_min_max
14941         local cache_size=$(do_facet ost$((MAXI+1)) \
14942                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14943         local large_file_size=$((cache_size * 2))
14944
14945         echo "OSS cache size: $cache_size KB"
14946         echo "Large file size: $large_file_size KB"
14947
14948         [ $MAXV -le $large_file_size ] &&
14949                 skip_env "max available OST size needs > $large_file_size KB"
14950
14951         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14952
14953         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14954                 error "dd of=$temp bs=$large_file_size count=1k failed"
14955         cp $temp $file
14956         ls -lh $temp $file
14957         cancel_lru_locks osc
14958         cmp $temp $file || error "$temp $file differ"
14959
14960         rm -f $temp $file
14961         true
14962 }
14963
14964 save_writethrough() {
14965         local facets=$(get_facets OST)
14966
14967         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14968 }
14969
14970 test_155a() {
14971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14972
14973         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14974
14975         save_writethrough $p
14976
14977         set_cache read on
14978         set_cache writethrough on
14979         test_155_small_load
14980         restore_lustre_params < $p
14981         rm -f $p
14982 }
14983 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14984
14985 test_155b() {
14986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14987
14988         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14989
14990         save_writethrough $p
14991
14992         set_cache read on
14993         set_cache writethrough off
14994         test_155_small_load
14995         restore_lustre_params < $p
14996         rm -f $p
14997 }
14998 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14999
15000 test_155c() {
15001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15002
15003         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15004
15005         save_writethrough $p
15006
15007         set_cache read off
15008         set_cache writethrough on
15009         test_155_small_load
15010         restore_lustre_params < $p
15011         rm -f $p
15012 }
15013 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15014
15015 test_155d() {
15016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15017
15018         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15019
15020         save_writethrough $p
15021
15022         set_cache read off
15023         set_cache writethrough off
15024         test_155_small_load
15025         restore_lustre_params < $p
15026         rm -f $p
15027 }
15028 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15029
15030 test_155e() {
15031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15032
15033         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15034
15035         save_writethrough $p
15036
15037         set_cache read on
15038         set_cache writethrough on
15039         test_155_big_load
15040         restore_lustre_params < $p
15041         rm -f $p
15042 }
15043 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15044
15045 test_155f() {
15046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15047
15048         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15049
15050         save_writethrough $p
15051
15052         set_cache read on
15053         set_cache writethrough off
15054         test_155_big_load
15055         restore_lustre_params < $p
15056         rm -f $p
15057 }
15058 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15059
15060 test_155g() {
15061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15062
15063         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15064
15065         save_writethrough $p
15066
15067         set_cache read off
15068         set_cache writethrough on
15069         test_155_big_load
15070         restore_lustre_params < $p
15071         rm -f $p
15072 }
15073 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15074
15075 test_155h() {
15076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15077
15078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15079
15080         save_writethrough $p
15081
15082         set_cache read off
15083         set_cache writethrough off
15084         test_155_big_load
15085         restore_lustre_params < $p
15086         rm -f $p
15087 }
15088 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15089
15090 test_156() {
15091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15092         remote_ost_nodsh && skip "remote OST with nodsh"
15093         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15094                 skip "stats not implemented on old servers"
15095         [ "$ost1_FSTYPE" = "zfs" ] &&
15096                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15097
15098         local CPAGES=3
15099         local BEFORE
15100         local AFTER
15101         local file="$DIR/$tfile"
15102         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15103
15104         save_writethrough $p
15105         roc_hit_init
15106
15107         log "Turn on read and write cache"
15108         set_cache read on
15109         set_cache writethrough on
15110
15111         log "Write data and read it back."
15112         log "Read should be satisfied from the cache."
15113         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15114         BEFORE=$(roc_hit)
15115         cancel_lru_locks osc
15116         cat $file >/dev/null
15117         AFTER=$(roc_hit)
15118         if ! let "AFTER - BEFORE == CPAGES"; then
15119                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15120         else
15121                 log "cache hits: before: $BEFORE, after: $AFTER"
15122         fi
15123
15124         log "Read again; it should be satisfied from the cache."
15125         BEFORE=$AFTER
15126         cancel_lru_locks osc
15127         cat $file >/dev/null
15128         AFTER=$(roc_hit)
15129         if ! let "AFTER - BEFORE == CPAGES"; then
15130                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15131         else
15132                 log "cache hits:: before: $BEFORE, after: $AFTER"
15133         fi
15134
15135         log "Turn off the read cache and turn on the write cache"
15136         set_cache read off
15137         set_cache writethrough on
15138
15139         log "Read again; it should be satisfied from the cache."
15140         BEFORE=$(roc_hit)
15141         cancel_lru_locks osc
15142         cat $file >/dev/null
15143         AFTER=$(roc_hit)
15144         if ! let "AFTER - BEFORE == CPAGES"; then
15145                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15146         else
15147                 log "cache hits:: before: $BEFORE, after: $AFTER"
15148         fi
15149
15150         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15151                 # > 2.12.56 uses pagecache if cached
15152                 log "Read again; it should not be satisfied from the cache."
15153                 BEFORE=$AFTER
15154                 cancel_lru_locks osc
15155                 cat $file >/dev/null
15156                 AFTER=$(roc_hit)
15157                 if ! let "AFTER - BEFORE == 0"; then
15158                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15159                 else
15160                         log "cache hits:: before: $BEFORE, after: $AFTER"
15161                 fi
15162         fi
15163
15164         log "Write data and read it back."
15165         log "Read should be satisfied from the cache."
15166         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15167         BEFORE=$(roc_hit)
15168         cancel_lru_locks osc
15169         cat $file >/dev/null
15170         AFTER=$(roc_hit)
15171         if ! let "AFTER - BEFORE == CPAGES"; then
15172                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15173         else
15174                 log "cache hits:: before: $BEFORE, after: $AFTER"
15175         fi
15176
15177         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15178                 # > 2.12.56 uses pagecache if cached
15179                 log "Read again; it should not be satisfied from the cache."
15180                 BEFORE=$AFTER
15181                 cancel_lru_locks osc
15182                 cat $file >/dev/null
15183                 AFTER=$(roc_hit)
15184                 if ! let "AFTER - BEFORE == 0"; then
15185                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15186                 else
15187                         log "cache hits:: before: $BEFORE, after: $AFTER"
15188                 fi
15189         fi
15190
15191         log "Turn off read and write cache"
15192         set_cache read off
15193         set_cache writethrough off
15194
15195         log "Write data and read it back"
15196         log "It should not be satisfied from the cache."
15197         rm -f $file
15198         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15199         cancel_lru_locks osc
15200         BEFORE=$(roc_hit)
15201         cat $file >/dev/null
15202         AFTER=$(roc_hit)
15203         if ! let "AFTER - BEFORE == 0"; then
15204                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15205         else
15206                 log "cache hits:: before: $BEFORE, after: $AFTER"
15207         fi
15208
15209         log "Turn on the read cache and turn off the write cache"
15210         set_cache read on
15211         set_cache writethrough off
15212
15213         log "Write data and read it back"
15214         log "It should not be satisfied from the cache."
15215         rm -f $file
15216         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15217         BEFORE=$(roc_hit)
15218         cancel_lru_locks osc
15219         cat $file >/dev/null
15220         AFTER=$(roc_hit)
15221         if ! let "AFTER - BEFORE == 0"; then
15222                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15223         else
15224                 log "cache hits:: before: $BEFORE, after: $AFTER"
15225         fi
15226
15227         log "Read again; it should be satisfied from the cache."
15228         BEFORE=$(roc_hit)
15229         cancel_lru_locks osc
15230         cat $file >/dev/null
15231         AFTER=$(roc_hit)
15232         if ! let "AFTER - BEFORE == CPAGES"; then
15233                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15234         else
15235                 log "cache hits:: before: $BEFORE, after: $AFTER"
15236         fi
15237
15238         restore_lustre_params < $p
15239         rm -f $p $file
15240 }
15241 run_test 156 "Verification of tunables"
15242
15243 test_160a() {
15244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15245         remote_mds_nodsh && skip "remote MDS with nodsh"
15246         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15247                 skip "Need MDS version at least 2.2.0"
15248
15249         changelog_register || error "changelog_register failed"
15250         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15251         changelog_users $SINGLEMDS | grep -q $cl_user ||
15252                 error "User $cl_user not found in changelog_users"
15253
15254         # change something
15255         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15256         changelog_clear 0 || error "changelog_clear failed"
15257         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15258         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15259         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15260         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15261         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15262         rm $DIR/$tdir/pics/desktop.jpg
15263
15264         changelog_dump | tail -10
15265
15266         echo "verifying changelog mask"
15267         changelog_chmask "-MKDIR"
15268         changelog_chmask "-CLOSE"
15269
15270         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15271         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15272
15273         changelog_chmask "+MKDIR"
15274         changelog_chmask "+CLOSE"
15275
15276         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15277         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15278
15279         changelog_dump | tail -10
15280         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15281         CLOSES=$(changelog_dump | grep -c "CLOSE")
15282         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15283         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15284
15285         # verify contents
15286         echo "verifying target fid"
15287         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15288         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15289         [ "$fidc" == "$fidf" ] ||
15290                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15291         echo "verifying parent fid"
15292         # The FID returned from the Changelog may be the directory shard on
15293         # a different MDT, and not the FID returned by path2fid on the parent.
15294         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15295         # since this is what will matter when recreating this file in the tree.
15296         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15297         local pathp=$($LFS fid2path $MOUNT "$fidp")
15298         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15299                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15300
15301         echo "getting records for $cl_user"
15302         changelog_users $SINGLEMDS
15303         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15304         local nclr=3
15305         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15306                 error "changelog_clear failed"
15307         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15308         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15309         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15310                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15311
15312         local min0_rec=$(changelog_users $SINGLEMDS |
15313                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15314         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15315                           awk '{ print $1; exit; }')
15316
15317         changelog_dump | tail -n 5
15318         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15319         [ $first_rec == $((min0_rec + 1)) ] ||
15320                 error "first index should be $min0_rec + 1 not $first_rec"
15321
15322         # LU-3446 changelog index reset on MDT restart
15323         local cur_rec1=$(changelog_users $SINGLEMDS |
15324                          awk '/^current.index:/ { print $NF }')
15325         changelog_clear 0 ||
15326                 error "clear all changelog records for $cl_user failed"
15327         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15328         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15329                 error "Fail to start $SINGLEMDS"
15330         local cur_rec2=$(changelog_users $SINGLEMDS |
15331                          awk '/^current.index:/ { print $NF }')
15332         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15333         [ $cur_rec1 == $cur_rec2 ] ||
15334                 error "current index should be $cur_rec1 not $cur_rec2"
15335
15336         echo "verifying users from this test are deregistered"
15337         changelog_deregister || error "changelog_deregister failed"
15338         changelog_users $SINGLEMDS | grep -q $cl_user &&
15339                 error "User '$cl_user' still in changelog_users"
15340
15341         # lctl get_param -n mdd.*.changelog_users
15342         # current index: 144
15343         # ID    index (idle seconds)
15344         # cl3   144 (2)
15345         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15346                 # this is the normal case where all users were deregistered
15347                 # make sure no new records are added when no users are present
15348                 local last_rec1=$(changelog_users $SINGLEMDS |
15349                                   awk '/^current.index:/ { print $NF }')
15350                 touch $DIR/$tdir/chloe
15351                 local last_rec2=$(changelog_users $SINGLEMDS |
15352                                   awk '/^current.index:/ { print $NF }')
15353                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15354                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15355         else
15356                 # any changelog users must be leftovers from a previous test
15357                 changelog_users $SINGLEMDS
15358                 echo "other changelog users; can't verify off"
15359         fi
15360 }
15361 run_test 160a "changelog sanity"
15362
15363 test_160b() { # LU-3587
15364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15365         remote_mds_nodsh && skip "remote MDS with nodsh"
15366         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15367                 skip "Need MDS version at least 2.2.0"
15368
15369         changelog_register || error "changelog_register failed"
15370         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15371         changelog_users $SINGLEMDS | grep -q $cl_user ||
15372                 error "User '$cl_user' not found in changelog_users"
15373
15374         local longname1=$(str_repeat a 255)
15375         local longname2=$(str_repeat b 255)
15376
15377         cd $DIR
15378         echo "creating very long named file"
15379         touch $longname1 || error "create of '$longname1' failed"
15380         echo "renaming very long named file"
15381         mv $longname1 $longname2
15382
15383         changelog_dump | grep RENME | tail -n 5
15384         rm -f $longname2
15385 }
15386 run_test 160b "Verify that very long rename doesn't crash in changelog"
15387
15388 test_160c() {
15389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15390         remote_mds_nodsh && skip "remote MDS with nodsh"
15391
15392         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15393                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15394                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15395                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15396
15397         local rc=0
15398
15399         # Registration step
15400         changelog_register || error "changelog_register failed"
15401
15402         rm -rf $DIR/$tdir
15403         mkdir -p $DIR/$tdir
15404         $MCREATE $DIR/$tdir/foo_160c
15405         changelog_chmask "-TRUNC"
15406         $TRUNCATE $DIR/$tdir/foo_160c 200
15407         changelog_chmask "+TRUNC"
15408         $TRUNCATE $DIR/$tdir/foo_160c 199
15409         changelog_dump | tail -n 5
15410         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15411         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15412 }
15413 run_test 160c "verify that changelog log catch the truncate event"
15414
15415 test_160d() {
15416         remote_mds_nodsh && skip "remote MDS with nodsh"
15417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15419         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15420                 skip "Need MDS version at least 2.7.60"
15421
15422         # Registration step
15423         changelog_register || error "changelog_register failed"
15424
15425         mkdir -p $DIR/$tdir/migrate_dir
15426         changelog_clear 0 || error "changelog_clear failed"
15427
15428         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15429         changelog_dump | tail -n 5
15430         local migrates=$(changelog_dump | grep -c "MIGRT")
15431         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15432 }
15433 run_test 160d "verify that changelog log catch the migrate event"
15434
15435 test_160e() {
15436         remote_mds_nodsh && skip "remote MDS with nodsh"
15437
15438         # Create a user
15439         changelog_register || error "changelog_register failed"
15440
15441         # Delete a future user (expect fail)
15442         local MDT0=$(facet_svc $SINGLEMDS)
15443         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15444         local rc=$?
15445
15446         if [ $rc -eq 0 ]; then
15447                 error "Deleted non-existant user cl77"
15448         elif [ $rc -ne 2 ]; then
15449                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15450         fi
15451
15452         # Clear to a bad index (1 billion should be safe)
15453         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15454         rc=$?
15455
15456         if [ $rc -eq 0 ]; then
15457                 error "Successfully cleared to invalid CL index"
15458         elif [ $rc -ne 22 ]; then
15459                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15460         fi
15461 }
15462 run_test 160e "changelog negative testing (should return errors)"
15463
15464 test_160f() {
15465         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15466         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15467                 skip "Need MDS version at least 2.10.56"
15468
15469         local mdts=$(comma_list $(mdts_nodes))
15470
15471         # Create a user
15472         changelog_register || error "first changelog_register failed"
15473         changelog_register || error "second changelog_register failed"
15474         local cl_users
15475         declare -A cl_user1
15476         declare -A cl_user2
15477         local user_rec1
15478         local user_rec2
15479         local i
15480
15481         # generate some changelog records to accumulate on each MDT
15482         # use all_char because created files should be evenly distributed
15483         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15484                 error "test_mkdir $tdir failed"
15485         log "$(date +%s): creating first files"
15486         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15487                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15488                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15489         done
15490
15491         # check changelogs have been generated
15492         local start=$SECONDS
15493         local idle_time=$((MDSCOUNT * 5 + 5))
15494         local nbcl=$(changelog_dump | wc -l)
15495         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15496
15497         for param in "changelog_max_idle_time=$idle_time" \
15498                      "changelog_gc=1" \
15499                      "changelog_min_gc_interval=2" \
15500                      "changelog_min_free_cat_entries=3"; do
15501                 local MDT0=$(facet_svc $SINGLEMDS)
15502                 local var="${param%=*}"
15503                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15504
15505                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15506                 do_nodes $mdts $LCTL set_param mdd.*.$param
15507         done
15508
15509         # force cl_user2 to be idle (1st part), but also cancel the
15510         # cl_user1 records so that it is not evicted later in the test.
15511         local sleep1=$((idle_time / 2))
15512         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15513         sleep $sleep1
15514
15515         # simulate changelog catalog almost full
15516         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15517         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15518
15519         for i in $(seq $MDSCOUNT); do
15520                 cl_users=(${CL_USERS[mds$i]})
15521                 cl_user1[mds$i]="${cl_users[0]}"
15522                 cl_user2[mds$i]="${cl_users[1]}"
15523
15524                 [ -n "${cl_user1[mds$i]}" ] ||
15525                         error "mds$i: no user registered"
15526                 [ -n "${cl_user2[mds$i]}" ] ||
15527                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15528
15529                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15530                 [ -n "$user_rec1" ] ||
15531                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15532                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15533                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15534                 [ -n "$user_rec2" ] ||
15535                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15536                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15537                      "$user_rec1 + 2 == $user_rec2"
15538                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15539                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15540                               "$user_rec1 + 2, but is $user_rec2"
15541                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15542                 [ -n "$user_rec2" ] ||
15543                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15544                 [ $user_rec1 == $user_rec2 ] ||
15545                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15546                               "$user_rec1, but is $user_rec2"
15547         done
15548
15549         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15550         local sleep2=$((idle_time - (SECONDS - start) + 1))
15551         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15552         sleep $sleep2
15553
15554         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15555         # cl_user1 should be OK because it recently processed records.
15556         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15557         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15558                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15559                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15560         done
15561
15562         # ensure gc thread is done
15563         for i in $(mdts_nodes); do
15564                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15565                         error "$i: GC-thread not done"
15566         done
15567
15568         local first_rec
15569         for (( i = 1; i <= MDSCOUNT; i++ )); do
15570                 # check cl_user1 still registered
15571                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15572                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15573                 # check cl_user2 unregistered
15574                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15575                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15576
15577                 # check changelogs are present and starting at $user_rec1 + 1
15578                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15579                 [ -n "$user_rec1" ] ||
15580                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15581                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15582                             awk '{ print $1; exit; }')
15583
15584                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15585                 [ $((user_rec1 + 1)) == $first_rec ] ||
15586                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15587         done
15588 }
15589 run_test 160f "changelog garbage collect (timestamped users)"
15590
15591 test_160g() {
15592         remote_mds_nodsh && skip "remote MDS with nodsh"
15593         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15594                 skip "Need MDS version at least 2.10.56"
15595
15596         local mdts=$(comma_list $(mdts_nodes))
15597
15598         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15599         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15600
15601         # Create a user
15602         changelog_register || error "first changelog_register failed"
15603         changelog_register || error "second changelog_register failed"
15604         local cl_users
15605         declare -A cl_user1
15606         declare -A cl_user2
15607         local user_rec1
15608         local user_rec2
15609         local i
15610
15611         # generate some changelog records to accumulate on each MDT
15612         # use all_char because created files should be evenly distributed
15613         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15614                 error "test_mkdir $tdir failed"
15615         for ((i = 0; i < MDSCOUNT; i++)); do
15616                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15617                         error "create $DIR/$tdir/d$i.1 failed"
15618         done
15619
15620         # check changelogs have been generated
15621         local nbcl=$(changelog_dump | wc -l)
15622         (( $nbcl > 0 )) || error "no changelogs found"
15623
15624         # reduce the max_idle_indexes value to make sure we exceed it
15625         for param in "changelog_max_idle_indexes=1" \
15626                      "changelog_gc=1" \
15627                      "changelog_min_gc_interval=2" \
15628                      "changelog_min_free_cat_entries=3"; do
15629                 local MDT0=$(facet_svc $SINGLEMDS)
15630                 local var="${param%=*}"
15631                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15632
15633                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15634                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15635                         error "unable to set mdd.*.$param"
15636         done
15637
15638         # simulate changelog catalog almost full
15639         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15640         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15641
15642         local start=$SECONDS
15643         for i in $(seq $MDSCOUNT); do
15644                 cl_users=(${CL_USERS[mds$i]})
15645                 cl_user1[mds$i]="${cl_users[0]}"
15646                 cl_user2[mds$i]="${cl_users[1]}"
15647
15648                 [ -n "${cl_user1[mds$i]}" ] ||
15649                         error "mds$i: no user registered"
15650                 [ -n "${cl_user2[mds$i]}" ] ||
15651                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15652
15653                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15654                 [ -n "$user_rec1" ] ||
15655                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15656                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15657                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15658                 [ -n "$user_rec2" ] ||
15659                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15660                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15661                      "$user_rec1 + 2 == $user_rec2"
15662                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15663                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15664                               "$user_rec1 + 2, but is $user_rec2"
15665                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15666                 [ -n "$user_rec2" ] ||
15667                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15668                 [ $user_rec1 == $user_rec2 ] ||
15669                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15670                               "$user_rec1, but is $user_rec2"
15671         done
15672
15673         # ensure we are past the previous changelog_min_gc_interval set above
15674         local sleep2=$((start + 2 - SECONDS))
15675         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15676
15677         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15678         # cl_user1 should be OK because it recently processed records.
15679         for ((i = 0; i < MDSCOUNT; i++)); do
15680                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15681                         error "create $DIR/$tdir/d$i.3 failed"
15682         done
15683
15684         # ensure gc thread is done
15685         for i in $(mdts_nodes); do
15686                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15687                         error "$i: GC-thread not done"
15688         done
15689
15690         local first_rec
15691         for (( i = 1; i <= MDSCOUNT; i++ )); do
15692                 # check cl_user1 still registered
15693                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15694                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15695                 # check cl_user2 unregistered
15696                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15697                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15698
15699                 # check changelogs are present and starting at $user_rec1 + 1
15700                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15701                 [ -n "$user_rec1" ] ||
15702                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15703                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15704                             awk '{ print $1; exit; }')
15705
15706                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15707                 [ $((user_rec1 + 1)) == $first_rec ] ||
15708                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15709         done
15710 }
15711 run_test 160g "changelog garbage collect (old users)"
15712
15713 test_160h() {
15714         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15715         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15716                 skip "Need MDS version at least 2.10.56"
15717
15718         local mdts=$(comma_list $(mdts_nodes))
15719
15720         # Create a user
15721         changelog_register || error "first changelog_register failed"
15722         changelog_register || error "second changelog_register failed"
15723         local cl_users
15724         declare -A cl_user1
15725         declare -A cl_user2
15726         local user_rec1
15727         local user_rec2
15728         local i
15729
15730         # generate some changelog records to accumulate on each MDT
15731         # use all_char because created files should be evenly distributed
15732         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15733                 error "test_mkdir $tdir failed"
15734         for ((i = 0; i < MDSCOUNT; i++)); do
15735                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15736                         error "create $DIR/$tdir/d$i.1 failed"
15737         done
15738
15739         # check changelogs have been generated
15740         local nbcl=$(changelog_dump | wc -l)
15741         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15742
15743         for param in "changelog_max_idle_time=10" \
15744                      "changelog_gc=1" \
15745                      "changelog_min_gc_interval=2"; do
15746                 local MDT0=$(facet_svc $SINGLEMDS)
15747                 local var="${param%=*}"
15748                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15749
15750                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15751                 do_nodes $mdts $LCTL set_param mdd.*.$param
15752         done
15753
15754         # force cl_user2 to be idle (1st part)
15755         sleep 9
15756
15757         for i in $(seq $MDSCOUNT); do
15758                 cl_users=(${CL_USERS[mds$i]})
15759                 cl_user1[mds$i]="${cl_users[0]}"
15760                 cl_user2[mds$i]="${cl_users[1]}"
15761
15762                 [ -n "${cl_user1[mds$i]}" ] ||
15763                         error "mds$i: no user registered"
15764                 [ -n "${cl_user2[mds$i]}" ] ||
15765                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15766
15767                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15768                 [ -n "$user_rec1" ] ||
15769                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15770                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15771                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15772                 [ -n "$user_rec2" ] ||
15773                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15774                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15775                      "$user_rec1 + 2 == $user_rec2"
15776                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15777                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15778                               "$user_rec1 + 2, but is $user_rec2"
15779                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15780                 [ -n "$user_rec2" ] ||
15781                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15782                 [ $user_rec1 == $user_rec2 ] ||
15783                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15784                               "$user_rec1, but is $user_rec2"
15785         done
15786
15787         # force cl_user2 to be idle (2nd part) and to reach
15788         # changelog_max_idle_time
15789         sleep 2
15790
15791         # force each GC-thread start and block then
15792         # one per MDT/MDD, set fail_val accordingly
15793         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15794         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15795
15796         # generate more changelogs to trigger fail_loc
15797         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15798                 error "create $DIR/$tdir/${tfile}bis failed"
15799
15800         # stop MDT to stop GC-thread, should be done in back-ground as it will
15801         # block waiting for the thread to be released and exit
15802         declare -A stop_pids
15803         for i in $(seq $MDSCOUNT); do
15804                 stop mds$i &
15805                 stop_pids[mds$i]=$!
15806         done
15807
15808         for i in $(mdts_nodes); do
15809                 local facet
15810                 local nb=0
15811                 local facets=$(facets_up_on_host $i)
15812
15813                 for facet in ${facets//,/ }; do
15814                         if [[ $facet == mds* ]]; then
15815                                 nb=$((nb + 1))
15816                         fi
15817                 done
15818                 # ensure each MDS's gc threads are still present and all in "R"
15819                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15820                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15821                         error "$i: expected $nb GC-thread"
15822                 wait_update $i \
15823                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15824                         "R" 20 ||
15825                         error "$i: GC-thread not found in R-state"
15826                 # check umounts of each MDT on MDS have reached kthread_stop()
15827                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15828                         error "$i: expected $nb umount"
15829                 wait_update $i \
15830                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15831                         error "$i: umount not found in D-state"
15832         done
15833
15834         # release all GC-threads
15835         do_nodes $mdts $LCTL set_param fail_loc=0
15836
15837         # wait for MDT stop to complete
15838         for i in $(seq $MDSCOUNT); do
15839                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15840         done
15841
15842         # XXX
15843         # may try to check if any orphan changelog records are present
15844         # via ldiskfs/zfs and llog_reader...
15845
15846         # re-start/mount MDTs
15847         for i in $(seq $MDSCOUNT); do
15848                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15849                         error "Fail to start mds$i"
15850         done
15851
15852         local first_rec
15853         for i in $(seq $MDSCOUNT); do
15854                 # check cl_user1 still registered
15855                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15856                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15857                 # check cl_user2 unregistered
15858                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15859                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15860
15861                 # check changelogs are present and starting at $user_rec1 + 1
15862                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15863                 [ -n "$user_rec1" ] ||
15864                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15865                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15866                             awk '{ print $1; exit; }')
15867
15868                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15869                 [ $((user_rec1 + 1)) == $first_rec ] ||
15870                         error "mds$i: first index should be $user_rec1 + 1, " \
15871                               "but is $first_rec"
15872         done
15873 }
15874 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15875               "during mount"
15876
15877 test_160i() {
15878
15879         local mdts=$(comma_list $(mdts_nodes))
15880
15881         changelog_register || error "first changelog_register failed"
15882
15883         # generate some changelog records to accumulate on each MDT
15884         # use all_char because created files should be evenly distributed
15885         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15886                 error "test_mkdir $tdir failed"
15887         for ((i = 0; i < MDSCOUNT; i++)); do
15888                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15889                         error "create $DIR/$tdir/d$i.1 failed"
15890         done
15891
15892         # check changelogs have been generated
15893         local nbcl=$(changelog_dump | wc -l)
15894         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15895
15896         # simulate race between register and unregister
15897         # XXX as fail_loc is set per-MDS, with DNE configs the race
15898         # simulation will only occur for one MDT per MDS and for the
15899         # others the normal race scenario will take place
15900         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15901         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15902         do_nodes $mdts $LCTL set_param fail_val=1
15903
15904         # unregister 1st user
15905         changelog_deregister &
15906         local pid1=$!
15907         # wait some time for deregister work to reach race rdv
15908         sleep 2
15909         # register 2nd user
15910         changelog_register || error "2nd user register failed"
15911
15912         wait $pid1 || error "1st user deregister failed"
15913
15914         local i
15915         local last_rec
15916         declare -A LAST_REC
15917         for i in $(seq $MDSCOUNT); do
15918                 if changelog_users mds$i | grep "^cl"; then
15919                         # make sure new records are added with one user present
15920                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15921                                           awk '/^current.index:/ { print $NF }')
15922                 else
15923                         error "mds$i has no user registered"
15924                 fi
15925         done
15926
15927         # generate more changelog records to accumulate on each MDT
15928         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15929                 error "create $DIR/$tdir/${tfile}bis failed"
15930
15931         for i in $(seq $MDSCOUNT); do
15932                 last_rec=$(changelog_users $SINGLEMDS |
15933                            awk '/^current.index:/ { print $NF }')
15934                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15935                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15936                         error "changelogs are off on mds$i"
15937         done
15938 }
15939 run_test 160i "changelog user register/unregister race"
15940
15941 test_160j() {
15942         remote_mds_nodsh && skip "remote MDS with nodsh"
15943         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15944                 skip "Need MDS version at least 2.12.56"
15945
15946         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15947         stack_trap "umount $MOUNT2" EXIT
15948
15949         changelog_register || error "first changelog_register failed"
15950         stack_trap "changelog_deregister" EXIT
15951
15952         # generate some changelog
15953         # use all_char because created files should be evenly distributed
15954         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15955                 error "mkdir $tdir failed"
15956         for ((i = 0; i < MDSCOUNT; i++)); do
15957                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15958                         error "create $DIR/$tdir/d$i.1 failed"
15959         done
15960
15961         # open the changelog device
15962         exec 3>/dev/changelog-$FSNAME-MDT0000
15963         stack_trap "exec 3>&-" EXIT
15964         exec 4</dev/changelog-$FSNAME-MDT0000
15965         stack_trap "exec 4<&-" EXIT
15966
15967         # umount the first lustre mount
15968         umount $MOUNT
15969         stack_trap "mount_client $MOUNT" EXIT
15970
15971         # read changelog, which may or may not fail, but should not crash
15972         cat <&4 >/dev/null
15973
15974         # clear changelog
15975         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15976         changelog_users $SINGLEMDS | grep -q $cl_user ||
15977                 error "User $cl_user not found in changelog_users"
15978
15979         printf 'clear:'$cl_user':0' >&3
15980 }
15981 run_test 160j "client can be umounted while its chanangelog is being used"
15982
15983 test_160k() {
15984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15985         remote_mds_nodsh && skip "remote MDS with nodsh"
15986
15987         mkdir -p $DIR/$tdir/1/1
15988
15989         changelog_register || error "changelog_register failed"
15990         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15991
15992         changelog_users $SINGLEMDS | grep -q $cl_user ||
15993                 error "User '$cl_user' not found in changelog_users"
15994 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15995         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15996         rmdir $DIR/$tdir/1/1 & sleep 1
15997         mkdir $DIR/$tdir/2
15998         touch $DIR/$tdir/2/2
15999         rm -rf $DIR/$tdir/2
16000
16001         wait
16002         sleep 4
16003
16004         changelog_dump | grep rmdir || error "rmdir not recorded"
16005 }
16006 run_test 160k "Verify that changelog records are not lost"
16007
16008 # Verifies that a file passed as a parameter has recently had an operation
16009 # performed on it that has generated an MTIME changelog which contains the
16010 # correct parent FID. As files might reside on a different MDT from the
16011 # parent directory in DNE configurations, the FIDs are translated to paths
16012 # before being compared, which should be identical
16013 compare_mtime_changelog() {
16014         local file="${1}"
16015         local mdtidx
16016         local mtime
16017         local cl_fid
16018         local pdir
16019         local dir
16020
16021         mdtidx=$($LFS getstripe --mdt-index $file)
16022         mdtidx=$(printf "%04x" $mdtidx)
16023
16024         # Obtain the parent FID from the MTIME changelog
16025         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16026         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16027
16028         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16029         [ -z "$cl_fid" ] && error "parent FID not present"
16030
16031         # Verify that the path for the parent FID is the same as the path for
16032         # the test directory
16033         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16034
16035         dir=$(dirname $1)
16036
16037         [[ "${pdir%/}" == "$dir" ]] ||
16038                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16039 }
16040
16041 test_160l() {
16042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16043
16044         remote_mds_nodsh && skip "remote MDS with nodsh"
16045         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16046                 skip "Need MDS version at least 2.13.55"
16047
16048         local cl_user
16049
16050         changelog_register || error "changelog_register failed"
16051         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16052
16053         changelog_users $SINGLEMDS | grep -q $cl_user ||
16054                 error "User '$cl_user' not found in changelog_users"
16055
16056         # Clear some types so that MTIME changelogs are generated
16057         changelog_chmask "-CREAT"
16058         changelog_chmask "-CLOSE"
16059
16060         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16061
16062         # Test CL_MTIME during setattr
16063         touch $DIR/$tdir/$tfile
16064         compare_mtime_changelog $DIR/$tdir/$tfile
16065
16066         # Test CL_MTIME during close
16067         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16068         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16069 }
16070 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16071
16072 test_160m() {
16073         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16074         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16075                 skip "Need MDS version at least 2.14.51"
16076         local cl_users
16077         local cl_user1
16078         local cl_user2
16079         local pid1
16080
16081         # Create a user
16082         changelog_register || error "first changelog_register failed"
16083         changelog_register || error "second changelog_register failed"
16084
16085         cl_users=(${CL_USERS[mds1]})
16086         cl_user1="${cl_users[0]}"
16087         cl_user2="${cl_users[1]}"
16088         # generate some changelog records to accumulate on MDT0
16089         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16090         createmany -m $DIR/$tdir/$tfile 50 ||
16091                 error "create $DIR/$tdir/$tfile failed"
16092         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16093         rm -f $DIR/$tdir
16094
16095         # check changelogs have been generated
16096         local nbcl=$(changelog_dump | wc -l)
16097         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16098
16099 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16100         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16101
16102         __changelog_clear mds1 $cl_user1 +10
16103         __changelog_clear mds1 $cl_user2 0 &
16104         pid1=$!
16105         sleep 2
16106         __changelog_clear mds1 $cl_user1 0 ||
16107                 error "fail to cancel record for $cl_user1"
16108         wait $pid1
16109         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16110 }
16111 run_test 160m "Changelog clear race"
16112
16113 test_160n() {
16114         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16115         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16116                 skip "Need MDS version at least 2.14.51"
16117         local cl_users
16118         local cl_user1
16119         local cl_user2
16120         local pid1
16121         local first_rec
16122         local last_rec=0
16123
16124         # Create a user
16125         changelog_register || error "first changelog_register failed"
16126
16127         cl_users=(${CL_USERS[mds1]})
16128         cl_user1="${cl_users[0]}"
16129
16130         # generate some changelog records to accumulate on MDT0
16131         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16132         first_rec=$(changelog_users $SINGLEMDS |
16133                         awk '/^current.index:/ { print $NF }')
16134         while (( last_rec < (( first_rec + 65000)) )); do
16135                 createmany -m $DIR/$tdir/$tfile 10000 ||
16136                         error "create $DIR/$tdir/$tfile failed"
16137
16138                 for i in $(seq 0 10000); do
16139                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16140                                 > /dev/null
16141                 done
16142
16143                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16144                         error "unlinkmany failed unlink"
16145                 last_rec=$(changelog_users $SINGLEMDS |
16146                         awk '/^current.index:/ { print $NF }')
16147                 echo last record $last_rec
16148                 (( last_rec == 0 )) && error "no changelog found"
16149         done
16150
16151 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16152         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16153
16154         __changelog_clear mds1 $cl_user1 0 &
16155         pid1=$!
16156         sleep 2
16157         __changelog_clear mds1 $cl_user1 0 ||
16158                 error "fail to cancel record for $cl_user1"
16159         wait $pid1
16160         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16161 }
16162 run_test 160n "Changelog destroy race"
16163
16164 test_161a() {
16165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16166
16167         test_mkdir -c1 $DIR/$tdir
16168         cp /etc/hosts $DIR/$tdir/$tfile
16169         test_mkdir -c1 $DIR/$tdir/foo1
16170         test_mkdir -c1 $DIR/$tdir/foo2
16171         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16172         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16173         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16174         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16175         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16176         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16177                 $LFS fid2path $DIR $FID
16178                 error "bad link ea"
16179         fi
16180         # middle
16181         rm $DIR/$tdir/foo2/zachary
16182         # last
16183         rm $DIR/$tdir/foo2/thor
16184         # first
16185         rm $DIR/$tdir/$tfile
16186         # rename
16187         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16188         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16189                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16190         rm $DIR/$tdir/foo2/maggie
16191
16192         # overflow the EA
16193         local longname=$tfile.avg_len_is_thirty_two_
16194         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16195                 error_noexit 'failed to unlink many hardlinks'" EXIT
16196         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16197                 error "failed to hardlink many files"
16198         links=$($LFS fid2path $DIR $FID | wc -l)
16199         echo -n "${links}/1000 links in link EA"
16200         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16201 }
16202 run_test 161a "link ea sanity"
16203
16204 test_161b() {
16205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16206         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16207
16208         local MDTIDX=1
16209         local remote_dir=$DIR/$tdir/remote_dir
16210
16211         mkdir -p $DIR/$tdir
16212         $LFS mkdir -i $MDTIDX $remote_dir ||
16213                 error "create remote directory failed"
16214
16215         cp /etc/hosts $remote_dir/$tfile
16216         mkdir -p $remote_dir/foo1
16217         mkdir -p $remote_dir/foo2
16218         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16219         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16220         ln $remote_dir/$tfile $remote_dir/foo1/luna
16221         ln $remote_dir/$tfile $remote_dir/foo2/thor
16222
16223         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16224                      tr -d ']')
16225         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16226                 $LFS fid2path $DIR $FID
16227                 error "bad link ea"
16228         fi
16229         # middle
16230         rm $remote_dir/foo2/zachary
16231         # last
16232         rm $remote_dir/foo2/thor
16233         # first
16234         rm $remote_dir/$tfile
16235         # rename
16236         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16237         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16238         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16239                 $LFS fid2path $DIR $FID
16240                 error "bad link rename"
16241         fi
16242         rm $remote_dir/foo2/maggie
16243
16244         # overflow the EA
16245         local longname=filename_avg_len_is_thirty_two_
16246         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16247                 error "failed to hardlink many files"
16248         links=$($LFS fid2path $DIR $FID | wc -l)
16249         echo -n "${links}/1000 links in link EA"
16250         [[ ${links} -gt 60 ]] ||
16251                 error "expected at least 60 links in link EA"
16252         unlinkmany $remote_dir/foo2/$longname 1000 ||
16253         error "failed to unlink many hardlinks"
16254 }
16255 run_test 161b "link ea sanity under remote directory"
16256
16257 test_161c() {
16258         remote_mds_nodsh && skip "remote MDS with nodsh"
16259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16260         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16261                 skip "Need MDS version at least 2.1.5"
16262
16263         # define CLF_RENAME_LAST 0x0001
16264         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16265         changelog_register || error "changelog_register failed"
16266
16267         rm -rf $DIR/$tdir
16268         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16269         touch $DIR/$tdir/foo_161c
16270         touch $DIR/$tdir/bar_161c
16271         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16272         changelog_dump | grep RENME | tail -n 5
16273         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16274         changelog_clear 0 || error "changelog_clear failed"
16275         if [ x$flags != "x0x1" ]; then
16276                 error "flag $flags is not 0x1"
16277         fi
16278
16279         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16280         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16281         touch $DIR/$tdir/foo_161c
16282         touch $DIR/$tdir/bar_161c
16283         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16284         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16285         changelog_dump | grep RENME | tail -n 5
16286         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16287         changelog_clear 0 || error "changelog_clear failed"
16288         if [ x$flags != "x0x0" ]; then
16289                 error "flag $flags is not 0x0"
16290         fi
16291         echo "rename overwrite a target having nlink > 1," \
16292                 "changelog record has flags of $flags"
16293
16294         # rename doesn't overwrite a target (changelog flag 0x0)
16295         touch $DIR/$tdir/foo_161c
16296         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16297         changelog_dump | grep RENME | tail -n 5
16298         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16299         changelog_clear 0 || error "changelog_clear failed"
16300         if [ x$flags != "x0x0" ]; then
16301                 error "flag $flags is not 0x0"
16302         fi
16303         echo "rename doesn't overwrite a target," \
16304                 "changelog record has flags of $flags"
16305
16306         # define CLF_UNLINK_LAST 0x0001
16307         # unlink a file having nlink = 1 (changelog flag 0x1)
16308         rm -f $DIR/$tdir/foo2_161c
16309         changelog_dump | grep UNLNK | tail -n 5
16310         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16311         changelog_clear 0 || error "changelog_clear failed"
16312         if [ x$flags != "x0x1" ]; then
16313                 error "flag $flags is not 0x1"
16314         fi
16315         echo "unlink a file having nlink = 1," \
16316                 "changelog record has flags of $flags"
16317
16318         # unlink a file having nlink > 1 (changelog flag 0x0)
16319         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16320         rm -f $DIR/$tdir/foobar_161c
16321         changelog_dump | grep UNLNK | tail -n 5
16322         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16323         changelog_clear 0 || error "changelog_clear failed"
16324         if [ x$flags != "x0x0" ]; then
16325                 error "flag $flags is not 0x0"
16326         fi
16327         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16328 }
16329 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16330
16331 test_161d() {
16332         remote_mds_nodsh && skip "remote MDS with nodsh"
16333         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16334
16335         local pid
16336         local fid
16337
16338         changelog_register || error "changelog_register failed"
16339
16340         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16341         # interfer with $MOUNT/.lustre/fid/ access
16342         mkdir $DIR/$tdir
16343         [[ $? -eq 0 ]] || error "mkdir failed"
16344
16345         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16346         $LCTL set_param fail_loc=0x8000140c
16347         # 5s pause
16348         $LCTL set_param fail_val=5
16349
16350         # create file
16351         echo foofoo > $DIR/$tdir/$tfile &
16352         pid=$!
16353
16354         # wait for create to be delayed
16355         sleep 2
16356
16357         ps -p $pid
16358         [[ $? -eq 0 ]] || error "create should be blocked"
16359
16360         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16361         stack_trap "rm -f $tempfile"
16362         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16363         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16364         # some delay may occur during ChangeLog publishing and file read just
16365         # above, that could allow file write to happen finally
16366         [[ -s $tempfile ]] && echo "file should be empty"
16367
16368         $LCTL set_param fail_loc=0
16369
16370         wait $pid
16371         [[ $? -eq 0 ]] || error "create failed"
16372 }
16373 run_test 161d "create with concurrent .lustre/fid access"
16374
16375 check_path() {
16376         local expected="$1"
16377         shift
16378         local fid="$2"
16379
16380         local path
16381         path=$($LFS fid2path "$@")
16382         local rc=$?
16383
16384         if [ $rc -ne 0 ]; then
16385                 error "path looked up of '$expected' failed: rc=$rc"
16386         elif [ "$path" != "$expected" ]; then
16387                 error "path looked up '$path' instead of '$expected'"
16388         else
16389                 echo "FID '$fid' resolves to path '$path' as expected"
16390         fi
16391 }
16392
16393 test_162a() { # was test_162
16394         test_mkdir -p -c1 $DIR/$tdir/d2
16395         touch $DIR/$tdir/d2/$tfile
16396         touch $DIR/$tdir/d2/x1
16397         touch $DIR/$tdir/d2/x2
16398         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16399         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16400         # regular file
16401         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16402         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16403
16404         # softlink
16405         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16406         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16407         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16408
16409         # softlink to wrong file
16410         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16411         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16412         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16413
16414         # hardlink
16415         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16416         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16417         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16418         # fid2path dir/fsname should both work
16419         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16420         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16421
16422         # hardlink count: check that there are 2 links
16423         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16424         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16425
16426         # hardlink indexing: remove the first link
16427         rm $DIR/$tdir/d2/p/q/r/hlink
16428         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16429 }
16430 run_test 162a "path lookup sanity"
16431
16432 test_162b() {
16433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16434         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16435
16436         mkdir $DIR/$tdir
16437         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16438                                 error "create striped dir failed"
16439
16440         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16441                                         tail -n 1 | awk '{print $2}')
16442         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16443
16444         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16445         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16446
16447         # regular file
16448         for ((i=0;i<5;i++)); do
16449                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16450                         error "get fid for f$i failed"
16451                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16452
16453                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16454                         error "get fid for d$i failed"
16455                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16456         done
16457
16458         return 0
16459 }
16460 run_test 162b "striped directory path lookup sanity"
16461
16462 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16463 test_162c() {
16464         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16465                 skip "Need MDS version at least 2.7.51"
16466
16467         local lpath=$tdir.local
16468         local rpath=$tdir.remote
16469
16470         test_mkdir $DIR/$lpath
16471         test_mkdir $DIR/$rpath
16472
16473         for ((i = 0; i <= 101; i++)); do
16474                 lpath="$lpath/$i"
16475                 mkdir $DIR/$lpath
16476                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16477                         error "get fid for local directory $DIR/$lpath failed"
16478                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16479
16480                 rpath="$rpath/$i"
16481                 test_mkdir $DIR/$rpath
16482                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16483                         error "get fid for remote directory $DIR/$rpath failed"
16484                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16485         done
16486
16487         return 0
16488 }
16489 run_test 162c "fid2path works with paths 100 or more directories deep"
16490
16491 oalr_event_count() {
16492         local event="${1}"
16493         local trace="${2}"
16494
16495         awk -v name="${FSNAME}-OST0000" \
16496             -v event="${event}" \
16497             '$1 == "TRACE" && $2 == event && $3 == name' \
16498             "${trace}" |
16499         wc -l
16500 }
16501
16502 oalr_expect_event_count() {
16503         local event="${1}"
16504         local trace="${2}"
16505         local expect="${3}"
16506         local count
16507
16508         count=$(oalr_event_count "${event}" "${trace}")
16509         if ((count == expect)); then
16510                 return 0
16511         fi
16512
16513         error_noexit "${event} event count was '${count}', expected ${expect}"
16514         cat "${trace}" >&2
16515         exit 1
16516 }
16517
16518 cleanup_165() {
16519         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16520         stop ost1
16521         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16522 }
16523
16524 setup_165() {
16525         sync # Flush previous IOs so we can count log entries.
16526         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16527         stack_trap cleanup_165 EXIT
16528 }
16529
16530 test_165a() {
16531         local trace="/tmp/${tfile}.trace"
16532         local rc
16533         local count
16534
16535         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16536                 skip "OFD access log unsupported"
16537
16538         setup_165
16539         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16540         sleep 5
16541
16542         do_facet ost1 ofd_access_log_reader --list
16543         stop ost1
16544
16545         do_facet ost1 killall -TERM ofd_access_log_reader
16546         wait
16547         rc=$?
16548
16549         if ((rc != 0)); then
16550                 error "ofd_access_log_reader exited with rc = '${rc}'"
16551         fi
16552
16553         # Parse trace file for discovery events:
16554         oalr_expect_event_count alr_log_add "${trace}" 1
16555         oalr_expect_event_count alr_log_eof "${trace}" 1
16556         oalr_expect_event_count alr_log_free "${trace}" 1
16557 }
16558 run_test 165a "ofd access log discovery"
16559
16560 test_165b() {
16561         local trace="/tmp/${tfile}.trace"
16562         local file="${DIR}/${tfile}"
16563         local pfid1
16564         local pfid2
16565         local -a entry
16566         local rc
16567         local count
16568         local size
16569         local flags
16570
16571         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16572                 skip "OFD access log unsupported"
16573
16574         setup_165
16575         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16576         sleep 5
16577
16578         do_facet ost1 ofd_access_log_reader --list
16579
16580         lfs setstripe -c 1 -i 0 "${file}"
16581         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16582                 error "cannot create '${file}'"
16583
16584         sleep 5
16585         do_facet ost1 killall -TERM ofd_access_log_reader
16586         wait
16587         rc=$?
16588
16589         if ((rc != 0)); then
16590                 error "ofd_access_log_reader exited with rc = '${rc}'"
16591         fi
16592
16593         oalr_expect_event_count alr_log_entry "${trace}" 1
16594
16595         pfid1=$($LFS path2fid "${file}")
16596
16597         # 1     2             3   4    5     6   7    8    9     10
16598         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16599         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16600
16601         echo "entry = '${entry[*]}'" >&2
16602
16603         pfid2=${entry[4]}
16604         if [[ "${pfid1}" != "${pfid2}" ]]; then
16605                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16606         fi
16607
16608         size=${entry[8]}
16609         if ((size != 1048576)); then
16610                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16611         fi
16612
16613         flags=${entry[10]}
16614         if [[ "${flags}" != "w" ]]; then
16615                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16616         fi
16617
16618         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16619         sleep 5
16620
16621         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16622                 error "cannot read '${file}'"
16623         sleep 5
16624
16625         do_facet ost1 killall -TERM ofd_access_log_reader
16626         wait
16627         rc=$?
16628
16629         if ((rc != 0)); then
16630                 error "ofd_access_log_reader exited with rc = '${rc}'"
16631         fi
16632
16633         oalr_expect_event_count alr_log_entry "${trace}" 1
16634
16635         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16636         echo "entry = '${entry[*]}'" >&2
16637
16638         pfid2=${entry[4]}
16639         if [[ "${pfid1}" != "${pfid2}" ]]; then
16640                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16641         fi
16642
16643         size=${entry[8]}
16644         if ((size != 524288)); then
16645                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16646         fi
16647
16648         flags=${entry[10]}
16649         if [[ "${flags}" != "r" ]]; then
16650                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16651         fi
16652 }
16653 run_test 165b "ofd access log entries are produced and consumed"
16654
16655 test_165c() {
16656         local trace="/tmp/${tfile}.trace"
16657         local file="${DIR}/${tdir}/${tfile}"
16658
16659         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16660                 skip "OFD access log unsupported"
16661
16662         test_mkdir "${DIR}/${tdir}"
16663
16664         setup_165
16665         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16666         sleep 5
16667
16668         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16669
16670         # 4096 / 64 = 64. Create twice as many entries.
16671         for ((i = 0; i < 128; i++)); do
16672                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16673                         error "cannot create file"
16674         done
16675
16676         sync
16677
16678         do_facet ost1 killall -TERM ofd_access_log_reader
16679         wait
16680         rc=$?
16681         if ((rc != 0)); then
16682                 error "ofd_access_log_reader exited with rc = '${rc}'"
16683         fi
16684
16685         unlinkmany  "${file}-%d" 128
16686 }
16687 run_test 165c "full ofd access logs do not block IOs"
16688
16689 oal_get_read_count() {
16690         local stats="$1"
16691
16692         # STATS lustre-OST0001 alr_read_count 1
16693
16694         do_facet ost1 cat "${stats}" |
16695         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16696              END { print count; }'
16697 }
16698
16699 oal_expect_read_count() {
16700         local stats="$1"
16701         local count
16702         local expect="$2"
16703
16704         # Ask ofd_access_log_reader to write stats.
16705         do_facet ost1 killall -USR1 ofd_access_log_reader
16706
16707         # Allow some time for things to happen.
16708         sleep 1
16709
16710         count=$(oal_get_read_count "${stats}")
16711         if ((count == expect)); then
16712                 return 0
16713         fi
16714
16715         error_noexit "bad read count, got ${count}, expected ${expect}"
16716         do_facet ost1 cat "${stats}" >&2
16717         exit 1
16718 }
16719
16720 test_165d() {
16721         local stats="/tmp/${tfile}.stats"
16722         local file="${DIR}/${tdir}/${tfile}"
16723         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16724
16725         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16726                 skip "OFD access log unsupported"
16727
16728         test_mkdir "${DIR}/${tdir}"
16729
16730         setup_165
16731         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16732         sleep 5
16733
16734         lfs setstripe -c 1 -i 0 "${file}"
16735
16736         do_facet ost1 lctl set_param "${param}=rw"
16737         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16738                 error "cannot create '${file}'"
16739         oal_expect_read_count "${stats}" 1
16740
16741         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16742                 error "cannot read '${file}'"
16743         oal_expect_read_count "${stats}" 2
16744
16745         do_facet ost1 lctl set_param "${param}=r"
16746         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16747                 error "cannot create '${file}'"
16748         oal_expect_read_count "${stats}" 2
16749
16750         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16751                 error "cannot read '${file}'"
16752         oal_expect_read_count "${stats}" 3
16753
16754         do_facet ost1 lctl set_param "${param}=w"
16755         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16756                 error "cannot create '${file}'"
16757         oal_expect_read_count "${stats}" 4
16758
16759         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16760                 error "cannot read '${file}'"
16761         oal_expect_read_count "${stats}" 4
16762
16763         do_facet ost1 lctl set_param "${param}=0"
16764         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16765                 error "cannot create '${file}'"
16766         oal_expect_read_count "${stats}" 4
16767
16768         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16769                 error "cannot read '${file}'"
16770         oal_expect_read_count "${stats}" 4
16771
16772         do_facet ost1 killall -TERM ofd_access_log_reader
16773         wait
16774         rc=$?
16775         if ((rc != 0)); then
16776                 error "ofd_access_log_reader exited with rc = '${rc}'"
16777         fi
16778 }
16779 run_test 165d "ofd_access_log mask works"
16780
16781 test_165e() {
16782         local stats="/tmp/${tfile}.stats"
16783         local file0="${DIR}/${tdir}-0/${tfile}"
16784         local file1="${DIR}/${tdir}-1/${tfile}"
16785
16786         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16787                 skip "OFD access log unsupported"
16788
16789         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16790
16791         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16792         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16793
16794         lfs setstripe -c 1 -i 0 "${file0}"
16795         lfs setstripe -c 1 -i 0 "${file1}"
16796
16797         setup_165
16798         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16799         sleep 5
16800
16801         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16802                 error "cannot create '${file0}'"
16803         sync
16804         oal_expect_read_count "${stats}" 0
16805
16806         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16807                 error "cannot create '${file1}'"
16808         sync
16809         oal_expect_read_count "${stats}" 1
16810
16811         do_facet ost1 killall -TERM ofd_access_log_reader
16812         wait
16813         rc=$?
16814         if ((rc != 0)); then
16815                 error "ofd_access_log_reader exited with rc = '${rc}'"
16816         fi
16817 }
16818 run_test 165e "ofd_access_log MDT index filter works"
16819
16820 test_165f() {
16821         local trace="/tmp/${tfile}.trace"
16822         local rc
16823         local count
16824
16825         setup_165
16826         do_facet ost1 timeout 60 ofd_access_log_reader \
16827                 --exit-on-close --debug=- --trace=- > "${trace}" &
16828         sleep 5
16829         stop ost1
16830
16831         wait
16832         rc=$?
16833
16834         if ((rc != 0)); then
16835                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16836                 cat "${trace}"
16837                 exit 1
16838         fi
16839 }
16840 run_test 165f "ofd_access_log_reader --exit-on-close works"
16841
16842 test_169() {
16843         # do directio so as not to populate the page cache
16844         log "creating a 10 Mb file"
16845         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16846                 error "multiop failed while creating a file"
16847         log "starting reads"
16848         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16849         log "truncating the file"
16850         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16851                 error "multiop failed while truncating the file"
16852         log "killing dd"
16853         kill %+ || true # reads might have finished
16854         echo "wait until dd is finished"
16855         wait
16856         log "removing the temporary file"
16857         rm -rf $DIR/$tfile || error "tmp file removal failed"
16858 }
16859 run_test 169 "parallel read and truncate should not deadlock"
16860
16861 test_170() {
16862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16863
16864         $LCTL clear     # bug 18514
16865         $LCTL debug_daemon start $TMP/${tfile}_log_good
16866         touch $DIR/$tfile
16867         $LCTL debug_daemon stop
16868         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16869                 error "sed failed to read log_good"
16870
16871         $LCTL debug_daemon start $TMP/${tfile}_log_good
16872         rm -rf $DIR/$tfile
16873         $LCTL debug_daemon stop
16874
16875         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16876                error "lctl df log_bad failed"
16877
16878         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16879         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16880
16881         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16882         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16883
16884         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16885                 error "bad_line good_line1 good_line2 are empty"
16886
16887         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16888         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16889         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16890
16891         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16892         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16893         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16894
16895         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16896                 error "bad_line_new good_line_new are empty"
16897
16898         local expected_good=$((good_line1 + good_line2*2))
16899
16900         rm -f $TMP/${tfile}*
16901         # LU-231, short malformed line may not be counted into bad lines
16902         if [ $bad_line -ne $bad_line_new ] &&
16903                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16904                 error "expected $bad_line bad lines, but got $bad_line_new"
16905                 return 1
16906         fi
16907
16908         if [ $expected_good -ne $good_line_new ]; then
16909                 error "expected $expected_good good lines, but got $good_line_new"
16910                 return 2
16911         fi
16912         true
16913 }
16914 run_test 170 "test lctl df to handle corrupted log ====================="
16915
16916 test_171() { # bug20592
16917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16918
16919         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16920         $LCTL set_param fail_loc=0x50e
16921         $LCTL set_param fail_val=3000
16922         multiop_bg_pause $DIR/$tfile O_s || true
16923         local MULTIPID=$!
16924         kill -USR1 $MULTIPID
16925         # cause log dump
16926         sleep 3
16927         wait $MULTIPID
16928         if dmesg | grep "recursive fault"; then
16929                 error "caught a recursive fault"
16930         fi
16931         $LCTL set_param fail_loc=0
16932         true
16933 }
16934 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16935
16936 # it would be good to share it with obdfilter-survey/iokit-libecho code
16937 setup_obdecho_osc () {
16938         local rc=0
16939         local ost_nid=$1
16940         local obdfilter_name=$2
16941         echo "Creating new osc for $obdfilter_name on $ost_nid"
16942         # make sure we can find loopback nid
16943         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16944
16945         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16946                            ${obdfilter_name}_osc_UUID || rc=2; }
16947         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16948                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16949         return $rc
16950 }
16951
16952 cleanup_obdecho_osc () {
16953         local obdfilter_name=$1
16954         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16955         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16956         return 0
16957 }
16958
16959 obdecho_test() {
16960         local OBD=$1
16961         local node=$2
16962         local pages=${3:-64}
16963         local rc=0
16964         local id
16965
16966         local count=10
16967         local obd_size=$(get_obd_size $node $OBD)
16968         local page_size=$(get_page_size $node)
16969         if [[ -n "$obd_size" ]]; then
16970                 local new_count=$((obd_size / (pages * page_size / 1024)))
16971                 [[ $new_count -ge $count ]] || count=$new_count
16972         fi
16973
16974         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16975         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16976                            rc=2; }
16977         if [ $rc -eq 0 ]; then
16978             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16979             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16980         fi
16981         echo "New object id is $id"
16982         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16983                            rc=4; }
16984         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16985                            "test_brw $count w v $pages $id" || rc=4; }
16986         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16987                            rc=4; }
16988         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16989                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16990         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16991                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16992         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16993         return $rc
16994 }
16995
16996 test_180a() {
16997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16998
16999         if ! [ -d /sys/fs/lustre/echo_client ] &&
17000            ! module_loaded obdecho; then
17001                 load_module obdecho/obdecho &&
17002                         stack_trap "rmmod obdecho" EXIT ||
17003                         error "unable to load obdecho on client"
17004         fi
17005
17006         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17007         local host=$($LCTL get_param -n osc.$osc.import |
17008                      awk '/current_connection:/ { print $2 }' )
17009         local target=$($LCTL get_param -n osc.$osc.import |
17010                        awk '/target:/ { print $2 }' )
17011         target=${target%_UUID}
17012
17013         if [ -n "$target" ]; then
17014                 setup_obdecho_osc $host $target &&
17015                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17016                         { error "obdecho setup failed with $?"; return; }
17017
17018                 obdecho_test ${target}_osc client ||
17019                         error "obdecho_test failed on ${target}_osc"
17020         else
17021                 $LCTL get_param osc.$osc.import
17022                 error "there is no osc.$osc.import target"
17023         fi
17024 }
17025 run_test 180a "test obdecho on osc"
17026
17027 test_180b() {
17028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17029         remote_ost_nodsh && skip "remote OST with nodsh"
17030
17031         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17032                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17033                 error "failed to load module obdecho"
17034
17035         local target=$(do_facet ost1 $LCTL dl |
17036                        awk '/obdfilter/ { print $4; exit; }')
17037
17038         if [ -n "$target" ]; then
17039                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17040         else
17041                 do_facet ost1 $LCTL dl
17042                 error "there is no obdfilter target on ost1"
17043         fi
17044 }
17045 run_test 180b "test obdecho directly on obdfilter"
17046
17047 test_180c() { # LU-2598
17048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17049         remote_ost_nodsh && skip "remote OST with nodsh"
17050         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17051                 skip "Need MDS version at least 2.4.0"
17052
17053         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17054                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17055                 error "failed to load module obdecho"
17056
17057         local target=$(do_facet ost1 $LCTL dl |
17058                        awk '/obdfilter/ { print $4; exit; }')
17059
17060         if [ -n "$target" ]; then
17061                 local pages=16384 # 64MB bulk I/O RPC size
17062
17063                 obdecho_test "$target" ost1 "$pages" ||
17064                         error "obdecho_test with pages=$pages failed with $?"
17065         else
17066                 do_facet ost1 $LCTL dl
17067                 error "there is no obdfilter target on ost1"
17068         fi
17069 }
17070 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17071
17072 test_181() { # bug 22177
17073         test_mkdir $DIR/$tdir
17074         # create enough files to index the directory
17075         createmany -o $DIR/$tdir/foobar 4000
17076         # print attributes for debug purpose
17077         lsattr -d .
17078         # open dir
17079         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17080         MULTIPID=$!
17081         # remove the files & current working dir
17082         unlinkmany $DIR/$tdir/foobar 4000
17083         rmdir $DIR/$tdir
17084         kill -USR1 $MULTIPID
17085         wait $MULTIPID
17086         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17087         return 0
17088 }
17089 run_test 181 "Test open-unlinked dir ========================"
17090
17091 test_182() {
17092         local fcount=1000
17093         local tcount=10
17094
17095         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17096
17097         $LCTL set_param mdc.*.rpc_stats=clear
17098
17099         for (( i = 0; i < $tcount; i++ )) ; do
17100                 mkdir $DIR/$tdir/$i
17101         done
17102
17103         for (( i = 0; i < $tcount; i++ )) ; do
17104                 createmany -o $DIR/$tdir/$i/f- $fcount &
17105         done
17106         wait
17107
17108         for (( i = 0; i < $tcount; i++ )) ; do
17109                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17110         done
17111         wait
17112
17113         $LCTL get_param mdc.*.rpc_stats
17114
17115         rm -rf $DIR/$tdir
17116 }
17117 run_test 182 "Test parallel modify metadata operations ================"
17118
17119 test_183() { # LU-2275
17120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17121         remote_mds_nodsh && skip "remote MDS with nodsh"
17122         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17123                 skip "Need MDS version at least 2.3.56"
17124
17125         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17126         echo aaa > $DIR/$tdir/$tfile
17127
17128 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17129         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17130
17131         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17132         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17133
17134         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17135
17136         # Flush negative dentry cache
17137         touch $DIR/$tdir/$tfile
17138
17139         # We are not checking for any leaked references here, they'll
17140         # become evident next time we do cleanup with module unload.
17141         rm -rf $DIR/$tdir
17142 }
17143 run_test 183 "No crash or request leak in case of strange dispositions ========"
17144
17145 # test suite 184 is for LU-2016, LU-2017
17146 test_184a() {
17147         check_swap_layouts_support
17148
17149         dir0=$DIR/$tdir/$testnum
17150         test_mkdir -p -c1 $dir0
17151         ref1=/etc/passwd
17152         ref2=/etc/group
17153         file1=$dir0/f1
17154         file2=$dir0/f2
17155         $LFS setstripe -c1 $file1
17156         cp $ref1 $file1
17157         $LFS setstripe -c2 $file2
17158         cp $ref2 $file2
17159         gen1=$($LFS getstripe -g $file1)
17160         gen2=$($LFS getstripe -g $file2)
17161
17162         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17163         gen=$($LFS getstripe -g $file1)
17164         [[ $gen1 != $gen ]] ||
17165                 "Layout generation on $file1 does not change"
17166         gen=$($LFS getstripe -g $file2)
17167         [[ $gen2 != $gen ]] ||
17168                 "Layout generation on $file2 does not change"
17169
17170         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17171         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17172
17173         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17174 }
17175 run_test 184a "Basic layout swap"
17176
17177 test_184b() {
17178         check_swap_layouts_support
17179
17180         dir0=$DIR/$tdir/$testnum
17181         mkdir -p $dir0 || error "creating dir $dir0"
17182         file1=$dir0/f1
17183         file2=$dir0/f2
17184         file3=$dir0/f3
17185         dir1=$dir0/d1
17186         dir2=$dir0/d2
17187         mkdir $dir1 $dir2
17188         $LFS setstripe -c1 $file1
17189         $LFS setstripe -c2 $file2
17190         $LFS setstripe -c1 $file3
17191         chown $RUNAS_ID $file3
17192         gen1=$($LFS getstripe -g $file1)
17193         gen2=$($LFS getstripe -g $file2)
17194
17195         $LFS swap_layouts $dir1 $dir2 &&
17196                 error "swap of directories layouts should fail"
17197         $LFS swap_layouts $dir1 $file1 &&
17198                 error "swap of directory and file layouts should fail"
17199         $RUNAS $LFS swap_layouts $file1 $file2 &&
17200                 error "swap of file we cannot write should fail"
17201         $LFS swap_layouts $file1 $file3 &&
17202                 error "swap of file with different owner should fail"
17203         /bin/true # to clear error code
17204 }
17205 run_test 184b "Forbidden layout swap (will generate errors)"
17206
17207 test_184c() {
17208         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17209         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17210         check_swap_layouts_support
17211         check_swap_layout_no_dom $DIR
17212
17213         local dir0=$DIR/$tdir/$testnum
17214         mkdir -p $dir0 || error "creating dir $dir0"
17215
17216         local ref1=$dir0/ref1
17217         local ref2=$dir0/ref2
17218         local file1=$dir0/file1
17219         local file2=$dir0/file2
17220         # create a file large enough for the concurrent test
17221         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17222         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17223         echo "ref file size: ref1($(stat -c %s $ref1))," \
17224              "ref2($(stat -c %s $ref2))"
17225
17226         cp $ref2 $file2
17227         dd if=$ref1 of=$file1 bs=16k &
17228         local DD_PID=$!
17229
17230         # Make sure dd starts to copy file, but wait at most 5 seconds
17231         local loops=0
17232         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17233
17234         $LFS swap_layouts $file1 $file2
17235         local rc=$?
17236         wait $DD_PID
17237         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17238         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17239
17240         # how many bytes copied before swapping layout
17241         local copied=$(stat -c %s $file2)
17242         local remaining=$(stat -c %s $ref1)
17243         remaining=$((remaining - copied))
17244         echo "Copied $copied bytes before swapping layout..."
17245
17246         cmp -n $copied $file1 $ref2 | grep differ &&
17247                 error "Content mismatch [0, $copied) of ref2 and file1"
17248         cmp -n $copied $file2 $ref1 ||
17249                 error "Content mismatch [0, $copied) of ref1 and file2"
17250         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17251                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17252
17253         # clean up
17254         rm -f $ref1 $ref2 $file1 $file2
17255 }
17256 run_test 184c "Concurrent write and layout swap"
17257
17258 test_184d() {
17259         check_swap_layouts_support
17260         check_swap_layout_no_dom $DIR
17261         [ -z "$(which getfattr 2>/dev/null)" ] &&
17262                 skip_env "no getfattr command"
17263
17264         local file1=$DIR/$tdir/$tfile-1
17265         local file2=$DIR/$tdir/$tfile-2
17266         local file3=$DIR/$tdir/$tfile-3
17267         local lovea1
17268         local lovea2
17269
17270         mkdir -p $DIR/$tdir
17271         touch $file1 || error "create $file1 failed"
17272         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17273                 error "create $file2 failed"
17274         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17275                 error "create $file3 failed"
17276         lovea1=$(get_layout_param $file1)
17277
17278         $LFS swap_layouts $file2 $file3 ||
17279                 error "swap $file2 $file3 layouts failed"
17280         $LFS swap_layouts $file1 $file2 ||
17281                 error "swap $file1 $file2 layouts failed"
17282
17283         lovea2=$(get_layout_param $file2)
17284         echo "$lovea1"
17285         echo "$lovea2"
17286         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17287
17288         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17289         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17290 }
17291 run_test 184d "allow stripeless layouts swap"
17292
17293 test_184e() {
17294         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17295                 skip "Need MDS version at least 2.6.94"
17296         check_swap_layouts_support
17297         check_swap_layout_no_dom $DIR
17298         [ -z "$(which getfattr 2>/dev/null)" ] &&
17299                 skip_env "no getfattr command"
17300
17301         local file1=$DIR/$tdir/$tfile-1
17302         local file2=$DIR/$tdir/$tfile-2
17303         local file3=$DIR/$tdir/$tfile-3
17304         local lovea
17305
17306         mkdir -p $DIR/$tdir
17307         touch $file1 || error "create $file1 failed"
17308         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17309                 error "create $file2 failed"
17310         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17311                 error "create $file3 failed"
17312
17313         $LFS swap_layouts $file1 $file2 ||
17314                 error "swap $file1 $file2 layouts failed"
17315
17316         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17317         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17318
17319         echo 123 > $file1 || error "Should be able to write into $file1"
17320
17321         $LFS swap_layouts $file1 $file3 ||
17322                 error "swap $file1 $file3 layouts failed"
17323
17324         echo 123 > $file1 || error "Should be able to write into $file1"
17325
17326         rm -rf $file1 $file2 $file3
17327 }
17328 run_test 184e "Recreate layout after stripeless layout swaps"
17329
17330 test_184f() {
17331         # Create a file with name longer than sizeof(struct stat) ==
17332         # 144 to see if we can get chars from the file name to appear
17333         # in the returned striping. Note that 'f' == 0x66.
17334         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17335
17336         mkdir -p $DIR/$tdir
17337         mcreate $DIR/$tdir/$file
17338         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17339                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17340         fi
17341 }
17342 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17343
17344 test_185() { # LU-2441
17345         # LU-3553 - no volatile file support in old servers
17346         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17347                 skip "Need MDS version at least 2.3.60"
17348
17349         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17350         touch $DIR/$tdir/spoo
17351         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17352         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17353                 error "cannot create/write a volatile file"
17354         [ "$FILESET" == "" ] &&
17355         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17356                 error "FID is still valid after close"
17357
17358         multiop_bg_pause $DIR/$tdir vVw4096_c
17359         local multi_pid=$!
17360
17361         local OLD_IFS=$IFS
17362         IFS=":"
17363         local fidv=($fid)
17364         IFS=$OLD_IFS
17365         # assume that the next FID for this client is sequential, since stdout
17366         # is unfortunately eaten by multiop_bg_pause
17367         local n=$((${fidv[1]} + 1))
17368         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17369         if [ "$FILESET" == "" ]; then
17370                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17371                         error "FID is missing before close"
17372         fi
17373         kill -USR1 $multi_pid
17374         # 1 second delay, so if mtime change we will see it
17375         sleep 1
17376         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17377         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17378 }
17379 run_test 185 "Volatile file support"
17380
17381 function create_check_volatile() {
17382         local idx=$1
17383         local tgt
17384
17385         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17386         local PID=$!
17387         sleep 1
17388         local FID=$(cat /tmp/${tfile}.fid)
17389         [ "$FID" == "" ] && error "can't get FID for volatile"
17390         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17391         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17392         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17393         kill -USR1 $PID
17394         wait
17395         sleep 1
17396         cancel_lru_locks mdc # flush opencache
17397         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17398         return 0
17399 }
17400
17401 test_185a(){
17402         # LU-12516 - volatile creation via .lustre
17403         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17404                 skip "Need MDS version at least 2.3.55"
17405
17406         create_check_volatile 0
17407         [ $MDSCOUNT -lt 2 ] && return 0
17408
17409         # DNE case
17410         create_check_volatile 1
17411
17412         return 0
17413 }
17414 run_test 185a "Volatile file creation in .lustre/fid/"
17415
17416 test_187a() {
17417         remote_mds_nodsh && skip "remote MDS with nodsh"
17418         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17419                 skip "Need MDS version at least 2.3.0"
17420
17421         local dir0=$DIR/$tdir/$testnum
17422         mkdir -p $dir0 || error "creating dir $dir0"
17423
17424         local file=$dir0/file1
17425         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17426         local dv1=$($LFS data_version $file)
17427         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17428         local dv2=$($LFS data_version $file)
17429         [[ $dv1 != $dv2 ]] ||
17430                 error "data version did not change on write $dv1 == $dv2"
17431
17432         # clean up
17433         rm -f $file1
17434 }
17435 run_test 187a "Test data version change"
17436
17437 test_187b() {
17438         remote_mds_nodsh && skip "remote MDS with nodsh"
17439         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17440                 skip "Need MDS version at least 2.3.0"
17441
17442         local dir0=$DIR/$tdir/$testnum
17443         mkdir -p $dir0 || error "creating dir $dir0"
17444
17445         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17446         [[ ${DV[0]} != ${DV[1]} ]] ||
17447                 error "data version did not change on write"\
17448                       " ${DV[0]} == ${DV[1]}"
17449
17450         # clean up
17451         rm -f $file1
17452 }
17453 run_test 187b "Test data version change on volatile file"
17454
17455 test_200() {
17456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17457         remote_mgs_nodsh && skip "remote MGS with nodsh"
17458         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17459
17460         local POOL=${POOL:-cea1}
17461         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17462         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17463         # Pool OST targets
17464         local first_ost=0
17465         local last_ost=$(($OSTCOUNT - 1))
17466         local ost_step=2
17467         local ost_list=$(seq $first_ost $ost_step $last_ost)
17468         local ost_range="$first_ost $last_ost $ost_step"
17469         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17470         local file_dir=$POOL_ROOT/file_tst
17471         local subdir=$test_path/subdir
17472         local rc=0
17473
17474         while : ; do
17475                 # former test_200a test_200b
17476                 pool_add $POOL                          || { rc=$? ; break; }
17477                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17478                 # former test_200c test_200d
17479                 mkdir -p $test_path
17480                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17481                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17482                 mkdir -p $subdir
17483                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17484                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17485                                                         || { rc=$? ; break; }
17486                 # former test_200e test_200f
17487                 local files=$((OSTCOUNT*3))
17488                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17489                                                         || { rc=$? ; break; }
17490                 pool_create_files $POOL $file_dir $files "$ost_list" \
17491                                                         || { rc=$? ; break; }
17492                 # former test_200g test_200h
17493                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17494                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17495
17496                 # former test_201a test_201b test_201c
17497                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17498
17499                 local f=$test_path/$tfile
17500                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17501                 pool_remove $POOL $f                    || { rc=$? ; break; }
17502                 break
17503         done
17504
17505         destroy_test_pools
17506
17507         return $rc
17508 }
17509 run_test 200 "OST pools"
17510
17511 # usage: default_attr <count | size | offset>
17512 default_attr() {
17513         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17514 }
17515
17516 # usage: check_default_stripe_attr
17517 check_default_stripe_attr() {
17518         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17519         case $1 in
17520         --stripe-count|-c)
17521                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17522         --stripe-size|-S)
17523                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17524         --stripe-index|-i)
17525                 EXPECTED=-1;;
17526         *)
17527                 error "unknown getstripe attr '$1'"
17528         esac
17529
17530         [ $ACTUAL == $EXPECTED ] ||
17531                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17532 }
17533
17534 test_204a() {
17535         test_mkdir $DIR/$tdir
17536         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17537
17538         check_default_stripe_attr --stripe-count
17539         check_default_stripe_attr --stripe-size
17540         check_default_stripe_attr --stripe-index
17541 }
17542 run_test 204a "Print default stripe attributes"
17543
17544 test_204b() {
17545         test_mkdir $DIR/$tdir
17546         $LFS setstripe --stripe-count 1 $DIR/$tdir
17547
17548         check_default_stripe_attr --stripe-size
17549         check_default_stripe_attr --stripe-index
17550 }
17551 run_test 204b "Print default stripe size and offset"
17552
17553 test_204c() {
17554         test_mkdir $DIR/$tdir
17555         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17556
17557         check_default_stripe_attr --stripe-count
17558         check_default_stripe_attr --stripe-index
17559 }
17560 run_test 204c "Print default stripe count and offset"
17561
17562 test_204d() {
17563         test_mkdir $DIR/$tdir
17564         $LFS setstripe --stripe-index 0 $DIR/$tdir
17565
17566         check_default_stripe_attr --stripe-count
17567         check_default_stripe_attr --stripe-size
17568 }
17569 run_test 204d "Print default stripe count and size"
17570
17571 test_204e() {
17572         test_mkdir $DIR/$tdir
17573         $LFS setstripe -d $DIR/$tdir
17574
17575         check_default_stripe_attr --stripe-count --raw
17576         check_default_stripe_attr --stripe-size --raw
17577         check_default_stripe_attr --stripe-index --raw
17578 }
17579 run_test 204e "Print raw stripe attributes"
17580
17581 test_204f() {
17582         test_mkdir $DIR/$tdir
17583         $LFS setstripe --stripe-count 1 $DIR/$tdir
17584
17585         check_default_stripe_attr --stripe-size --raw
17586         check_default_stripe_attr --stripe-index --raw
17587 }
17588 run_test 204f "Print raw stripe size and offset"
17589
17590 test_204g() {
17591         test_mkdir $DIR/$tdir
17592         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17593
17594         check_default_stripe_attr --stripe-count --raw
17595         check_default_stripe_attr --stripe-index --raw
17596 }
17597 run_test 204g "Print raw stripe count and offset"
17598
17599 test_204h() {
17600         test_mkdir $DIR/$tdir
17601         $LFS setstripe --stripe-index 0 $DIR/$tdir
17602
17603         check_default_stripe_attr --stripe-count --raw
17604         check_default_stripe_attr --stripe-size --raw
17605 }
17606 run_test 204h "Print raw stripe count and size"
17607
17608 # Figure out which job scheduler is being used, if any,
17609 # or use a fake one
17610 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17611         JOBENV=SLURM_JOB_ID
17612 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17613         JOBENV=LSB_JOBID
17614 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17615         JOBENV=PBS_JOBID
17616 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17617         JOBENV=LOADL_STEP_ID
17618 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17619         JOBENV=JOB_ID
17620 else
17621         $LCTL list_param jobid_name > /dev/null 2>&1
17622         if [ $? -eq 0 ]; then
17623                 JOBENV=nodelocal
17624         else
17625                 JOBENV=FAKE_JOBID
17626         fi
17627 fi
17628 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17629
17630 verify_jobstats() {
17631         local cmd=($1)
17632         shift
17633         local facets="$@"
17634
17635 # we don't really need to clear the stats for this test to work, since each
17636 # command has a unique jobid, but it makes debugging easier if needed.
17637 #       for facet in $facets; do
17638 #               local dev=$(convert_facet2label $facet)
17639 #               # clear old jobstats
17640 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17641 #       done
17642
17643         # use a new JobID for each test, or we might see an old one
17644         [ "$JOBENV" = "FAKE_JOBID" ] &&
17645                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17646
17647         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17648
17649         [ "$JOBENV" = "nodelocal" ] && {
17650                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17651                 $LCTL set_param jobid_name=$FAKE_JOBID
17652                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17653         }
17654
17655         log "Test: ${cmd[*]}"
17656         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17657
17658         if [ $JOBENV = "FAKE_JOBID" ]; then
17659                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17660         else
17661                 ${cmd[*]}
17662         fi
17663
17664         # all files are created on OST0000
17665         for facet in $facets; do
17666                 local stats="*.$(convert_facet2label $facet).job_stats"
17667
17668                 # strip out libtool wrappers for in-tree executables
17669                 if [ $(do_facet $facet lctl get_param $stats |
17670                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17671                         do_facet $facet lctl get_param $stats
17672                         error "No jobstats for $JOBVAL found on $facet::$stats"
17673                 fi
17674         done
17675 }
17676
17677 jobstats_set() {
17678         local new_jobenv=$1
17679
17680         set_persistent_param_and_check client "jobid_var" \
17681                 "$FSNAME.sys.jobid_var" $new_jobenv
17682 }
17683
17684 test_205a() { # Job stats
17685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17686         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17687                 skip "Need MDS version with at least 2.7.1"
17688         remote_mgs_nodsh && skip "remote MGS with nodsh"
17689         remote_mds_nodsh && skip "remote MDS with nodsh"
17690         remote_ost_nodsh && skip "remote OST with nodsh"
17691         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17692                 skip "Server doesn't support jobstats"
17693         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17694
17695         local old_jobenv=$($LCTL get_param -n jobid_var)
17696         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17697
17698         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17699                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17700         else
17701                 stack_trap "do_facet mgs $PERM_CMD \
17702                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17703         fi
17704         changelog_register
17705
17706         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17707                                 mdt.*.job_cleanup_interval | head -n 1)
17708         local new_interval=5
17709         do_facet $SINGLEMDS \
17710                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17711         stack_trap "do_facet $SINGLEMDS \
17712                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17713         local start=$SECONDS
17714
17715         local cmd
17716         # mkdir
17717         cmd="mkdir $DIR/$tdir"
17718         verify_jobstats "$cmd" "$SINGLEMDS"
17719         # rmdir
17720         cmd="rmdir $DIR/$tdir"
17721         verify_jobstats "$cmd" "$SINGLEMDS"
17722         # mkdir on secondary MDT
17723         if [ $MDSCOUNT -gt 1 ]; then
17724                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17725                 verify_jobstats "$cmd" "mds2"
17726         fi
17727         # mknod
17728         cmd="mknod $DIR/$tfile c 1 3"
17729         verify_jobstats "$cmd" "$SINGLEMDS"
17730         # unlink
17731         cmd="rm -f $DIR/$tfile"
17732         verify_jobstats "$cmd" "$SINGLEMDS"
17733         # create all files on OST0000 so verify_jobstats can find OST stats
17734         # open & close
17735         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17736         verify_jobstats "$cmd" "$SINGLEMDS"
17737         # setattr
17738         cmd="touch $DIR/$tfile"
17739         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17740         # write
17741         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17742         verify_jobstats "$cmd" "ost1"
17743         # read
17744         cancel_lru_locks osc
17745         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17746         verify_jobstats "$cmd" "ost1"
17747         # truncate
17748         cmd="$TRUNCATE $DIR/$tfile 0"
17749         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17750         # rename
17751         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17752         verify_jobstats "$cmd" "$SINGLEMDS"
17753         # jobstats expiry - sleep until old stats should be expired
17754         local left=$((new_interval + 5 - (SECONDS - start)))
17755         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17756                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17757                         "0" $left
17758         cmd="mkdir $DIR/$tdir.expire"
17759         verify_jobstats "$cmd" "$SINGLEMDS"
17760         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17761             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17762
17763         # Ensure that jobid are present in changelog (if supported by MDS)
17764         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17765                 changelog_dump | tail -10
17766                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17767                 [ $jobids -eq 9 ] ||
17768                         error "Wrong changelog jobid count $jobids != 9"
17769
17770                 # LU-5862
17771                 JOBENV="disable"
17772                 jobstats_set $JOBENV
17773                 touch $DIR/$tfile
17774                 changelog_dump | grep $tfile
17775                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17776                 [ $jobids -eq 0 ] ||
17777                         error "Unexpected jobids when jobid_var=$JOBENV"
17778         fi
17779
17780         # test '%j' access to environment variable - if supported
17781         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17782                 JOBENV="JOBCOMPLEX"
17783                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17784
17785                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17786         fi
17787
17788         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17789                 JOBENV="JOBCOMPLEX"
17790                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17791
17792                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17793         fi
17794
17795         # test '%j' access to per-session jobid - if supported
17796         if lctl list_param jobid_this_session > /dev/null 2>&1
17797         then
17798                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17799                 lctl set_param jobid_this_session=$USER
17800
17801                 JOBENV="JOBCOMPLEX"
17802                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17803
17804                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17805         fi
17806 }
17807 run_test 205a "Verify job stats"
17808
17809 # LU-13117, LU-13597
17810 test_205b() {
17811         job_stats="mdt.*.job_stats"
17812         $LCTL set_param $job_stats=clear
17813         # Setting jobid_var to USER might not be supported
17814         $LCTL set_param jobid_var=USER || true
17815         $LCTL set_param jobid_name="%e.%u"
17816         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17817         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17818                 grep "job_id:.*foolish" &&
17819                         error "Unexpected jobid found"
17820         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17821                 grep "open:.*min.*max.*sum" ||
17822                         error "wrong job_stats format found"
17823 }
17824 run_test 205b "Verify job stats jobid and output format"
17825
17826 # LU-13733
17827 test_205c() {
17828         $LCTL set_param llite.*.stats=0
17829         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17830         $LCTL get_param llite.*.stats
17831         $LCTL get_param llite.*.stats | grep \
17832                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17833                         error "wrong client stats format found"
17834 }
17835 run_test 205c "Verify client stats format"
17836
17837 # LU-1480, LU-1773 and LU-1657
17838 test_206() {
17839         mkdir -p $DIR/$tdir
17840         $LFS setstripe -c -1 $DIR/$tdir
17841 #define OBD_FAIL_LOV_INIT 0x1403
17842         $LCTL set_param fail_loc=0xa0001403
17843         $LCTL set_param fail_val=1
17844         touch $DIR/$tdir/$tfile || true
17845 }
17846 run_test 206 "fail lov_init_raid0() doesn't lbug"
17847
17848 test_207a() {
17849         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17850         local fsz=`stat -c %s $DIR/$tfile`
17851         cancel_lru_locks mdc
17852
17853         # do not return layout in getattr intent
17854 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17855         $LCTL set_param fail_loc=0x170
17856         local sz=`stat -c %s $DIR/$tfile`
17857
17858         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17859
17860         rm -rf $DIR/$tfile
17861 }
17862 run_test 207a "can refresh layout at glimpse"
17863
17864 test_207b() {
17865         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17866         local cksum=`md5sum $DIR/$tfile`
17867         local fsz=`stat -c %s $DIR/$tfile`
17868         cancel_lru_locks mdc
17869         cancel_lru_locks osc
17870
17871         # do not return layout in getattr intent
17872 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17873         $LCTL set_param fail_loc=0x171
17874
17875         # it will refresh layout after the file is opened but before read issues
17876         echo checksum is "$cksum"
17877         echo "$cksum" |md5sum -c --quiet || error "file differs"
17878
17879         rm -rf $DIR/$tfile
17880 }
17881 run_test 207b "can refresh layout at open"
17882
17883 test_208() {
17884         # FIXME: in this test suite, only RD lease is used. This is okay
17885         # for now as only exclusive open is supported. After generic lease
17886         # is done, this test suite should be revised. - Jinshan
17887
17888         remote_mds_nodsh && skip "remote MDS with nodsh"
17889         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17890                 skip "Need MDS version at least 2.4.52"
17891
17892         echo "==== test 1: verify get lease work"
17893         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17894
17895         echo "==== test 2: verify lease can be broken by upcoming open"
17896         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17897         local PID=$!
17898         sleep 1
17899
17900         $MULTIOP $DIR/$tfile oO_RDONLY:c
17901         kill -USR1 $PID && wait $PID || error "break lease error"
17902
17903         echo "==== test 3: verify lease can't be granted if an open already exists"
17904         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17905         local PID=$!
17906         sleep 1
17907
17908         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17909         kill -USR1 $PID && wait $PID || error "open file error"
17910
17911         echo "==== test 4: lease can sustain over recovery"
17912         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17913         PID=$!
17914         sleep 1
17915
17916         fail mds1
17917
17918         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17919
17920         echo "==== test 5: lease broken can't be regained by replay"
17921         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17922         PID=$!
17923         sleep 1
17924
17925         # open file to break lease and then recovery
17926         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17927         fail mds1
17928
17929         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17930
17931         rm -f $DIR/$tfile
17932 }
17933 run_test 208 "Exclusive open"
17934
17935 test_209() {
17936         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17937                 skip_env "must have disp_stripe"
17938
17939         touch $DIR/$tfile
17940         sync; sleep 5; sync;
17941
17942         echo 3 > /proc/sys/vm/drop_caches
17943         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17944                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17945         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17946
17947         # open/close 500 times
17948         for i in $(seq 500); do
17949                 cat $DIR/$tfile
17950         done
17951
17952         echo 3 > /proc/sys/vm/drop_caches
17953         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17954                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17955         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17956
17957         echo "before: $req_before, after: $req_after"
17958         [ $((req_after - req_before)) -ge 300 ] &&
17959                 error "open/close requests are not freed"
17960         return 0
17961 }
17962 run_test 209 "read-only open/close requests should be freed promptly"
17963
17964 test_210() {
17965         local pid
17966
17967         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17968         pid=$!
17969         sleep 1
17970
17971         $LFS getstripe $DIR/$tfile
17972         kill -USR1 $pid
17973         wait $pid || error "multiop failed"
17974
17975         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17976         pid=$!
17977         sleep 1
17978
17979         $LFS getstripe $DIR/$tfile
17980         kill -USR1 $pid
17981         wait $pid || error "multiop failed"
17982 }
17983 run_test 210 "lfs getstripe does not break leases"
17984
17985 test_212() {
17986         size=`date +%s`
17987         size=$((size % 8192 + 1))
17988         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17989         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17990         rm -f $DIR/f212 $DIR/f212.xyz
17991 }
17992 run_test 212 "Sendfile test ============================================"
17993
17994 test_213() {
17995         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17996         cancel_lru_locks osc
17997         lctl set_param fail_loc=0x8000040f
17998         # generate a read lock
17999         cat $DIR/$tfile > /dev/null
18000         # write to the file, it will try to cancel the above read lock.
18001         cat /etc/hosts >> $DIR/$tfile
18002 }
18003 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18004
18005 test_214() { # for bug 20133
18006         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18007         for (( i=0; i < 340; i++ )) ; do
18008                 touch $DIR/$tdir/d214c/a$i
18009         done
18010
18011         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18012         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18013         ls $DIR/d214c || error "ls $DIR/d214c failed"
18014         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18015         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18016 }
18017 run_test 214 "hash-indexed directory test - bug 20133"
18018
18019 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18020 create_lnet_proc_files() {
18021         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18022 }
18023
18024 # counterpart of create_lnet_proc_files
18025 remove_lnet_proc_files() {
18026         rm -f $TMP/lnet_$1.sys
18027 }
18028
18029 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18030 # 3rd arg as regexp for body
18031 check_lnet_proc_stats() {
18032         local l=$(cat "$TMP/lnet_$1" |wc -l)
18033         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18034
18035         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18036 }
18037
18038 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18039 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18040 # optional and can be regexp for 2nd line (lnet.routes case)
18041 check_lnet_proc_entry() {
18042         local blp=2          # blp stands for 'position of 1st line of body'
18043         [ -z "$5" ] || blp=3 # lnet.routes case
18044
18045         local l=$(cat "$TMP/lnet_$1" |wc -l)
18046         # subtracting one from $blp because the body can be empty
18047         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18048
18049         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18050                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18051
18052         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18053                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18054
18055         # bail out if any unexpected line happened
18056         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18057         [ "$?" != 0 ] || error "$2 misformatted"
18058 }
18059
18060 test_215() { # for bugs 18102, 21079, 21517
18061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18062
18063         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18064         local P='[1-9][0-9]*'           # positive numeric
18065         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18066         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18067         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18068         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18069
18070         local L1 # regexp for 1st line
18071         local L2 # regexp for 2nd line (optional)
18072         local BR # regexp for the rest (body)
18073
18074         # lnet.stats should look as 11 space-separated non-negative numerics
18075         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18076         create_lnet_proc_files "stats"
18077         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18078         remove_lnet_proc_files "stats"
18079
18080         # lnet.routes should look like this:
18081         # Routing disabled/enabled
18082         # net hops priority state router
18083         # where net is a string like tcp0, hops > 0, priority >= 0,
18084         # state is up/down,
18085         # router is a string like 192.168.1.1@tcp2
18086         L1="^Routing (disabled|enabled)$"
18087         L2="^net +hops +priority +state +router$"
18088         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18089         create_lnet_proc_files "routes"
18090         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18091         remove_lnet_proc_files "routes"
18092
18093         # lnet.routers should look like this:
18094         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18095         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18096         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18097         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18098         L1="^ref +rtr_ref +alive +router$"
18099         BR="^$P +$P +(up|down) +$NID$"
18100         create_lnet_proc_files "routers"
18101         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18102         remove_lnet_proc_files "routers"
18103
18104         # lnet.peers should look like this:
18105         # nid refs state last max rtr min tx min queue
18106         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18107         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18108         # numeric (0 or >0 or <0), queue >= 0.
18109         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18110         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18111         create_lnet_proc_files "peers"
18112         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18113         remove_lnet_proc_files "peers"
18114
18115         # lnet.buffers  should look like this:
18116         # pages count credits min
18117         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18118         L1="^pages +count +credits +min$"
18119         BR="^ +$N +$N +$I +$I$"
18120         create_lnet_proc_files "buffers"
18121         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18122         remove_lnet_proc_files "buffers"
18123
18124         # lnet.nis should look like this:
18125         # nid status alive refs peer rtr max tx min
18126         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18127         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18128         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18129         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18130         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18131         create_lnet_proc_files "nis"
18132         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18133         remove_lnet_proc_files "nis"
18134
18135         # can we successfully write to lnet.stats?
18136         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18137 }
18138 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18139
18140 test_216() { # bug 20317
18141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18142         remote_ost_nodsh && skip "remote OST with nodsh"
18143
18144         local node
18145         local facets=$(get_facets OST)
18146         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18147
18148         save_lustre_params client "osc.*.contention_seconds" > $p
18149         save_lustre_params $facets \
18150                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18151         save_lustre_params $facets \
18152                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18153         save_lustre_params $facets \
18154                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18155         clear_stats osc.*.osc_stats
18156
18157         # agressive lockless i/o settings
18158         do_nodes $(comma_list $(osts_nodes)) \
18159                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18160                         ldlm.namespaces.filter-*.contended_locks=0 \
18161                         ldlm.namespaces.filter-*.contention_seconds=60"
18162         lctl set_param -n osc.*.contention_seconds=60
18163
18164         $DIRECTIO write $DIR/$tfile 0 10 4096
18165         $CHECKSTAT -s 40960 $DIR/$tfile
18166
18167         # disable lockless i/o
18168         do_nodes $(comma_list $(osts_nodes)) \
18169                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18170                         ldlm.namespaces.filter-*.contended_locks=32 \
18171                         ldlm.namespaces.filter-*.contention_seconds=0"
18172         lctl set_param -n osc.*.contention_seconds=0
18173         clear_stats osc.*.osc_stats
18174
18175         dd if=/dev/zero of=$DIR/$tfile count=0
18176         $CHECKSTAT -s 0 $DIR/$tfile
18177
18178         restore_lustre_params <$p
18179         rm -f $p
18180         rm $DIR/$tfile
18181 }
18182 run_test 216 "check lockless direct write updates file size and kms correctly"
18183
18184 test_217() { # bug 22430
18185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18186
18187         local node
18188         local nid
18189
18190         for node in $(nodes_list); do
18191                 nid=$(host_nids_address $node $NETTYPE)
18192                 if [[ $nid = *-* ]] ; then
18193                         echo "lctl ping $(h2nettype $nid)"
18194                         lctl ping $(h2nettype $nid)
18195                 else
18196                         echo "skipping $node (no hyphen detected)"
18197                 fi
18198         done
18199 }
18200 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18201
18202 test_218() {
18203        # do directio so as not to populate the page cache
18204        log "creating a 10 Mb file"
18205        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18206        log "starting reads"
18207        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18208        log "truncating the file"
18209        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18210        log "killing dd"
18211        kill %+ || true # reads might have finished
18212        echo "wait until dd is finished"
18213        wait
18214        log "removing the temporary file"
18215        rm -rf $DIR/$tfile || error "tmp file removal failed"
18216 }
18217 run_test 218 "parallel read and truncate should not deadlock"
18218
18219 test_219() {
18220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18221
18222         # write one partial page
18223         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18224         # set no grant so vvp_io_commit_write will do sync write
18225         $LCTL set_param fail_loc=0x411
18226         # write a full page at the end of file
18227         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18228
18229         $LCTL set_param fail_loc=0
18230         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18231         $LCTL set_param fail_loc=0x411
18232         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18233
18234         # LU-4201
18235         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18236         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18237 }
18238 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18239
18240 test_220() { #LU-325
18241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18242         remote_ost_nodsh && skip "remote OST with nodsh"
18243         remote_mds_nodsh && skip "remote MDS with nodsh"
18244         remote_mgs_nodsh && skip "remote MGS with nodsh"
18245
18246         local OSTIDX=0
18247
18248         # create on MDT0000 so the last_id and next_id are correct
18249         mkdir $DIR/$tdir
18250         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18251         OST=${OST%_UUID}
18252
18253         # on the mdt's osc
18254         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18255         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18256                         osp.$mdtosc_proc1.prealloc_last_id)
18257         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18258                         osp.$mdtosc_proc1.prealloc_next_id)
18259
18260         $LFS df -i
18261
18262         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18263         #define OBD_FAIL_OST_ENOINO              0x229
18264         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18265         create_pool $FSNAME.$TESTNAME || return 1
18266         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18267
18268         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18269
18270         MDSOBJS=$((last_id - next_id))
18271         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18272
18273         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18274         echo "OST still has $count kbytes free"
18275
18276         echo "create $MDSOBJS files @next_id..."
18277         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18278
18279         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18280                         osp.$mdtosc_proc1.prealloc_last_id)
18281         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18282                         osp.$mdtosc_proc1.prealloc_next_id)
18283
18284         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18285         $LFS df -i
18286
18287         echo "cleanup..."
18288
18289         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18290         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18291
18292         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18293                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18294         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18295                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18296         echo "unlink $MDSOBJS files @$next_id..."
18297         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18298 }
18299 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18300
18301 test_221() {
18302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18303
18304         dd if=`which date` of=$MOUNT/date oflag=sync
18305         chmod +x $MOUNT/date
18306
18307         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18308         $LCTL set_param fail_loc=0x80001401
18309
18310         $MOUNT/date > /dev/null
18311         rm -f $MOUNT/date
18312 }
18313 run_test 221 "make sure fault and truncate race to not cause OOM"
18314
18315 test_222a () {
18316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18317
18318         rm -rf $DIR/$tdir
18319         test_mkdir $DIR/$tdir
18320         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18321         createmany -o $DIR/$tdir/$tfile 10
18322         cancel_lru_locks mdc
18323         cancel_lru_locks osc
18324         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18325         $LCTL set_param fail_loc=0x31a
18326         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18327         $LCTL set_param fail_loc=0
18328         rm -r $DIR/$tdir
18329 }
18330 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18331
18332 test_222b () {
18333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18334
18335         rm -rf $DIR/$tdir
18336         test_mkdir $DIR/$tdir
18337         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18338         createmany -o $DIR/$tdir/$tfile 10
18339         cancel_lru_locks mdc
18340         cancel_lru_locks osc
18341         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18342         $LCTL set_param fail_loc=0x31a
18343         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18344         $LCTL set_param fail_loc=0
18345 }
18346 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18347
18348 test_223 () {
18349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18350
18351         rm -rf $DIR/$tdir
18352         test_mkdir $DIR/$tdir
18353         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18354         createmany -o $DIR/$tdir/$tfile 10
18355         cancel_lru_locks mdc
18356         cancel_lru_locks osc
18357         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18358         $LCTL set_param fail_loc=0x31b
18359         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18360         $LCTL set_param fail_loc=0
18361         rm -r $DIR/$tdir
18362 }
18363 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18364
18365 test_224a() { # LU-1039, MRP-303
18366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18367
18368         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18369         $LCTL set_param fail_loc=0x508
18370         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18371         $LCTL set_param fail_loc=0
18372         df $DIR
18373 }
18374 run_test 224a "Don't panic on bulk IO failure"
18375
18376 test_224b() { # LU-1039, MRP-303
18377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18378
18379         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18380         cancel_lru_locks osc
18381         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18382         $LCTL set_param fail_loc=0x515
18383         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18384         $LCTL set_param fail_loc=0
18385         df $DIR
18386 }
18387 run_test 224b "Don't panic on bulk IO failure"
18388
18389 test_224c() { # LU-6441
18390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18391         remote_mds_nodsh && skip "remote MDS with nodsh"
18392
18393         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18394         save_writethrough $p
18395         set_cache writethrough on
18396
18397         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18398         local at_max=$($LCTL get_param -n at_max)
18399         local timeout=$($LCTL get_param -n timeout)
18400         local test_at="at_max"
18401         local param_at="$FSNAME.sys.at_max"
18402         local test_timeout="timeout"
18403         local param_timeout="$FSNAME.sys.timeout"
18404
18405         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18406
18407         set_persistent_param_and_check client "$test_at" "$param_at" 0
18408         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18409
18410         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18411         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18412         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18413         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18414         sync
18415         do_facet ost1 "$LCTL set_param fail_loc=0"
18416
18417         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18418         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18419                 $timeout
18420
18421         $LCTL set_param -n $pages_per_rpc
18422         restore_lustre_params < $p
18423         rm -f $p
18424 }
18425 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18426
18427 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18428 test_225a () {
18429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18430         if [ -z ${MDSSURVEY} ]; then
18431                 skip_env "mds-survey not found"
18432         fi
18433         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18434                 skip "Need MDS version at least 2.2.51"
18435
18436         local mds=$(facet_host $SINGLEMDS)
18437         local target=$(do_nodes $mds 'lctl dl' |
18438                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18439
18440         local cmd1="file_count=1000 thrhi=4"
18441         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18442         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18443         local cmd="$cmd1 $cmd2 $cmd3"
18444
18445         rm -f ${TMP}/mds_survey*
18446         echo + $cmd
18447         eval $cmd || error "mds-survey with zero-stripe failed"
18448         cat ${TMP}/mds_survey*
18449         rm -f ${TMP}/mds_survey*
18450 }
18451 run_test 225a "Metadata survey sanity with zero-stripe"
18452
18453 test_225b () {
18454         if [ -z ${MDSSURVEY} ]; then
18455                 skip_env "mds-survey not found"
18456         fi
18457         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18458                 skip "Need MDS version at least 2.2.51"
18459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18460         remote_mds_nodsh && skip "remote MDS with nodsh"
18461         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18462                 skip_env "Need to mount OST to test"
18463         fi
18464
18465         local mds=$(facet_host $SINGLEMDS)
18466         local target=$(do_nodes $mds 'lctl dl' |
18467                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18468
18469         local cmd1="file_count=1000 thrhi=4"
18470         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18471         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18472         local cmd="$cmd1 $cmd2 $cmd3"
18473
18474         rm -f ${TMP}/mds_survey*
18475         echo + $cmd
18476         eval $cmd || error "mds-survey with stripe_count failed"
18477         cat ${TMP}/mds_survey*
18478         rm -f ${TMP}/mds_survey*
18479 }
18480 run_test 225b "Metadata survey sanity with stripe_count = 1"
18481
18482 mcreate_path2fid () {
18483         local mode=$1
18484         local major=$2
18485         local minor=$3
18486         local name=$4
18487         local desc=$5
18488         local path=$DIR/$tdir/$name
18489         local fid
18490         local rc
18491         local fid_path
18492
18493         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18494                 error "cannot create $desc"
18495
18496         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18497         rc=$?
18498         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18499
18500         fid_path=$($LFS fid2path $MOUNT $fid)
18501         rc=$?
18502         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18503
18504         [ "$path" == "$fid_path" ] ||
18505                 error "fid2path returned $fid_path, expected $path"
18506
18507         echo "pass with $path and $fid"
18508 }
18509
18510 test_226a () {
18511         rm -rf $DIR/$tdir
18512         mkdir -p $DIR/$tdir
18513
18514         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18515         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18516         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18517         mcreate_path2fid 0040666 0 0 dir "directory"
18518         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18519         mcreate_path2fid 0100666 0 0 file "regular file"
18520         mcreate_path2fid 0120666 0 0 link "symbolic link"
18521         mcreate_path2fid 0140666 0 0 sock "socket"
18522 }
18523 run_test 226a "call path2fid and fid2path on files of all type"
18524
18525 test_226b () {
18526         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18527
18528         local MDTIDX=1
18529
18530         rm -rf $DIR/$tdir
18531         mkdir -p $DIR/$tdir
18532         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18533                 error "create remote directory failed"
18534         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18535         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18536                                 "character special file (null)"
18537         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18538                                 "character special file (no device)"
18539         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18540         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18541                                 "block special file (loop)"
18542         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18543         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18544         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18545 }
18546 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18547
18548 test_226c () {
18549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18550         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18551                 skip "Need MDS version at least 2.13.55"
18552
18553         local submnt=/mnt/submnt
18554         local srcfile=/etc/passwd
18555         local dstfile=$submnt/passwd
18556         local path
18557         local fid
18558
18559         rm -rf $DIR/$tdir
18560         rm -rf $submnt
18561         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18562                 error "create remote directory failed"
18563         mkdir -p $submnt || error "create $submnt failed"
18564         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18565                 error "mount $submnt failed"
18566         stack_trap "umount $submnt" EXIT
18567
18568         cp $srcfile $dstfile
18569         fid=$($LFS path2fid $dstfile)
18570         path=$($LFS fid2path $submnt "$fid")
18571         [ "$path" = "$dstfile" ] ||
18572                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18573 }
18574 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18575
18576 # LU-1299 Executing or running ldd on a truncated executable does not
18577 # cause an out-of-memory condition.
18578 test_227() {
18579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18580         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18581
18582         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18583         chmod +x $MOUNT/date
18584
18585         $MOUNT/date > /dev/null
18586         ldd $MOUNT/date > /dev/null
18587         rm -f $MOUNT/date
18588 }
18589 run_test 227 "running truncated executable does not cause OOM"
18590
18591 # LU-1512 try to reuse idle OI blocks
18592 test_228a() {
18593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18594         remote_mds_nodsh && skip "remote MDS with nodsh"
18595         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18596
18597         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18598         local myDIR=$DIR/$tdir
18599
18600         mkdir -p $myDIR
18601         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18602         $LCTL set_param fail_loc=0x80001002
18603         createmany -o $myDIR/t- 10000
18604         $LCTL set_param fail_loc=0
18605         # The guard is current the largest FID holder
18606         touch $myDIR/guard
18607         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18608                     tr -d '[')
18609         local IDX=$(($SEQ % 64))
18610
18611         do_facet $SINGLEMDS sync
18612         # Make sure journal flushed.
18613         sleep 6
18614         local blk1=$(do_facet $SINGLEMDS \
18615                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18616                      grep Blockcount | awk '{print $4}')
18617
18618         # Remove old files, some OI blocks will become idle.
18619         unlinkmany $myDIR/t- 10000
18620         # Create new files, idle OI blocks should be reused.
18621         createmany -o $myDIR/t- 2000
18622         do_facet $SINGLEMDS sync
18623         # Make sure journal flushed.
18624         sleep 6
18625         local blk2=$(do_facet $SINGLEMDS \
18626                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18627                      grep Blockcount | awk '{print $4}')
18628
18629         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18630 }
18631 run_test 228a "try to reuse idle OI blocks"
18632
18633 test_228b() {
18634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18635         remote_mds_nodsh && skip "remote MDS with nodsh"
18636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18637
18638         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18639         local myDIR=$DIR/$tdir
18640
18641         mkdir -p $myDIR
18642         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18643         $LCTL set_param fail_loc=0x80001002
18644         createmany -o $myDIR/t- 10000
18645         $LCTL set_param fail_loc=0
18646         # The guard is current the largest FID holder
18647         touch $myDIR/guard
18648         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18649                     tr -d '[')
18650         local IDX=$(($SEQ % 64))
18651
18652         do_facet $SINGLEMDS sync
18653         # Make sure journal flushed.
18654         sleep 6
18655         local blk1=$(do_facet $SINGLEMDS \
18656                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18657                      grep Blockcount | awk '{print $4}')
18658
18659         # Remove old files, some OI blocks will become idle.
18660         unlinkmany $myDIR/t- 10000
18661
18662         # stop the MDT
18663         stop $SINGLEMDS || error "Fail to stop MDT."
18664         # remount the MDT
18665         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18666
18667         df $MOUNT || error "Fail to df."
18668         # Create new files, idle OI blocks should be reused.
18669         createmany -o $myDIR/t- 2000
18670         do_facet $SINGLEMDS sync
18671         # Make sure journal flushed.
18672         sleep 6
18673         local blk2=$(do_facet $SINGLEMDS \
18674                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18675                      grep Blockcount | awk '{print $4}')
18676
18677         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18678 }
18679 run_test 228b "idle OI blocks can be reused after MDT restart"
18680
18681 #LU-1881
18682 test_228c() {
18683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18684         remote_mds_nodsh && skip "remote MDS with nodsh"
18685         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18686
18687         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18688         local myDIR=$DIR/$tdir
18689
18690         mkdir -p $myDIR
18691         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18692         $LCTL set_param fail_loc=0x80001002
18693         # 20000 files can guarantee there are index nodes in the OI file
18694         createmany -o $myDIR/t- 20000
18695         $LCTL set_param fail_loc=0
18696         # The guard is current the largest FID holder
18697         touch $myDIR/guard
18698         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18699                     tr -d '[')
18700         local IDX=$(($SEQ % 64))
18701
18702         do_facet $SINGLEMDS sync
18703         # Make sure journal flushed.
18704         sleep 6
18705         local blk1=$(do_facet $SINGLEMDS \
18706                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18707                      grep Blockcount | awk '{print $4}')
18708
18709         # Remove old files, some OI blocks will become idle.
18710         unlinkmany $myDIR/t- 20000
18711         rm -f $myDIR/guard
18712         # The OI file should become empty now
18713
18714         # Create new files, idle OI blocks should be reused.
18715         createmany -o $myDIR/t- 2000
18716         do_facet $SINGLEMDS sync
18717         # Make sure journal flushed.
18718         sleep 6
18719         local blk2=$(do_facet $SINGLEMDS \
18720                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18721                      grep Blockcount | awk '{print $4}')
18722
18723         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18724 }
18725 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18726
18727 test_229() { # LU-2482, LU-3448
18728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18729         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18730         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18731                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18732
18733         rm -f $DIR/$tfile
18734
18735         # Create a file with a released layout and stripe count 2.
18736         $MULTIOP $DIR/$tfile H2c ||
18737                 error "failed to create file with released layout"
18738
18739         $LFS getstripe -v $DIR/$tfile
18740
18741         local pattern=$($LFS getstripe -L $DIR/$tfile)
18742         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18743
18744         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18745                 error "getstripe"
18746         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18747         stat $DIR/$tfile || error "failed to stat released file"
18748
18749         chown $RUNAS_ID $DIR/$tfile ||
18750                 error "chown $RUNAS_ID $DIR/$tfile failed"
18751
18752         chgrp $RUNAS_ID $DIR/$tfile ||
18753                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18754
18755         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18756         rm $DIR/$tfile || error "failed to remove released file"
18757 }
18758 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18759
18760 test_230a() {
18761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18763         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18764                 skip "Need MDS version at least 2.11.52"
18765
18766         local MDTIDX=1
18767
18768         test_mkdir $DIR/$tdir
18769         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18770         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18771         [ $mdt_idx -ne 0 ] &&
18772                 error "create local directory on wrong MDT $mdt_idx"
18773
18774         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18775                         error "create remote directory failed"
18776         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18777         [ $mdt_idx -ne $MDTIDX ] &&
18778                 error "create remote directory on wrong MDT $mdt_idx"
18779
18780         createmany -o $DIR/$tdir/test_230/t- 10 ||
18781                 error "create files on remote directory failed"
18782         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18783         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18784         rm -r $DIR/$tdir || error "unlink remote directory failed"
18785 }
18786 run_test 230a "Create remote directory and files under the remote directory"
18787
18788 test_230b() {
18789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18790         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18791         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18792                 skip "Need MDS version at least 2.11.52"
18793
18794         local MDTIDX=1
18795         local mdt_index
18796         local i
18797         local file
18798         local pid
18799         local stripe_count
18800         local migrate_dir=$DIR/$tdir/migrate_dir
18801         local other_dir=$DIR/$tdir/other_dir
18802
18803         test_mkdir $DIR/$tdir
18804         test_mkdir -i0 -c1 $migrate_dir
18805         test_mkdir -i0 -c1 $other_dir
18806         for ((i=0; i<10; i++)); do
18807                 mkdir -p $migrate_dir/dir_${i}
18808                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18809                         error "create files under remote dir failed $i"
18810         done
18811
18812         cp /etc/passwd $migrate_dir/$tfile
18813         cp /etc/passwd $other_dir/$tfile
18814         chattr +SAD $migrate_dir
18815         chattr +SAD $migrate_dir/$tfile
18816
18817         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18818         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18819         local old_dir_mode=$(stat -c%f $migrate_dir)
18820         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18821
18822         mkdir -p $migrate_dir/dir_default_stripe2
18823         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18824         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18825
18826         mkdir -p $other_dir
18827         ln $migrate_dir/$tfile $other_dir/luna
18828         ln $migrate_dir/$tfile $migrate_dir/sofia
18829         ln $other_dir/$tfile $migrate_dir/david
18830         ln -s $migrate_dir/$tfile $other_dir/zachary
18831         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18832         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18833
18834         local len
18835         local lnktgt
18836
18837         # inline symlink
18838         for len in 58 59 60; do
18839                 lnktgt=$(str_repeat 'l' $len)
18840                 touch $migrate_dir/$lnktgt
18841                 ln -s $lnktgt $migrate_dir/${len}char_ln
18842         done
18843
18844         # PATH_MAX
18845         for len in 4094 4095; do
18846                 lnktgt=$(str_repeat 'l' $len)
18847                 ln -s $lnktgt $migrate_dir/${len}char_ln
18848         done
18849
18850         # NAME_MAX
18851         for len in 254 255; do
18852                 touch $migrate_dir/$(str_repeat 'l' $len)
18853         done
18854
18855         $LFS migrate -m $MDTIDX $migrate_dir ||
18856                 error "fails on migrating remote dir to MDT1"
18857
18858         echo "migratate to MDT1, then checking.."
18859         for ((i = 0; i < 10; i++)); do
18860                 for file in $(find $migrate_dir/dir_${i}); do
18861                         mdt_index=$($LFS getstripe -m $file)
18862                         # broken symlink getstripe will fail
18863                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18864                                 error "$file is not on MDT${MDTIDX}"
18865                 done
18866         done
18867
18868         # the multiple link file should still in MDT0
18869         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18870         [ $mdt_index == 0 ] ||
18871                 error "$file is not on MDT${MDTIDX}"
18872
18873         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18874         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18875                 error " expect $old_dir_flag get $new_dir_flag"
18876
18877         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18878         [ "$old_file_flag" = "$new_file_flag" ] ||
18879                 error " expect $old_file_flag get $new_file_flag"
18880
18881         local new_dir_mode=$(stat -c%f $migrate_dir)
18882         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18883                 error "expect mode $old_dir_mode get $new_dir_mode"
18884
18885         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18886         [ "$old_file_mode" = "$new_file_mode" ] ||
18887                 error "expect mode $old_file_mode get $new_file_mode"
18888
18889         diff /etc/passwd $migrate_dir/$tfile ||
18890                 error "$tfile different after migration"
18891
18892         diff /etc/passwd $other_dir/luna ||
18893                 error "luna different after migration"
18894
18895         diff /etc/passwd $migrate_dir/sofia ||
18896                 error "sofia different after migration"
18897
18898         diff /etc/passwd $migrate_dir/david ||
18899                 error "david different after migration"
18900
18901         diff /etc/passwd $other_dir/zachary ||
18902                 error "zachary different after migration"
18903
18904         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18905                 error "${tfile}_ln different after migration"
18906
18907         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18908                 error "${tfile}_ln_other different after migration"
18909
18910         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18911         [ $stripe_count = 2 ] ||
18912                 error "dir strpe_count $d != 2 after migration."
18913
18914         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18915         [ $stripe_count = 2 ] ||
18916                 error "file strpe_count $d != 2 after migration."
18917
18918         #migrate back to MDT0
18919         MDTIDX=0
18920
18921         $LFS migrate -m $MDTIDX $migrate_dir ||
18922                 error "fails on migrating remote dir to MDT0"
18923
18924         echo "migrate back to MDT0, checking.."
18925         for file in $(find $migrate_dir); do
18926                 mdt_index=$($LFS getstripe -m $file)
18927                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18928                         error "$file is not on MDT${MDTIDX}"
18929         done
18930
18931         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18932         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18933                 error " expect $old_dir_flag get $new_dir_flag"
18934
18935         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18936         [ "$old_file_flag" = "$new_file_flag" ] ||
18937                 error " expect $old_file_flag get $new_file_flag"
18938
18939         local new_dir_mode=$(stat -c%f $migrate_dir)
18940         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18941                 error "expect mode $old_dir_mode get $new_dir_mode"
18942
18943         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18944         [ "$old_file_mode" = "$new_file_mode" ] ||
18945                 error "expect mode $old_file_mode get $new_file_mode"
18946
18947         diff /etc/passwd ${migrate_dir}/$tfile ||
18948                 error "$tfile different after migration"
18949
18950         diff /etc/passwd ${other_dir}/luna ||
18951                 error "luna different after migration"
18952
18953         diff /etc/passwd ${migrate_dir}/sofia ||
18954                 error "sofia different after migration"
18955
18956         diff /etc/passwd ${other_dir}/zachary ||
18957                 error "zachary different after migration"
18958
18959         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18960                 error "${tfile}_ln different after migration"
18961
18962         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18963                 error "${tfile}_ln_other different after migration"
18964
18965         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18966         [ $stripe_count = 2 ] ||
18967                 error "dir strpe_count $d != 2 after migration."
18968
18969         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18970         [ $stripe_count = 2 ] ||
18971                 error "file strpe_count $d != 2 after migration."
18972
18973         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18974 }
18975 run_test 230b "migrate directory"
18976
18977 test_230c() {
18978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18979         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18980         remote_mds_nodsh && skip "remote MDS with nodsh"
18981         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18982                 skip "Need MDS version at least 2.11.52"
18983
18984         local MDTIDX=1
18985         local total=3
18986         local mdt_index
18987         local file
18988         local migrate_dir=$DIR/$tdir/migrate_dir
18989
18990         #If migrating directory fails in the middle, all entries of
18991         #the directory is still accessiable.
18992         test_mkdir $DIR/$tdir
18993         test_mkdir -i0 -c1 $migrate_dir
18994         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18995         stat $migrate_dir
18996         createmany -o $migrate_dir/f $total ||
18997                 error "create files under ${migrate_dir} failed"
18998
18999         # fail after migrating top dir, and this will fail only once, so the
19000         # first sub file migration will fail (currently f3), others succeed.
19001         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19002         do_facet mds1 lctl set_param fail_loc=0x1801
19003         local t=$(ls $migrate_dir | wc -l)
19004         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19005                 error "migrate should fail"
19006         local u=$(ls $migrate_dir | wc -l)
19007         [ "$u" == "$t" ] || error "$u != $t during migration"
19008
19009         # add new dir/file should succeed
19010         mkdir $migrate_dir/dir ||
19011                 error "mkdir failed under migrating directory"
19012         touch $migrate_dir/file ||
19013                 error "create file failed under migrating directory"
19014
19015         # add file with existing name should fail
19016         for file in $migrate_dir/f*; do
19017                 stat $file > /dev/null || error "stat $file failed"
19018                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19019                         error "open(O_CREAT|O_EXCL) $file should fail"
19020                 $MULTIOP $file m && error "create $file should fail"
19021                 touch $DIR/$tdir/remote_dir/$tfile ||
19022                         error "touch $tfile failed"
19023                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19024                         error "link $file should fail"
19025                 mdt_index=$($LFS getstripe -m $file)
19026                 if [ $mdt_index == 0 ]; then
19027                         # file failed to migrate is not allowed to rename to
19028                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19029                                 error "rename to $file should fail"
19030                 else
19031                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19032                                 error "rename to $file failed"
19033                 fi
19034                 echo hello >> $file || error "write $file failed"
19035         done
19036
19037         # resume migration with different options should fail
19038         $LFS migrate -m 0 $migrate_dir &&
19039                 error "migrate -m 0 $migrate_dir should fail"
19040
19041         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19042                 error "migrate -c 2 $migrate_dir should fail"
19043
19044         # resume migration should succeed
19045         $LFS migrate -m $MDTIDX $migrate_dir ||
19046                 error "migrate $migrate_dir failed"
19047
19048         echo "Finish migration, then checking.."
19049         for file in $(find $migrate_dir); do
19050                 mdt_index=$($LFS getstripe -m $file)
19051                 [ $mdt_index == $MDTIDX ] ||
19052                         error "$file is not on MDT${MDTIDX}"
19053         done
19054
19055         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19056 }
19057 run_test 230c "check directory accessiblity if migration failed"
19058
19059 test_230d() {
19060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19062         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19063                 skip "Need MDS version at least 2.11.52"
19064         # LU-11235
19065         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19066
19067         local migrate_dir=$DIR/$tdir/migrate_dir
19068         local old_index
19069         local new_index
19070         local old_count
19071         local new_count
19072         local new_hash
19073         local mdt_index
19074         local i
19075         local j
19076
19077         old_index=$((RANDOM % MDSCOUNT))
19078         old_count=$((MDSCOUNT - old_index))
19079         new_index=$((RANDOM % MDSCOUNT))
19080         new_count=$((MDSCOUNT - new_index))
19081         new_hash=1 # for all_char
19082
19083         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19084         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19085
19086         test_mkdir $DIR/$tdir
19087         test_mkdir -i $old_index -c $old_count $migrate_dir
19088
19089         for ((i=0; i<100; i++)); do
19090                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19091                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19092                         error "create files under remote dir failed $i"
19093         done
19094
19095         echo -n "Migrate from MDT$old_index "
19096         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19097         echo -n "to MDT$new_index"
19098         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19099         echo
19100
19101         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19102         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19103                 error "migrate remote dir error"
19104
19105         echo "Finish migration, then checking.."
19106         for file in $(find $migrate_dir); do
19107                 mdt_index=$($LFS getstripe -m $file)
19108                 if [ $mdt_index -lt $new_index ] ||
19109                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19110                         error "$file is on MDT$mdt_index"
19111                 fi
19112         done
19113
19114         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19115 }
19116 run_test 230d "check migrate big directory"
19117
19118 test_230e() {
19119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19121         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19122                 skip "Need MDS version at least 2.11.52"
19123
19124         local i
19125         local j
19126         local a_fid
19127         local b_fid
19128
19129         mkdir -p $DIR/$tdir
19130         mkdir $DIR/$tdir/migrate_dir
19131         mkdir $DIR/$tdir/other_dir
19132         touch $DIR/$tdir/migrate_dir/a
19133         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19134         ls $DIR/$tdir/other_dir
19135
19136         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19137                 error "migrate dir fails"
19138
19139         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19140         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19141
19142         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19143         [ $mdt_index == 0 ] || error "a is not on MDT0"
19144
19145         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19146                 error "migrate dir fails"
19147
19148         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19149         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19150
19151         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19152         [ $mdt_index == 1 ] || error "a is not on MDT1"
19153
19154         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19155         [ $mdt_index == 1 ] || error "b is not on MDT1"
19156
19157         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19158         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19159
19160         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19161
19162         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19163 }
19164 run_test 230e "migrate mulitple local link files"
19165
19166 test_230f() {
19167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19168         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19169         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19170                 skip "Need MDS version at least 2.11.52"
19171
19172         local a_fid
19173         local ln_fid
19174
19175         mkdir -p $DIR/$tdir
19176         mkdir $DIR/$tdir/migrate_dir
19177         $LFS mkdir -i1 $DIR/$tdir/other_dir
19178         touch $DIR/$tdir/migrate_dir/a
19179         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19180         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19181         ls $DIR/$tdir/other_dir
19182
19183         # a should be migrated to MDT1, since no other links on MDT0
19184         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19185                 error "#1 migrate dir fails"
19186         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19187         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19188         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19189         [ $mdt_index == 1 ] || error "a is not on MDT1"
19190
19191         # a should stay on MDT1, because it is a mulitple link file
19192         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19193                 error "#2 migrate dir fails"
19194         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19195         [ $mdt_index == 1 ] || error "a is not on MDT1"
19196
19197         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19198                 error "#3 migrate dir fails"
19199
19200         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19201         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19202         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19203
19204         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19205         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19206
19207         # a should be migrated to MDT0, since no other links on MDT1
19208         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19209                 error "#4 migrate dir fails"
19210         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19211         [ $mdt_index == 0 ] || error "a is not on MDT0"
19212
19213         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19214 }
19215 run_test 230f "migrate mulitple remote link files"
19216
19217 test_230g() {
19218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19220         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19221                 skip "Need MDS version at least 2.11.52"
19222
19223         mkdir -p $DIR/$tdir/migrate_dir
19224
19225         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19226                 error "migrating dir to non-exist MDT succeeds"
19227         true
19228 }
19229 run_test 230g "migrate dir to non-exist MDT"
19230
19231 test_230h() {
19232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19234         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19235                 skip "Need MDS version at least 2.11.52"
19236
19237         local mdt_index
19238
19239         mkdir -p $DIR/$tdir/migrate_dir
19240
19241         $LFS migrate -m1 $DIR &&
19242                 error "migrating mountpoint1 should fail"
19243
19244         $LFS migrate -m1 $DIR/$tdir/.. &&
19245                 error "migrating mountpoint2 should fail"
19246
19247         # same as mv
19248         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19249                 error "migrating $tdir/migrate_dir/.. should fail"
19250
19251         true
19252 }
19253 run_test 230h "migrate .. and root"
19254
19255 test_230i() {
19256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19258         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19259                 skip "Need MDS version at least 2.11.52"
19260
19261         mkdir -p $DIR/$tdir/migrate_dir
19262
19263         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19264                 error "migration fails with a tailing slash"
19265
19266         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19267                 error "migration fails with two tailing slashes"
19268 }
19269 run_test 230i "lfs migrate -m tolerates trailing slashes"
19270
19271 test_230j() {
19272         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19273         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19274                 skip "Need MDS version at least 2.11.52"
19275
19276         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19277         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19278                 error "create $tfile failed"
19279         cat /etc/passwd > $DIR/$tdir/$tfile
19280
19281         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19282
19283         cmp /etc/passwd $DIR/$tdir/$tfile ||
19284                 error "DoM file mismatch after migration"
19285 }
19286 run_test 230j "DoM file data not changed after dir migration"
19287
19288 test_230k() {
19289         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19290         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19291                 skip "Need MDS version at least 2.11.56"
19292
19293         local total=20
19294         local files_on_starting_mdt=0
19295
19296         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19297         $LFS getdirstripe $DIR/$tdir
19298         for i in $(seq $total); do
19299                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19300                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19301                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19302         done
19303
19304         echo "$files_on_starting_mdt files on MDT0"
19305
19306         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19307         $LFS getdirstripe $DIR/$tdir
19308
19309         files_on_starting_mdt=0
19310         for i in $(seq $total); do
19311                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19312                         error "file $tfile.$i mismatch after migration"
19313                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19314                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19315         done
19316
19317         echo "$files_on_starting_mdt files on MDT1 after migration"
19318         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19319
19320         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19321         $LFS getdirstripe $DIR/$tdir
19322
19323         files_on_starting_mdt=0
19324         for i in $(seq $total); do
19325                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19326                         error "file $tfile.$i mismatch after 2nd migration"
19327                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19328                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19329         done
19330
19331         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19332         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19333
19334         true
19335 }
19336 run_test 230k "file data not changed after dir migration"
19337
19338 test_230l() {
19339         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19340         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19341                 skip "Need MDS version at least 2.11.56"
19342
19343         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19344         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19345                 error "create files under remote dir failed $i"
19346         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19347 }
19348 run_test 230l "readdir between MDTs won't crash"
19349
19350 test_230m() {
19351         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19352         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19353                 skip "Need MDS version at least 2.11.56"
19354
19355         local MDTIDX=1
19356         local mig_dir=$DIR/$tdir/migrate_dir
19357         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19358         local shortstr="b"
19359         local val
19360
19361         echo "Creating files and dirs with xattrs"
19362         test_mkdir $DIR/$tdir
19363         test_mkdir -i0 -c1 $mig_dir
19364         mkdir $mig_dir/dir
19365         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19366                 error "cannot set xattr attr1 on dir"
19367         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19368                 error "cannot set xattr attr2 on dir"
19369         touch $mig_dir/dir/f0
19370         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19371                 error "cannot set xattr attr1 on file"
19372         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19373                 error "cannot set xattr attr2 on file"
19374         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19375         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19376         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19377         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19378         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19379         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19380         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19381         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19382         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19383
19384         echo "Migrating to MDT1"
19385         $LFS migrate -m $MDTIDX $mig_dir ||
19386                 error "fails on migrating dir to MDT1"
19387
19388         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19389         echo "Checking xattrs"
19390         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19391         [ "$val" = $longstr ] ||
19392                 error "expecting xattr1 $longstr on dir, found $val"
19393         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19394         [ "$val" = $shortstr ] ||
19395                 error "expecting xattr2 $shortstr on dir, found $val"
19396         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19397         [ "$val" = $longstr ] ||
19398                 error "expecting xattr1 $longstr on file, found $val"
19399         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19400         [ "$val" = $shortstr ] ||
19401                 error "expecting xattr2 $shortstr on file, found $val"
19402 }
19403 run_test 230m "xattrs not changed after dir migration"
19404
19405 test_230n() {
19406         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19407         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19408                 skip "Need MDS version at least 2.13.53"
19409
19410         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19411         cat /etc/hosts > $DIR/$tdir/$tfile
19412         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19413         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19414
19415         cmp /etc/hosts $DIR/$tdir/$tfile ||
19416                 error "File data mismatch after migration"
19417 }
19418 run_test 230n "Dir migration with mirrored file"
19419
19420 test_230o() {
19421         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19422         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19423                 skip "Need MDS version at least 2.13.52"
19424
19425         local mdts=$(comma_list $(mdts_nodes))
19426         local timeout=100
19427         local restripe_status
19428         local delta
19429         local i
19430
19431         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19432
19433         # in case "crush" hash type is not set
19434         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19435
19436         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19437                            mdt.*MDT0000.enable_dir_restripe)
19438         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19439         stack_trap "do_nodes $mdts $LCTL set_param \
19440                     mdt.*.enable_dir_restripe=$restripe_status"
19441
19442         mkdir $DIR/$tdir
19443         createmany -m $DIR/$tdir/f 100 ||
19444                 error "create files under remote dir failed $i"
19445         createmany -d $DIR/$tdir/d 100 ||
19446                 error "create dirs under remote dir failed $i"
19447
19448         for i in $(seq 2 $MDSCOUNT); do
19449                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19450                 $LFS setdirstripe -c $i $DIR/$tdir ||
19451                         error "split -c $i $tdir failed"
19452                 wait_update $HOSTNAME \
19453                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19454                         error "dir split not finished"
19455                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19456                         awk '/migrate/ {sum += $2} END { print sum }')
19457                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19458                 # delta is around total_files/stripe_count
19459                 (( $delta < 200 / (i - 1) + 4 )) ||
19460                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19461         done
19462 }
19463 run_test 230o "dir split"
19464
19465 test_230p() {
19466         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19467         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19468                 skip "Need MDS version at least 2.13.52"
19469
19470         local mdts=$(comma_list $(mdts_nodes))
19471         local timeout=100
19472         local restripe_status
19473         local delta
19474         local i
19475
19476         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19477
19478         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19479
19480         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19481                            mdt.*MDT0000.enable_dir_restripe)
19482         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19483         stack_trap "do_nodes $mdts $LCTL set_param \
19484                     mdt.*.enable_dir_restripe=$restripe_status"
19485
19486         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19487         createmany -m $DIR/$tdir/f 100 ||
19488                 error "create files under remote dir failed $i"
19489         createmany -d $DIR/$tdir/d 100 ||
19490                 error "create dirs under remote dir failed $i"
19491
19492         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19493                 local mdt_hash="crush"
19494
19495                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19496                 $LFS setdirstripe -c $i $DIR/$tdir ||
19497                         error "split -c $i $tdir failed"
19498                 [ $i -eq 1 ] && mdt_hash="none"
19499                 wait_update $HOSTNAME \
19500                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19501                         error "dir merge not finished"
19502                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19503                         awk '/migrate/ {sum += $2} END { print sum }')
19504                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19505                 # delta is around total_files/stripe_count
19506                 (( $delta < 200 / i + 4 )) ||
19507                         error "$delta files migrated >= $((200 / i + 4))"
19508         done
19509 }
19510 run_test 230p "dir merge"
19511
19512 test_230q() {
19513         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19514         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19515                 skip "Need MDS version at least 2.13.52"
19516
19517         local mdts=$(comma_list $(mdts_nodes))
19518         local saved_threshold=$(do_facet mds1 \
19519                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19520         local saved_delta=$(do_facet mds1 \
19521                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19522         local threshold=100
19523         local delta=2
19524         local total=0
19525         local stripe_count=0
19526         local stripe_index
19527         local nr_files
19528         local create
19529
19530         # test with fewer files on ZFS
19531         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19532
19533         stack_trap "do_nodes $mdts $LCTL set_param \
19534                     mdt.*.dir_split_count=$saved_threshold"
19535         stack_trap "do_nodes $mdts $LCTL set_param \
19536                     mdt.*.dir_split_delta=$saved_delta"
19537         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19538         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19539         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19540         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19541         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19542         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19543
19544         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19545         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19546
19547         create=$((threshold * 3 / 2))
19548         while [ $stripe_count -lt $MDSCOUNT ]; do
19549                 createmany -m $DIR/$tdir/f $total $create ||
19550                         error "create sub files failed"
19551                 stat $DIR/$tdir > /dev/null
19552                 total=$((total + create))
19553                 stripe_count=$((stripe_count + delta))
19554                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19555
19556                 wait_update $HOSTNAME \
19557                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19558                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19559
19560                 wait_update $HOSTNAME \
19561                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19562                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19563
19564                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19565                 echo "$nr_files/$total files on MDT$stripe_index after split"
19566                 # allow 10% margin of imbalance with crush hash
19567                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19568                         error "$nr_files files on MDT$stripe_index after split"
19569
19570                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19571                 [ $nr_files -eq $total ] ||
19572                         error "total sub files $nr_files != $total"
19573         done
19574 }
19575 run_test 230q "dir auto split"
19576
19577 test_230r() {
19578         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19579         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19580         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19581                 skip "Need MDS version at least 2.13.54"
19582
19583         # maximum amount of local locks:
19584         # parent striped dir - 2 locks
19585         # new stripe in parent to migrate to - 1 lock
19586         # source and target - 2 locks
19587         # Total 5 locks for regular file
19588         mkdir -p $DIR/$tdir
19589         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19590         touch $DIR/$tdir/dir1/eee
19591
19592         # create 4 hardlink for 4 more locks
19593         # Total: 9 locks > RS_MAX_LOCKS (8)
19594         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19595         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19596         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19597         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19598         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19599         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19600         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19601         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19602
19603         cancel_lru_locks mdc
19604
19605         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19606                 error "migrate dir fails"
19607
19608         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19609 }
19610 run_test 230r "migrate with too many local locks"
19611
19612 test_230s() {
19613         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19614                 skip "Need MDS version at least 2.13.57"
19615
19616         local mdts=$(comma_list $(mdts_nodes))
19617         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19618                                 mdt.*MDT0000.enable_dir_restripe)
19619
19620         stack_trap "do_nodes $mdts $LCTL set_param \
19621                     mdt.*.enable_dir_restripe=$restripe_status"
19622
19623         local st
19624         for st in 0 1; do
19625                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19626                 test_mkdir $DIR/$tdir
19627                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19628                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19629                 rmdir $DIR/$tdir
19630         done
19631 }
19632 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19633
19634 test_230t()
19635 {
19636         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19637         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19638                 skip "Need MDS version at least 2.14.50"
19639
19640         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19641         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19642         $LFS project -p 1 -s $DIR/$tdir ||
19643                 error "set $tdir project id failed"
19644         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19645                 error "set subdir project id failed"
19646         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19647 }
19648 run_test 230t "migrate directory with project ID set"
19649
19650 test_231a()
19651 {
19652         # For simplicity this test assumes that max_pages_per_rpc
19653         # is the same across all OSCs
19654         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19655         local bulk_size=$((max_pages * PAGE_SIZE))
19656         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19657                                        head -n 1)
19658
19659         mkdir -p $DIR/$tdir
19660         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19661                 error "failed to set stripe with -S ${brw_size}M option"
19662
19663         # clear the OSC stats
19664         $LCTL set_param osc.*.stats=0 &>/dev/null
19665         stop_writeback
19666
19667         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19668         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19669                 oflag=direct &>/dev/null || error "dd failed"
19670
19671         sync; sleep 1; sync # just to be safe
19672         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19673         if [ x$nrpcs != "x1" ]; then
19674                 $LCTL get_param osc.*.stats
19675                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19676         fi
19677
19678         start_writeback
19679         # Drop the OSC cache, otherwise we will read from it
19680         cancel_lru_locks osc
19681
19682         # clear the OSC stats
19683         $LCTL set_param osc.*.stats=0 &>/dev/null
19684
19685         # Client reads $bulk_size.
19686         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19687                 iflag=direct &>/dev/null || error "dd failed"
19688
19689         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19690         if [ x$nrpcs != "x1" ]; then
19691                 $LCTL get_param osc.*.stats
19692                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19693         fi
19694 }
19695 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19696
19697 test_231b() {
19698         mkdir -p $DIR/$tdir
19699         local i
19700         for i in {0..1023}; do
19701                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19702                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19703                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19704         done
19705         sync
19706 }
19707 run_test 231b "must not assert on fully utilized OST request buffer"
19708
19709 test_232a() {
19710         mkdir -p $DIR/$tdir
19711         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19712
19713         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19714         do_facet ost1 $LCTL set_param fail_loc=0x31c
19715
19716         # ignore dd failure
19717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19718
19719         do_facet ost1 $LCTL set_param fail_loc=0
19720         umount_client $MOUNT || error "umount failed"
19721         mount_client $MOUNT || error "mount failed"
19722         stop ost1 || error "cannot stop ost1"
19723         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19724 }
19725 run_test 232a "failed lock should not block umount"
19726
19727 test_232b() {
19728         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19729                 skip "Need MDS version at least 2.10.58"
19730
19731         mkdir -p $DIR/$tdir
19732         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19733         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19734         sync
19735         cancel_lru_locks osc
19736
19737         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19738         do_facet ost1 $LCTL set_param fail_loc=0x31c
19739
19740         # ignore failure
19741         $LFS data_version $DIR/$tdir/$tfile || true
19742
19743         do_facet ost1 $LCTL set_param fail_loc=0
19744         umount_client $MOUNT || error "umount failed"
19745         mount_client $MOUNT || error "mount failed"
19746         stop ost1 || error "cannot stop ost1"
19747         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19748 }
19749 run_test 232b "failed data version lock should not block umount"
19750
19751 test_233a() {
19752         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19753                 skip "Need MDS version at least 2.3.64"
19754         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19755
19756         local fid=$($LFS path2fid $MOUNT)
19757
19758         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19759                 error "cannot access $MOUNT using its FID '$fid'"
19760 }
19761 run_test 233a "checking that OBF of the FS root succeeds"
19762
19763 test_233b() {
19764         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19765                 skip "Need MDS version at least 2.5.90"
19766         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19767
19768         local fid=$($LFS path2fid $MOUNT/.lustre)
19769
19770         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19771                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19772
19773         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19774         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19775                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19776 }
19777 run_test 233b "checking that OBF of the FS .lustre succeeds"
19778
19779 test_234() {
19780         local p="$TMP/sanityN-$TESTNAME.parameters"
19781         save_lustre_params client "llite.*.xattr_cache" > $p
19782         lctl set_param llite.*.xattr_cache 1 ||
19783                 skip_env "xattr cache is not supported"
19784
19785         mkdir -p $DIR/$tdir || error "mkdir failed"
19786         touch $DIR/$tdir/$tfile || error "touch failed"
19787         # OBD_FAIL_LLITE_XATTR_ENOMEM
19788         $LCTL set_param fail_loc=0x1405
19789         getfattr -n user.attr $DIR/$tdir/$tfile &&
19790                 error "getfattr should have failed with ENOMEM"
19791         $LCTL set_param fail_loc=0x0
19792         rm -rf $DIR/$tdir
19793
19794         restore_lustre_params < $p
19795         rm -f $p
19796 }
19797 run_test 234 "xattr cache should not crash on ENOMEM"
19798
19799 test_235() {
19800         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19801                 skip "Need MDS version at least 2.4.52"
19802
19803         flock_deadlock $DIR/$tfile
19804         local RC=$?
19805         case $RC in
19806                 0)
19807                 ;;
19808                 124) error "process hangs on a deadlock"
19809                 ;;
19810                 *) error "error executing flock_deadlock $DIR/$tfile"
19811                 ;;
19812         esac
19813 }
19814 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19815
19816 #LU-2935
19817 test_236() {
19818         check_swap_layouts_support
19819
19820         local ref1=/etc/passwd
19821         local ref2=/etc/group
19822         local file1=$DIR/$tdir/f1
19823         local file2=$DIR/$tdir/f2
19824
19825         test_mkdir -c1 $DIR/$tdir
19826         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19827         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19828         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19829         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19830         local fd=$(free_fd)
19831         local cmd="exec $fd<>$file2"
19832         eval $cmd
19833         rm $file2
19834         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19835                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19836         cmd="exec $fd>&-"
19837         eval $cmd
19838         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19839
19840         #cleanup
19841         rm -rf $DIR/$tdir
19842 }
19843 run_test 236 "Layout swap on open unlinked file"
19844
19845 # LU-4659 linkea consistency
19846 test_238() {
19847         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19848                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19849                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19850                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19851
19852         touch $DIR/$tfile
19853         ln $DIR/$tfile $DIR/$tfile.lnk
19854         touch $DIR/$tfile.new
19855         mv $DIR/$tfile.new $DIR/$tfile
19856         local fid1=$($LFS path2fid $DIR/$tfile)
19857         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19858         local path1=$($LFS fid2path $FSNAME "$fid1")
19859         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19860         local path2=$($LFS fid2path $FSNAME "$fid2")
19861         [ $tfile.lnk == $path2 ] ||
19862                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19863         rm -f $DIR/$tfile*
19864 }
19865 run_test 238 "Verify linkea consistency"
19866
19867 test_239A() { # was test_239
19868         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19869                 skip "Need MDS version at least 2.5.60"
19870
19871         local list=$(comma_list $(mdts_nodes))
19872
19873         mkdir -p $DIR/$tdir
19874         createmany -o $DIR/$tdir/f- 5000
19875         unlinkmany $DIR/$tdir/f- 5000
19876         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19877                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19878         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19879                         osp.*MDT*.sync_in_flight" | calc_sum)
19880         [ "$changes" -eq 0 ] || error "$changes not synced"
19881 }
19882 run_test 239A "osp_sync test"
19883
19884 test_239a() { #LU-5297
19885         remote_mds_nodsh && skip "remote MDS with nodsh"
19886
19887         touch $DIR/$tfile
19888         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19889         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19890         chgrp $RUNAS_GID $DIR/$tfile
19891         wait_delete_completed
19892 }
19893 run_test 239a "process invalid osp sync record correctly"
19894
19895 test_239b() { #LU-5297
19896         remote_mds_nodsh && skip "remote MDS with nodsh"
19897
19898         touch $DIR/$tfile1
19899         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19900         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19901         chgrp $RUNAS_GID $DIR/$tfile1
19902         wait_delete_completed
19903         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19904         touch $DIR/$tfile2
19905         chgrp $RUNAS_GID $DIR/$tfile2
19906         wait_delete_completed
19907 }
19908 run_test 239b "process osp sync record with ENOMEM error correctly"
19909
19910 test_240() {
19911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19912         remote_mds_nodsh && skip "remote MDS with nodsh"
19913
19914         mkdir -p $DIR/$tdir
19915
19916         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19917                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19918         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19919                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19920
19921         umount_client $MOUNT || error "umount failed"
19922         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19923         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19924         mount_client $MOUNT || error "failed to mount client"
19925
19926         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19927         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19928 }
19929 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19930
19931 test_241_bio() {
19932         local count=$1
19933         local bsize=$2
19934
19935         for LOOP in $(seq $count); do
19936                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19937                 cancel_lru_locks $OSC || true
19938         done
19939 }
19940
19941 test_241_dio() {
19942         local count=$1
19943         local bsize=$2
19944
19945         for LOOP in $(seq $1); do
19946                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19947                         2>/dev/null
19948         done
19949 }
19950
19951 test_241a() { # was test_241
19952         local bsize=$PAGE_SIZE
19953
19954         (( bsize < 40960 )) && bsize=40960
19955         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19956         ls -la $DIR/$tfile
19957         cancel_lru_locks $OSC
19958         test_241_bio 1000 $bsize &
19959         PID=$!
19960         test_241_dio 1000 $bsize
19961         wait $PID
19962 }
19963 run_test 241a "bio vs dio"
19964
19965 test_241b() {
19966         local bsize=$PAGE_SIZE
19967
19968         (( bsize < 40960 )) && bsize=40960
19969         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19970         ls -la $DIR/$tfile
19971         test_241_dio 1000 $bsize &
19972         PID=$!
19973         test_241_dio 1000 $bsize
19974         wait $PID
19975 }
19976 run_test 241b "dio vs dio"
19977
19978 test_242() {
19979         remote_mds_nodsh && skip "remote MDS with nodsh"
19980
19981         mkdir -p $DIR/$tdir
19982         touch $DIR/$tdir/$tfile
19983
19984         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19985         do_facet mds1 lctl set_param fail_loc=0x105
19986         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19987
19988         do_facet mds1 lctl set_param fail_loc=0
19989         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19990 }
19991 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19992
19993 test_243()
19994 {
19995         test_mkdir $DIR/$tdir
19996         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19997 }
19998 run_test 243 "various group lock tests"
19999
20000 test_244a()
20001 {
20002         test_mkdir $DIR/$tdir
20003         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20004         sendfile_grouplock $DIR/$tdir/$tfile || \
20005                 error "sendfile+grouplock failed"
20006         rm -rf $DIR/$tdir
20007 }
20008 run_test 244a "sendfile with group lock tests"
20009
20010 test_244b()
20011 {
20012         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20013
20014         local threads=50
20015         local size=$((1024*1024))
20016
20017         test_mkdir $DIR/$tdir
20018         for i in $(seq 1 $threads); do
20019                 local file=$DIR/$tdir/file_$((i / 10))
20020                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20021                 local pids[$i]=$!
20022         done
20023         for i in $(seq 1 $threads); do
20024                 wait ${pids[$i]}
20025         done
20026 }
20027 run_test 244b "multi-threaded write with group lock"
20028
20029 test_245() {
20030         local flagname="multi_mod_rpcs"
20031         local connect_data_name="max_mod_rpcs"
20032         local out
20033
20034         # check if multiple modify RPCs flag is set
20035         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20036                 grep "connect_flags:")
20037         echo "$out"
20038
20039         echo "$out" | grep -qw $flagname
20040         if [ $? -ne 0 ]; then
20041                 echo "connect flag $flagname is not set"
20042                 return
20043         fi
20044
20045         # check if multiple modify RPCs data is set
20046         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20047         echo "$out"
20048
20049         echo "$out" | grep -qw $connect_data_name ||
20050                 error "import should have connect data $connect_data_name"
20051 }
20052 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20053
20054 cleanup_247() {
20055         local submount=$1
20056
20057         trap 0
20058         umount_client $submount
20059         rmdir $submount
20060 }
20061
20062 test_247a() {
20063         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20064                 grep -q subtree ||
20065                 skip_env "Fileset feature is not supported"
20066
20067         local submount=${MOUNT}_$tdir
20068
20069         mkdir $MOUNT/$tdir
20070         mkdir -p $submount || error "mkdir $submount failed"
20071         FILESET="$FILESET/$tdir" mount_client $submount ||
20072                 error "mount $submount failed"
20073         trap "cleanup_247 $submount" EXIT
20074         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20075         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20076                 error "read $MOUNT/$tdir/$tfile failed"
20077         cleanup_247 $submount
20078 }
20079 run_test 247a "mount subdir as fileset"
20080
20081 test_247b() {
20082         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20083                 skip_env "Fileset feature is not supported"
20084
20085         local submount=${MOUNT}_$tdir
20086
20087         rm -rf $MOUNT/$tdir
20088         mkdir -p $submount || error "mkdir $submount failed"
20089         SKIP_FILESET=1
20090         FILESET="$FILESET/$tdir" mount_client $submount &&
20091                 error "mount $submount should fail"
20092         rmdir $submount
20093 }
20094 run_test 247b "mount subdir that dose not exist"
20095
20096 test_247c() {
20097         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20098                 skip_env "Fileset feature is not supported"
20099
20100         local submount=${MOUNT}_$tdir
20101
20102         mkdir -p $MOUNT/$tdir/dir1
20103         mkdir -p $submount || error "mkdir $submount failed"
20104         trap "cleanup_247 $submount" EXIT
20105         FILESET="$FILESET/$tdir" mount_client $submount ||
20106                 error "mount $submount failed"
20107         local fid=$($LFS path2fid $MOUNT/)
20108         $LFS fid2path $submount $fid && error "fid2path should fail"
20109         cleanup_247 $submount
20110 }
20111 run_test 247c "running fid2path outside subdirectory root"
20112
20113 test_247d() {
20114         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20115                 skip "Fileset feature is not supported"
20116
20117         local submount=${MOUNT}_$tdir
20118
20119         mkdir -p $MOUNT/$tdir/dir1
20120         mkdir -p $submount || error "mkdir $submount failed"
20121         FILESET="$FILESET/$tdir" mount_client $submount ||
20122                 error "mount $submount failed"
20123         trap "cleanup_247 $submount" EXIT
20124
20125         local td=$submount/dir1
20126         local fid=$($LFS path2fid $td)
20127         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20128
20129         # check that we get the same pathname back
20130         local rootpath
20131         local found
20132         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20133                 echo "$rootpath $fid"
20134                 found=$($LFS fid2path $rootpath "$fid")
20135                 [ -n "found" ] || error "fid2path should succeed"
20136                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20137         done
20138         # check wrong root path format
20139         rootpath=$submount"_wrong"
20140         found=$($LFS fid2path $rootpath "$fid")
20141         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20142
20143         cleanup_247 $submount
20144 }
20145 run_test 247d "running fid2path inside subdirectory root"
20146
20147 # LU-8037
20148 test_247e() {
20149         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20150                 grep -q subtree ||
20151                 skip "Fileset feature is not supported"
20152
20153         local submount=${MOUNT}_$tdir
20154
20155         mkdir $MOUNT/$tdir
20156         mkdir -p $submount || error "mkdir $submount failed"
20157         FILESET="$FILESET/.." mount_client $submount &&
20158                 error "mount $submount should fail"
20159         rmdir $submount
20160 }
20161 run_test 247e "mount .. as fileset"
20162
20163 test_247f() {
20164         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20165         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20166                 skip "Need at least version 2.13.52"
20167         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20168                 skip "Need at least version 2.14.50"
20169         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20170                 grep -q subtree ||
20171                 skip "Fileset feature is not supported"
20172
20173         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20174         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20175                 error "mkdir remote failed"
20176         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20177         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20178                 error "mkdir striped failed"
20179         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20180
20181         local submount=${MOUNT}_$tdir
20182
20183         mkdir -p $submount || error "mkdir $submount failed"
20184         stack_trap "rmdir $submount"
20185
20186         local dir
20187         local stat
20188         local fileset=$FILESET
20189         local mdts=$(comma_list $(mdts_nodes))
20190
20191         stat=$(do_facet mds1 $LCTL get_param -n \
20192                 mdt.*MDT0000.enable_remote_subdir_mount)
20193         stack_trap "do_nodes $mdts $LCTL set_param \
20194                 mdt.*.enable_remote_subdir_mount=$stat"
20195
20196         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20197         stack_trap "umount_client $submount"
20198         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20199                 error "mount remote dir $dir should fail"
20200
20201         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20202                 $tdir/striped/. ; do
20203                 FILESET="$fileset/$dir" mount_client $submount ||
20204                         error "mount $dir failed"
20205                 umount_client $submount
20206         done
20207
20208         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20209         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20210                 error "mount $tdir/remote failed"
20211 }
20212 run_test 247f "mount striped or remote directory as fileset"
20213
20214 test_247g() {
20215         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20216         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20217                 skip "Need at least version 2.14.50"
20218
20219         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20220                 error "mkdir $tdir failed"
20221         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20222
20223         local submount=${MOUNT}_$tdir
20224
20225         mkdir -p $submount || error "mkdir $submount failed"
20226         stack_trap "rmdir $submount"
20227
20228         FILESET="$fileset/$tdir" mount_client $submount ||
20229                 error "mount $dir failed"
20230         stack_trap "umount $submount"
20231
20232         local mdts=$(comma_list $(mdts_nodes))
20233
20234         local nrpcs
20235
20236         stat $submount > /dev/null
20237         cancel_lru_locks $MDC
20238         stat $submount > /dev/null
20239         stat $submount/$tfile > /dev/null
20240         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20241         stat $submount/$tfile > /dev/null
20242         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20243                 awk '/getattr/ {sum += $2} END {print sum}')
20244
20245         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20246 }
20247 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20248
20249 test_248a() {
20250         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20251         [ -z "$fast_read_sav" ] && skip "no fast read support"
20252
20253         # create a large file for fast read verification
20254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20255
20256         # make sure the file is created correctly
20257         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20258                 { rm -f $DIR/$tfile; skip "file creation error"; }
20259
20260         echo "Test 1: verify that fast read is 4 times faster on cache read"
20261
20262         # small read with fast read enabled
20263         $LCTL set_param -n llite.*.fast_read=1
20264         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20265                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20266                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20267         # small read with fast read disabled
20268         $LCTL set_param -n llite.*.fast_read=0
20269         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20270                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20271                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20272
20273         # verify that fast read is 4 times faster for cache read
20274         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20275                 error_not_in_vm "fast read was not 4 times faster: " \
20276                            "$t_fast vs $t_slow"
20277
20278         echo "Test 2: verify the performance between big and small read"
20279         $LCTL set_param -n llite.*.fast_read=1
20280
20281         # 1k non-cache read
20282         cancel_lru_locks osc
20283         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20284                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20285                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20286
20287         # 1M non-cache read
20288         cancel_lru_locks osc
20289         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20290                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20291                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20292
20293         # verify that big IO is not 4 times faster than small IO
20294         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20295                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20296
20297         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20298         rm -f $DIR/$tfile
20299 }
20300 run_test 248a "fast read verification"
20301
20302 test_248b() {
20303         # Default short_io_bytes=16384, try both smaller and larger sizes.
20304         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20305         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20306         echo "bs=53248 count=113 normal buffered write"
20307         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20308                 error "dd of initial data file failed"
20309         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20310
20311         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20312         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20313                 error "dd with sync normal writes failed"
20314         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20315
20316         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20317         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20318                 error "dd with sync small writes failed"
20319         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20320
20321         cancel_lru_locks osc
20322
20323         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20324         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20325         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20326         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20327                 iflag=direct || error "dd with O_DIRECT small read failed"
20328         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20329         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20330                 error "compare $TMP/$tfile.1 failed"
20331
20332         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20333         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20334
20335         # just to see what the maximum tunable value is, and test parsing
20336         echo "test invalid parameter 2MB"
20337         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20338                 error "too-large short_io_bytes allowed"
20339         echo "test maximum parameter 512KB"
20340         # if we can set a larger short_io_bytes, run test regardless of version
20341         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20342                 # older clients may not allow setting it this large, that's OK
20343                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20344                         skip "Need at least client version 2.13.50"
20345                 error "medium short_io_bytes failed"
20346         fi
20347         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20348         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20349
20350         echo "test large parameter 64KB"
20351         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20352         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20353
20354         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20355         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20356                 error "dd with sync large writes failed"
20357         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20358
20359         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20360         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20361         num=$((113 * 4096 / PAGE_SIZE))
20362         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20363         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20364                 error "dd with O_DIRECT large writes failed"
20365         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20366                 error "compare $DIR/$tfile.3 failed"
20367
20368         cancel_lru_locks osc
20369
20370         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20371         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20372                 error "dd with O_DIRECT large read failed"
20373         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20374                 error "compare $TMP/$tfile.2 failed"
20375
20376         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20377         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20378                 error "dd with O_DIRECT large read failed"
20379         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20380                 error "compare $TMP/$tfile.3 failed"
20381 }
20382 run_test 248b "test short_io read and write for both small and large sizes"
20383
20384 test_249() { # LU-7890
20385         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20386                 skip "Need at least version 2.8.54"
20387
20388         rm -f $DIR/$tfile
20389         $LFS setstripe -c 1 $DIR/$tfile
20390         # Offset 2T == 4k * 512M
20391         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20392                 error "dd to 2T offset failed"
20393 }
20394 run_test 249 "Write above 2T file size"
20395
20396 test_250() {
20397         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20398          && skip "no 16TB file size limit on ZFS"
20399
20400         $LFS setstripe -c 1 $DIR/$tfile
20401         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20402         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20403         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20404         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20405                 conv=notrunc,fsync && error "append succeeded"
20406         return 0
20407 }
20408 run_test 250 "Write above 16T limit"
20409
20410 test_251() {
20411         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20412
20413         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20414         #Skip once - writing the first stripe will succeed
20415         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20416         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20417                 error "short write happened"
20418
20419         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20420         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20421                 error "short read happened"
20422
20423         rm -f $DIR/$tfile
20424 }
20425 run_test 251 "Handling short read and write correctly"
20426
20427 test_252() {
20428         remote_mds_nodsh && skip "remote MDS with nodsh"
20429         remote_ost_nodsh && skip "remote OST with nodsh"
20430         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20431                 skip_env "ldiskfs only test"
20432         fi
20433
20434         local tgt
20435         local dev
20436         local out
20437         local uuid
20438         local num
20439         local gen
20440
20441         # check lr_reader on OST0000
20442         tgt=ost1
20443         dev=$(facet_device $tgt)
20444         out=$(do_facet $tgt $LR_READER $dev)
20445         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20446         echo "$out"
20447         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20448         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20449                 error "Invalid uuid returned by $LR_READER on target $tgt"
20450         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20451
20452         # check lr_reader -c on MDT0000
20453         tgt=mds1
20454         dev=$(facet_device $tgt)
20455         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20456                 skip "$LR_READER does not support additional options"
20457         fi
20458         out=$(do_facet $tgt $LR_READER -c $dev)
20459         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20460         echo "$out"
20461         num=$(echo "$out" | grep -c "mdtlov")
20462         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20463                 error "Invalid number of mdtlov clients returned by $LR_READER"
20464         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20465
20466         # check lr_reader -cr on MDT0000
20467         out=$(do_facet $tgt $LR_READER -cr $dev)
20468         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20469         echo "$out"
20470         echo "$out" | grep -q "^reply_data:$" ||
20471                 error "$LR_READER should have returned 'reply_data' section"
20472         num=$(echo "$out" | grep -c "client_generation")
20473         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20474 }
20475 run_test 252 "check lr_reader tool"
20476
20477 test_253() {
20478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20479         remote_mds_nodsh && skip "remote MDS with nodsh"
20480         remote_mgs_nodsh && skip "remote MGS with nodsh"
20481
20482         local ostidx=0
20483         local rc=0
20484         local ost_name=$(ostname_from_index $ostidx)
20485
20486         # on the mdt's osc
20487         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20488         do_facet $SINGLEMDS $LCTL get_param -n \
20489                 osp.$mdtosc_proc1.reserved_mb_high ||
20490                 skip  "remote MDS does not support reserved_mb_high"
20491
20492         rm -rf $DIR/$tdir
20493         wait_mds_ost_sync
20494         wait_delete_completed
20495         mkdir $DIR/$tdir
20496
20497         pool_add $TESTNAME || error "Pool creation failed"
20498         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20499
20500         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20501                 error "Setstripe failed"
20502
20503         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20504
20505         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20506                     grep "watermarks")
20507         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20508
20509         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20510                         osp.$mdtosc_proc1.prealloc_status)
20511         echo "prealloc_status $oa_status"
20512
20513         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20514                 error "File creation should fail"
20515
20516         #object allocation was stopped, but we still able to append files
20517         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20518                 oflag=append || error "Append failed"
20519
20520         rm -f $DIR/$tdir/$tfile.0
20521
20522         # For this test, we want to delete the files we created to go out of
20523         # space but leave the watermark, so we remain nearly out of space
20524         ost_watermarks_enospc_delete_files $tfile $ostidx
20525
20526         wait_delete_completed
20527
20528         sleep_maxage
20529
20530         for i in $(seq 10 12); do
20531                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20532                         2>/dev/null || error "File creation failed after rm"
20533         done
20534
20535         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20536                         osp.$mdtosc_proc1.prealloc_status)
20537         echo "prealloc_status $oa_status"
20538
20539         if (( oa_status != 0 )); then
20540                 error "Object allocation still disable after rm"
20541         fi
20542 }
20543 run_test 253 "Check object allocation limit"
20544
20545 test_254() {
20546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20547         remote_mds_nodsh && skip "remote MDS with nodsh"
20548         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20549                 skip "MDS does not support changelog_size"
20550
20551         local cl_user
20552         local MDT0=$(facet_svc $SINGLEMDS)
20553
20554         changelog_register || error "changelog_register failed"
20555
20556         changelog_clear 0 || error "changelog_clear failed"
20557
20558         local size1=$(do_facet $SINGLEMDS \
20559                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20560         echo "Changelog size $size1"
20561
20562         rm -rf $DIR/$tdir
20563         $LFS mkdir -i 0 $DIR/$tdir
20564         # change something
20565         mkdir -p $DIR/$tdir/pics/2008/zachy
20566         touch $DIR/$tdir/pics/2008/zachy/timestamp
20567         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20568         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20569         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20570         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20571         rm $DIR/$tdir/pics/desktop.jpg
20572
20573         local size2=$(do_facet $SINGLEMDS \
20574                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20575         echo "Changelog size after work $size2"
20576
20577         (( $size2 > $size1 )) ||
20578                 error "new Changelog size=$size2 less than old size=$size1"
20579 }
20580 run_test 254 "Check changelog size"
20581
20582 ladvise_no_type()
20583 {
20584         local type=$1
20585         local file=$2
20586
20587         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20588                 awk -F: '{print $2}' | grep $type > /dev/null
20589         if [ $? -ne 0 ]; then
20590                 return 0
20591         fi
20592         return 1
20593 }
20594
20595 ladvise_no_ioctl()
20596 {
20597         local file=$1
20598
20599         lfs ladvise -a willread $file > /dev/null 2>&1
20600         if [ $? -eq 0 ]; then
20601                 return 1
20602         fi
20603
20604         lfs ladvise -a willread $file 2>&1 |
20605                 grep "Inappropriate ioctl for device" > /dev/null
20606         if [ $? -eq 0 ]; then
20607                 return 0
20608         fi
20609         return 1
20610 }
20611
20612 percent() {
20613         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20614 }
20615
20616 # run a random read IO workload
20617 # usage: random_read_iops <filename> <filesize> <iosize>
20618 random_read_iops() {
20619         local file=$1
20620         local fsize=$2
20621         local iosize=${3:-4096}
20622
20623         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20624                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20625 }
20626
20627 drop_file_oss_cache() {
20628         local file="$1"
20629         local nodes="$2"
20630
20631         $LFS ladvise -a dontneed $file 2>/dev/null ||
20632                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20633 }
20634
20635 ladvise_willread_performance()
20636 {
20637         local repeat=10
20638         local average_origin=0
20639         local average_cache=0
20640         local average_ladvise=0
20641
20642         for ((i = 1; i <= $repeat; i++)); do
20643                 echo "Iter $i/$repeat: reading without willread hint"
20644                 cancel_lru_locks osc
20645                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20646                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20647                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20648                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20649
20650                 cancel_lru_locks osc
20651                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20652                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20653                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20654
20655                 cancel_lru_locks osc
20656                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20657                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20658                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20659                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20660                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20661         done
20662         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20663         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20664         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20665
20666         speedup_cache=$(percent $average_cache $average_origin)
20667         speedup_ladvise=$(percent $average_ladvise $average_origin)
20668
20669         echo "Average uncached read: $average_origin"
20670         echo "Average speedup with OSS cached read: " \
20671                 "$average_cache = +$speedup_cache%"
20672         echo "Average speedup with ladvise willread: " \
20673                 "$average_ladvise = +$speedup_ladvise%"
20674
20675         local lowest_speedup=20
20676         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20677                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20678                         "got $average_cache%. Skipping ladvise willread check."
20679                 return 0
20680         fi
20681
20682         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20683         # it is still good to run until then to exercise 'ladvise willread'
20684         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20685                 [ "$ost1_FSTYPE" = "zfs" ] &&
20686                 echo "osd-zfs does not support dontneed or drop_caches" &&
20687                 return 0
20688
20689         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20690         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20691                 error_not_in_vm "Speedup with willread is less than " \
20692                         "$lowest_speedup%, got $average_ladvise%"
20693 }
20694
20695 test_255a() {
20696         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20697                 skip "lustre < 2.8.54 does not support ladvise "
20698         remote_ost_nodsh && skip "remote OST with nodsh"
20699
20700         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20701
20702         ladvise_no_type willread $DIR/$tfile &&
20703                 skip "willread ladvise is not supported"
20704
20705         ladvise_no_ioctl $DIR/$tfile &&
20706                 skip "ladvise ioctl is not supported"
20707
20708         local size_mb=100
20709         local size=$((size_mb * 1048576))
20710         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20711                 error "dd to $DIR/$tfile failed"
20712
20713         lfs ladvise -a willread $DIR/$tfile ||
20714                 error "Ladvise failed with no range argument"
20715
20716         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20717                 error "Ladvise failed with no -l or -e argument"
20718
20719         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20720                 error "Ladvise failed with only -e argument"
20721
20722         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20723                 error "Ladvise failed with only -l argument"
20724
20725         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20726                 error "End offset should not be smaller than start offset"
20727
20728         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20729                 error "End offset should not be equal to start offset"
20730
20731         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20732                 error "Ladvise failed with overflowing -s argument"
20733
20734         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20735                 error "Ladvise failed with overflowing -e argument"
20736
20737         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20738                 error "Ladvise failed with overflowing -l argument"
20739
20740         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20741                 error "Ladvise succeeded with conflicting -l and -e arguments"
20742
20743         echo "Synchronous ladvise should wait"
20744         local delay=4
20745 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20746         do_nodes $(comma_list $(osts_nodes)) \
20747                 $LCTL set_param fail_val=$delay fail_loc=0x237
20748
20749         local start_ts=$SECONDS
20750         lfs ladvise -a willread $DIR/$tfile ||
20751                 error "Ladvise failed with no range argument"
20752         local end_ts=$SECONDS
20753         local inteval_ts=$((end_ts - start_ts))
20754
20755         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20756                 error "Synchronous advice didn't wait reply"
20757         fi
20758
20759         echo "Asynchronous ladvise shouldn't wait"
20760         local start_ts=$SECONDS
20761         lfs ladvise -a willread -b $DIR/$tfile ||
20762                 error "Ladvise failed with no range argument"
20763         local end_ts=$SECONDS
20764         local inteval_ts=$((end_ts - start_ts))
20765
20766         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20767                 error "Asynchronous advice blocked"
20768         fi
20769
20770         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20771         ladvise_willread_performance
20772 }
20773 run_test 255a "check 'lfs ladvise -a willread'"
20774
20775 facet_meminfo() {
20776         local facet=$1
20777         local info=$2
20778
20779         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20780 }
20781
20782 test_255b() {
20783         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20784                 skip "lustre < 2.8.54 does not support ladvise "
20785         remote_ost_nodsh && skip "remote OST with nodsh"
20786
20787         lfs setstripe -c 1 -i 0 $DIR/$tfile
20788
20789         ladvise_no_type dontneed $DIR/$tfile &&
20790                 skip "dontneed ladvise is not supported"
20791
20792         ladvise_no_ioctl $DIR/$tfile &&
20793                 skip "ladvise ioctl is not supported"
20794
20795         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20796                 [ "$ost1_FSTYPE" = "zfs" ] &&
20797                 skip "zfs-osd does not support 'ladvise dontneed'"
20798
20799         local size_mb=100
20800         local size=$((size_mb * 1048576))
20801         # In order to prevent disturbance of other processes, only check 3/4
20802         # of the memory usage
20803         local kibibytes=$((size_mb * 1024 * 3 / 4))
20804
20805         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20806                 error "dd to $DIR/$tfile failed"
20807
20808         #force write to complete before dropping OST cache & checking memory
20809         sync
20810
20811         local total=$(facet_meminfo ost1 MemTotal)
20812         echo "Total memory: $total KiB"
20813
20814         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20815         local before_read=$(facet_meminfo ost1 Cached)
20816         echo "Cache used before read: $before_read KiB"
20817
20818         lfs ladvise -a willread $DIR/$tfile ||
20819                 error "Ladvise willread failed"
20820         local after_read=$(facet_meminfo ost1 Cached)
20821         echo "Cache used after read: $after_read KiB"
20822
20823         lfs ladvise -a dontneed $DIR/$tfile ||
20824                 error "Ladvise dontneed again failed"
20825         local no_read=$(facet_meminfo ost1 Cached)
20826         echo "Cache used after dontneed ladvise: $no_read KiB"
20827
20828         if [ $total -lt $((before_read + kibibytes)) ]; then
20829                 echo "Memory is too small, abort checking"
20830                 return 0
20831         fi
20832
20833         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20834                 error "Ladvise willread should use more memory" \
20835                         "than $kibibytes KiB"
20836         fi
20837
20838         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20839                 error "Ladvise dontneed should release more memory" \
20840                         "than $kibibytes KiB"
20841         fi
20842 }
20843 run_test 255b "check 'lfs ladvise -a dontneed'"
20844
20845 test_255c() {
20846         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20847                 skip "lustre < 2.10.50 does not support lockahead"
20848
20849         local ost1_imp=$(get_osc_import_name client ost1)
20850         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20851                          cut -d'.' -f2)
20852         local count
20853         local new_count
20854         local difference
20855         local i
20856         local rc
20857
20858         test_mkdir -p $DIR/$tdir
20859         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20860
20861         #test 10 returns only success/failure
20862         i=10
20863         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20864         rc=$?
20865         if [ $rc -eq 255 ]; then
20866                 error "Ladvise test${i} failed, ${rc}"
20867         fi
20868
20869         #test 11 counts lock enqueue requests, all others count new locks
20870         i=11
20871         count=$(do_facet ost1 \
20872                 $LCTL get_param -n ost.OSS.ost.stats)
20873         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20874
20875         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20876         rc=$?
20877         if [ $rc -eq 255 ]; then
20878                 error "Ladvise test${i} failed, ${rc}"
20879         fi
20880
20881         new_count=$(do_facet ost1 \
20882                 $LCTL get_param -n ost.OSS.ost.stats)
20883         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20884                    awk '{ print $2 }')
20885
20886         difference="$((new_count - count))"
20887         if [ $difference -ne $rc ]; then
20888                 error "Ladvise test${i}, bad enqueue count, returned " \
20889                       "${rc}, actual ${difference}"
20890         fi
20891
20892         for i in $(seq 12 21); do
20893                 # If we do not do this, we run the risk of having too many
20894                 # locks and starting lock cancellation while we are checking
20895                 # lock counts.
20896                 cancel_lru_locks osc
20897
20898                 count=$($LCTL get_param -n \
20899                        ldlm.namespaces.$imp_name.lock_unused_count)
20900
20901                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20902                 rc=$?
20903                 if [ $rc -eq 255 ]; then
20904                         error "Ladvise test ${i} failed, ${rc}"
20905                 fi
20906
20907                 new_count=$($LCTL get_param -n \
20908                        ldlm.namespaces.$imp_name.lock_unused_count)
20909                 difference="$((new_count - count))"
20910
20911                 # Test 15 output is divided by 100 to map down to valid return
20912                 if [ $i -eq 15 ]; then
20913                         rc="$((rc * 100))"
20914                 fi
20915
20916                 if [ $difference -ne $rc ]; then
20917                         error "Ladvise test ${i}, bad lock count, returned " \
20918                               "${rc}, actual ${difference}"
20919                 fi
20920         done
20921
20922         #test 22 returns only success/failure
20923         i=22
20924         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20925         rc=$?
20926         if [ $rc -eq 255 ]; then
20927                 error "Ladvise test${i} failed, ${rc}"
20928         fi
20929 }
20930 run_test 255c "suite of ladvise lockahead tests"
20931
20932 test_256() {
20933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20934         remote_mds_nodsh && skip "remote MDS with nodsh"
20935         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20936         changelog_users $SINGLEMDS | grep "^cl" &&
20937                 skip "active changelog user"
20938
20939         local cl_user
20940         local cat_sl
20941         local mdt_dev
20942
20943         mdt_dev=$(mdsdevname 1)
20944         echo $mdt_dev
20945
20946         changelog_register || error "changelog_register failed"
20947
20948         rm -rf $DIR/$tdir
20949         mkdir -p $DIR/$tdir
20950
20951         changelog_clear 0 || error "changelog_clear failed"
20952
20953         # change something
20954         touch $DIR/$tdir/{1..10}
20955
20956         # stop the MDT
20957         stop $SINGLEMDS || error "Fail to stop MDT"
20958
20959         # remount the MDT
20960
20961         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20962
20963         #after mount new plainllog is used
20964         touch $DIR/$tdir/{11..19}
20965         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20966         stack_trap "rm -f $tmpfile"
20967         cat_sl=$(do_facet $SINGLEMDS "sync; \
20968                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20969                  llog_reader $tmpfile | grep -c type=1064553b")
20970         do_facet $SINGLEMDS llog_reader $tmpfile
20971
20972         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20973
20974         changelog_clear 0 || error "changelog_clear failed"
20975
20976         cat_sl=$(do_facet $SINGLEMDS "sync; \
20977                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20978                  llog_reader $tmpfile | grep -c type=1064553b")
20979
20980         if (( cat_sl == 2 )); then
20981                 error "Empty plain llog was not deleted from changelog catalog"
20982         elif (( cat_sl != 1 )); then
20983                 error "Active plain llog shouldn't be deleted from catalog"
20984         fi
20985 }
20986 run_test 256 "Check llog delete for empty and not full state"
20987
20988 test_257() {
20989         remote_mds_nodsh && skip "remote MDS with nodsh"
20990         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20991                 skip "Need MDS version at least 2.8.55"
20992
20993         test_mkdir $DIR/$tdir
20994
20995         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20996                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20997         stat $DIR/$tdir
20998
20999 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21000         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21001         local facet=mds$((mdtidx + 1))
21002         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21003         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21004
21005         stop $facet || error "stop MDS failed"
21006         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21007                 error "start MDS fail"
21008         wait_recovery_complete $facet
21009 }
21010 run_test 257 "xattr locks are not lost"
21011
21012 # Verify we take the i_mutex when security requires it
21013 test_258a() {
21014 #define OBD_FAIL_IMUTEX_SEC 0x141c
21015         $LCTL set_param fail_loc=0x141c
21016         touch $DIR/$tfile
21017         chmod u+s $DIR/$tfile
21018         chmod a+rwx $DIR/$tfile
21019         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21020         RC=$?
21021         if [ $RC -ne 0 ]; then
21022                 error "error, failed to take i_mutex, rc=$?"
21023         fi
21024         rm -f $DIR/$tfile
21025 }
21026 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21027
21028 # Verify we do NOT take the i_mutex in the normal case
21029 test_258b() {
21030 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21031         $LCTL set_param fail_loc=0x141d
21032         touch $DIR/$tfile
21033         chmod a+rwx $DIR
21034         chmod a+rw $DIR/$tfile
21035         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21036         RC=$?
21037         if [ $RC -ne 0 ]; then
21038                 error "error, took i_mutex unnecessarily, rc=$?"
21039         fi
21040         rm -f $DIR/$tfile
21041
21042 }
21043 run_test 258b "verify i_mutex security behavior"
21044
21045 test_259() {
21046         local file=$DIR/$tfile
21047         local before
21048         local after
21049
21050         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21051
21052         stack_trap "rm -f $file" EXIT
21053
21054         wait_delete_completed
21055         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21056         echo "before: $before"
21057
21058         $LFS setstripe -i 0 -c 1 $file
21059         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21060         sync_all_data
21061         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21062         echo "after write: $after"
21063
21064 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21065         do_facet ost1 $LCTL set_param fail_loc=0x2301
21066         $TRUNCATE $file 0
21067         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21068         echo "after truncate: $after"
21069
21070         stop ost1
21071         do_facet ost1 $LCTL set_param fail_loc=0
21072         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21073         sleep 2
21074         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21075         echo "after restart: $after"
21076         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21077                 error "missing truncate?"
21078
21079         return 0
21080 }
21081 run_test 259 "crash at delayed truncate"
21082
21083 test_260() {
21084 #define OBD_FAIL_MDC_CLOSE               0x806
21085         $LCTL set_param fail_loc=0x80000806
21086         touch $DIR/$tfile
21087
21088 }
21089 run_test 260 "Check mdc_close fail"
21090
21091 ### Data-on-MDT sanity tests ###
21092 test_270a() {
21093         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21094                 skip "Need MDS version at least 2.10.55 for DoM"
21095
21096         # create DoM file
21097         local dom=$DIR/$tdir/dom_file
21098         local tmp=$DIR/$tdir/tmp_file
21099
21100         mkdir -p $DIR/$tdir
21101
21102         # basic checks for DoM component creation
21103         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21104                 error "Can set MDT layout to non-first entry"
21105
21106         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21107                 error "Can define multiple entries as MDT layout"
21108
21109         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21110
21111         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21112         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21113         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21114
21115         local mdtidx=$($LFS getstripe -m $dom)
21116         local mdtname=MDT$(printf %04x $mdtidx)
21117         local facet=mds$((mdtidx + 1))
21118         local space_check=1
21119
21120         # Skip free space checks with ZFS
21121         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21122
21123         # write
21124         sync
21125         local size_tmp=$((65536 * 3))
21126         local mdtfree1=$(do_facet $facet \
21127                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21128
21129         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21130         # check also direct IO along write
21131         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21132         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21133         sync
21134         cmp $tmp $dom || error "file data is different"
21135         [ $(stat -c%s $dom) == $size_tmp ] ||
21136                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21137         if [ $space_check == 1 ]; then
21138                 local mdtfree2=$(do_facet $facet \
21139                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21140
21141                 # increase in usage from by $size_tmp
21142                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21143                         error "MDT free space wrong after write: " \
21144                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21145         fi
21146
21147         # truncate
21148         local size_dom=10000
21149
21150         $TRUNCATE $dom $size_dom
21151         [ $(stat -c%s $dom) == $size_dom ] ||
21152                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21153         if [ $space_check == 1 ]; then
21154                 mdtfree1=$(do_facet $facet \
21155                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21156                 # decrease in usage from $size_tmp to new $size_dom
21157                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21158                   $(((size_tmp - size_dom) / 1024)) ] ||
21159                         error "MDT free space is wrong after truncate: " \
21160                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21161         fi
21162
21163         # append
21164         cat $tmp >> $dom
21165         sync
21166         size_dom=$((size_dom + size_tmp))
21167         [ $(stat -c%s $dom) == $size_dom ] ||
21168                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21169         if [ $space_check == 1 ]; then
21170                 mdtfree2=$(do_facet $facet \
21171                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21172                 # increase in usage by $size_tmp from previous
21173                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21174                         error "MDT free space is wrong after append: " \
21175                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21176         fi
21177
21178         # delete
21179         rm $dom
21180         if [ $space_check == 1 ]; then
21181                 mdtfree1=$(do_facet $facet \
21182                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21183                 # decrease in usage by $size_dom from previous
21184                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21185                         error "MDT free space is wrong after removal: " \
21186                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21187         fi
21188
21189         # combined striping
21190         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21191                 error "Can't create DoM + OST striping"
21192
21193         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21194         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21195         # check also direct IO along write
21196         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21197         sync
21198         cmp $tmp $dom || error "file data is different"
21199         [ $(stat -c%s $dom) == $size_tmp ] ||
21200                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21201         rm $dom $tmp
21202
21203         return 0
21204 }
21205 run_test 270a "DoM: basic functionality tests"
21206
21207 test_270b() {
21208         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21209                 skip "Need MDS version at least 2.10.55"
21210
21211         local dom=$DIR/$tdir/dom_file
21212         local max_size=1048576
21213
21214         mkdir -p $DIR/$tdir
21215         $LFS setstripe -E $max_size -L mdt $dom
21216
21217         # truncate over the limit
21218         $TRUNCATE $dom $(($max_size + 1)) &&
21219                 error "successful truncate over the maximum size"
21220         # write over the limit
21221         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21222                 error "successful write over the maximum size"
21223         # append over the limit
21224         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21225         echo "12345" >> $dom && error "successful append over the maximum size"
21226         rm $dom
21227
21228         return 0
21229 }
21230 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21231
21232 test_270c() {
21233         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21234                 skip "Need MDS version at least 2.10.55"
21235
21236         mkdir -p $DIR/$tdir
21237         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21238
21239         # check files inherit DoM EA
21240         touch $DIR/$tdir/first
21241         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21242                 error "bad pattern"
21243         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21244                 error "bad stripe count"
21245         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21246                 error "bad stripe size"
21247
21248         # check directory inherits DoM EA and uses it as default
21249         mkdir $DIR/$tdir/subdir
21250         touch $DIR/$tdir/subdir/second
21251         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21252                 error "bad pattern in sub-directory"
21253         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21254                 error "bad stripe count in sub-directory"
21255         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21256                 error "bad stripe size in sub-directory"
21257         return 0
21258 }
21259 run_test 270c "DoM: DoM EA inheritance tests"
21260
21261 test_270d() {
21262         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21263                 skip "Need MDS version at least 2.10.55"
21264
21265         mkdir -p $DIR/$tdir
21266         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21267
21268         # inherit default DoM striping
21269         mkdir $DIR/$tdir/subdir
21270         touch $DIR/$tdir/subdir/f1
21271
21272         # change default directory striping
21273         $LFS setstripe -c 1 $DIR/$tdir/subdir
21274         touch $DIR/$tdir/subdir/f2
21275         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21276                 error "wrong default striping in file 2"
21277         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21278                 error "bad pattern in file 2"
21279         return 0
21280 }
21281 run_test 270d "DoM: change striping from DoM to RAID0"
21282
21283 test_270e() {
21284         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21285                 skip "Need MDS version at least 2.10.55"
21286
21287         mkdir -p $DIR/$tdir/dom
21288         mkdir -p $DIR/$tdir/norm
21289         DOMFILES=20
21290         NORMFILES=10
21291         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21292         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21293
21294         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21295         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21296
21297         # find DoM files by layout
21298         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21299         [ $NUM -eq  $DOMFILES ] ||
21300                 error "lfs find -L: found $NUM, expected $DOMFILES"
21301         echo "Test 1: lfs find 20 DOM files by layout: OK"
21302
21303         # there should be 1 dir with default DOM striping
21304         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21305         [ $NUM -eq  1 ] ||
21306                 error "lfs find -L: found $NUM, expected 1 dir"
21307         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21308
21309         # find DoM files by stripe size
21310         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21311         [ $NUM -eq  $DOMFILES ] ||
21312                 error "lfs find -S: found $NUM, expected $DOMFILES"
21313         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21314
21315         # find files by stripe offset except DoM files
21316         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21317         [ $NUM -eq  $NORMFILES ] ||
21318                 error "lfs find -i: found $NUM, expected $NORMFILES"
21319         echo "Test 5: lfs find no DOM files by stripe index: OK"
21320         return 0
21321 }
21322 run_test 270e "DoM: lfs find with DoM files test"
21323
21324 test_270f() {
21325         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21326                 skip "Need MDS version at least 2.10.55"
21327
21328         local mdtname=${FSNAME}-MDT0000-mdtlov
21329         local dom=$DIR/$tdir/dom_file
21330         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21331                                                 lod.$mdtname.dom_stripesize)
21332         local dom_limit=131072
21333
21334         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21335         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21336                                                 lod.$mdtname.dom_stripesize)
21337         [ ${dom_limit} -eq ${dom_current} ] ||
21338                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21339
21340         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21341         $LFS setstripe -d $DIR/$tdir
21342         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21343                 error "Can't set directory default striping"
21344
21345         # exceed maximum stripe size
21346         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21347                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21348         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21349                 error "Able to create DoM component size more than LOD limit"
21350
21351         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21352         dom_current=$(do_facet mds1 $LCTL get_param -n \
21353                                                 lod.$mdtname.dom_stripesize)
21354         [ 0 -eq ${dom_current} ] ||
21355                 error "Can't set zero DoM stripe limit"
21356         rm $dom
21357
21358         # attempt to create DoM file on server with disabled DoM should
21359         # remove DoM entry from layout and be succeed
21360         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21361                 error "Can't create DoM file (DoM is disabled)"
21362         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21363                 error "File has DoM component while DoM is disabled"
21364         rm $dom
21365
21366         # attempt to create DoM file with only DoM stripe should return error
21367         $LFS setstripe -E $dom_limit -L mdt $dom &&
21368                 error "Able to create DoM-only file while DoM is disabled"
21369
21370         # too low values to be aligned with smallest stripe size 64K
21371         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21372         dom_current=$(do_facet mds1 $LCTL get_param -n \
21373                                                 lod.$mdtname.dom_stripesize)
21374         [ 30000 -eq ${dom_current} ] &&
21375                 error "Can set too small DoM stripe limit"
21376
21377         # 64K is a minimal stripe size in Lustre, expect limit of that size
21378         [ 65536 -eq ${dom_current} ] ||
21379                 error "Limit is not set to 64K but ${dom_current}"
21380
21381         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21382         dom_current=$(do_facet mds1 $LCTL get_param -n \
21383                                                 lod.$mdtname.dom_stripesize)
21384         echo $dom_current
21385         [ 2147483648 -eq ${dom_current} ] &&
21386                 error "Can set too large DoM stripe limit"
21387
21388         do_facet mds1 $LCTL set_param -n \
21389                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21390         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21391                 error "Can't create DoM component size after limit change"
21392         do_facet mds1 $LCTL set_param -n \
21393                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21394         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21395                 error "Can't create DoM file after limit decrease"
21396         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21397                 error "Can create big DoM component after limit decrease"
21398         touch ${dom}_def ||
21399                 error "Can't create file with old default layout"
21400
21401         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21402         return 0
21403 }
21404 run_test 270f "DoM: maximum DoM stripe size checks"
21405
21406 test_270g() {
21407         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21408                 skip "Need MDS version at least 2.13.52"
21409         local dom=$DIR/$tdir/$tfile
21410
21411         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21412         local lodname=${FSNAME}-MDT0000-mdtlov
21413
21414         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21415         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21416         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21417         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21418
21419         local dom_limit=1024
21420         local dom_threshold="50%"
21421
21422         $LFS setstripe -d $DIR/$tdir
21423         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21424                 error "Can't set directory default striping"
21425
21426         do_facet mds1 $LCTL set_param -n \
21427                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21428         # set 0 threshold and create DOM file to change tunable stripesize
21429         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21430         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21431                 error "Failed to create $dom file"
21432         # now tunable dom_cur_stripesize should reach maximum
21433         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21434                                         lod.${lodname}.dom_stripesize_cur_kb)
21435         [[ $dom_current == $dom_limit ]] ||
21436                 error "Current DOM stripesize is not maximum"
21437         rm $dom
21438
21439         # set threshold for further tests
21440         do_facet mds1 $LCTL set_param -n \
21441                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21442         echo "DOM threshold is $dom_threshold free space"
21443         local dom_def
21444         local dom_set
21445         # Spoof bfree to exceed threshold
21446         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21447         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21448         for spfree in 40 20 0 15 30 55; do
21449                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21450                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21451                         error "Failed to create $dom file"
21452                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21453                                         lod.${lodname}.dom_stripesize_cur_kb)
21454                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21455                 [[ $dom_def != $dom_current ]] ||
21456                         error "Default stripe size was not changed"
21457                 if [[ $spfree > 0 ]] ; then
21458                         dom_set=$($LFS getstripe -S $dom)
21459                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21460                                 error "DOM component size is still old"
21461                 else
21462                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21463                                 error "DoM component is set with no free space"
21464                 fi
21465                 rm $dom
21466                 dom_current=$dom_def
21467         done
21468 }
21469 run_test 270g "DoM: default DoM stripe size depends on free space"
21470
21471 test_270h() {
21472         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21473                 skip "Need MDS version at least 2.13.53"
21474
21475         local mdtname=${FSNAME}-MDT0000-mdtlov
21476         local dom=$DIR/$tdir/$tfile
21477         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21478
21479         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21480         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21481
21482         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21483         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21484                 error "can't create OST file"
21485         # mirrored file with DOM entry in the second mirror
21486         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21487                 error "can't create mirror with DoM component"
21488
21489         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21490
21491         # DOM component in the middle and has other enries in the same mirror,
21492         # should succeed but lost DoM component
21493         $LFS setstripe --copy=${dom}_1 $dom ||
21494                 error "Can't create file from OST|DOM mirror layout"
21495         # check new file has no DoM layout after all
21496         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21497                 error "File has DoM component while DoM is disabled"
21498 }
21499 run_test 270h "DoM: DoM stripe removal when disabled on server"
21500
21501 test_271a() {
21502         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21503                 skip "Need MDS version at least 2.10.55"
21504
21505         local dom=$DIR/$tdir/dom
21506
21507         mkdir -p $DIR/$tdir
21508
21509         $LFS setstripe -E 1024K -L mdt $dom
21510
21511         lctl set_param -n mdc.*.stats=clear
21512         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21513         cat $dom > /dev/null
21514         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21515         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21516         ls $dom
21517         rm -f $dom
21518 }
21519 run_test 271a "DoM: data is cached for read after write"
21520
21521 test_271b() {
21522         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21523                 skip "Need MDS version at least 2.10.55"
21524
21525         local dom=$DIR/$tdir/dom
21526
21527         mkdir -p $DIR/$tdir
21528
21529         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21530
21531         lctl set_param -n mdc.*.stats=clear
21532         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21533         cancel_lru_locks mdc
21534         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21535         # second stat to check size is cached on client
21536         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21537         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21538         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21539         rm -f $dom
21540 }
21541 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21542
21543 test_271ba() {
21544         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21545                 skip "Need MDS version at least 2.10.55"
21546
21547         local dom=$DIR/$tdir/dom
21548
21549         mkdir -p $DIR/$tdir
21550
21551         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21552
21553         lctl set_param -n mdc.*.stats=clear
21554         lctl set_param -n osc.*.stats=clear
21555         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21556         cancel_lru_locks mdc
21557         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21558         # second stat to check size is cached on client
21559         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21560         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21561         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21562         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21563         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21564         rm -f $dom
21565 }
21566 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21567
21568
21569 get_mdc_stats() {
21570         local mdtidx=$1
21571         local param=$2
21572         local mdt=MDT$(printf %04x $mdtidx)
21573
21574         if [ -z $param ]; then
21575                 lctl get_param -n mdc.*$mdt*.stats
21576         else
21577                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21578         fi
21579 }
21580
21581 test_271c() {
21582         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21583                 skip "Need MDS version at least 2.10.55"
21584
21585         local dom=$DIR/$tdir/dom
21586
21587         mkdir -p $DIR/$tdir
21588
21589         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21590
21591         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21592         local facet=mds$((mdtidx + 1))
21593
21594         cancel_lru_locks mdc
21595         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21596         createmany -o $dom 1000
21597         lctl set_param -n mdc.*.stats=clear
21598         smalliomany -w $dom 1000 200
21599         get_mdc_stats $mdtidx
21600         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21601         # Each file has 1 open, 1 IO enqueues, total 2000
21602         # but now we have also +1 getxattr for security.capability, total 3000
21603         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21604         unlinkmany $dom 1000
21605
21606         cancel_lru_locks mdc
21607         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21608         createmany -o $dom 1000
21609         lctl set_param -n mdc.*.stats=clear
21610         smalliomany -w $dom 1000 200
21611         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21612         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21613         # for OPEN and IO lock.
21614         [ $((enq - enq_2)) -ge 1000 ] ||
21615                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21616         unlinkmany $dom 1000
21617         return 0
21618 }
21619 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21620
21621 cleanup_271def_tests() {
21622         trap 0
21623         rm -f $1
21624 }
21625
21626 test_271d() {
21627         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21628                 skip "Need MDS version at least 2.10.57"
21629
21630         local dom=$DIR/$tdir/dom
21631         local tmp=$TMP/$tfile
21632         trap "cleanup_271def_tests $tmp" EXIT
21633
21634         mkdir -p $DIR/$tdir
21635
21636         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21637
21638         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21639
21640         cancel_lru_locks mdc
21641         dd if=/dev/urandom of=$tmp bs=1000 count=1
21642         dd if=$tmp of=$dom bs=1000 count=1
21643         cancel_lru_locks mdc
21644
21645         cat /etc/hosts >> $tmp
21646         lctl set_param -n mdc.*.stats=clear
21647
21648         # append data to the same file it should update local page
21649         echo "Append to the same page"
21650         cat /etc/hosts >> $dom
21651         local num=$(get_mdc_stats $mdtidx ost_read)
21652         local ra=$(get_mdc_stats $mdtidx req_active)
21653         local rw=$(get_mdc_stats $mdtidx req_waittime)
21654
21655         [ -z $num ] || error "$num READ RPC occured"
21656         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21657         echo "... DONE"
21658
21659         # compare content
21660         cmp $tmp $dom || error "file miscompare"
21661
21662         cancel_lru_locks mdc
21663         lctl set_param -n mdc.*.stats=clear
21664
21665         echo "Open and read file"
21666         cat $dom > /dev/null
21667         local num=$(get_mdc_stats $mdtidx ost_read)
21668         local ra=$(get_mdc_stats $mdtidx req_active)
21669         local rw=$(get_mdc_stats $mdtidx req_waittime)
21670
21671         [ -z $num ] || error "$num READ RPC occured"
21672         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21673         echo "... DONE"
21674
21675         # compare content
21676         cmp $tmp $dom || error "file miscompare"
21677
21678         return 0
21679 }
21680 run_test 271d "DoM: read on open (1K file in reply buffer)"
21681
21682 test_271f() {
21683         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21684                 skip "Need MDS version at least 2.10.57"
21685
21686         local dom=$DIR/$tdir/dom
21687         local tmp=$TMP/$tfile
21688         trap "cleanup_271def_tests $tmp" EXIT
21689
21690         mkdir -p $DIR/$tdir
21691
21692         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21693
21694         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21695
21696         cancel_lru_locks mdc
21697         dd if=/dev/urandom of=$tmp bs=265000 count=1
21698         dd if=$tmp of=$dom bs=265000 count=1
21699         cancel_lru_locks mdc
21700         cat /etc/hosts >> $tmp
21701         lctl set_param -n mdc.*.stats=clear
21702
21703         echo "Append to the same page"
21704         cat /etc/hosts >> $dom
21705         local num=$(get_mdc_stats $mdtidx ost_read)
21706         local ra=$(get_mdc_stats $mdtidx req_active)
21707         local rw=$(get_mdc_stats $mdtidx req_waittime)
21708
21709         [ -z $num ] || error "$num READ RPC occured"
21710         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21711         echo "... DONE"
21712
21713         # compare content
21714         cmp $tmp $dom || error "file miscompare"
21715
21716         cancel_lru_locks mdc
21717         lctl set_param -n mdc.*.stats=clear
21718
21719         echo "Open and read file"
21720         cat $dom > /dev/null
21721         local num=$(get_mdc_stats $mdtidx ost_read)
21722         local ra=$(get_mdc_stats $mdtidx req_active)
21723         local rw=$(get_mdc_stats $mdtidx req_waittime)
21724
21725         [ -z $num ] && num=0
21726         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21727         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21728         echo "... DONE"
21729
21730         # compare content
21731         cmp $tmp $dom || error "file miscompare"
21732
21733         return 0
21734 }
21735 run_test 271f "DoM: read on open (200K file and read tail)"
21736
21737 test_271g() {
21738         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21739                 skip "Skipping due to old client or server version"
21740
21741         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21742         # to get layout
21743         $CHECKSTAT -t file $DIR1/$tfile
21744
21745         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21746         MULTIOP_PID=$!
21747         sleep 1
21748         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21749         $LCTL set_param fail_loc=0x80000314
21750         rm $DIR1/$tfile || error "Unlink fails"
21751         RC=$?
21752         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21753         [ $RC -eq 0 ] || error "Failed write to stale object"
21754 }
21755 run_test 271g "Discard DoM data vs client flush race"
21756
21757 test_272a() {
21758         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21759                 skip "Need MDS version at least 2.11.50"
21760
21761         local dom=$DIR/$tdir/dom
21762         mkdir -p $DIR/$tdir
21763
21764         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21765         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21766                 error "failed to write data into $dom"
21767         local old_md5=$(md5sum $dom)
21768
21769         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21770                 error "failed to migrate to the same DoM component"
21771
21772         local new_md5=$(md5sum $dom)
21773
21774         [ "$old_md5" == "$new_md5" ] ||
21775                 error "md5sum differ: $old_md5, $new_md5"
21776
21777         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21778                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21779 }
21780 run_test 272a "DoM migration: new layout with the same DOM component"
21781
21782 test_272b() {
21783         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21784                 skip "Need MDS version at least 2.11.50"
21785
21786         local dom=$DIR/$tdir/dom
21787         mkdir -p $DIR/$tdir
21788         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21789
21790         local mdtidx=$($LFS getstripe -m $dom)
21791         local mdtname=MDT$(printf %04x $mdtidx)
21792         local facet=mds$((mdtidx + 1))
21793
21794         local mdtfree1=$(do_facet $facet \
21795                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21796         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21797                 error "failed to write data into $dom"
21798         local old_md5=$(md5sum $dom)
21799         cancel_lru_locks mdc
21800         local mdtfree1=$(do_facet $facet \
21801                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21802
21803         $LFS migrate -c2 $dom ||
21804                 error "failed to migrate to the new composite layout"
21805         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21806                 error "MDT stripe was not removed"
21807
21808         cancel_lru_locks mdc
21809         local new_md5=$(md5sum $dom)
21810         [ "$old_md5" == "$new_md5" ] ||
21811                 error "$old_md5 != $new_md5"
21812
21813         # Skip free space checks with ZFS
21814         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21815                 local mdtfree2=$(do_facet $facet \
21816                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21817                 [ $mdtfree2 -gt $mdtfree1 ] ||
21818                         error "MDT space is not freed after migration"
21819         fi
21820         return 0
21821 }
21822 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21823
21824 test_272c() {
21825         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21826                 skip "Need MDS version at least 2.11.50"
21827
21828         local dom=$DIR/$tdir/$tfile
21829         mkdir -p $DIR/$tdir
21830         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21831
21832         local mdtidx=$($LFS getstripe -m $dom)
21833         local mdtname=MDT$(printf %04x $mdtidx)
21834         local facet=mds$((mdtidx + 1))
21835
21836         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21837                 error "failed to write data into $dom"
21838         local old_md5=$(md5sum $dom)
21839         cancel_lru_locks mdc
21840         local mdtfree1=$(do_facet $facet \
21841                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21842
21843         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21844                 error "failed to migrate to the new composite layout"
21845         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21846                 error "MDT stripe was not removed"
21847
21848         cancel_lru_locks mdc
21849         local new_md5=$(md5sum $dom)
21850         [ "$old_md5" == "$new_md5" ] ||
21851                 error "$old_md5 != $new_md5"
21852
21853         # Skip free space checks with ZFS
21854         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21855                 local mdtfree2=$(do_facet $facet \
21856                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21857                 [ $mdtfree2 -gt $mdtfree1 ] ||
21858                         error "MDS space is not freed after migration"
21859         fi
21860         return 0
21861 }
21862 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21863
21864 test_272d() {
21865         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21866                 skip "Need MDS version at least 2.12.55"
21867
21868         local dom=$DIR/$tdir/$tfile
21869         mkdir -p $DIR/$tdir
21870         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21871
21872         local mdtidx=$($LFS getstripe -m $dom)
21873         local mdtname=MDT$(printf %04x $mdtidx)
21874         local facet=mds$((mdtidx + 1))
21875
21876         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21877                 error "failed to write data into $dom"
21878         local old_md5=$(md5sum $dom)
21879         cancel_lru_locks mdc
21880         local mdtfree1=$(do_facet $facet \
21881                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21882
21883         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21884                 error "failed mirroring to the new composite layout"
21885         $LFS mirror resync $dom ||
21886                 error "failed mirror resync"
21887         $LFS mirror split --mirror-id 1 -d $dom ||
21888                 error "failed mirror split"
21889
21890         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21891                 error "MDT stripe was not removed"
21892
21893         cancel_lru_locks mdc
21894         local new_md5=$(md5sum $dom)
21895         [ "$old_md5" == "$new_md5" ] ||
21896                 error "$old_md5 != $new_md5"
21897
21898         # Skip free space checks with ZFS
21899         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21900                 local mdtfree2=$(do_facet $facet \
21901                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21902                 [ $mdtfree2 -gt $mdtfree1 ] ||
21903                         error "MDS space is not freed after DOM mirror deletion"
21904         fi
21905         return 0
21906 }
21907 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21908
21909 test_272e() {
21910         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21911                 skip "Need MDS version at least 2.12.55"
21912
21913         local dom=$DIR/$tdir/$tfile
21914         mkdir -p $DIR/$tdir
21915         $LFS setstripe -c 2 $dom
21916
21917         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21918                 error "failed to write data into $dom"
21919         local old_md5=$(md5sum $dom)
21920         cancel_lru_locks mdc
21921
21922         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21923                 error "failed mirroring to the DOM layout"
21924         $LFS mirror resync $dom ||
21925                 error "failed mirror resync"
21926         $LFS mirror split --mirror-id 1 -d $dom ||
21927                 error "failed mirror split"
21928
21929         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21930                 error "MDT stripe was not removed"
21931
21932         cancel_lru_locks mdc
21933         local new_md5=$(md5sum $dom)
21934         [ "$old_md5" == "$new_md5" ] ||
21935                 error "$old_md5 != $new_md5"
21936
21937         return 0
21938 }
21939 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21940
21941 test_272f() {
21942         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21943                 skip "Need MDS version at least 2.12.55"
21944
21945         local dom=$DIR/$tdir/$tfile
21946         mkdir -p $DIR/$tdir
21947         $LFS setstripe -c 2 $dom
21948
21949         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21950                 error "failed to write data into $dom"
21951         local old_md5=$(md5sum $dom)
21952         cancel_lru_locks mdc
21953
21954         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21955                 error "failed migrating to the DOM file"
21956
21957         cancel_lru_locks mdc
21958         local new_md5=$(md5sum $dom)
21959         [ "$old_md5" != "$new_md5" ] &&
21960                 error "$old_md5 != $new_md5"
21961
21962         return 0
21963 }
21964 run_test 272f "DoM migration: OST-striped file to DOM file"
21965
21966 test_273a() {
21967         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21968                 skip "Need MDS version at least 2.11.50"
21969
21970         # Layout swap cannot be done if either file has DOM component,
21971         # this will never be supported, migration should be used instead
21972
21973         local dom=$DIR/$tdir/$tfile
21974         mkdir -p $DIR/$tdir
21975
21976         $LFS setstripe -c2 ${dom}_plain
21977         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21978         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21979                 error "can swap layout with DoM component"
21980         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21981                 error "can swap layout with DoM component"
21982
21983         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21984         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21985                 error "can swap layout with DoM component"
21986         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21987                 error "can swap layout with DoM component"
21988         return 0
21989 }
21990 run_test 273a "DoM: layout swapping should fail with DOM"
21991
21992 test_273b() {
21993         mkdir -p $DIR/$tdir
21994         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21995
21996 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21997         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21998
21999         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22000 }
22001 run_test 273b "DoM: race writeback and object destroy"
22002
22003 test_275() {
22004         remote_ost_nodsh && skip "remote OST with nodsh"
22005         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22006                 skip "Need OST version >= 2.10.57"
22007
22008         local file=$DIR/$tfile
22009         local oss
22010
22011         oss=$(comma_list $(osts_nodes))
22012
22013         dd if=/dev/urandom of=$file bs=1M count=2 ||
22014                 error "failed to create a file"
22015         cancel_lru_locks osc
22016
22017         #lock 1
22018         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22019                 error "failed to read a file"
22020
22021 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22022         $LCTL set_param fail_loc=0x8000031f
22023
22024         cancel_lru_locks osc &
22025         sleep 1
22026
22027 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22028         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22029         #IO takes another lock, but matches the PENDING one
22030         #and places it to the IO RPC
22031         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22032                 error "failed to read a file with PENDING lock"
22033 }
22034 run_test 275 "Read on a canceled duplicate lock"
22035
22036 test_276() {
22037         remote_ost_nodsh && skip "remote OST with nodsh"
22038         local pid
22039
22040         do_facet ost1 "(while true; do \
22041                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22042                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22043         pid=$!
22044
22045         for LOOP in $(seq 20); do
22046                 stop ost1
22047                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22048         done
22049         kill -9 $pid
22050         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22051                 rm $TMP/sanity_276_pid"
22052 }
22053 run_test 276 "Race between mount and obd_statfs"
22054
22055 test_277() {
22056         $LCTL set_param ldlm.namespaces.*.lru_size=0
22057         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22058         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22059                         grep ^used_mb | awk '{print $2}')
22060         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22062                 oflag=direct conv=notrunc
22063         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22064                         grep ^used_mb | awk '{print $2}')
22065         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22066 }
22067 run_test 277 "Direct IO shall drop page cache"
22068
22069 test_278() {
22070         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22071         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22072         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22073                 skip "needs the same host for mdt1 mdt2" && return
22074
22075         local pid1
22076         local pid2
22077
22078 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22079         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22080         stop mds2 &
22081         pid2=$!
22082
22083         stop mds1
22084
22085         echo "Starting MDTs"
22086         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22087         wait $pid2
22088 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22089 #will return NULL
22090         do_facet mds2 $LCTL set_param fail_loc=0
22091
22092         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22093         wait_recovery_complete mds2
22094 }
22095 run_test 278 "Race starting MDS between MDTs stop/start"
22096
22097 test_280() {
22098         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22099                 skip "Need MGS version at least 2.13.52"
22100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22101         combined_mgs_mds || skip "needs combined MGS/MDT"
22102
22103         umount_client $MOUNT
22104 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22105         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22106
22107         mount_client $MOUNT &
22108         sleep 1
22109         stop mgs || error "stop mgs failed"
22110         #for a race mgs would crash
22111         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22112         # make sure we unmount client before remounting
22113         wait
22114         umount_client $MOUNT
22115         mount_client $MOUNT || error "mount client failed"
22116 }
22117 run_test 280 "Race between MGS umount and client llog processing"
22118
22119 cleanup_test_300() {
22120         trap 0
22121         umask $SAVE_UMASK
22122 }
22123 test_striped_dir() {
22124         local mdt_index=$1
22125         local stripe_count
22126         local stripe_index
22127
22128         mkdir -p $DIR/$tdir
22129
22130         SAVE_UMASK=$(umask)
22131         trap cleanup_test_300 RETURN EXIT
22132
22133         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22134                                                 $DIR/$tdir/striped_dir ||
22135                 error "set striped dir error"
22136
22137         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22138         [ "$mode" = "755" ] || error "expect 755 got $mode"
22139
22140         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22141                 error "getdirstripe failed"
22142         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22143         if [ "$stripe_count" != "2" ]; then
22144                 error "1:stripe_count is $stripe_count, expect 2"
22145         fi
22146         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22147         if [ "$stripe_count" != "2" ]; then
22148                 error "2:stripe_count is $stripe_count, expect 2"
22149         fi
22150
22151         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22152         if [ "$stripe_index" != "$mdt_index" ]; then
22153                 error "stripe_index is $stripe_index, expect $mdt_index"
22154         fi
22155
22156         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22157                 error "nlink error after create striped dir"
22158
22159         mkdir $DIR/$tdir/striped_dir/a
22160         mkdir $DIR/$tdir/striped_dir/b
22161
22162         stat $DIR/$tdir/striped_dir/a ||
22163                 error "create dir under striped dir failed"
22164         stat $DIR/$tdir/striped_dir/b ||
22165                 error "create dir under striped dir failed"
22166
22167         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22168                 error "nlink error after mkdir"
22169
22170         rmdir $DIR/$tdir/striped_dir/a
22171         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22172                 error "nlink error after rmdir"
22173
22174         rmdir $DIR/$tdir/striped_dir/b
22175         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22176                 error "nlink error after rmdir"
22177
22178         chattr +i $DIR/$tdir/striped_dir
22179         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22180                 error "immutable flags not working under striped dir!"
22181         chattr -i $DIR/$tdir/striped_dir
22182
22183         rmdir $DIR/$tdir/striped_dir ||
22184                 error "rmdir striped dir error"
22185
22186         cleanup_test_300
22187
22188         true
22189 }
22190
22191 test_300a() {
22192         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22193                 skip "skipped for lustre < 2.7.0"
22194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22196
22197         test_striped_dir 0 || error "failed on striped dir on MDT0"
22198         test_striped_dir 1 || error "failed on striped dir on MDT0"
22199 }
22200 run_test 300a "basic striped dir sanity test"
22201
22202 test_300b() {
22203         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22204                 skip "skipped for lustre < 2.7.0"
22205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22207
22208         local i
22209         local mtime1
22210         local mtime2
22211         local mtime3
22212
22213         test_mkdir $DIR/$tdir || error "mkdir fail"
22214         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22215                 error "set striped dir error"
22216         for i in {0..9}; do
22217                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22218                 sleep 1
22219                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22220                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22221                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22222                 sleep 1
22223                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22224                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22225                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22226         done
22227         true
22228 }
22229 run_test 300b "check ctime/mtime for striped dir"
22230
22231 test_300c() {
22232         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22233                 skip "skipped for lustre < 2.7.0"
22234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22236
22237         local file_count
22238
22239         mkdir -p $DIR/$tdir
22240         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22241                 error "set striped dir error"
22242
22243         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22244                 error "chown striped dir failed"
22245
22246         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22247                 error "create 5k files failed"
22248
22249         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22250
22251         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22252
22253         rm -rf $DIR/$tdir
22254 }
22255 run_test 300c "chown && check ls under striped directory"
22256
22257 test_300d() {
22258         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22259                 skip "skipped for lustre < 2.7.0"
22260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22262
22263         local stripe_count
22264         local file
22265
22266         mkdir -p $DIR/$tdir
22267         $LFS setstripe -c 2 $DIR/$tdir
22268
22269         #local striped directory
22270         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22271                 error "set striped dir error"
22272         #look at the directories for debug purposes
22273         ls -l $DIR/$tdir
22274         $LFS getdirstripe $DIR/$tdir
22275         ls -l $DIR/$tdir/striped_dir
22276         $LFS getdirstripe $DIR/$tdir/striped_dir
22277         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22278                 error "create 10 files failed"
22279
22280         #remote striped directory
22281         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22282                 error "set striped dir error"
22283         #look at the directories for debug purposes
22284         ls -l $DIR/$tdir
22285         $LFS getdirstripe $DIR/$tdir
22286         ls -l $DIR/$tdir/remote_striped_dir
22287         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22288         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22289                 error "create 10 files failed"
22290
22291         for file in $(find $DIR/$tdir); do
22292                 stripe_count=$($LFS getstripe -c $file)
22293                 [ $stripe_count -eq 2 ] ||
22294                         error "wrong stripe $stripe_count for $file"
22295         done
22296
22297         rm -rf $DIR/$tdir
22298 }
22299 run_test 300d "check default stripe under striped directory"
22300
22301 test_300e() {
22302         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22303                 skip "Need MDS version at least 2.7.55"
22304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22306
22307         local stripe_count
22308         local file
22309
22310         mkdir -p $DIR/$tdir
22311
22312         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22313                 error "set striped dir error"
22314
22315         touch $DIR/$tdir/striped_dir/a
22316         touch $DIR/$tdir/striped_dir/b
22317         touch $DIR/$tdir/striped_dir/c
22318
22319         mkdir $DIR/$tdir/striped_dir/dir_a
22320         mkdir $DIR/$tdir/striped_dir/dir_b
22321         mkdir $DIR/$tdir/striped_dir/dir_c
22322
22323         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22324                 error "set striped adir under striped dir error"
22325
22326         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22327                 error "set striped bdir under striped dir error"
22328
22329         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22330                 error "set striped cdir under striped dir error"
22331
22332         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22333                 error "rename dir under striped dir fails"
22334
22335         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22336                 error "rename dir under different stripes fails"
22337
22338         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22339                 error "rename file under striped dir should succeed"
22340
22341         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22342                 error "rename dir under striped dir should succeed"
22343
22344         rm -rf $DIR/$tdir
22345 }
22346 run_test 300e "check rename under striped directory"
22347
22348 test_300f() {
22349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22351         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22352                 skip "Need MDS version at least 2.7.55"
22353
22354         local stripe_count
22355         local file
22356
22357         rm -rf $DIR/$tdir
22358         mkdir -p $DIR/$tdir
22359
22360         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22361                 error "set striped dir error"
22362
22363         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22364                 error "set striped dir error"
22365
22366         touch $DIR/$tdir/striped_dir/a
22367         mkdir $DIR/$tdir/striped_dir/dir_a
22368         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22369                 error "create striped dir under striped dir fails"
22370
22371         touch $DIR/$tdir/striped_dir1/b
22372         mkdir $DIR/$tdir/striped_dir1/dir_b
22373         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22374                 error "create striped dir under striped dir fails"
22375
22376         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22377                 error "rename dir under different striped dir should fail"
22378
22379         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22380                 error "rename striped dir under diff striped dir should fail"
22381
22382         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22383                 error "rename file under diff striped dirs fails"
22384
22385         rm -rf $DIR/$tdir
22386 }
22387 run_test 300f "check rename cross striped directory"
22388
22389 test_300_check_default_striped_dir()
22390 {
22391         local dirname=$1
22392         local default_count=$2
22393         local default_index=$3
22394         local stripe_count
22395         local stripe_index
22396         local dir_stripe_index
22397         local dir
22398
22399         echo "checking $dirname $default_count $default_index"
22400         $LFS setdirstripe -D -c $default_count -i $default_index \
22401                                 -H all_char $DIR/$tdir/$dirname ||
22402                 error "set default stripe on striped dir error"
22403         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22404         [ $stripe_count -eq $default_count ] ||
22405                 error "expect $default_count get $stripe_count for $dirname"
22406
22407         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22408         [ $stripe_index -eq $default_index ] ||
22409                 error "expect $default_index get $stripe_index for $dirname"
22410
22411         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22412                                                 error "create dirs failed"
22413
22414         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22415         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22416         for dir in $(find $DIR/$tdir/$dirname/*); do
22417                 stripe_count=$($LFS getdirstripe -c $dir)
22418                 (( $stripe_count == $default_count )) ||
22419                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22420                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22421                 error "stripe count $default_count != $stripe_count for $dir"
22422
22423                 stripe_index=$($LFS getdirstripe -i $dir)
22424                 [ $default_index -eq -1 ] ||
22425                         [ $stripe_index -eq $default_index ] ||
22426                         error "$stripe_index != $default_index for $dir"
22427
22428                 #check default stripe
22429                 stripe_count=$($LFS getdirstripe -D -c $dir)
22430                 [ $stripe_count -eq $default_count ] ||
22431                 error "default count $default_count != $stripe_count for $dir"
22432
22433                 stripe_index=$($LFS getdirstripe -D -i $dir)
22434                 [ $stripe_index -eq $default_index ] ||
22435                 error "default index $default_index != $stripe_index for $dir"
22436         done
22437         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22438 }
22439
22440 test_300g() {
22441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22442         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22443                 skip "Need MDS version at least 2.7.55"
22444
22445         local dir
22446         local stripe_count
22447         local stripe_index
22448
22449         mkdir $DIR/$tdir
22450         mkdir $DIR/$tdir/normal_dir
22451
22452         #Checking when client cache stripe index
22453         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22454         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22455                 error "create striped_dir failed"
22456
22457         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22458                 error "create dir0 fails"
22459         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22460         [ $stripe_index -eq 0 ] ||
22461                 error "dir0 expect index 0 got $stripe_index"
22462
22463         mkdir $DIR/$tdir/striped_dir/dir1 ||
22464                 error "create dir1 fails"
22465         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22466         [ $stripe_index -eq 1 ] ||
22467                 error "dir1 expect index 1 got $stripe_index"
22468
22469         #check default stripe count/stripe index
22470         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22471         test_300_check_default_striped_dir normal_dir 1 0
22472         test_300_check_default_striped_dir normal_dir -1 1
22473         test_300_check_default_striped_dir normal_dir 2 -1
22474
22475         #delete default stripe information
22476         echo "delete default stripeEA"
22477         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22478                 error "set default stripe on striped dir error"
22479
22480         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22481         for dir in $(find $DIR/$tdir/normal_dir/*); do
22482                 stripe_count=$($LFS getdirstripe -c $dir)
22483                 [ $stripe_count -eq 0 ] ||
22484                         error "expect 1 get $stripe_count for $dir"
22485                 stripe_index=$($LFS getdirstripe -i $dir)
22486                 [ $stripe_index -eq 0 ] ||
22487                         error "expect 0 get $stripe_index for $dir"
22488         done
22489 }
22490 run_test 300g "check default striped directory for normal directory"
22491
22492 test_300h() {
22493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22494         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22495                 skip "Need MDS version at least 2.7.55"
22496
22497         local dir
22498         local stripe_count
22499
22500         mkdir $DIR/$tdir
22501         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22502                 error "set striped dir error"
22503
22504         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22505         test_300_check_default_striped_dir striped_dir 1 0
22506         test_300_check_default_striped_dir striped_dir -1 1
22507         test_300_check_default_striped_dir striped_dir 2 -1
22508
22509         #delete default stripe information
22510         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22511                 error "set default stripe on striped dir error"
22512
22513         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22514         for dir in $(find $DIR/$tdir/striped_dir/*); do
22515                 stripe_count=$($LFS getdirstripe -c $dir)
22516                 [ $stripe_count -eq 0 ] ||
22517                         error "expect 1 get $stripe_count for $dir"
22518         done
22519 }
22520 run_test 300h "check default striped directory for striped directory"
22521
22522 test_300i() {
22523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22524         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22525         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22526                 skip "Need MDS version at least 2.7.55"
22527
22528         local stripe_count
22529         local file
22530
22531         mkdir $DIR/$tdir
22532
22533         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22534                 error "set striped dir error"
22535
22536         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22537                 error "create files under striped dir failed"
22538
22539         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22540                 error "set striped hashdir error"
22541
22542         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22543                 error "create dir0 under hash dir failed"
22544         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22545                 error "create dir1 under hash dir failed"
22546         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22547                 error "create dir2 under hash dir failed"
22548
22549         # unfortunately, we need to umount to clear dir layout cache for now
22550         # once we fully implement dir layout, we can drop this
22551         umount_client $MOUNT || error "umount failed"
22552         mount_client $MOUNT || error "mount failed"
22553
22554         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22555         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22556         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22557
22558         #set the stripe to be unknown hash type
22559         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22560         $LCTL set_param fail_loc=0x1901
22561         for ((i = 0; i < 10; i++)); do
22562                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22563                         error "stat f-$i failed"
22564                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22565         done
22566
22567         touch $DIR/$tdir/striped_dir/f0 &&
22568                 error "create under striped dir with unknown hash should fail"
22569
22570         $LCTL set_param fail_loc=0
22571
22572         umount_client $MOUNT || error "umount failed"
22573         mount_client $MOUNT || error "mount failed"
22574
22575         return 0
22576 }
22577 run_test 300i "client handle unknown hash type striped directory"
22578
22579 test_300j() {
22580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22582         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22583                 skip "Need MDS version at least 2.7.55"
22584
22585         local stripe_count
22586         local file
22587
22588         mkdir $DIR/$tdir
22589
22590         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22591         $LCTL set_param fail_loc=0x1702
22592         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22593                 error "set striped dir error"
22594
22595         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22596                 error "create files under striped dir failed"
22597
22598         $LCTL set_param fail_loc=0
22599
22600         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22601
22602         return 0
22603 }
22604 run_test 300j "test large update record"
22605
22606 test_300k() {
22607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22609         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22610                 skip "Need MDS version at least 2.7.55"
22611
22612         # this test needs a huge transaction
22613         local kb
22614         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22615              osd*.$FSNAME-MDT0000.kbytestotal")
22616         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22617
22618         local stripe_count
22619         local file
22620
22621         mkdir $DIR/$tdir
22622
22623         #define OBD_FAIL_LARGE_STRIPE   0x1703
22624         $LCTL set_param fail_loc=0x1703
22625         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22626                 error "set striped dir error"
22627         $LCTL set_param fail_loc=0
22628
22629         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22630                 error "getstripeddir fails"
22631         rm -rf $DIR/$tdir/striped_dir ||
22632                 error "unlink striped dir fails"
22633
22634         return 0
22635 }
22636 run_test 300k "test large striped directory"
22637
22638 test_300l() {
22639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22640         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22641         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22642                 skip "Need MDS version at least 2.7.55"
22643
22644         local stripe_index
22645
22646         test_mkdir -p $DIR/$tdir/striped_dir
22647         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22648                         error "chown $RUNAS_ID failed"
22649         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22650                 error "set default striped dir failed"
22651
22652         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22653         $LCTL set_param fail_loc=0x80000158
22654         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22655
22656         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22657         [ $stripe_index -eq 1 ] ||
22658                 error "expect 1 get $stripe_index for $dir"
22659 }
22660 run_test 300l "non-root user to create dir under striped dir with stale layout"
22661
22662 test_300m() {
22663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22664         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22665         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22666                 skip "Need MDS version at least 2.7.55"
22667
22668         mkdir -p $DIR/$tdir/striped_dir
22669         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22670                 error "set default stripes dir error"
22671
22672         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22673
22674         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22675         [ $stripe_count -eq 0 ] ||
22676                         error "expect 0 get $stripe_count for a"
22677
22678         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22679                 error "set default stripes dir error"
22680
22681         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22682
22683         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22684         [ $stripe_count -eq 0 ] ||
22685                         error "expect 0 get $stripe_count for b"
22686
22687         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22688                 error "set default stripes dir error"
22689
22690         mkdir $DIR/$tdir/striped_dir/c &&
22691                 error "default stripe_index is invalid, mkdir c should fails"
22692
22693         rm -rf $DIR/$tdir || error "rmdir fails"
22694 }
22695 run_test 300m "setstriped directory on single MDT FS"
22696
22697 cleanup_300n() {
22698         local list=$(comma_list $(mdts_nodes))
22699
22700         trap 0
22701         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22702 }
22703
22704 test_300n() {
22705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22707         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22708                 skip "Need MDS version at least 2.7.55"
22709         remote_mds_nodsh && skip "remote MDS with nodsh"
22710
22711         local stripe_index
22712         local list=$(comma_list $(mdts_nodes))
22713
22714         trap cleanup_300n RETURN EXIT
22715         mkdir -p $DIR/$tdir
22716         chmod 777 $DIR/$tdir
22717         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22718                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22719                 error "create striped dir succeeds with gid=0"
22720
22721         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22722         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22723                 error "create striped dir fails with gid=-1"
22724
22725         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22726         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22727                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22728                 error "set default striped dir succeeds with gid=0"
22729
22730
22731         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22732         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22733                 error "set default striped dir fails with gid=-1"
22734
22735
22736         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22737         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22738                                         error "create test_dir fails"
22739         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22740                                         error "create test_dir1 fails"
22741         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22742                                         error "create test_dir2 fails"
22743         cleanup_300n
22744 }
22745 run_test 300n "non-root user to create dir under striped dir with default EA"
22746
22747 test_300o() {
22748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22750         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22751                 skip "Need MDS version at least 2.7.55"
22752
22753         local numfree1
22754         local numfree2
22755
22756         mkdir -p $DIR/$tdir
22757
22758         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22759         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22760         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22761                 skip "not enough free inodes $numfree1 $numfree2"
22762         fi
22763
22764         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22765         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22766         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22767                 skip "not enough free space $numfree1 $numfree2"
22768         fi
22769
22770         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22771                 error "setdirstripe fails"
22772
22773         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22774                 error "create dirs fails"
22775
22776         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22777         ls $DIR/$tdir/striped_dir > /dev/null ||
22778                 error "ls striped dir fails"
22779         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22780                 error "unlink big striped dir fails"
22781 }
22782 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22783
22784 test_300p() {
22785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22787         remote_mds_nodsh && skip "remote MDS with nodsh"
22788
22789         mkdir -p $DIR/$tdir
22790
22791         #define OBD_FAIL_OUT_ENOSPC     0x1704
22792         do_facet mds2 lctl set_param fail_loc=0x80001704
22793         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22794                  && error "create striped directory should fail"
22795
22796         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22797
22798         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22799         true
22800 }
22801 run_test 300p "create striped directory without space"
22802
22803 test_300q() {
22804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22806
22807         local fd=$(free_fd)
22808         local cmd="exec $fd<$tdir"
22809         cd $DIR
22810         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22811         eval $cmd
22812         cmd="exec $fd<&-"
22813         trap "eval $cmd" EXIT
22814         cd $tdir || error "cd $tdir fails"
22815         rmdir  ../$tdir || error "rmdir $tdir fails"
22816         mkdir local_dir && error "create dir succeeds"
22817         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22818         eval $cmd
22819         return 0
22820 }
22821 run_test 300q "create remote directory under orphan directory"
22822
22823 test_300r() {
22824         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22825                 skip "Need MDS version at least 2.7.55" && return
22826         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22827
22828         mkdir $DIR/$tdir
22829
22830         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22831                 error "set striped dir error"
22832
22833         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22834                 error "getstripeddir fails"
22835
22836         local stripe_count
22837         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22838                       awk '/lmv_stripe_count:/ { print $2 }')
22839
22840         [ $MDSCOUNT -ne $stripe_count ] &&
22841                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22842
22843         rm -rf $DIR/$tdir/striped_dir ||
22844                 error "unlink striped dir fails"
22845 }
22846 run_test 300r "test -1 striped directory"
22847
22848 test_300s_helper() {
22849         local count=$1
22850
22851         local stripe_dir=$DIR/$tdir/striped_dir.$count
22852
22853         $LFS mkdir -c $count $stripe_dir ||
22854                 error "lfs mkdir -c error"
22855
22856         $LFS getdirstripe $stripe_dir ||
22857                 error "lfs getdirstripe fails"
22858
22859         local stripe_count
22860         stripe_count=$($LFS getdirstripe $stripe_dir |
22861                       awk '/lmv_stripe_count:/ { print $2 }')
22862
22863         [ $count -ne $stripe_count ] &&
22864                 error_noexit "bad stripe count $stripe_count expected $count"
22865
22866         local dupe_stripes
22867         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22868                 awk '/0x/ {count[$1] += 1}; END {
22869                         for (idx in count) {
22870                                 if (count[idx]>1) {
22871                                         print "index " idx " count " count[idx]
22872                                 }
22873                         }
22874                 }')
22875
22876         if [[ -n "$dupe_stripes" ]] ; then
22877                 lfs getdirstripe $stripe_dir
22878                 error_noexit "Dupe MDT above: $dupe_stripes "
22879         fi
22880
22881         rm -rf $stripe_dir ||
22882                 error_noexit "unlink $stripe_dir fails"
22883 }
22884
22885 test_300s() {
22886         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22887                 skip "Need MDS version at least 2.7.55" && return
22888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22889
22890         mkdir $DIR/$tdir
22891         for count in $(seq 2 $MDSCOUNT); do
22892                 test_300s_helper $count
22893         done
22894 }
22895 run_test 300s "test lfs mkdir -c without -i"
22896
22897
22898 prepare_remote_file() {
22899         mkdir $DIR/$tdir/src_dir ||
22900                 error "create remote source failed"
22901
22902         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22903                  error "cp to remote source failed"
22904         touch $DIR/$tdir/src_dir/a
22905
22906         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22907                 error "create remote target dir failed"
22908
22909         touch $DIR/$tdir/tgt_dir/b
22910
22911         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22912                 error "rename dir cross MDT failed!"
22913
22914         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22915                 error "src_child still exists after rename"
22916
22917         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22918                 error "missing file(a) after rename"
22919
22920         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22921                 error "diff after rename"
22922 }
22923
22924 test_310a() {
22925         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22927
22928         local remote_file=$DIR/$tdir/tgt_dir/b
22929
22930         mkdir -p $DIR/$tdir
22931
22932         prepare_remote_file || error "prepare remote file failed"
22933
22934         #open-unlink file
22935         $OPENUNLINK $remote_file $remote_file ||
22936                 error "openunlink $remote_file failed"
22937         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22938 }
22939 run_test 310a "open unlink remote file"
22940
22941 test_310b() {
22942         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22944
22945         local remote_file=$DIR/$tdir/tgt_dir/b
22946
22947         mkdir -p $DIR/$tdir
22948
22949         prepare_remote_file || error "prepare remote file failed"
22950
22951         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22952         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22953         $CHECKSTAT -t file $remote_file || error "check file failed"
22954 }
22955 run_test 310b "unlink remote file with multiple links while open"
22956
22957 test_310c() {
22958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22959         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22960
22961         local remote_file=$DIR/$tdir/tgt_dir/b
22962
22963         mkdir -p $DIR/$tdir
22964
22965         prepare_remote_file || error "prepare remote file failed"
22966
22967         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22968         multiop_bg_pause $remote_file O_uc ||
22969                         error "mulitop failed for remote file"
22970         MULTIPID=$!
22971         $MULTIOP $DIR/$tfile Ouc
22972         kill -USR1 $MULTIPID
22973         wait $MULTIPID
22974 }
22975 run_test 310c "open-unlink remote file with multiple links"
22976
22977 #LU-4825
22978 test_311() {
22979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22980         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22981         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22982                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22983         remote_mds_nodsh && skip "remote MDS with nodsh"
22984
22985         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22986         local mdts=$(comma_list $(mdts_nodes))
22987
22988         mkdir -p $DIR/$tdir
22989         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22990         createmany -o $DIR/$tdir/$tfile. 1000
22991
22992         # statfs data is not real time, let's just calculate it
22993         old_iused=$((old_iused + 1000))
22994
22995         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22996                         osp.*OST0000*MDT0000.create_count")
22997         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22998                                 osp.*OST0000*MDT0000.max_create_count")
22999         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23000
23001         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23002         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23003         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23004
23005         unlinkmany $DIR/$tdir/$tfile. 1000
23006
23007         do_nodes $mdts "$LCTL set_param -n \
23008                         osp.*OST0000*.max_create_count=$max_count"
23009         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23010                 do_nodes $mdts "$LCTL set_param -n \
23011                                 osp.*OST0000*.create_count=$count"
23012         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23013                         grep "=0" && error "create_count is zero"
23014
23015         local new_iused
23016         for i in $(seq 120); do
23017                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23018                 # system may be too busy to destroy all objs in time, use
23019                 # a somewhat small value to not fail autotest
23020                 [ $((old_iused - new_iused)) -gt 400 ] && break
23021                 sleep 1
23022         done
23023
23024         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23025         [ $((old_iused - new_iused)) -gt 400 ] ||
23026                 error "objs not destroyed after unlink"
23027 }
23028 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23029
23030 zfs_oid_to_objid()
23031 {
23032         local ost=$1
23033         local objid=$2
23034
23035         local vdevdir=$(dirname $(facet_vdevice $ost))
23036         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23037         local zfs_zapid=$(do_facet $ost $cmd |
23038                           grep -w "/O/0/d$((objid%32))" -C 5 |
23039                           awk '/Object/{getline; print $1}')
23040         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23041                           awk "/$objid = /"'{printf $3}')
23042
23043         echo $zfs_objid
23044 }
23045
23046 zfs_object_blksz() {
23047         local ost=$1
23048         local objid=$2
23049
23050         local vdevdir=$(dirname $(facet_vdevice $ost))
23051         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23052         local blksz=$(do_facet $ost $cmd $objid |
23053                       awk '/dblk/{getline; printf $4}')
23054
23055         case "${blksz: -1}" in
23056                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23057                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23058                 *) ;;
23059         esac
23060
23061         echo $blksz
23062 }
23063
23064 test_312() { # LU-4856
23065         remote_ost_nodsh && skip "remote OST with nodsh"
23066         [ "$ost1_FSTYPE" = "zfs" ] ||
23067                 skip_env "the test only applies to zfs"
23068
23069         local max_blksz=$(do_facet ost1 \
23070                           $ZFS get -p recordsize $(facet_device ost1) |
23071                           awk '!/VALUE/{print $3}')
23072
23073         # to make life a little bit easier
23074         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23075         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23076
23077         local tf=$DIR/$tdir/$tfile
23078         touch $tf
23079         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23080
23081         # Get ZFS object id
23082         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23083         # block size change by sequential overwrite
23084         local bs
23085
23086         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23087                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23088
23089                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23090                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23091         done
23092         rm -f $tf
23093
23094         # block size change by sequential append write
23095         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23096         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23097         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23098         local count
23099
23100         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23101                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23102                         oflag=sync conv=notrunc
23103
23104                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23105                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23106                         error "blksz error, actual $blksz, " \
23107                                 "expected: 2 * $count * $PAGE_SIZE"
23108         done
23109         rm -f $tf
23110
23111         # random write
23112         touch $tf
23113         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23114         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23115
23116         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23117         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23118         [ $blksz -eq $PAGE_SIZE ] ||
23119                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23120
23121         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23122         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23123         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23124
23125         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23126         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23127         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23128 }
23129 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23130
23131 test_313() {
23132         remote_ost_nodsh && skip "remote OST with nodsh"
23133
23134         local file=$DIR/$tfile
23135
23136         rm -f $file
23137         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23138
23139         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23140         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23141         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23142                 error "write should failed"
23143         do_facet ost1 "$LCTL set_param fail_loc=0"
23144         rm -f $file
23145 }
23146 run_test 313 "io should fail after last_rcvd update fail"
23147
23148 test_314() {
23149         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23150
23151         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23152         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23153         rm -f $DIR/$tfile
23154         wait_delete_completed
23155         do_facet ost1 "$LCTL set_param fail_loc=0"
23156 }
23157 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23158
23159 test_315() { # LU-618
23160         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23161
23162         local file=$DIR/$tfile
23163         rm -f $file
23164
23165         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23166                 error "multiop file write failed"
23167         $MULTIOP $file oO_RDONLY:r4063232_c &
23168         PID=$!
23169
23170         sleep 2
23171
23172         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23173         kill -USR1 $PID
23174
23175         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23176         rm -f $file
23177 }
23178 run_test 315 "read should be accounted"
23179
23180 test_316() {
23181         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23182         large_xattr_enabled || skip_env "ea_inode feature disabled"
23183
23184         rm -rf $DIR/$tdir/d
23185         mkdir -p $DIR/$tdir/d
23186         chown nobody $DIR/$tdir/d
23187         touch $DIR/$tdir/d/file
23188
23189         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23190 }
23191 run_test 316 "lfs mv"
23192
23193 test_317() {
23194         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23195                 skip "Need MDS version at least 2.11.53"
23196         if [ "$ost1_FSTYPE" == "zfs" ]; then
23197                 skip "LU-10370: no implementation for ZFS"
23198         fi
23199
23200         local trunc_sz
23201         local grant_blk_size
23202
23203         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23204                         awk '/grant_block_size:/ { print $2; exit; }')
23205         #
23206         # Create File of size 5M. Truncate it to below size's and verify
23207         # blocks count.
23208         #
23209         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23210                 error "Create file $DIR/$tfile failed"
23211         stack_trap "rm -f $DIR/$tfile" EXIT
23212
23213         for trunc_sz in 2097152 4097 4000 509 0; do
23214                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23215                         error "truncate $tfile to $trunc_sz failed"
23216                 local sz=$(stat --format=%s $DIR/$tfile)
23217                 local blk=$(stat --format=%b $DIR/$tfile)
23218                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23219                                      grant_blk_size) * 8))
23220
23221                 if [[ $blk -ne $trunc_blk ]]; then
23222                         $(which stat) $DIR/$tfile
23223                         error "Expected Block $trunc_blk got $blk for $tfile"
23224                 fi
23225
23226                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23227                         error "Expected Size $trunc_sz got $sz for $tfile"
23228         done
23229
23230         #
23231         # sparse file test
23232         # Create file with a hole and write actual two blocks. Block count
23233         # must be 16.
23234         #
23235         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23236                 conv=fsync || error "Create file : $DIR/$tfile"
23237
23238         # Calculate the final truncate size.
23239         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23240
23241         #
23242         # truncate to size $trunc_sz bytes. Strip the last block
23243         # The block count must drop to 8
23244         #
23245         $TRUNCATE $DIR/$tfile $trunc_sz ||
23246                 error "truncate $tfile to $trunc_sz failed"
23247
23248         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23249         sz=$(stat --format=%s $DIR/$tfile)
23250         blk=$(stat --format=%b $DIR/$tfile)
23251
23252         if [[ $blk -ne $trunc_bsz ]]; then
23253                 $(which stat) $DIR/$tfile
23254                 error "Expected Block $trunc_bsz got $blk for $tfile"
23255         fi
23256
23257         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23258                 error "Expected Size $trunc_sz got $sz for $tfile"
23259 }
23260 run_test 317 "Verify blocks get correctly update after truncate"
23261
23262 test_318() {
23263         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23264         local old_max_active=$($LCTL get_param -n \
23265                             ${llite_name}.max_read_ahead_async_active \
23266                             2>/dev/null)
23267
23268         $LCTL set_param llite.*.max_read_ahead_async_active=256
23269         local max_active=$($LCTL get_param -n \
23270                            ${llite_name}.max_read_ahead_async_active \
23271                            2>/dev/null)
23272         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23273
23274         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23275                 error "set max_read_ahead_async_active should succeed"
23276
23277         $LCTL set_param llite.*.max_read_ahead_async_active=512
23278         max_active=$($LCTL get_param -n \
23279                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23280         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23281
23282         # restore @max_active
23283         [ $old_max_active -ne 0 ] && $LCTL set_param \
23284                 llite.*.max_read_ahead_async_active=$old_max_active
23285
23286         local old_threshold=$($LCTL get_param -n \
23287                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23288         local max_per_file_mb=$($LCTL get_param -n \
23289                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23290
23291         local invalid=$(($max_per_file_mb + 1))
23292         $LCTL set_param \
23293                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23294                         && error "set $invalid should fail"
23295
23296         local valid=$(($invalid - 1))
23297         $LCTL set_param \
23298                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23299                         error "set $valid should succeed"
23300         local threshold=$($LCTL get_param -n \
23301                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23302         [ $threshold -eq $valid ] || error \
23303                 "expect threshold $valid got $threshold"
23304         $LCTL set_param \
23305                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23306 }
23307 run_test 318 "Verify async readahead tunables"
23308
23309 test_319() {
23310         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23311
23312         local before=$(date +%s)
23313         local evict
23314         local mdir=$DIR/$tdir
23315         local file=$mdir/xxx
23316
23317         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23318         touch $file
23319
23320 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23321         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23322         $LFS mv -m1 $file &
23323
23324         sleep 1
23325         dd if=$file of=/dev/null
23326         wait
23327         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23328           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23329
23330         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23331 }
23332 run_test 319 "lost lease lock on migrate error"
23333
23334 test_398a() { # LU-4198
23335         local ost1_imp=$(get_osc_import_name client ost1)
23336         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23337                          cut -d'.' -f2)
23338
23339         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23340         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23341
23342         # request a new lock on client
23343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23344
23345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23346         local lock_count=$($LCTL get_param -n \
23347                            ldlm.namespaces.$imp_name.lru_size)
23348         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23349
23350         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23351
23352         # no lock cached, should use lockless IO and not enqueue new lock
23353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23354         lock_count=$($LCTL get_param -n \
23355                      ldlm.namespaces.$imp_name.lru_size)
23356         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23357 }
23358 run_test 398a "direct IO should cancel lock otherwise lockless"
23359
23360 test_398b() { # LU-4198
23361         which fio || skip_env "no fio installed"
23362         $LFS setstripe -c -1 $DIR/$tfile
23363
23364         local size=12
23365         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23366
23367         local njobs=4
23368         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23369         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23370                 --numjobs=$njobs --fallocate=none \
23371                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23372                 --filename=$DIR/$tfile &
23373         bg_pid=$!
23374
23375         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23376         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23377                 --numjobs=$njobs --fallocate=none \
23378                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23379                 --filename=$DIR/$tfile || true
23380         wait $bg_pid
23381
23382         rm -f $DIR/$tfile
23383 }
23384 run_test 398b "DIO and buffer IO race"
23385
23386 test_398c() { # LU-4198
23387         local ost1_imp=$(get_osc_import_name client ost1)
23388         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23389                          cut -d'.' -f2)
23390
23391         which fio || skip_env "no fio installed"
23392
23393         saved_debug=$($LCTL get_param -n debug)
23394         $LCTL set_param debug=0
23395
23396         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23397         ((size /= 1024)) # by megabytes
23398         ((size /= 2)) # write half of the OST at most
23399         [ $size -gt 40 ] && size=40 #reduce test time anyway
23400
23401         $LFS setstripe -c 1 $DIR/$tfile
23402
23403         # it seems like ldiskfs reserves more space than necessary if the
23404         # writing blocks are not mapped, so it extends the file firstly
23405         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23406         cancel_lru_locks osc
23407
23408         # clear and verify rpc_stats later
23409         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23410
23411         local njobs=4
23412         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23413         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23414                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23415                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23416                 --filename=$DIR/$tfile
23417         [ $? -eq 0 ] || error "fio write error"
23418
23419         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23420                 error "Locks were requested while doing AIO"
23421
23422         # get the percentage of 1-page I/O
23423         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23424                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23425                 awk '{print $7}')
23426         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23427
23428         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23429         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23430                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23431                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23432                 --filename=$DIR/$tfile
23433         [ $? -eq 0 ] || error "fio mixed read write error"
23434
23435         echo "AIO with large block size ${size}M"
23436         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23437                 --numjobs=1 --fallocate=none --ioengine=libaio \
23438                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23439                 --filename=$DIR/$tfile
23440         [ $? -eq 0 ] || error "fio large block size failed"
23441
23442         rm -f $DIR/$tfile
23443         $LCTL set_param debug="$saved_debug"
23444 }
23445 run_test 398c "run fio to test AIO"
23446
23447 test_398d() { #  LU-13846
23448         which aiocp || skip_env "no aiocp installed"
23449         local aio_file=$DIR/$tfile.aio
23450
23451         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23452
23453         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23454         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23455         stack_trap "rm -f $DIR/$tfile $aio_file"
23456
23457         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23458
23459         # make sure we don't crash and fail properly
23460         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23461                 error "aio not aligned with PAGE SIZE should fail"
23462
23463         rm -f $DIR/$tfile $aio_file
23464 }
23465 run_test 398d "run aiocp to verify block size > stripe size"
23466
23467 test_398e() {
23468         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23469         touch $DIR/$tfile.new
23470         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23471 }
23472 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23473
23474 test_398f() { #  LU-14687
23475         which aiocp || skip_env "no aiocp installed"
23476         local aio_file=$DIR/$tfile.aio
23477
23478         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23479
23480         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23481         stack_trap "rm -f $DIR/$tfile $aio_file"
23482
23483         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23484         $LCTL set_param fail_loc=0x1418
23485         # make sure we don't crash and fail properly
23486         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23487                 error "aio with page allocation failure succeeded"
23488         $LCTL set_param fail_loc=0
23489         diff $DIR/$tfile $aio_file
23490         [[ $? != 0 ]] || error "no diff after failed aiocp"
23491 }
23492 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23493
23494 test_fake_rw() {
23495         local read_write=$1
23496         if [ "$read_write" = "write" ]; then
23497                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23498         elif [ "$read_write" = "read" ]; then
23499                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23500         else
23501                 error "argument error"
23502         fi
23503
23504         # turn off debug for performance testing
23505         local saved_debug=$($LCTL get_param -n debug)
23506         $LCTL set_param debug=0
23507
23508         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23509
23510         # get ost1 size - $FSNAME-OST0000
23511         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23512         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23513         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23514
23515         if [ "$read_write" = "read" ]; then
23516                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23517         fi
23518
23519         local start_time=$(date +%s.%N)
23520         $dd_cmd bs=1M count=$blocks oflag=sync ||
23521                 error "real dd $read_write error"
23522         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23523
23524         if [ "$read_write" = "write" ]; then
23525                 rm -f $DIR/$tfile
23526         fi
23527
23528         # define OBD_FAIL_OST_FAKE_RW           0x238
23529         do_facet ost1 $LCTL set_param fail_loc=0x238
23530
23531         local start_time=$(date +%s.%N)
23532         $dd_cmd bs=1M count=$blocks oflag=sync ||
23533                 error "fake dd $read_write error"
23534         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23535
23536         if [ "$read_write" = "write" ]; then
23537                 # verify file size
23538                 cancel_lru_locks osc
23539                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23540                         error "$tfile size not $blocks MB"
23541         fi
23542         do_facet ost1 $LCTL set_param fail_loc=0
23543
23544         echo "fake $read_write $duration_fake vs. normal $read_write" \
23545                 "$duration in seconds"
23546         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23547                 error_not_in_vm "fake write is slower"
23548
23549         $LCTL set_param -n debug="$saved_debug"
23550         rm -f $DIR/$tfile
23551 }
23552 test_399a() { # LU-7655 for OST fake write
23553         remote_ost_nodsh && skip "remote OST with nodsh"
23554
23555         test_fake_rw write
23556 }
23557 run_test 399a "fake write should not be slower than normal write"
23558
23559 test_399b() { # LU-8726 for OST fake read
23560         remote_ost_nodsh && skip "remote OST with nodsh"
23561         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23562                 skip_env "ldiskfs only test"
23563         fi
23564
23565         test_fake_rw read
23566 }
23567 run_test 399b "fake read should not be slower than normal read"
23568
23569 test_400a() { # LU-1606, was conf-sanity test_74
23570         if ! which $CC > /dev/null 2>&1; then
23571                 skip_env "$CC is not installed"
23572         fi
23573
23574         local extra_flags=''
23575         local out=$TMP/$tfile
23576         local prefix=/usr/include/lustre
23577         local prog
23578
23579         # Oleg removes c files in his test rig so test if any c files exist
23580         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23581                 skip_env "Needed c test files are missing"
23582
23583         if ! [[ -d $prefix ]]; then
23584                 # Assume we're running in tree and fixup the include path.
23585                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23586                 extra_flags+=" -L$LUSTRE/utils/.lib"
23587         fi
23588
23589         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23590                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23591                         error "client api broken"
23592         done
23593         rm -f $out
23594 }
23595 run_test 400a "Lustre client api program can compile and link"
23596
23597 test_400b() { # LU-1606, LU-5011
23598         local header
23599         local out=$TMP/$tfile
23600         local prefix=/usr/include/linux/lustre
23601
23602         # We use a hard coded prefix so that this test will not fail
23603         # when run in tree. There are headers in lustre/include/lustre/
23604         # that are not packaged (like lustre_idl.h) and have more
23605         # complicated include dependencies (like config.h and lnet/types.h).
23606         # Since this test about correct packaging we just skip them when
23607         # they don't exist (see below) rather than try to fixup cppflags.
23608
23609         if ! which $CC > /dev/null 2>&1; then
23610                 skip_env "$CC is not installed"
23611         fi
23612
23613         for header in $prefix/*.h; do
23614                 if ! [[ -f "$header" ]]; then
23615                         continue
23616                 fi
23617
23618                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23619                         continue # lustre_ioctl.h is internal header
23620                 fi
23621
23622                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23623                         error "cannot compile '$header'"
23624         done
23625         rm -f $out
23626 }
23627 run_test 400b "packaged headers can be compiled"
23628
23629 test_401a() { #LU-7437
23630         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23631         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23632
23633         #count the number of parameters by "list_param -R"
23634         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23635         #count the number of parameters by listing proc files
23636         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23637         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23638         echo "proc_dirs='$proc_dirs'"
23639         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23640         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23641                       sort -u | wc -l)
23642
23643         [ $params -eq $procs ] ||
23644                 error "found $params parameters vs. $procs proc files"
23645
23646         # test the list_param -D option only returns directories
23647         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23648         #count the number of parameters by listing proc directories
23649         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23650                 sort -u | wc -l)
23651
23652         [ $params -eq $procs ] ||
23653                 error "found $params parameters vs. $procs proc files"
23654 }
23655 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23656
23657 test_401b() {
23658         # jobid_var may not allow arbitrary values, so use jobid_name
23659         # if available
23660         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23661                 local testname=jobid_name tmp='testing%p'
23662         else
23663                 local testname=jobid_var tmp=testing
23664         fi
23665
23666         local save=$($LCTL get_param -n $testname)
23667
23668         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23669                 error "no error returned when setting bad parameters"
23670
23671         local jobid_new=$($LCTL get_param -n foe $testname baz)
23672         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23673
23674         $LCTL set_param -n fog=bam $testname=$save bat=fog
23675         local jobid_old=$($LCTL get_param -n foe $testname bag)
23676         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23677 }
23678 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23679
23680 test_401c() {
23681         # jobid_var may not allow arbitrary values, so use jobid_name
23682         # if available
23683         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23684                 local testname=jobid_name
23685         else
23686                 local testname=jobid_var
23687         fi
23688
23689         local jobid_var_old=$($LCTL get_param -n $testname)
23690         local jobid_var_new
23691
23692         $LCTL set_param $testname= &&
23693                 error "no error returned for 'set_param a='"
23694
23695         jobid_var_new=$($LCTL get_param -n $testname)
23696         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23697                 error "$testname was changed by setting without value"
23698
23699         $LCTL set_param $testname &&
23700                 error "no error returned for 'set_param a'"
23701
23702         jobid_var_new=$($LCTL get_param -n $testname)
23703         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23704                 error "$testname was changed by setting without value"
23705 }
23706 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23707
23708 test_401d() {
23709         # jobid_var may not allow arbitrary values, so use jobid_name
23710         # if available
23711         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23712                 local testname=jobid_name new_value='foo=bar%p'
23713         else
23714                 local testname=jobid_var new_valuie=foo=bar
23715         fi
23716
23717         local jobid_var_old=$($LCTL get_param -n $testname)
23718         local jobid_var_new
23719
23720         $LCTL set_param $testname=$new_value ||
23721                 error "'set_param a=b' did not accept a value containing '='"
23722
23723         jobid_var_new=$($LCTL get_param -n $testname)
23724         [[ "$jobid_var_new" == "$new_value" ]] ||
23725                 error "'set_param a=b' failed on a value containing '='"
23726
23727         # Reset the $testname to test the other format
23728         $LCTL set_param $testname=$jobid_var_old
23729         jobid_var_new=$($LCTL get_param -n $testname)
23730         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23731                 error "failed to reset $testname"
23732
23733         $LCTL set_param $testname $new_value ||
23734                 error "'set_param a b' did not accept a value containing '='"
23735
23736         jobid_var_new=$($LCTL get_param -n $testname)
23737         [[ "$jobid_var_new" == "$new_value" ]] ||
23738                 error "'set_param a b' failed on a value containing '='"
23739
23740         $LCTL set_param $testname $jobid_var_old
23741         jobid_var_new=$($LCTL get_param -n $testname)
23742         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23743                 error "failed to reset $testname"
23744 }
23745 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23746
23747 test_402() {
23748         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23749         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23750                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23751         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23752                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23753                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23754         remote_mds_nodsh && skip "remote MDS with nodsh"
23755
23756         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23757 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23758         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23759         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23760                 echo "Touch failed - OK"
23761 }
23762 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23763
23764 test_403() {
23765         local file1=$DIR/$tfile.1
23766         local file2=$DIR/$tfile.2
23767         local tfile=$TMP/$tfile
23768
23769         rm -f $file1 $file2 $tfile
23770
23771         touch $file1
23772         ln $file1 $file2
23773
23774         # 30 sec OBD_TIMEOUT in ll_getattr()
23775         # right before populating st_nlink
23776         $LCTL set_param fail_loc=0x80001409
23777         stat -c %h $file1 > $tfile &
23778
23779         # create an alias, drop all locks and reclaim the dentry
23780         < $file2
23781         cancel_lru_locks mdc
23782         cancel_lru_locks osc
23783         sysctl -w vm.drop_caches=2
23784
23785         wait
23786
23787         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23788
23789         rm -f $tfile $file1 $file2
23790 }
23791 run_test 403 "i_nlink should not drop to zero due to aliasing"
23792
23793 test_404() { # LU-6601
23794         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23795                 skip "Need server version newer than 2.8.52"
23796         remote_mds_nodsh && skip "remote MDS with nodsh"
23797
23798         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23799                 awk '/osp .*-osc-MDT/ { print $4}')
23800
23801         local osp
23802         for osp in $mosps; do
23803                 echo "Deactivate: " $osp
23804                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23805                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23806                         awk -vp=$osp '$4 == p { print $2 }')
23807                 [ $stat = IN ] || {
23808                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23809                         error "deactivate error"
23810                 }
23811                 echo "Activate: " $osp
23812                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23813                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23814                         awk -vp=$osp '$4 == p { print $2 }')
23815                 [ $stat = UP ] || {
23816                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23817                         error "activate error"
23818                 }
23819         done
23820 }
23821 run_test 404 "validate manual {de}activated works properly for OSPs"
23822
23823 test_405() {
23824         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23825         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23826                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23827                         skip "Layout swap lock is not supported"
23828
23829         check_swap_layouts_support
23830         check_swap_layout_no_dom $DIR
23831
23832         test_mkdir $DIR/$tdir
23833         swap_lock_test -d $DIR/$tdir ||
23834                 error "One layout swap locked test failed"
23835 }
23836 run_test 405 "Various layout swap lock tests"
23837
23838 test_406() {
23839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23840         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23841         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23843         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23844                 skip "Need MDS version at least 2.8.50"
23845
23846         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23847         local test_pool=$TESTNAME
23848
23849         pool_add $test_pool || error "pool_add failed"
23850         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23851                 error "pool_add_targets failed"
23852
23853         save_layout_restore_at_exit $MOUNT
23854
23855         # parent set default stripe count only, child will stripe from both
23856         # parent and fs default
23857         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23858                 error "setstripe $MOUNT failed"
23859         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23860         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23861         for i in $(seq 10); do
23862                 local f=$DIR/$tdir/$tfile.$i
23863                 touch $f || error "touch failed"
23864                 local count=$($LFS getstripe -c $f)
23865                 [ $count -eq $OSTCOUNT ] ||
23866                         error "$f stripe count $count != $OSTCOUNT"
23867                 local offset=$($LFS getstripe -i $f)
23868                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23869                 local size=$($LFS getstripe -S $f)
23870                 [ $size -eq $((def_stripe_size * 2)) ] ||
23871                         error "$f stripe size $size != $((def_stripe_size * 2))"
23872                 local pool=$($LFS getstripe -p $f)
23873                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23874         done
23875
23876         # change fs default striping, delete parent default striping, now child
23877         # will stripe from new fs default striping only
23878         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23879                 error "change $MOUNT default stripe failed"
23880         $LFS setstripe -c 0 $DIR/$tdir ||
23881                 error "delete $tdir default stripe failed"
23882         for i in $(seq 11 20); do
23883                 local f=$DIR/$tdir/$tfile.$i
23884                 touch $f || error "touch $f failed"
23885                 local count=$($LFS getstripe -c $f)
23886                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23887                 local offset=$($LFS getstripe -i $f)
23888                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23889                 local size=$($LFS getstripe -S $f)
23890                 [ $size -eq $def_stripe_size ] ||
23891                         error "$f stripe size $size != $def_stripe_size"
23892                 local pool=$($LFS getstripe -p $f)
23893                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23894         done
23895
23896         unlinkmany $DIR/$tdir/$tfile. 1 20
23897
23898         local f=$DIR/$tdir/$tfile
23899         pool_remove_all_targets $test_pool $f
23900         pool_remove $test_pool $f
23901 }
23902 run_test 406 "DNE support fs default striping"
23903
23904 test_407() {
23905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23906         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23907                 skip "Need MDS version at least 2.8.55"
23908         remote_mds_nodsh && skip "remote MDS with nodsh"
23909
23910         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23911                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23912         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23913                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23914         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23915
23916         #define OBD_FAIL_DT_TXN_STOP    0x2019
23917         for idx in $(seq $MDSCOUNT); do
23918                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23919         done
23920         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23921         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23922                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23923         true
23924 }
23925 run_test 407 "transaction fail should cause operation fail"
23926
23927 test_408() {
23928         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23929
23930         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23931         lctl set_param fail_loc=0x8000040a
23932         # let ll_prepare_partial_page() fail
23933         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23934
23935         rm -f $DIR/$tfile
23936
23937         # create at least 100 unused inodes so that
23938         # shrink_icache_memory(0) should not return 0
23939         touch $DIR/$tfile-{0..100}
23940         rm -f $DIR/$tfile-{0..100}
23941         sync
23942
23943         echo 2 > /proc/sys/vm/drop_caches
23944 }
23945 run_test 408 "drop_caches should not hang due to page leaks"
23946
23947 test_409()
23948 {
23949         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23950
23951         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23952         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23953         touch $DIR/$tdir/guard || error "(2) Fail to create"
23954
23955         local PREFIX=$(str_repeat 'A' 128)
23956         echo "Create 1K hard links start at $(date)"
23957         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23958                 error "(3) Fail to hard link"
23959
23960         echo "Links count should be right although linkEA overflow"
23961         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23962         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23963         [ $linkcount -eq 1001 ] ||
23964                 error "(5) Unexpected hard links count: $linkcount"
23965
23966         echo "List all links start at $(date)"
23967         ls -l $DIR/$tdir/foo > /dev/null ||
23968                 error "(6) Fail to list $DIR/$tdir/foo"
23969
23970         echo "Unlink hard links start at $(date)"
23971         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23972                 error "(7) Fail to unlink"
23973         echo "Unlink hard links finished at $(date)"
23974 }
23975 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23976
23977 test_410()
23978 {
23979         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23980                 skip "Need client version at least 2.9.59"
23981         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23982                 skip "Need MODULES build"
23983
23984         # Create a file, and stat it from the kernel
23985         local testfile=$DIR/$tfile
23986         touch $testfile
23987
23988         local run_id=$RANDOM
23989         local my_ino=$(stat --format "%i" $testfile)
23990
23991         # Try to insert the module. This will always fail as the
23992         # module is designed to not be inserted.
23993         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23994             &> /dev/null
23995
23996         # Anything but success is a test failure
23997         dmesg | grep -q \
23998             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23999             error "no inode match"
24000 }
24001 run_test 410 "Test inode number returned from kernel thread"
24002
24003 cleanup_test411_cgroup() {
24004         trap 0
24005         rmdir "$1"
24006 }
24007
24008 test_411() {
24009         local cg_basedir=/sys/fs/cgroup/memory
24010         # LU-9966
24011         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24012                 skip "no setup for cgroup"
24013
24014         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24015                 error "test file creation failed"
24016         cancel_lru_locks osc
24017
24018         # Create a very small memory cgroup to force a slab allocation error
24019         local cgdir=$cg_basedir/osc_slab_alloc
24020         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24021         trap "cleanup_test411_cgroup $cgdir" EXIT
24022         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24023         echo 1M > $cgdir/memory.limit_in_bytes
24024
24025         # Should not LBUG, just be killed by oom-killer
24026         # dd will return 0 even allocation failure in some environment.
24027         # So don't check return value
24028         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24029         cleanup_test411_cgroup $cgdir
24030
24031         return 0
24032 }
24033 run_test 411 "Slab allocation error with cgroup does not LBUG"
24034
24035 test_412() {
24036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24037         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24038                 skip "Need server version at least 2.10.55"
24039         fi
24040
24041         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24042                 error "mkdir failed"
24043         $LFS getdirstripe $DIR/$tdir
24044         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24045         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24046                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24047         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24048         [ $stripe_count -eq 2 ] ||
24049                 error "expect 2 get $stripe_count"
24050 }
24051 run_test 412 "mkdir on specific MDTs"
24052
24053 test_qos_mkdir() {
24054         local mkdir_cmd=$1
24055         local stripe_count=$2
24056         local mdts=$(comma_list $(mdts_nodes))
24057
24058         local testdir
24059         local lmv_qos_prio_free
24060         local lmv_qos_threshold_rr
24061         local lmv_qos_maxage
24062         local lod_qos_prio_free
24063         local lod_qos_threshold_rr
24064         local lod_qos_maxage
24065         local count
24066         local i
24067
24068         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24069         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24070         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24071                 head -n1)
24072         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24073         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24074         stack_trap "$LCTL set_param \
24075                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24076         stack_trap "$LCTL set_param \
24077                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24078         stack_trap "$LCTL set_param \
24079                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24080
24081         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24082                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24083         lod_qos_prio_free=${lod_qos_prio_free%%%}
24084         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24085                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24086         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24087         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24088                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24089         stack_trap "do_nodes $mdts $LCTL set_param \
24090                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24091         stack_trap "do_nodes $mdts $LCTL set_param \
24092                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24093                 EXIT
24094         stack_trap "do_nodes $mdts $LCTL set_param \
24095                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24096
24097         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24098         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24099
24100         testdir=$DIR/$tdir-s$stripe_count/rr
24101
24102         local stripe_index=$($LFS getstripe -m $testdir)
24103         local test_mkdir_rr=true
24104
24105         getfattr -d -m dmv $testdir | grep dmv
24106         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24107                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24108
24109                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24110         fi
24111
24112         echo
24113         $test_mkdir_rr &&
24114                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24115                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24116
24117         for i in $(seq $((100 * MDSCOUNT))); do
24118                 eval $mkdir_cmd $testdir/subdir$i ||
24119                         error "$mkdir_cmd subdir$i failed"
24120         done
24121
24122         for i in $(seq $MDSCOUNT); do
24123                 count=$($LFS getdirstripe -i $testdir/* |
24124                                 grep ^$((i - 1))$ | wc -l)
24125                 echo "$count directories created on MDT$((i - 1))"
24126                 if $test_mkdir_rr; then
24127                         (( $count == 100 )) ||
24128                                 error "subdirs are not evenly distributed"
24129                 elif [ $((i - 1)) -eq $stripe_index ]; then
24130                         (( $count == 100 * MDSCOUNT )) ||
24131                                 error "$count subdirs created on MDT$((i - 1))"
24132                 else
24133                         (( $count == 0 )) ||
24134                                 error "$count subdirs created on MDT$((i - 1))"
24135                 fi
24136
24137                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24138                         count=$($LFS getdirstripe $testdir/* |
24139                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24140                         echo "$count stripes created on MDT$((i - 1))"
24141                         # deviation should < 5% of average
24142                         (( $count < 95 * stripe_count )) ||
24143                         (( $count > 105 * stripe_count)) &&
24144                                 error "stripes are not evenly distributed"
24145                 fi
24146         done
24147
24148         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24149         do_nodes $mdts $LCTL set_param \
24150                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24151
24152         echo
24153         echo "Check for uneven MDTs: "
24154
24155         local ffree
24156         local bavail
24157         local max
24158         local min
24159         local max_index
24160         local min_index
24161         local tmp
24162
24163         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24164         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24165         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24166
24167         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24168         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24169         max_index=0
24170         min_index=0
24171         for ((i = 1; i < ${#ffree[@]}; i++)); do
24172                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24173                 if [ $tmp -gt $max ]; then
24174                         max=$tmp
24175                         max_index=$i
24176                 fi
24177                 if [ $tmp -lt $min ]; then
24178                         min=$tmp
24179                         min_index=$i
24180                 fi
24181         done
24182
24183         (( ${ffree[min_index]} == 0 )) &&
24184                 skip "no free files in MDT$min_index"
24185         (( ${ffree[min_index]} > 100000000 )) &&
24186                 skip "too many free files in MDT$min_index"
24187
24188         # Check if we need to generate uneven MDTs
24189         local threshold=50
24190         local diff=$(((max - min) * 100 / min))
24191         local value="$(generate_string 1024)"
24192
24193         while [ $diff -lt $threshold ]; do
24194                 # generate uneven MDTs, create till $threshold% diff
24195                 echo -n "weight diff=$diff% must be > $threshold% ..."
24196                 count=$((${ffree[min_index]} / 10))
24197                 # 50 sec per 10000 files in vm
24198                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24199                         skip "$count files to create"
24200                 echo "Fill MDT$min_index with $count files"
24201                 [ -d $DIR/$tdir-MDT$min_index ] ||
24202                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24203                         error "mkdir $tdir-MDT$min_index failed"
24204                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24205                         error "create d$count failed"
24206
24207                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24208                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24209                 max=$(((${ffree[max_index]} >> 8) * \
24210                         (${bavail[max_index]} * bsize >> 16)))
24211                 min=$(((${ffree[min_index]} >> 8) * \
24212                         (${bavail[min_index]} * bsize >> 16)))
24213                 diff=$(((max - min) * 100 / min))
24214         done
24215
24216         echo "MDT filesfree available: ${ffree[@]}"
24217         echo "MDT blocks available: ${bavail[@]}"
24218         echo "weight diff=$diff%"
24219
24220         echo
24221         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24222
24223         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24224         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24225         # decrease statfs age, so that it can be updated in time
24226         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24227         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24228
24229         sleep 1
24230
24231         testdir=$DIR/$tdir-s$stripe_count/qos
24232
24233         for i in $(seq $((100 * MDSCOUNT))); do
24234                 eval $mkdir_cmd $testdir/subdir$i ||
24235                         error "$mkdir_cmd subdir$i failed"
24236         done
24237
24238         for i in $(seq $MDSCOUNT); do
24239                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24240                         wc -l)
24241                 echo "$count directories created on MDT$((i - 1))"
24242
24243                 if [ $stripe_count -gt 1 ]; then
24244                         count=$($LFS getdirstripe $testdir/* |
24245                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24246                         echo "$count stripes created on MDT$((i - 1))"
24247                 fi
24248         done
24249
24250         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24251         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24252
24253         # D-value should > 10% of averge
24254         (( $max - $min < 10 )) &&
24255                 error "subdirs shouldn't be evenly distributed"
24256
24257         # ditto
24258         if [ $stripe_count -gt 1 ]; then
24259                 max=$($LFS getdirstripe $testdir/* |
24260                         grep -P "^\s+$max_index\t" | wc -l)
24261                 min=$($LFS getdirstripe $testdir/* |
24262                         grep -P "^\s+$min_index\t" | wc -l)
24263                 (( $max - $min < 10 * $stripe_count )) &&
24264                         error "stripes shouldn't be evenly distributed"|| true
24265         fi
24266 }
24267
24268 test_413a() {
24269         [ $MDSCOUNT -lt 2 ] &&
24270                 skip "We need at least 2 MDTs for this test"
24271
24272         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24273                 skip "Need server version at least 2.12.52"
24274
24275         local stripe_count
24276
24277         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24278                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24279                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24280                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24281                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24282         done
24283 }
24284 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24285
24286 test_413b() {
24287         [ $MDSCOUNT -lt 2 ] &&
24288                 skip "We need at least 2 MDTs for this test"
24289
24290         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24291                 skip "Need server version at least 2.12.52"
24292
24293         local testdir
24294         local stripe_count
24295
24296         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24297                 testdir=$DIR/$tdir-s$stripe_count
24298                 mkdir $testdir || error "mkdir $testdir failed"
24299                 mkdir $testdir/rr || error "mkdir rr failed"
24300                 mkdir $testdir/qos || error "mkdir qos failed"
24301                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24302                         $testdir/rr || error "setdirstripe rr failed"
24303                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24304                         error "setdirstripe failed"
24305                 test_qos_mkdir "mkdir" $stripe_count
24306         done
24307 }
24308 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24309
24310 test_413c() {
24311         [ $MDSCOUNT -ge 2 ] ||
24312                 skip "We need at least 2 MDTs for this test"
24313
24314         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24315                 skip "Need server version at least 2.14.50"
24316
24317         local testdir
24318         local inherit
24319         local inherit_rr
24320
24321         testdir=$DIR/${tdir}-s1
24322         mkdir $testdir || error "mkdir $testdir failed"
24323         mkdir $testdir/rr || error "mkdir rr failed"
24324         mkdir $testdir/qos || error "mkdir qos failed"
24325         # default max_inherit is -1, default max_inherit_rr is 0
24326         $LFS setdirstripe -D -c 1 $testdir/rr ||
24327                 error "setdirstripe rr failed"
24328         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24329                 error "setdirstripe qos failed"
24330         test_qos_mkdir "mkdir" 1
24331
24332         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24333         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24334         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24335         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24336         (( $inherit_rr == 0 )) ||
24337                 error "rr/level1 inherit-rr $inherit_rr != 0"
24338
24339         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24340         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24341         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24342         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24343         (( $inherit_rr == 0 )) ||
24344                 error "qos/level1 inherit-rr $inherit_rr !=0"
24345         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24346         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24347                 error "level2 shouldn't have default LMV" || true
24348 }
24349 run_test 413c "mkdir with default LMV max inherit rr"
24350
24351 test_414() {
24352 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24353         $LCTL set_param fail_loc=0x80000521
24354         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24355         rm -f $DIR/$tfile
24356 }
24357 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24358
24359 test_415() {
24360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24361         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24362                 skip "Need server version at least 2.11.52"
24363
24364         # LU-11102
24365         local total
24366         local setattr_pid
24367         local start_time
24368         local end_time
24369         local duration
24370
24371         total=500
24372         # this test may be slow on ZFS
24373         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24374
24375         # though this test is designed for striped directory, let's test normal
24376         # directory too since lock is always saved as CoS lock.
24377         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24378         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24379
24380         (
24381                 while true; do
24382                         touch $DIR/$tdir
24383                 done
24384         ) &
24385         setattr_pid=$!
24386
24387         start_time=$(date +%s)
24388         for i in $(seq $total); do
24389                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24390                         > /dev/null
24391         done
24392         end_time=$(date +%s)
24393         duration=$((end_time - start_time))
24394
24395         kill -9 $setattr_pid
24396
24397         echo "rename $total files took $duration sec"
24398         [ $duration -lt 100 ] || error "rename took $duration sec"
24399 }
24400 run_test 415 "lock revoke is not missing"
24401
24402 test_416() {
24403         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24404                 skip "Need server version at least 2.11.55"
24405
24406         # define OBD_FAIL_OSD_TXN_START    0x19a
24407         do_facet mds1 lctl set_param fail_loc=0x19a
24408
24409         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24410
24411         true
24412 }
24413 run_test 416 "transaction start failure won't cause system hung"
24414
24415 cleanup_417() {
24416         trap 0
24417         do_nodes $(comma_list $(mdts_nodes)) \
24418                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24419         do_nodes $(comma_list $(mdts_nodes)) \
24420                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24421         do_nodes $(comma_list $(mdts_nodes)) \
24422                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24423 }
24424
24425 test_417() {
24426         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24427         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24428                 skip "Need MDS version at least 2.11.56"
24429
24430         trap cleanup_417 RETURN EXIT
24431
24432         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24433         do_nodes $(comma_list $(mdts_nodes)) \
24434                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24435         $LFS migrate -m 0 $DIR/$tdir.1 &&
24436                 error "migrate dir $tdir.1 should fail"
24437
24438         do_nodes $(comma_list $(mdts_nodes)) \
24439                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24440         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24441                 error "create remote dir $tdir.2 should fail"
24442
24443         do_nodes $(comma_list $(mdts_nodes)) \
24444                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24445         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24446                 error "create striped dir $tdir.3 should fail"
24447         true
24448 }
24449 run_test 417 "disable remote dir, striped dir and dir migration"
24450
24451 # Checks that the outputs of df [-i] and lfs df [-i] match
24452 #
24453 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24454 check_lfs_df() {
24455         local dir=$2
24456         local inodes
24457         local df_out
24458         local lfs_df_out
24459         local count
24460         local passed=false
24461
24462         # blocks or inodes
24463         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24464
24465         for count in {1..100}; do
24466                 cancel_lru_locks
24467                 sync; sleep 0.2
24468
24469                 # read the lines of interest
24470                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24471                         error "df $inodes $dir | tail -n +2 failed"
24472                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24473                         error "lfs df $inodes $dir | grep summary: failed"
24474
24475                 # skip first substrings of each output as they are different
24476                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24477                 # compare the two outputs
24478                 passed=true
24479                 for i in {1..5}; do
24480                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24481                 done
24482                 $passed && break
24483         done
24484
24485         if ! $passed; then
24486                 df -P $inodes $dir
24487                 echo
24488                 lfs df $inodes $dir
24489                 error "df and lfs df $1 output mismatch: "      \
24490                       "df ${inodes}: ${df_out[*]}, "            \
24491                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24492         fi
24493 }
24494
24495 test_418() {
24496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24497
24498         local dir=$DIR/$tdir
24499         local numfiles=$((RANDOM % 4096 + 2))
24500         local numblocks=$((RANDOM % 256 + 1))
24501
24502         wait_delete_completed
24503         test_mkdir $dir
24504
24505         # check block output
24506         check_lfs_df blocks $dir
24507         # check inode output
24508         check_lfs_df inodes $dir
24509
24510         # create a single file and retest
24511         echo "Creating a single file and testing"
24512         createmany -o $dir/$tfile- 1 &>/dev/null ||
24513                 error "creating 1 file in $dir failed"
24514         check_lfs_df blocks $dir
24515         check_lfs_df inodes $dir
24516
24517         # create a random number of files
24518         echo "Creating $((numfiles - 1)) files and testing"
24519         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24520                 error "creating $((numfiles - 1)) files in $dir failed"
24521
24522         # write a random number of blocks to the first test file
24523         echo "Writing $numblocks 4K blocks and testing"
24524         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24525                 count=$numblocks &>/dev/null ||
24526                 error "dd to $dir/${tfile}-0 failed"
24527
24528         # retest
24529         check_lfs_df blocks $dir
24530         check_lfs_df inodes $dir
24531
24532         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24533                 error "unlinking $numfiles files in $dir failed"
24534 }
24535 run_test 418 "df and lfs df outputs match"
24536
24537 test_419()
24538 {
24539         local dir=$DIR/$tdir
24540
24541         mkdir -p $dir
24542         touch $dir/file
24543
24544         cancel_lru_locks mdc
24545
24546         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24547         $LCTL set_param fail_loc=0x1410
24548         cat $dir/file
24549         $LCTL set_param fail_loc=0
24550         rm -rf $dir
24551 }
24552 run_test 419 "Verify open file by name doesn't crash kernel"
24553
24554 test_420()
24555 {
24556         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24557                 skip "Need MDS version at least 2.12.53"
24558
24559         local SAVE_UMASK=$(umask)
24560         local dir=$DIR/$tdir
24561         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24562
24563         mkdir -p $dir
24564         umask 0000
24565         mkdir -m03777 $dir/testdir
24566         ls -dn $dir/testdir
24567         # Need to remove trailing '.' when SELinux is enabled
24568         local dirperms=$(ls -dn $dir/testdir |
24569                          awk '{ sub(/\.$/, "", $1); print $1}')
24570         [ $dirperms == "drwxrwsrwt" ] ||
24571                 error "incorrect perms on $dir/testdir"
24572
24573         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24574                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24575         ls -n $dir/testdir/testfile
24576         local fileperms=$(ls -n $dir/testdir/testfile |
24577                           awk '{ sub(/\.$/, "", $1); print $1}')
24578         [ $fileperms == "-rwxr-xr-x" ] ||
24579                 error "incorrect perms on $dir/testdir/testfile"
24580
24581         umask $SAVE_UMASK
24582 }
24583 run_test 420 "clear SGID bit on non-directories for non-members"
24584
24585 test_421a() {
24586         local cnt
24587         local fid1
24588         local fid2
24589
24590         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24591                 skip "Need MDS version at least 2.12.54"
24592
24593         test_mkdir $DIR/$tdir
24594         createmany -o $DIR/$tdir/f 3
24595         cnt=$(ls -1 $DIR/$tdir | wc -l)
24596         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24597
24598         fid1=$(lfs path2fid $DIR/$tdir/f1)
24599         fid2=$(lfs path2fid $DIR/$tdir/f2)
24600         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24601
24602         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24603         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24604
24605         cnt=$(ls -1 $DIR/$tdir | wc -l)
24606         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24607
24608         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24609         createmany -o $DIR/$tdir/f 3
24610         cnt=$(ls -1 $DIR/$tdir | wc -l)
24611         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24612
24613         fid1=$(lfs path2fid $DIR/$tdir/f1)
24614         fid2=$(lfs path2fid $DIR/$tdir/f2)
24615         echo "remove using fsname $FSNAME"
24616         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24617
24618         cnt=$(ls -1 $DIR/$tdir | wc -l)
24619         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24620 }
24621 run_test 421a "simple rm by fid"
24622
24623 test_421b() {
24624         local cnt
24625         local FID1
24626         local FID2
24627
24628         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24629                 skip "Need MDS version at least 2.12.54"
24630
24631         test_mkdir $DIR/$tdir
24632         createmany -o $DIR/$tdir/f 3
24633         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24634         MULTIPID=$!
24635
24636         FID1=$(lfs path2fid $DIR/$tdir/f1)
24637         FID2=$(lfs path2fid $DIR/$tdir/f2)
24638         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24639
24640         kill -USR1 $MULTIPID
24641         wait
24642
24643         cnt=$(ls $DIR/$tdir | wc -l)
24644         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24645 }
24646 run_test 421b "rm by fid on open file"
24647
24648 test_421c() {
24649         local cnt
24650         local FIDS
24651
24652         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24653                 skip "Need MDS version at least 2.12.54"
24654
24655         test_mkdir $DIR/$tdir
24656         createmany -o $DIR/$tdir/f 3
24657         touch $DIR/$tdir/$tfile
24658         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24659         cnt=$(ls -1 $DIR/$tdir | wc -l)
24660         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24661
24662         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24663         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24664
24665         cnt=$(ls $DIR/$tdir | wc -l)
24666         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24667 }
24668 run_test 421c "rm by fid against hardlinked files"
24669
24670 test_421d() {
24671         local cnt
24672         local FIDS
24673
24674         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24675                 skip "Need MDS version at least 2.12.54"
24676
24677         test_mkdir $DIR/$tdir
24678         createmany -o $DIR/$tdir/f 4097
24679         cnt=$(ls -1 $DIR/$tdir | wc -l)
24680         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24681
24682         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24683         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24684
24685         cnt=$(ls $DIR/$tdir | wc -l)
24686         rm -rf $DIR/$tdir
24687         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24688 }
24689 run_test 421d "rmfid en masse"
24690
24691 test_421e() {
24692         local cnt
24693         local FID
24694
24695         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24696         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24697                 skip "Need MDS version at least 2.12.54"
24698
24699         mkdir -p $DIR/$tdir
24700         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24701         createmany -o $DIR/$tdir/striped_dir/f 512
24702         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24703         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24704
24705         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24706                 sed "s/[/][^:]*://g")
24707         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24708
24709         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24710         rm -rf $DIR/$tdir
24711         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24712 }
24713 run_test 421e "rmfid in DNE"
24714
24715 test_421f() {
24716         local cnt
24717         local FID
24718
24719         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24720                 skip "Need MDS version at least 2.12.54"
24721
24722         test_mkdir $DIR/$tdir
24723         touch $DIR/$tdir/f
24724         cnt=$(ls -1 $DIR/$tdir | wc -l)
24725         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24726
24727         FID=$(lfs path2fid $DIR/$tdir/f)
24728         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24729         # rmfid should fail
24730         cnt=$(ls -1 $DIR/$tdir | wc -l)
24731         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24732
24733         chmod a+rw $DIR/$tdir
24734         ls -la $DIR/$tdir
24735         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24736         # rmfid should fail
24737         cnt=$(ls -1 $DIR/$tdir | wc -l)
24738         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24739
24740         rm -f $DIR/$tdir/f
24741         $RUNAS touch $DIR/$tdir/f
24742         FID=$(lfs path2fid $DIR/$tdir/f)
24743         echo "rmfid as root"
24744         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24745         cnt=$(ls -1 $DIR/$tdir | wc -l)
24746         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24747
24748         rm -f $DIR/$tdir/f
24749         $RUNAS touch $DIR/$tdir/f
24750         cnt=$(ls -1 $DIR/$tdir | wc -l)
24751         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24752         FID=$(lfs path2fid $DIR/$tdir/f)
24753         # rmfid w/o user_fid2path mount option should fail
24754         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24755         cnt=$(ls -1 $DIR/$tdir | wc -l)
24756         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24757
24758         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24759         stack_trap "rmdir $tmpdir"
24760         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24761                 error "failed to mount client'"
24762         stack_trap "umount_client $tmpdir"
24763
24764         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24765         # rmfid should succeed
24766         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24767         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24768
24769         # rmfid shouldn't allow to remove files due to dir's permission
24770         chmod a+rwx $tmpdir/$tdir
24771         touch $tmpdir/$tdir/f
24772         ls -la $tmpdir/$tdir
24773         FID=$(lfs path2fid $tmpdir/$tdir/f)
24774         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24775         return 0
24776 }
24777 run_test 421f "rmfid checks permissions"
24778
24779 test_421g() {
24780         local cnt
24781         local FIDS
24782
24783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24784         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24785                 skip "Need MDS version at least 2.12.54"
24786
24787         mkdir -p $DIR/$tdir
24788         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24789         createmany -o $DIR/$tdir/striped_dir/f 512
24790         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24791         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24792
24793         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24794                 sed "s/[/][^:]*://g")
24795
24796         rm -f $DIR/$tdir/striped_dir/f1*
24797         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24798         removed=$((512 - cnt))
24799
24800         # few files have been just removed, so we expect
24801         # rmfid to fail on their fids
24802         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24803         [ $removed != $errors ] && error "$errors != $removed"
24804
24805         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24806         rm -rf $DIR/$tdir
24807         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24808 }
24809 run_test 421g "rmfid to return errors properly"
24810
24811 test_422() {
24812         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24813         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24814         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24815         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24816         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24817
24818         local amc=$(at_max_get client)
24819         local amo=$(at_max_get mds1)
24820         local timeout=`lctl get_param -n timeout`
24821
24822         at_max_set 0 client
24823         at_max_set 0 mds1
24824
24825 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24826         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24827                         fail_val=$(((2*timeout + 10)*1000))
24828         touch $DIR/$tdir/d3/file &
24829         sleep 2
24830 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24831         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24832                         fail_val=$((2*timeout + 5))
24833         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24834         local pid=$!
24835         sleep 1
24836         kill -9 $pid
24837         sleep $((2 * timeout))
24838         echo kill $pid
24839         kill -9 $pid
24840         lctl mark touch
24841         touch $DIR/$tdir/d2/file3
24842         touch $DIR/$tdir/d2/file4
24843         touch $DIR/$tdir/d2/file5
24844
24845         wait
24846         at_max_set $amc client
24847         at_max_set $amo mds1
24848
24849         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24850         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24851                 error "Watchdog is always throttled"
24852 }
24853 run_test 422 "kill a process with RPC in progress"
24854
24855 stat_test() {
24856     df -h $MOUNT &
24857     df -h $MOUNT &
24858     df -h $MOUNT &
24859     df -h $MOUNT &
24860     df -h $MOUNT &
24861     df -h $MOUNT &
24862 }
24863
24864 test_423() {
24865     local _stats
24866     # ensure statfs cache is expired
24867     sleep 2;
24868
24869     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24870     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24871
24872     return 0
24873 }
24874 run_test 423 "statfs should return a right data"
24875
24876 test_424() {
24877 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24878         $LCTL set_param fail_loc=0x80000522
24879         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24880         rm -f $DIR/$tfile
24881 }
24882 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24883
24884 test_425() {
24885         test_mkdir -c -1 $DIR/$tdir
24886         $LFS setstripe -c -1 $DIR/$tdir
24887
24888         lru_resize_disable "" 100
24889         stack_trap "lru_resize_enable" EXIT
24890
24891         sleep 5
24892
24893         for i in $(seq $((MDSCOUNT * 125))); do
24894                 local t=$DIR/$tdir/$tfile_$i
24895
24896                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24897                         error_noexit "Create file $t"
24898         done
24899         stack_trap "rm -rf $DIR/$tdir" EXIT
24900
24901         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24902                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24903                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24904
24905                 [ $lock_count -le $lru_size ] ||
24906                         error "osc lock count $lock_count > lru size $lru_size"
24907         done
24908
24909         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24910                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24911                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24912
24913                 [ $lock_count -le $lru_size ] ||
24914                         error "mdc lock count $lock_count > lru size $lru_size"
24915         done
24916 }
24917 run_test 425 "lock count should not exceed lru size"
24918
24919 test_426() {
24920         splice-test -r $DIR/$tfile
24921         splice-test -rd $DIR/$tfile
24922         splice-test $DIR/$tfile
24923         splice-test -d $DIR/$tfile
24924 }
24925 run_test 426 "splice test on Lustre"
24926
24927 test_427() {
24928         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24929         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24930                 skip "Need MDS version at least 2.12.4"
24931         local log
24932
24933         mkdir $DIR/$tdir
24934         mkdir $DIR/$tdir/1
24935         mkdir $DIR/$tdir/2
24936         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24937         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24938
24939         $LFS getdirstripe $DIR/$tdir/1/dir
24940
24941         #first setfattr for creating updatelog
24942         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24943
24944 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24945         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24946         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24947         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24948
24949         sleep 2
24950         fail mds2
24951         wait_recovery_complete mds2 $((2*TIMEOUT))
24952
24953         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24954         echo $log | grep "get update log failed" &&
24955                 error "update log corruption is detected" || true
24956 }
24957 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24958
24959 test_428() {
24960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24961         local cache_limit=$CACHE_MAX
24962
24963         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24964         $LCTL set_param -n llite.*.max_cached_mb=64
24965
24966         mkdir $DIR/$tdir
24967         $LFS setstripe -c 1 $DIR/$tdir
24968         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24969         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24970         #test write
24971         for f in $(seq 4); do
24972                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24973         done
24974         wait
24975
24976         cancel_lru_locks osc
24977         # Test read
24978         for f in $(seq 4); do
24979                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24980         done
24981         wait
24982 }
24983 run_test 428 "large block size IO should not hang"
24984
24985 test_429() { # LU-7915 / LU-10948
24986         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24987         local testfile=$DIR/$tfile
24988         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24989         local new_flag=1
24990         local first_rpc
24991         local second_rpc
24992         local third_rpc
24993
24994         $LCTL get_param $ll_opencache_threshold_count ||
24995                 skip "client does not have opencache parameter"
24996
24997         set_opencache $new_flag
24998         stack_trap "restore_opencache"
24999         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25000                 error "enable opencache failed"
25001         touch $testfile
25002         # drop MDC DLM locks
25003         cancel_lru_locks mdc
25004         # clear MDC RPC stats counters
25005         $LCTL set_param $mdc_rpcstats=clear
25006
25007         # According to the current implementation, we need to run 3 times
25008         # open & close file to verify if opencache is enabled correctly.
25009         # 1st, RPCs are sent for lookup/open and open handle is released on
25010         #      close finally.
25011         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25012         #      so open handle won't be released thereafter.
25013         # 3rd, No RPC is sent out.
25014         $MULTIOP $testfile oc || error "multiop failed"
25015         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25016         echo "1st: $first_rpc RPCs in flight"
25017
25018         $MULTIOP $testfile oc || error "multiop failed"
25019         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25020         echo "2nd: $second_rpc RPCs in flight"
25021
25022         $MULTIOP $testfile oc || error "multiop failed"
25023         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25024         echo "3rd: $third_rpc RPCs in flight"
25025
25026         #verify no MDC RPC is sent
25027         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25028 }
25029 run_test 429 "verify if opencache flag on client side does work"
25030
25031 lseek_test_430() {
25032         local offset
25033         local file=$1
25034
25035         # data at [200K, 400K)
25036         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25037                 error "256K->512K dd fails"
25038         # data at [2M, 3M)
25039         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25040                 error "2M->3M dd fails"
25041         # data at [4M, 5M)
25042         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25043                 error "4M->5M dd fails"
25044         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25045         # start at first component hole #1
25046         printf "Seeking hole from 1000 ... "
25047         offset=$(lseek_test -l 1000 $file)
25048         echo $offset
25049         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25050         printf "Seeking data from 1000 ... "
25051         offset=$(lseek_test -d 1000 $file)
25052         echo $offset
25053         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25054
25055         # start at first component data block
25056         printf "Seeking hole from 300000 ... "
25057         offset=$(lseek_test -l 300000 $file)
25058         echo $offset
25059         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25060         printf "Seeking data from 300000 ... "
25061         offset=$(lseek_test -d 300000 $file)
25062         echo $offset
25063         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25064
25065         # start at the first component but beyond end of object size
25066         printf "Seeking hole from 1000000 ... "
25067         offset=$(lseek_test -l 1000000 $file)
25068         echo $offset
25069         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25070         printf "Seeking data from 1000000 ... "
25071         offset=$(lseek_test -d 1000000 $file)
25072         echo $offset
25073         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25074
25075         # start at second component stripe 2 (empty file)
25076         printf "Seeking hole from 1500000 ... "
25077         offset=$(lseek_test -l 1500000 $file)
25078         echo $offset
25079         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25080         printf "Seeking data from 1500000 ... "
25081         offset=$(lseek_test -d 1500000 $file)
25082         echo $offset
25083         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25084
25085         # start at second component stripe 1 (all data)
25086         printf "Seeking hole from 3000000 ... "
25087         offset=$(lseek_test -l 3000000 $file)
25088         echo $offset
25089         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25090         printf "Seeking data from 3000000 ... "
25091         offset=$(lseek_test -d 3000000 $file)
25092         echo $offset
25093         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25094
25095         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25096                 error "2nd dd fails"
25097         echo "Add data block at 640K...1280K"
25098
25099         # start at before new data block, in hole
25100         printf "Seeking hole from 600000 ... "
25101         offset=$(lseek_test -l 600000 $file)
25102         echo $offset
25103         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25104         printf "Seeking data from 600000 ... "
25105         offset=$(lseek_test -d 600000 $file)
25106         echo $offset
25107         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25108
25109         # start at the first component new data block
25110         printf "Seeking hole from 1000000 ... "
25111         offset=$(lseek_test -l 1000000 $file)
25112         echo $offset
25113         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25114         printf "Seeking data from 1000000 ... "
25115         offset=$(lseek_test -d 1000000 $file)
25116         echo $offset
25117         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25118
25119         # start at second component stripe 2, new data
25120         printf "Seeking hole from 1200000 ... "
25121         offset=$(lseek_test -l 1200000 $file)
25122         echo $offset
25123         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25124         printf "Seeking data from 1200000 ... "
25125         offset=$(lseek_test -d 1200000 $file)
25126         echo $offset
25127         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25128
25129         # start beyond file end
25130         printf "Using offset > filesize ... "
25131         lseek_test -l 4000000 $file && error "lseek should fail"
25132         printf "Using offset > filesize ... "
25133         lseek_test -d 4000000 $file && error "lseek should fail"
25134
25135         printf "Done\n\n"
25136 }
25137
25138 test_430a() {
25139         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25140                 skip "MDT does not support SEEK_HOLE"
25141
25142         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25143                 skip "OST does not support SEEK_HOLE"
25144
25145         local file=$DIR/$tdir/$tfile
25146
25147         mkdir -p $DIR/$tdir
25148
25149         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25150         # OST stripe #1 will have continuous data at [1M, 3M)
25151         # OST stripe #2 is empty
25152         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25153         lseek_test_430 $file
25154         rm $file
25155         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25156         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25157         lseek_test_430 $file
25158         rm $file
25159         $LFS setstripe -c2 -S 512K $file
25160         echo "Two stripes, stripe size 512K"
25161         lseek_test_430 $file
25162         rm $file
25163         # FLR with stale mirror
25164         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25165                        -N -c2 -S 1M $file
25166         echo "Mirrored file:"
25167         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25168         echo "Plain 2 stripes 1M"
25169         lseek_test_430 $file
25170         rm $file
25171 }
25172 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25173
25174 test_430b() {
25175         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25176                 skip "OST does not support SEEK_HOLE"
25177
25178         local offset
25179         local file=$DIR/$tdir/$tfile
25180
25181         mkdir -p $DIR/$tdir
25182         # Empty layout lseek should fail
25183         $MCREATE $file
25184         # seek from 0
25185         printf "Seeking hole from 0 ... "
25186         lseek_test -l 0 $file && error "lseek should fail"
25187         printf "Seeking data from 0 ... "
25188         lseek_test -d 0 $file && error "lseek should fail"
25189         rm $file
25190
25191         # 1M-hole file
25192         $LFS setstripe -E 1M -c2 -E eof $file
25193         $TRUNCATE $file 1048576
25194         printf "Seeking hole from 1000000 ... "
25195         offset=$(lseek_test -l 1000000 $file)
25196         echo $offset
25197         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25198         printf "Seeking data from 1000000 ... "
25199         lseek_test -d 1000000 $file && error "lseek should fail"
25200         rm $file
25201
25202         # full component followed by non-inited one
25203         $LFS setstripe -E 1M -c2 -E eof $file
25204         dd if=/dev/urandom of=$file bs=1M count=1
25205         printf "Seeking hole from 1000000 ... "
25206         offset=$(lseek_test -l 1000000 $file)
25207         echo $offset
25208         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25209         printf "Seeking hole from 1048576 ... "
25210         lseek_test -l 1048576 $file && error "lseek should fail"
25211         # init second component and truncate back
25212         echo "123" >> $file
25213         $TRUNCATE $file 1048576
25214         printf "Seeking hole from 1000000 ... "
25215         offset=$(lseek_test -l 1000000 $file)
25216         echo $offset
25217         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25218         printf "Seeking hole from 1048576 ... "
25219         lseek_test -l 1048576 $file && error "lseek should fail"
25220         # boundary checks for big values
25221         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25222         offset=$(lseek_test -d 0 $file.10g)
25223         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25224         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25225         offset=$(lseek_test -d 0 $file.100g)
25226         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25227         return 0
25228 }
25229 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25230
25231 test_430c() {
25232         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25233                 skip "OST does not support SEEK_HOLE"
25234
25235         local file=$DIR/$tdir/$tfile
25236         local start
25237
25238         mkdir -p $DIR/$tdir
25239         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25240
25241         # cp version 8.33+ prefers lseek over fiemap
25242         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25243                 start=$SECONDS
25244                 time cp $file /dev/null
25245                 (( SECONDS - start < 5 )) ||
25246                         error "cp: too long runtime $((SECONDS - start))"
25247
25248         fi
25249         # tar version 1.29+ supports SEEK_HOLE/DATA
25250         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25251                 start=$SECONDS
25252                 time tar cS $file - | cat > /dev/null
25253                 (( SECONDS - start < 5 )) ||
25254                         error "tar: too long runtime $((SECONDS - start))"
25255         fi
25256 }
25257 run_test 430c "lseek: external tools check"
25258
25259 test_431() { # LU-14187
25260         local file=$DIR/$tdir/$tfile
25261
25262         mkdir -p $DIR/$tdir
25263         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25264         dd if=/dev/urandom of=$file bs=4k count=1
25265         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25266         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25267         #define OBD_FAIL_OST_RESTART_IO 0x251
25268         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25269         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25270         cp $file $file.0
25271         cancel_lru_locks
25272         sync_all_data
25273         echo 3 > /proc/sys/vm/drop_caches
25274         diff  $file $file.0 || error "data diff"
25275 }
25276 run_test 431 "Restart transaction for IO"
25277
25278 prep_801() {
25279         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25280         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25281                 skip "Need server version at least 2.9.55"
25282
25283         start_full_debug_logging
25284 }
25285
25286 post_801() {
25287         stop_full_debug_logging
25288 }
25289
25290 barrier_stat() {
25291         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25292                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25293                            awk '/The barrier for/ { print $7 }')
25294                 echo $st
25295         else
25296                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25297                 echo \'$st\'
25298         fi
25299 }
25300
25301 barrier_expired() {
25302         local expired
25303
25304         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25305                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25306                           awk '/will be expired/ { print $7 }')
25307         else
25308                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25309         fi
25310
25311         echo $expired
25312 }
25313
25314 test_801a() {
25315         prep_801
25316
25317         echo "Start barrier_freeze at: $(date)"
25318         #define OBD_FAIL_BARRIER_DELAY          0x2202
25319         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25320         # Do not reduce barrier time - See LU-11873
25321         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25322
25323         sleep 2
25324         local b_status=$(barrier_stat)
25325         echo "Got barrier status at: $(date)"
25326         [ "$b_status" = "'freezing_p1'" ] ||
25327                 error "(1) unexpected barrier status $b_status"
25328
25329         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25330         wait
25331         b_status=$(barrier_stat)
25332         [ "$b_status" = "'frozen'" ] ||
25333                 error "(2) unexpected barrier status $b_status"
25334
25335         local expired=$(barrier_expired)
25336         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25337         sleep $((expired + 3))
25338
25339         b_status=$(barrier_stat)
25340         [ "$b_status" = "'expired'" ] ||
25341                 error "(3) unexpected barrier status $b_status"
25342
25343         # Do not reduce barrier time - See LU-11873
25344         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25345                 error "(4) fail to freeze barrier"
25346
25347         b_status=$(barrier_stat)
25348         [ "$b_status" = "'frozen'" ] ||
25349                 error "(5) unexpected barrier status $b_status"
25350
25351         echo "Start barrier_thaw at: $(date)"
25352         #define OBD_FAIL_BARRIER_DELAY          0x2202
25353         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25354         do_facet mgs $LCTL barrier_thaw $FSNAME &
25355
25356         sleep 2
25357         b_status=$(barrier_stat)
25358         echo "Got barrier status at: $(date)"
25359         [ "$b_status" = "'thawing'" ] ||
25360                 error "(6) unexpected barrier status $b_status"
25361
25362         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25363         wait
25364         b_status=$(barrier_stat)
25365         [ "$b_status" = "'thawed'" ] ||
25366                 error "(7) unexpected barrier status $b_status"
25367
25368         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25369         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25370         do_facet mgs $LCTL barrier_freeze $FSNAME
25371
25372         b_status=$(barrier_stat)
25373         [ "$b_status" = "'failed'" ] ||
25374                 error "(8) unexpected barrier status $b_status"
25375
25376         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25377         do_facet mgs $LCTL barrier_thaw $FSNAME
25378
25379         post_801
25380 }
25381 run_test 801a "write barrier user interfaces and stat machine"
25382
25383 test_801b() {
25384         prep_801
25385
25386         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25387         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25388         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25389         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25390         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25391
25392         cancel_lru_locks mdc
25393
25394         # 180 seconds should be long enough
25395         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25396
25397         local b_status=$(barrier_stat)
25398         [ "$b_status" = "'frozen'" ] ||
25399                 error "(6) unexpected barrier status $b_status"
25400
25401         mkdir $DIR/$tdir/d0/d10 &
25402         mkdir_pid=$!
25403
25404         touch $DIR/$tdir/d1/f13 &
25405         touch_pid=$!
25406
25407         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25408         ln_pid=$!
25409
25410         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25411         mv_pid=$!
25412
25413         rm -f $DIR/$tdir/d4/f12 &
25414         rm_pid=$!
25415
25416         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25417
25418         # To guarantee taht the 'stat' is not blocked
25419         b_status=$(barrier_stat)
25420         [ "$b_status" = "'frozen'" ] ||
25421                 error "(8) unexpected barrier status $b_status"
25422
25423         # let above commands to run at background
25424         sleep 5
25425
25426         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25427         ps -p $touch_pid || error "(10) touch should be blocked"
25428         ps -p $ln_pid || error "(11) link should be blocked"
25429         ps -p $mv_pid || error "(12) rename should be blocked"
25430         ps -p $rm_pid || error "(13) unlink should be blocked"
25431
25432         b_status=$(barrier_stat)
25433         [ "$b_status" = "'frozen'" ] ||
25434                 error "(14) unexpected barrier status $b_status"
25435
25436         do_facet mgs $LCTL barrier_thaw $FSNAME
25437         b_status=$(barrier_stat)
25438         [ "$b_status" = "'thawed'" ] ||
25439                 error "(15) unexpected barrier status $b_status"
25440
25441         wait $mkdir_pid || error "(16) mkdir should succeed"
25442         wait $touch_pid || error "(17) touch should succeed"
25443         wait $ln_pid || error "(18) link should succeed"
25444         wait $mv_pid || error "(19) rename should succeed"
25445         wait $rm_pid || error "(20) unlink should succeed"
25446
25447         post_801
25448 }
25449 run_test 801b "modification will be blocked by write barrier"
25450
25451 test_801c() {
25452         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25453
25454         prep_801
25455
25456         stop mds2 || error "(1) Fail to stop mds2"
25457
25458         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25459
25460         local b_status=$(barrier_stat)
25461         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25462                 do_facet mgs $LCTL barrier_thaw $FSNAME
25463                 error "(2) unexpected barrier status $b_status"
25464         }
25465
25466         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25467                 error "(3) Fail to rescan barrier bitmap"
25468
25469         # Do not reduce barrier time - See LU-11873
25470         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25471
25472         b_status=$(barrier_stat)
25473         [ "$b_status" = "'frozen'" ] ||
25474                 error "(4) unexpected barrier status $b_status"
25475
25476         do_facet mgs $LCTL barrier_thaw $FSNAME
25477         b_status=$(barrier_stat)
25478         [ "$b_status" = "'thawed'" ] ||
25479                 error "(5) unexpected barrier status $b_status"
25480
25481         local devname=$(mdsdevname 2)
25482
25483         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25484
25485         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25486                 error "(7) Fail to rescan barrier bitmap"
25487
25488         post_801
25489 }
25490 run_test 801c "rescan barrier bitmap"
25491
25492 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25493 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25494 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25495 saved_MOUNT_OPTS=$MOUNT_OPTS
25496
25497 cleanup_802a() {
25498         trap 0
25499
25500         stopall
25501         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25502         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25503         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25504         MOUNT_OPTS=$saved_MOUNT_OPTS
25505         setupall
25506 }
25507
25508 test_802a() {
25509         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25510         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25511         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25512                 skip "Need server version at least 2.9.55"
25513
25514         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25515
25516         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25517
25518         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25519                 error "(2) Fail to copy"
25520
25521         trap cleanup_802a EXIT
25522
25523         # sync by force before remount as readonly
25524         sync; sync_all_data; sleep 3; sync_all_data
25525
25526         stopall
25527
25528         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25529         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25530         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25531
25532         echo "Mount the server as read only"
25533         setupall server_only || error "(3) Fail to start servers"
25534
25535         echo "Mount client without ro should fail"
25536         mount_client $MOUNT &&
25537                 error "(4) Mount client without 'ro' should fail"
25538
25539         echo "Mount client with ro should succeed"
25540         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25541         mount_client $MOUNT ||
25542                 error "(5) Mount client with 'ro' should succeed"
25543
25544         echo "Modify should be refused"
25545         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25546
25547         echo "Read should be allowed"
25548         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25549                 error "(7) Read should succeed under ro mode"
25550
25551         cleanup_802a
25552 }
25553 run_test 802a "simulate readonly device"
25554
25555 test_802b() {
25556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25557         remote_mds_nodsh && skip "remote MDS with nodsh"
25558
25559         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25560                 skip "readonly option not available"
25561
25562         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25563
25564         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25565                 error "(2) Fail to copy"
25566
25567         # write back all cached data before setting MDT to readonly
25568         cancel_lru_locks
25569         sync_all_data
25570
25571         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25572         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25573
25574         echo "Modify should be refused"
25575         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25576
25577         echo "Read should be allowed"
25578         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25579                 error "(7) Read should succeed under ro mode"
25580
25581         # disable readonly
25582         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25583 }
25584 run_test 802b "be able to set MDTs to readonly"
25585
25586 test_803a() {
25587         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25588         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25589                 skip "MDS needs to be newer than 2.10.54"
25590
25591         mkdir -p $DIR/$tdir
25592         # Create some objects on all MDTs to trigger related logs objects
25593         for idx in $(seq $MDSCOUNT); do
25594                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25595                         $DIR/$tdir/dir${idx} ||
25596                         error "Fail to create $DIR/$tdir/dir${idx}"
25597         done
25598
25599         sync; sleep 3
25600         wait_delete_completed # ensure old test cleanups are finished
25601         echo "before create:"
25602         $LFS df -i $MOUNT
25603         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25604
25605         for i in {1..10}; do
25606                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25607                         error "Fail to create $DIR/$tdir/foo$i"
25608         done
25609
25610         sync; sleep 3
25611         echo "after create:"
25612         $LFS df -i $MOUNT
25613         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25614
25615         # allow for an llog to be cleaned up during the test
25616         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25617                 error "before ($before_used) + 10 > after ($after_used)"
25618
25619         for i in {1..10}; do
25620                 rm -rf $DIR/$tdir/foo$i ||
25621                         error "Fail to remove $DIR/$tdir/foo$i"
25622         done
25623
25624         sleep 3 # avoid MDT return cached statfs
25625         wait_delete_completed
25626         echo "after unlink:"
25627         $LFS df -i $MOUNT
25628         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25629
25630         # allow for an llog to be created during the test
25631         [ $after_used -le $((before_used + 1)) ] ||
25632                 error "after ($after_used) > before ($before_used) + 1"
25633 }
25634 run_test 803a "verify agent object for remote object"
25635
25636 test_803b() {
25637         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25638         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25639                 skip "MDS needs to be newer than 2.13.56"
25640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25641
25642         for i in $(seq 0 $((MDSCOUNT - 1))); do
25643                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25644         done
25645
25646         local before=0
25647         local after=0
25648
25649         local tmp
25650
25651         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25652         for i in $(seq 0 $((MDSCOUNT - 1))); do
25653                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25654                         awk '/getattr/ { print $2 }')
25655                 before=$((before + tmp))
25656         done
25657         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25658         for i in $(seq 0 $((MDSCOUNT - 1))); do
25659                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25660                         awk '/getattr/ { print $2 }')
25661                 after=$((after + tmp))
25662         done
25663
25664         [ $before -eq $after ] || error "getattr count $before != $after"
25665 }
25666 run_test 803b "remote object can getattr from cache"
25667
25668 test_804() {
25669         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25670         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25671                 skip "MDS needs to be newer than 2.10.54"
25672         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25673
25674         mkdir -p $DIR/$tdir
25675         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25676                 error "Fail to create $DIR/$tdir/dir0"
25677
25678         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25679         local dev=$(mdsdevname 2)
25680
25681         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25682                 grep ${fid} || error "NOT found agent entry for dir0"
25683
25684         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25685                 error "Fail to create $DIR/$tdir/dir1"
25686
25687         touch $DIR/$tdir/dir1/foo0 ||
25688                 error "Fail to create $DIR/$tdir/dir1/foo0"
25689         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25690         local rc=0
25691
25692         for idx in $(seq $MDSCOUNT); do
25693                 dev=$(mdsdevname $idx)
25694                 do_facet mds${idx} \
25695                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25696                         grep ${fid} && rc=$idx
25697         done
25698
25699         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25700                 error "Fail to rename foo0 to foo1"
25701         if [ $rc -eq 0 ]; then
25702                 for idx in $(seq $MDSCOUNT); do
25703                         dev=$(mdsdevname $idx)
25704                         do_facet mds${idx} \
25705                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25706                         grep ${fid} && rc=$idx
25707                 done
25708         fi
25709
25710         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25711                 error "Fail to rename foo1 to foo2"
25712         if [ $rc -eq 0 ]; then
25713                 for idx in $(seq $MDSCOUNT); do
25714                         dev=$(mdsdevname $idx)
25715                         do_facet mds${idx} \
25716                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25717                         grep ${fid} && rc=$idx
25718                 done
25719         fi
25720
25721         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25722
25723         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25724                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25725         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25726                 error "Fail to rename foo2 to foo0"
25727         unlink $DIR/$tdir/dir1/foo0 ||
25728                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25729         rm -rf $DIR/$tdir/dir0 ||
25730                 error "Fail to rm $DIR/$tdir/dir0"
25731
25732         for idx in $(seq $MDSCOUNT); do
25733                 dev=$(mdsdevname $idx)
25734                 rc=0
25735
25736                 stop mds${idx}
25737                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25738                         rc=$?
25739                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25740                         error "mount mds$idx failed"
25741                 df $MOUNT > /dev/null 2>&1
25742
25743                 # e2fsck should not return error
25744                 [ $rc -eq 0 ] ||
25745                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25746         done
25747 }
25748 run_test 804 "verify agent entry for remote entry"
25749
25750 cleanup_805() {
25751         do_facet $SINGLEMDS zfs set quota=$old $fsset
25752         unlinkmany $DIR/$tdir/f- 1000000
25753         trap 0
25754 }
25755
25756 test_805() {
25757         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25758         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25759         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25760                 skip "netfree not implemented before 0.7"
25761         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25762                 skip "Need MDS version at least 2.10.57"
25763
25764         local fsset
25765         local freekb
25766         local usedkb
25767         local old
25768         local quota
25769         local pref="osd-zfs.$FSNAME-MDT0000."
25770
25771         # limit available space on MDS dataset to meet nospace issue
25772         # quickly. then ZFS 0.7.2 can use reserved space if asked
25773         # properly (using netfree flag in osd_declare_destroy()
25774         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25775         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25776                 gawk '{print $3}')
25777         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25778         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25779         let "usedkb=usedkb-freekb"
25780         let "freekb=freekb/2"
25781         if let "freekb > 5000"; then
25782                 let "freekb=5000"
25783         fi
25784         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25785         trap cleanup_805 EXIT
25786         mkdir $DIR/$tdir
25787         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25788                 error "Can't set PFL layout"
25789         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25790         rm -rf $DIR/$tdir || error "not able to remove"
25791         do_facet $SINGLEMDS zfs set quota=$old $fsset
25792         trap 0
25793 }
25794 run_test 805 "ZFS can remove from full fs"
25795
25796 # Size-on-MDS test
25797 check_lsom_data()
25798 {
25799         local file=$1
25800         local expect=$(stat -c %s $file)
25801
25802         check_lsom_size $1 $expect
25803
25804         local blocks=$($LFS getsom -b $file)
25805         expect=$(stat -c %b $file)
25806         [[ $blocks == $expect ]] ||
25807                 error "$file expected blocks: $expect, got: $blocks"
25808 }
25809
25810 check_lsom_size()
25811 {
25812         local size
25813         local expect=$2
25814
25815         cancel_lru_locks mdc
25816
25817         size=$($LFS getsom -s $1)
25818         [[ $size == $expect ]] ||
25819                 error "$file expected size: $expect, got: $size"
25820 }
25821
25822 test_806() {
25823         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25824                 skip "Need MDS version at least 2.11.52"
25825
25826         local bs=1048576
25827
25828         touch $DIR/$tfile || error "touch $tfile failed"
25829
25830         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25831         save_lustre_params client "llite.*.xattr_cache" > $save
25832         lctl set_param llite.*.xattr_cache=0
25833         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25834
25835         # single-threaded write
25836         echo "Test SOM for single-threaded write"
25837         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25838                 error "write $tfile failed"
25839         check_lsom_size $DIR/$tfile $bs
25840
25841         local num=32
25842         local size=$(($num * $bs))
25843         local offset=0
25844         local i
25845
25846         echo "Test SOM for single client multi-threaded($num) write"
25847         $TRUNCATE $DIR/$tfile 0
25848         for ((i = 0; i < $num; i++)); do
25849                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25850                 local pids[$i]=$!
25851                 offset=$((offset + $bs))
25852         done
25853         for (( i=0; i < $num; i++ )); do
25854                 wait ${pids[$i]}
25855         done
25856         check_lsom_size $DIR/$tfile $size
25857
25858         $TRUNCATE $DIR/$tfile 0
25859         for ((i = 0; i < $num; i++)); do
25860                 offset=$((offset - $bs))
25861                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25862                 local pids[$i]=$!
25863         done
25864         for (( i=0; i < $num; i++ )); do
25865                 wait ${pids[$i]}
25866         done
25867         check_lsom_size $DIR/$tfile $size
25868
25869         # multi-client writes
25870         num=$(get_node_count ${CLIENTS//,/ })
25871         size=$(($num * $bs))
25872         offset=0
25873         i=0
25874
25875         echo "Test SOM for multi-client ($num) writes"
25876         $TRUNCATE $DIR/$tfile 0
25877         for client in ${CLIENTS//,/ }; do
25878                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25879                 local pids[$i]=$!
25880                 i=$((i + 1))
25881                 offset=$((offset + $bs))
25882         done
25883         for (( i=0; i < $num; i++ )); do
25884                 wait ${pids[$i]}
25885         done
25886         check_lsom_size $DIR/$tfile $offset
25887
25888         i=0
25889         $TRUNCATE $DIR/$tfile 0
25890         for client in ${CLIENTS//,/ }; do
25891                 offset=$((offset - $bs))
25892                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25893                 local pids[$i]=$!
25894                 i=$((i + 1))
25895         done
25896         for (( i=0; i < $num; i++ )); do
25897                 wait ${pids[$i]}
25898         done
25899         check_lsom_size $DIR/$tfile $size
25900
25901         # verify truncate
25902         echo "Test SOM for truncate"
25903         $TRUNCATE $DIR/$tfile 1048576
25904         check_lsom_size $DIR/$tfile 1048576
25905         $TRUNCATE $DIR/$tfile 1234
25906         check_lsom_size $DIR/$tfile 1234
25907
25908         # verify SOM blocks count
25909         echo "Verify SOM block count"
25910         $TRUNCATE $DIR/$tfile 0
25911         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25912                 error "failed to write file $tfile"
25913         check_lsom_data $DIR/$tfile
25914 }
25915 run_test 806 "Verify Lazy Size on MDS"
25916
25917 test_807() {
25918         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25919         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25920                 skip "Need MDS version at least 2.11.52"
25921
25922         # Registration step
25923         changelog_register || error "changelog_register failed"
25924         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25925         changelog_users $SINGLEMDS | grep -q $cl_user ||
25926                 error "User $cl_user not found in changelog_users"
25927
25928         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25929         save_lustre_params client "llite.*.xattr_cache" > $save
25930         lctl set_param llite.*.xattr_cache=0
25931         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25932
25933         rm -rf $DIR/$tdir || error "rm $tdir failed"
25934         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25935         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25936         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25937         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25938                 error "truncate $tdir/trunc failed"
25939
25940         local bs=1048576
25941         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25942                 error "write $tfile failed"
25943
25944         # multi-client wirtes
25945         local num=$(get_node_count ${CLIENTS//,/ })
25946         local offset=0
25947         local i=0
25948
25949         echo "Test SOM for multi-client ($num) writes"
25950         touch $DIR/$tfile || error "touch $tfile failed"
25951         $TRUNCATE $DIR/$tfile 0
25952         for client in ${CLIENTS//,/ }; do
25953                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25954                 local pids[$i]=$!
25955                 i=$((i + 1))
25956                 offset=$((offset + $bs))
25957         done
25958         for (( i=0; i < $num; i++ )); do
25959                 wait ${pids[$i]}
25960         done
25961
25962         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25963         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25964         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25965         check_lsom_data $DIR/$tdir/trunc
25966         check_lsom_data $DIR/$tdir/single_dd
25967         check_lsom_data $DIR/$tfile
25968
25969         rm -rf $DIR/$tdir
25970         # Deregistration step
25971         changelog_deregister || error "changelog_deregister failed"
25972 }
25973 run_test 807 "verify LSOM syncing tool"
25974
25975 check_som_nologged()
25976 {
25977         local lines=$($LFS changelog $FSNAME-MDT0000 |
25978                 grep 'x=trusted.som' | wc -l)
25979         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25980 }
25981
25982 test_808() {
25983         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25984                 skip "Need MDS version at least 2.11.55"
25985
25986         # Registration step
25987         changelog_register || error "changelog_register failed"
25988
25989         touch $DIR/$tfile || error "touch $tfile failed"
25990         check_som_nologged
25991
25992         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25993                 error "write $tfile failed"
25994         check_som_nologged
25995
25996         $TRUNCATE $DIR/$tfile 1234
25997         check_som_nologged
25998
25999         $TRUNCATE $DIR/$tfile 1048576
26000         check_som_nologged
26001
26002         # Deregistration step
26003         changelog_deregister || error "changelog_deregister failed"
26004 }
26005 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26006
26007 check_som_nodata()
26008 {
26009         $LFS getsom $1
26010         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26011 }
26012
26013 test_809() {
26014         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26015                 skip "Need MDS version at least 2.11.56"
26016
26017         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26018                 error "failed to create DoM-only file $DIR/$tfile"
26019         touch $DIR/$tfile || error "touch $tfile failed"
26020         check_som_nodata $DIR/$tfile
26021
26022         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26023                 error "write $tfile failed"
26024         check_som_nodata $DIR/$tfile
26025
26026         $TRUNCATE $DIR/$tfile 1234
26027         check_som_nodata $DIR/$tfile
26028
26029         $TRUNCATE $DIR/$tfile 4097
26030         check_som_nodata $DIR/$file
26031 }
26032 run_test 809 "Verify no SOM xattr store for DoM-only files"
26033
26034 test_810() {
26035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26036         $GSS && skip_env "could not run with gss"
26037         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26038                 skip "OST < 2.12.58 doesn't align checksum"
26039
26040         set_checksums 1
26041         stack_trap "set_checksums $ORIG_CSUM" EXIT
26042         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26043
26044         local csum
26045         local before
26046         local after
26047         for csum in $CKSUM_TYPES; do
26048                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26049                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26050                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26051                         eval set -- $i
26052                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26053                         before=$(md5sum $DIR/$tfile)
26054                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26055                         after=$(md5sum $DIR/$tfile)
26056                         [ "$before" == "$after" ] ||
26057                                 error "$csum: $before != $after bs=$1 seek=$2"
26058                 done
26059         done
26060 }
26061 run_test 810 "partial page writes on ZFS (LU-11663)"
26062
26063 test_812a() {
26064         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26065                 skip "OST < 2.12.51 doesn't support this fail_loc"
26066
26067         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26068         # ensure ost1 is connected
26069         stat $DIR/$tfile >/dev/null || error "can't stat"
26070         wait_osc_import_state client ost1 FULL
26071         # no locks, no reqs to let the connection idle
26072         cancel_lru_locks osc
26073
26074         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26075 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26076         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26077         wait_osc_import_state client ost1 CONNECTING
26078         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26079
26080         stat $DIR/$tfile >/dev/null || error "can't stat file"
26081 }
26082 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26083
26084 test_812b() { # LU-12378
26085         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26086                 skip "OST < 2.12.51 doesn't support this fail_loc"
26087
26088         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26089         # ensure ost1 is connected
26090         stat $DIR/$tfile >/dev/null || error "can't stat"
26091         wait_osc_import_state client ost1 FULL
26092         # no locks, no reqs to let the connection idle
26093         cancel_lru_locks osc
26094
26095         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26096 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26097         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26098         wait_osc_import_state client ost1 CONNECTING
26099         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26100
26101         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26102         wait_osc_import_state client ost1 IDLE
26103 }
26104 run_test 812b "do not drop no resend request for idle connect"
26105
26106 test_812c() {
26107         local old
26108
26109         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26110
26111         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26112         $LFS getstripe $DIR/$tfile
26113         $LCTL set_param osc.*.idle_timeout=10
26114         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26115         # ensure ost1 is connected
26116         stat $DIR/$tfile >/dev/null || error "can't stat"
26117         wait_osc_import_state client ost1 FULL
26118         # no locks, no reqs to let the connection idle
26119         cancel_lru_locks osc
26120
26121 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26122         $LCTL set_param fail_loc=0x80000533
26123         sleep 15
26124         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26125 }
26126 run_test 812c "idle import vs lock enqueue race"
26127
26128 test_813() {
26129         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26130         [ -z "$file_heat_sav" ] && skip "no file heat support"
26131
26132         local readsample
26133         local writesample
26134         local readbyte
26135         local writebyte
26136         local readsample1
26137         local writesample1
26138         local readbyte1
26139         local writebyte1
26140
26141         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26142         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26143
26144         $LCTL set_param -n llite.*.file_heat=1
26145         echo "Turn on file heat"
26146         echo "Period second: $period_second, Decay percentage: $decay_pct"
26147
26148         echo "QQQQ" > $DIR/$tfile
26149         echo "QQQQ" > $DIR/$tfile
26150         echo "QQQQ" > $DIR/$tfile
26151         cat $DIR/$tfile > /dev/null
26152         cat $DIR/$tfile > /dev/null
26153         cat $DIR/$tfile > /dev/null
26154         cat $DIR/$tfile > /dev/null
26155
26156         local out=$($LFS heat_get $DIR/$tfile)
26157
26158         $LFS heat_get $DIR/$tfile
26159         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26160         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26161         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26162         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26163
26164         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26165         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26166         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26167         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26168
26169         sleep $((period_second + 3))
26170         echo "Sleep $((period_second + 3)) seconds..."
26171         # The recursion formula to calculate the heat of the file f is as
26172         # follow:
26173         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26174         # Where Hi is the heat value in the period between time points i*I and
26175         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26176         # to the weight of Ci.
26177         out=$($LFS heat_get $DIR/$tfile)
26178         $LFS heat_get $DIR/$tfile
26179         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26180         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26181         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26182         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26183
26184         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26185                 error "read sample ($readsample) is wrong"
26186         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26187                 error "write sample ($writesample) is wrong"
26188         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26189                 error "read bytes ($readbyte) is wrong"
26190         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26191                 error "write bytes ($writebyte) is wrong"
26192
26193         echo "QQQQ" > $DIR/$tfile
26194         echo "QQQQ" > $DIR/$tfile
26195         echo "QQQQ" > $DIR/$tfile
26196         cat $DIR/$tfile > /dev/null
26197         cat $DIR/$tfile > /dev/null
26198         cat $DIR/$tfile > /dev/null
26199         cat $DIR/$tfile > /dev/null
26200
26201         sleep $((period_second + 3))
26202         echo "Sleep $((period_second + 3)) seconds..."
26203
26204         out=$($LFS heat_get $DIR/$tfile)
26205         $LFS heat_get $DIR/$tfile
26206         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26207         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26208         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26209         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26210
26211         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26212                 4 * $decay_pct) / 100") -eq 1 ] ||
26213                 error "read sample ($readsample1) is wrong"
26214         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26215                 3 * $decay_pct) / 100") -eq 1 ] ||
26216                 error "write sample ($writesample1) is wrong"
26217         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26218                 20 * $decay_pct) / 100") -eq 1 ] ||
26219                 error "read bytes ($readbyte1) is wrong"
26220         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26221                 15 * $decay_pct) / 100") -eq 1 ] ||
26222                 error "write bytes ($writebyte1) is wrong"
26223
26224         echo "Turn off file heat for the file $DIR/$tfile"
26225         $LFS heat_set -o $DIR/$tfile
26226
26227         echo "QQQQ" > $DIR/$tfile
26228         echo "QQQQ" > $DIR/$tfile
26229         echo "QQQQ" > $DIR/$tfile
26230         cat $DIR/$tfile > /dev/null
26231         cat $DIR/$tfile > /dev/null
26232         cat $DIR/$tfile > /dev/null
26233         cat $DIR/$tfile > /dev/null
26234
26235         out=$($LFS heat_get $DIR/$tfile)
26236         $LFS heat_get $DIR/$tfile
26237         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26238         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26239         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26240         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26241
26242         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26243         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26244         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26245         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26246
26247         echo "Trun on file heat for the file $DIR/$tfile"
26248         $LFS heat_set -O $DIR/$tfile
26249
26250         echo "QQQQ" > $DIR/$tfile
26251         echo "QQQQ" > $DIR/$tfile
26252         echo "QQQQ" > $DIR/$tfile
26253         cat $DIR/$tfile > /dev/null
26254         cat $DIR/$tfile > /dev/null
26255         cat $DIR/$tfile > /dev/null
26256         cat $DIR/$tfile > /dev/null
26257
26258         out=$($LFS heat_get $DIR/$tfile)
26259         $LFS heat_get $DIR/$tfile
26260         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26261         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26262         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26263         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26264
26265         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26266         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26267         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26268         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26269
26270         $LFS heat_set -c $DIR/$tfile
26271         $LCTL set_param -n llite.*.file_heat=0
26272         echo "Turn off file heat support for the Lustre filesystem"
26273
26274         echo "QQQQ" > $DIR/$tfile
26275         echo "QQQQ" > $DIR/$tfile
26276         echo "QQQQ" > $DIR/$tfile
26277         cat $DIR/$tfile > /dev/null
26278         cat $DIR/$tfile > /dev/null
26279         cat $DIR/$tfile > /dev/null
26280         cat $DIR/$tfile > /dev/null
26281
26282         out=$($LFS heat_get $DIR/$tfile)
26283         $LFS heat_get $DIR/$tfile
26284         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26285         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26286         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26287         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26288
26289         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26290         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26291         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26292         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26293
26294         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26295         rm -f $DIR/$tfile
26296 }
26297 run_test 813 "File heat verfication"
26298
26299 test_814()
26300 {
26301         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26302         echo -n y >> $DIR/$tfile
26303         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26304         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26305 }
26306 run_test 814 "sparse cp works as expected (LU-12361)"
26307
26308 test_815()
26309 {
26310         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26311         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26312 }
26313 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26314
26315 test_816() {
26316         local ost1_imp=$(get_osc_import_name client ost1)
26317         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26318                          cut -d'.' -f2)
26319
26320         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26321         # ensure ost1 is connected
26322
26323         stat $DIR/$tfile >/dev/null || error "can't stat"
26324         wait_osc_import_state client ost1 FULL
26325         # no locks, no reqs to let the connection idle
26326         cancel_lru_locks osc
26327         lru_resize_disable osc
26328         local before
26329         local now
26330         before=$($LCTL get_param -n \
26331                  ldlm.namespaces.$imp_name.lru_size)
26332
26333         wait_osc_import_state client ost1 IDLE
26334         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26335         now=$($LCTL get_param -n \
26336               ldlm.namespaces.$imp_name.lru_size)
26337         [ $before == $now ] || error "lru_size changed $before != $now"
26338 }
26339 run_test 816 "do not reset lru_resize on idle reconnect"
26340
26341 cleanup_817() {
26342         umount $tmpdir
26343         exportfs -u localhost:$DIR/nfsexp
26344         rm -rf $DIR/nfsexp
26345 }
26346
26347 test_817() {
26348         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26349
26350         mkdir -p $DIR/nfsexp
26351         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26352                 error "failed to export nfs"
26353
26354         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26355         stack_trap cleanup_817 EXIT
26356
26357         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26358                 error "failed to mount nfs to $tmpdir"
26359
26360         cp /bin/true $tmpdir
26361         $DIR/nfsexp/true || error "failed to execute 'true' command"
26362 }
26363 run_test 817 "nfsd won't cache write lock for exec file"
26364
26365 test_818() {
26366         mkdir $DIR/$tdir
26367         $LFS setstripe -c1 -i0 $DIR/$tfile
26368         $LFS setstripe -c1 -i1 $DIR/$tfile
26369         stop $SINGLEMDS
26370         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26371         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26372         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26373                 error "start $SINGLEMDS failed"
26374         rm -rf $DIR/$tdir
26375 }
26376 run_test 818 "unlink with failed llog"
26377
26378 test_819a() {
26379         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26380         cancel_lru_locks osc
26381         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26382         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26383         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26384         rm -f $TDIR/$tfile
26385 }
26386 run_test 819a "too big niobuf in read"
26387
26388 test_819b() {
26389         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26390         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26391         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26392         cancel_lru_locks osc
26393         sleep 1
26394         rm -f $TDIR/$tfile
26395 }
26396 run_test 819b "too big niobuf in write"
26397
26398
26399 function test_820_start_ost() {
26400         sleep 5
26401
26402         for num in $(seq $OSTCOUNT); do
26403                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26404         done
26405 }
26406
26407 test_820() {
26408         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26409
26410         mkdir $DIR/$tdir
26411         umount_client $MOUNT || error "umount failed"
26412         for num in $(seq $OSTCOUNT); do
26413                 stop ost$num
26414         done
26415
26416         # mount client with no active OSTs
26417         # so that the client can't initialize max LOV EA size
26418         # from OSC notifications
26419         mount_client $MOUNT || error "mount failed"
26420         # delay OST starting to keep this 0 max EA size for a while
26421         test_820_start_ost &
26422
26423         # create a directory on MDS2
26424         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26425                 error "Failed to create directory"
26426         # open intent should update default EA size
26427         # see mdc_update_max_ea_from_body()
26428         # notice this is the very first RPC to MDS2
26429         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26430         ret=$?
26431         echo $out
26432         # With SSK, this situation can lead to -EPERM being returned.
26433         # In that case, simply retry.
26434         if [ $ret -ne 0 ] && $SHARED_KEY; then
26435                 if echo "$out" | grep -q "not permitted"; then
26436                         cp /etc/services $DIR/$tdir/mds2
26437                         ret=$?
26438                 fi
26439         fi
26440         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26441 }
26442 run_test 820 "update max EA from open intent"
26443
26444 test_822() {
26445         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26446
26447         save_lustre_params mds1 \
26448                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26449         do_facet $SINGLEMDS "$LCTL set_param -n \
26450                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26451         do_facet $SINGLEMDS "$LCTL set_param -n \
26452                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26453
26454         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26455         local maxage=$(do_facet mds1 $LCTL get_param -n \
26456                        osp.$FSNAME-OST0000*MDT0000.maxage)
26457         sleep $((maxage + 1))
26458
26459         #define OBD_FAIL_NET_ERROR_RPC          0x532
26460         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26461
26462         stack_trap "restore_lustre_params < $p; rm $p"
26463
26464         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26465                       osp.$FSNAME-OST0000*MDT0000.create_count")
26466         for i in $(seq 1 $count); do
26467                 touch $DIR/$tfile.${i} || error "touch failed"
26468         done
26469 }
26470 run_test 822 "test precreate failure"
26471
26472 #
26473 # tests that do cleanup/setup should be run at the end
26474 #
26475
26476 test_900() {
26477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26478         local ls
26479
26480         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26481         $LCTL set_param fail_loc=0x903
26482
26483         cancel_lru_locks MGC
26484
26485         FAIL_ON_ERROR=true cleanup
26486         FAIL_ON_ERROR=true setup
26487 }
26488 run_test 900 "umount should not race with any mgc requeue thread"
26489
26490 # LUS-6253/LU-11185
26491 test_901() {
26492         local oldc
26493         local newc
26494         local olds
26495         local news
26496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26497
26498         # some get_param have a bug to handle dot in param name
26499         cancel_lru_locks MGC
26500         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26501         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26502         umount_client $MOUNT || error "umount failed"
26503         mount_client $MOUNT || error "mount failed"
26504         cancel_lru_locks MGC
26505         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26506         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26507
26508         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26509         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26510
26511         return 0
26512 }
26513 run_test 901 "don't leak a mgc lock on client umount"
26514
26515 # LU-13377
26516 test_902() {
26517         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26518                 skip "client does not have LU-13377 fix"
26519         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26520         $LCTL set_param fail_loc=0x1415
26521         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26522         cancel_lru_locks osc
26523         rm -f $DIR/$tfile
26524 }
26525 run_test 902 "test short write doesn't hang lustre"
26526
26527 complete $SECONDS
26528 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26529 check_and_cleanup_lustre
26530 if [ "$I_MOUNTED" != "yes" ]; then
26531         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26532 fi
26533 exit_status