Whamcloud - gitweb
LU-12682 llite: fake symlink type of foreign file/dir
[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 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 -ge 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 test_27p() {
1912         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1914         remote_mds_nodsh && skip "remote MDS with nodsh"
1915         remote_ost_nodsh && skip "remote OST with nodsh"
1916
1917         reset_enospc
1918         rm -f $DIR/$tdir/$tfile
1919         test_mkdir $DIR/$tdir
1920
1921         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1922         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1923         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1924
1925         exhaust_precreations 0 0x80000215
1926         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1927         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1928         $LFS getstripe $DIR/$tdir/$tfile
1929
1930         reset_enospc
1931 }
1932 run_test 27p "append to a truncated file with some full OSTs"
1933
1934 test_27q() {
1935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1937         remote_mds_nodsh && skip "remote MDS with nodsh"
1938         remote_ost_nodsh && skip "remote OST with nodsh"
1939
1940         reset_enospc
1941         rm -f $DIR/$tdir/$tfile
1942
1943         test_mkdir $DIR/$tdir
1944         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1945         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1946                 error "truncate $DIR/$tdir/$tfile failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_all_precreations 0x215
1950
1951         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1952         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1953
1954         reset_enospc
1955 }
1956 run_test 27q "append to truncated file with all OSTs full (should error)"
1957
1958 test_27r() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966         exhaust_precreations 0 0x80000215
1967
1968         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1969
1970         reset_enospc
1971 }
1972 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1973
1974 test_27s() { # bug 10725
1975         test_mkdir $DIR/$tdir
1976         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1977         local stripe_count=0
1978         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1979         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1980                 error "stripe width >= 2^32 succeeded" || true
1981
1982 }
1983 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1984
1985 test_27t() { # bug 10864
1986         WDIR=$(pwd)
1987         WLFS=$(which lfs)
1988         cd $DIR
1989         touch $tfile
1990         $WLFS getstripe $tfile
1991         cd $WDIR
1992 }
1993 run_test 27t "check that utils parse path correctly"
1994
1995 test_27u() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998
1999         local index
2000         local list=$(comma_list $(mdts_nodes))
2001
2002 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2003         do_nodes $list $LCTL set_param fail_loc=0x139
2004         test_mkdir -p $DIR/$tdir
2005         trap simple_cleanup_common EXIT
2006         createmany -o $DIR/$tdir/t- 1000
2007         do_nodes $list $LCTL set_param fail_loc=0
2008
2009         TLOG=$TMP/$tfile.getstripe
2010         $LFS getstripe $DIR/$tdir > $TLOG
2011         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2012         unlinkmany $DIR/$tdir/t- 1000
2013         trap 0
2014         [[ $OBJS -gt 0 ]] &&
2015                 error "$OBJS objects created on OST-0. See $TLOG" ||
2016                 rm -f $TLOG
2017 }
2018 run_test 27u "skip object creation on OSC w/o objects"
2019
2020 test_27v() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2023         remote_mds_nodsh && skip "remote MDS with nodsh"
2024         remote_ost_nodsh && skip "remote OST with nodsh"
2025
2026         exhaust_all_precreations 0x215
2027         reset_enospc
2028
2029         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2030
2031         touch $DIR/$tdir/$tfile
2032         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2033         # all except ost1
2034         for (( i=1; i < OSTCOUNT; i++ )); do
2035                 do_facet ost$i lctl set_param fail_loc=0x705
2036         done
2037         local START=`date +%s`
2038         createmany -o $DIR/$tdir/$tfile 32
2039
2040         local FINISH=`date +%s`
2041         local TIMEOUT=`lctl get_param -n timeout`
2042         local PROCESS=$((FINISH - START))
2043         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2044                error "$FINISH - $START >= $TIMEOUT / 2"
2045         sleep $((TIMEOUT / 2 - PROCESS))
2046         reset_enospc
2047 }
2048 run_test 27v "skip object creation on slow OST"
2049
2050 test_27w() { # bug 10997
2051         test_mkdir $DIR/$tdir
2052         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2053         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2054                 error "stripe size $size != 65536" || true
2055         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2056                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2057 }
2058 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2059
2060 test_27wa() {
2061         [[ $OSTCOUNT -lt 2 ]] &&
2062                 skip_env "skipping multiple stripe count/offset test"
2063
2064         test_mkdir $DIR/$tdir
2065         for i in $(seq 1 $OSTCOUNT); do
2066                 offset=$((i - 1))
2067                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2068                         error "setstripe -c $i -i $offset failed"
2069                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2070                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2071                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2072                 [ $index -ne $offset ] &&
2073                         error "stripe offset $index != $offset" || true
2074         done
2075 }
2076 run_test 27wa "check $LFS setstripe -c -i options"
2077
2078 test_27x() {
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082
2083         OFFSET=$(($OSTCOUNT - 1))
2084         OSTIDX=0
2085         local OST=$(ostname_from_index $OSTIDX)
2086
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2089         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2090         sleep_maxage
2091         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2092         for i in $(seq 0 $OFFSET); do
2093                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2094                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2095                 error "OST0 was degraded but new created file still use it"
2096         done
2097         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2098 }
2099 run_test 27x "create files while OST0 is degraded"
2100
2101 test_27y() {
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         remote_mds_nodsh && skip "remote MDS with nodsh"
2104         remote_ost_nodsh && skip "remote OST with nodsh"
2105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2106
2107         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2108         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2109                 osp.$mdtosc.prealloc_last_id)
2110         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2111                 osp.$mdtosc.prealloc_next_id)
2112         local fcount=$((last_id - next_id))
2113         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2114         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2115
2116         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2117                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2118         local OST_DEACTIVE_IDX=-1
2119         local OSC
2120         local OSTIDX
2121         local OST
2122
2123         for OSC in $MDS_OSCS; do
2124                 OST=$(osc_to_ost $OSC)
2125                 OSTIDX=$(index_from_ostuuid $OST)
2126                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2127                         OST_DEACTIVE_IDX=$OSTIDX
2128                 fi
2129                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2130                         echo $OSC "is Deactivated:"
2131                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2132                 fi
2133         done
2134
2135         OSTIDX=$(index_from_ostuuid $OST)
2136         test_mkdir $DIR/$tdir
2137         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2138
2139         for OSC in $MDS_OSCS; do
2140                 OST=$(osc_to_ost $OSC)
2141                 OSTIDX=$(index_from_ostuuid $OST)
2142                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2143                         echo $OST "is degraded:"
2144                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2145                                                 obdfilter.$OST.degraded=1
2146                 fi
2147         done
2148
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $fcount
2151
2152         for OSC in $MDS_OSCS; do
2153                 OST=$(osc_to_ost $OSC)
2154                 OSTIDX=$(index_from_ostuuid $OST)
2155                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2156                         echo $OST "is recovered from degraded:"
2157                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2158                                                 obdfilter.$OST.degraded=0
2159                 else
2160                         do_facet $SINGLEMDS lctl --device %$OSC activate
2161                 fi
2162         done
2163
2164         # all osp devices get activated, hence -1 stripe count restored
2165         local stripe_count=0
2166
2167         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2168         # devices get activated.
2169         sleep_maxage
2170         $LFS setstripe -c -1 $DIR/$tfile
2171         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2172         rm -f $DIR/$tfile
2173         [ $stripe_count -ne $OSTCOUNT ] &&
2174                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2175         return 0
2176 }
2177 run_test 27y "create files while OST0 is degraded and the rest inactive"
2178
2179 check_seq_oid()
2180 {
2181         log "check file $1"
2182
2183         lmm_count=$($LFS getstripe -c $1)
2184         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2185         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2186
2187         local old_ifs="$IFS"
2188         IFS=$'[:]'
2189         fid=($($LFS path2fid $1))
2190         IFS="$old_ifs"
2191
2192         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2193         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2194
2195         # compare lmm_seq and lu_fid->f_seq
2196         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2197         # compare lmm_object_id and lu_fid->oid
2198         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2199
2200         # check the trusted.fid attribute of the OST objects of the file
2201         local have_obdidx=false
2202         local stripe_nr=0
2203         $LFS getstripe $1 | while read obdidx oid hex seq; do
2204                 # skip lines up to and including "obdidx"
2205                 [ -z "$obdidx" ] && break
2206                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2207                 $have_obdidx || continue
2208
2209                 local ost=$((obdidx + 1))
2210                 local dev=$(ostdevname $ost)
2211                 local oid_hex
2212
2213                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2214
2215                 seq=$(echo $seq | sed -e "s/^0x//g")
2216                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2217                         oid_hex=$(echo $oid)
2218                 else
2219                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2220                 fi
2221                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2222
2223                 local ff=""
2224                 #
2225                 # Don't unmount/remount the OSTs if we don't need to do that.
2226                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2227                 # update too, until that use mount/ll_decode_filter_fid/mount.
2228                 # Re-enable when debugfs will understand new filter_fid.
2229                 #
2230                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2231                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2232                                 $dev 2>/dev/null" | grep "parent=")
2233                 fi
2234                 if [ -z "$ff" ]; then
2235                         stop ost$ost
2236                         mount_fstype ost$ost
2237                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2238                                 $(facet_mntpt ost$ost)/$obj_file)
2239                         unmount_fstype ost$ost
2240                         start ost$ost $dev $OST_MOUNT_OPTS
2241                         clients_up
2242                 fi
2243
2244                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2245
2246                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2247
2248                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2249                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2250                 #
2251                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2252                 #       stripe_size=1048576 component_id=1 component_start=0 \
2253                 #       component_end=33554432
2254                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2255                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2256                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2257                 local ff_pstripe
2258                 if grep -q 'stripe=' <<<$ff; then
2259                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2260                 else
2261                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2262                         # into f_ver in this case.  See comment on ff_parent.
2263                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2264                 fi
2265
2266                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2267                 [ $ff_pseq = $lmm_seq ] ||
2268                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2269                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2270                 [ $ff_poid = $lmm_oid ] ||
2271                         error "FF parent OID $ff_poid != $lmm_oid"
2272                 (($ff_pstripe == $stripe_nr)) ||
2273                         error "FF stripe $ff_pstripe != $stripe_nr"
2274
2275                 stripe_nr=$((stripe_nr + 1))
2276                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2277                         continue
2278                 if grep -q 'stripe_count=' <<<$ff; then
2279                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2280                                             -e 's/ .*//' <<<$ff)
2281                         [ $lmm_count = $ff_scnt ] ||
2282                                 error "FF stripe count $lmm_count != $ff_scnt"
2283                 fi
2284         done
2285 }
2286
2287 test_27z() {
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2293                 { error "setstripe -c -1 failed"; return 1; }
2294         # We need to send a write to every object to get parent FID info set.
2295         # This _should_ also work for setattr, but does not currently.
2296         # touch $DIR/$tdir/$tfile-1 ||
2297         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2298                 { error "dd $tfile-1 failed"; return 2; }
2299         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2300                 { error "setstripe -c -1 failed"; return 3; }
2301         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2302                 { error "dd $tfile-2 failed"; return 4; }
2303
2304         # make sure write RPCs have been sent to OSTs
2305         sync; sleep 5; sync
2306
2307         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2308         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2309 }
2310 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2311
2312 test_27A() { # b=19102
2313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2314
2315         save_layout_restore_at_exit $MOUNT
2316         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2317         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2318                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2319         local default_size=$($LFS getstripe -S $MOUNT)
2320         local default_offset=$($LFS getstripe -i $MOUNT)
2321         local dsize=$(do_facet $SINGLEMDS \
2322                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2323         [ $default_size -eq $dsize ] ||
2324                 error "stripe size $default_size != $dsize"
2325         [ $default_offset -eq -1 ] ||
2326                 error "stripe offset $default_offset != -1"
2327 }
2328 run_test 27A "check filesystem-wide default LOV EA values"
2329
2330 test_27B() { # LU-2523
2331         test_mkdir $DIR/$tdir
2332         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2333         touch $DIR/$tdir/f0
2334         # open f1 with O_LOV_DELAY_CREATE
2335         # rename f0 onto f1
2336         # call setstripe ioctl on open file descriptor for f1
2337         # close
2338         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2339                 $DIR/$tdir/f0
2340
2341         rm -f $DIR/$tdir/f1
2342         # open f1 with O_LOV_DELAY_CREATE
2343         # unlink f1
2344         # call setstripe ioctl on open file descriptor for f1
2345         # close
2346         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2347
2348         # Allow multiop to fail in imitation of NFS's busted semantics.
2349         true
2350 }
2351 run_test 27B "call setstripe on open unlinked file/rename victim"
2352
2353 # 27C family tests full striping and overstriping
2354 test_27Ca() { #LU-2871
2355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2356
2357         declare -a ost_idx
2358         local index
2359         local found
2360         local i
2361         local j
2362
2363         test_mkdir $DIR/$tdir
2364         cd $DIR/$tdir
2365         for i in $(seq 0 $((OSTCOUNT - 1))); do
2366                 # set stripe across all OSTs starting from OST$i
2367                 $LFS setstripe -i $i -c -1 $tfile$i
2368                 # get striping information
2369                 ost_idx=($($LFS getstripe $tfile$i |
2370                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2371                 echo ${ost_idx[@]}
2372
2373                 # check the layout
2374                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2375                         error "${#ost_idx[@]} != $OSTCOUNT"
2376
2377                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2378                         found=0
2379                         for j in $(echo ${ost_idx[@]}); do
2380                                 if [ $index -eq $j ]; then
2381                                         found=1
2382                                         break
2383                                 fi
2384                         done
2385                         [ $found = 1 ] ||
2386                                 error "Can not find $index in ${ost_idx[@]}"
2387                 done
2388         done
2389 }
2390 run_test 27Ca "check full striping across all OSTs"
2391
2392 test_27Cb() {
2393         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2394                 skip "server does not support overstriping"
2395         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2396                 skip_env "too many osts, skipping"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT * 2))
2400         [ $setcount -ge 160 ] || large_xattr_enabled ||
2401                 skip_env "ea_inode feature disabled"
2402
2403         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2404                 error "setstripe failed"
2405
2406         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2407         [ $count -eq $setcount ] ||
2408                 error "stripe count $count, should be $setcount"
2409
2410         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2411                 error "overstriped should be set in pattern"
2412
2413         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2414                 error "dd failed"
2415 }
2416 run_test 27Cb "more stripes than OSTs with -C"
2417
2418 test_27Cc() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2422
2423         test_mkdir -p $DIR/$tdir
2424         local setcount=$(($OSTCOUNT - 1))
2425
2426         [ $setcount -ge 160 ] || large_xattr_enabled ||
2427                 skip_env "ea_inode feature disabled"
2428
2429         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2430                 error "setstripe failed"
2431
2432         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2433         [ $count -eq $setcount ] ||
2434                 error "stripe count $count, should be $setcount"
2435
2436         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2437                 error "overstriped should not be set in pattern"
2438
2439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2440                 error "dd failed"
2441 }
2442 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2443
2444 test_27Cd() {
2445         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2446                 skip "server does not support overstriping"
2447         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2448         large_xattr_enabled || skip_env "ea_inode feature disabled"
2449
2450         test_mkdir -p $DIR/$tdir
2451         local setcount=$LOV_MAX_STRIPE_COUNT
2452
2453         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2454                 error "setstripe failed"
2455
2456         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2457         [ $count -eq $setcount ] ||
2458                 error "stripe count $count, should be $setcount"
2459
2460         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2461                 error "overstriped should be set in pattern"
2462
2463         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2464                 error "dd failed"
2465
2466         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2467 }
2468 run_test 27Cd "test maximum stripe count"
2469
2470 test_27Ce() {
2471         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2472                 skip "server does not support overstriping"
2473         test_mkdir -p $DIR/$tdir
2474
2475         pool_add $TESTNAME || error "Pool creation failed"
2476         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2477
2478         local setcount=8
2479
2480         $LFS setstripe  -C $setcount -p "$TESTNAME" $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 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         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2494 }
2495 run_test 27Ce "test pool with overstriping"
2496
2497 test_27Cf() {
2498         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2499                 skip "server does not support overstriping"
2500         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2501                 skip_env "too many osts, skipping"
2502
2503         test_mkdir -p $DIR/$tdir
2504
2505         local setcount=$(($OSTCOUNT * 2))
2506         [ $setcount -ge 160 ] || large_xattr_enabled ||
2507                 skip_env "ea_inode feature disabled"
2508
2509         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2510                 error "setstripe failed"
2511
2512         echo 1 > $DIR/$tdir/$tfile
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2519                 error "overstriped should be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523
2524         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2525 }
2526 run_test 27Cf "test default inheritance with overstriping"
2527
2528 test_27D() {
2529         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2530         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2531         remote_mds_nodsh && skip "remote MDS with nodsh"
2532
2533         local POOL=${POOL:-testpool}
2534         local first_ost=0
2535         local last_ost=$(($OSTCOUNT - 1))
2536         local ost_step=1
2537         local ost_list=$(seq $first_ost $ost_step $last_ost)
2538         local ost_range="$first_ost $last_ost $ost_step"
2539
2540         test_mkdir $DIR/$tdir
2541         pool_add $POOL || error "pool_add failed"
2542         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2543
2544         local skip27D
2545         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2546                 skip27D+="-s 29"
2547         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2548                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2549                         skip27D+=" -s 30,31"
2550         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2551           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip27D+=" -s 32,33"
2553         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2554                 skip27D+=" -s 34"
2555         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2556                 error "llapi_layout_test failed"
2557
2558         destroy_test_pools || error "destroy test pools failed"
2559 }
2560 run_test 27D "validate llapi_layout API"
2561
2562 # Verify that default_easize is increased from its initial value after
2563 # accessing a widely striped file.
2564 test_27E() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2567                 skip "client does not have LU-3338 fix"
2568
2569         # 72 bytes is the minimum space required to store striping
2570         # information for a file striped across one OST:
2571         # (sizeof(struct lov_user_md_v3) +
2572         #  sizeof(struct lov_user_ost_data_v1))
2573         local min_easize=72
2574         $LCTL set_param -n llite.*.default_easize $min_easize ||
2575                 error "lctl set_param failed"
2576         local easize=$($LCTL get_param -n llite.*.default_easize)
2577
2578         [ $easize -eq $min_easize ] ||
2579                 error "failed to set default_easize"
2580
2581         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2582                 error "setstripe failed"
2583         # In order to ensure stat() call actually talks to MDS we need to
2584         # do something drastic to this file to shake off all lock, e.g.
2585         # rename it (kills lookup lock forcing cache cleaning)
2586         mv $DIR/$tfile $DIR/${tfile}-1
2587         ls -l $DIR/${tfile}-1
2588         rm $DIR/${tfile}-1
2589
2590         easize=$($LCTL get_param -n llite.*.default_easize)
2591
2592         [ $easize -gt $min_easize ] ||
2593                 error "default_easize not updated"
2594 }
2595 run_test 27E "check that default extended attribute size properly increases"
2596
2597 test_27F() { # LU-5346/LU-7975
2598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2599         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2600         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2601                 skip "Need MDS version at least 2.8.51"
2602         remote_ost_nodsh && skip "remote OST with nodsh"
2603
2604         test_mkdir $DIR/$tdir
2605         rm -f $DIR/$tdir/f0
2606         $LFS setstripe -c 2 $DIR/$tdir
2607
2608         # stop all OSTs to reproduce situation for LU-7975 ticket
2609         for num in $(seq $OSTCOUNT); do
2610                 stop ost$num
2611         done
2612
2613         # open/create f0 with O_LOV_DELAY_CREATE
2614         # truncate f0 to a non-0 size
2615         # close
2616         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2617
2618         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2619         # open/write it again to force delayed layout creation
2620         cat /etc/hosts > $DIR/$tdir/f0 &
2621         catpid=$!
2622
2623         # restart OSTs
2624         for num in $(seq $OSTCOUNT); do
2625                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2626                         error "ost$num failed to start"
2627         done
2628
2629         wait $catpid || error "cat failed"
2630
2631         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2632         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2633                 error "wrong stripecount"
2634
2635 }
2636 run_test 27F "Client resend delayed layout creation with non-zero size"
2637
2638 test_27G() { #LU-10629
2639         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2640                 skip "Need MDS version at least 2.11.51"
2641         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2642         remote_mds_nodsh && skip "remote MDS with nodsh"
2643         local POOL=${POOL:-testpool}
2644         local ostrange="0 0 1"
2645
2646         test_mkdir $DIR/$tdir
2647         touch $DIR/$tdir/$tfile.nopool
2648         pool_add $POOL || error "pool_add failed"
2649         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2650         $LFS setstripe -p $POOL $DIR/$tdir
2651
2652         local pool=$($LFS getstripe -p $DIR/$tdir)
2653
2654         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2655         touch $DIR/$tdir/$tfile.default
2656         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2657         $LFS find $DIR/$tdir -type f --pool $POOL
2658         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2659         [[ "$found" == "2" ]] ||
2660                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2661
2662         $LFS setstripe -d $DIR/$tdir
2663
2664         pool=$($LFS getstripe -p -d $DIR/$tdir)
2665
2666         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2667 }
2668 run_test 27G "Clear OST pool from stripe"
2669
2670 test_27H() {
2671         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2672                 skip "Need MDS version newer than 2.11.54"
2673         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2674         test_mkdir $DIR/$tdir
2675         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2676         touch $DIR/$tdir/$tfile
2677         $LFS getstripe -c $DIR/$tdir/$tfile
2678         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2679                 error "two-stripe file doesn't have two stripes"
2680
2681         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2682         $LFS getstripe -y $DIR/$tdir/$tfile
2683         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2684              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2685                 error "expected l_ost_idx: [02]$ not matched"
2686
2687         # make sure ost list has been cleared
2688         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2689         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2690                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2691         touch $DIR/$tdir/f3
2692         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2693 }
2694 run_test 27H "Set specific OSTs stripe"
2695
2696 test_27I() {
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2699         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2700                 skip "Need MDS version newer than 2.12.52"
2701         local pool=$TESTNAME
2702         local ostrange="1 1 1"
2703
2704         save_layout_restore_at_exit $MOUNT
2705         $LFS setstripe -c 2 -i 0 $MOUNT
2706         pool_add $pool || error "pool_add failed"
2707         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2708         test_mkdir $DIR/$tdir
2709         $LFS setstripe -p $pool $DIR/$tdir
2710         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2711         $LFS getstripe $DIR/$tdir/$tfile
2712 }
2713 run_test 27I "check that root dir striping does not break parent dir one"
2714
2715 test_27J() {
2716         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2717                 skip "Need MDS version newer than 2.12.51"
2718
2719         test_mkdir $DIR/$tdir
2720         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2721         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2722
2723         # create foreign file (raw way)
2724         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2725                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2726
2727         # verify foreign file (raw way)
2728         parse_foreign_file -f $DIR/$tdir/$tfile |
2729                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2730                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2731         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2732                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2733         parse_foreign_file -f $DIR/$tdir/$tfile |
2734                 grep "lov_foreign_size: 73" ||
2735                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2736         parse_foreign_file -f $DIR/$tdir/$tfile |
2737                 grep "lov_foreign_type: 1" ||
2738                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2739         parse_foreign_file -f $DIR/$tdir/$tfile |
2740                 grep "lov_foreign_flags: 0x0000DA08" ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2742         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2743                 grep "lov_foreign_value: 0x" |
2744                 sed -e 's/lov_foreign_value: 0x//')
2745         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2746         [[ $lov = ${lov2// /} ]] ||
2747                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2748
2749         # create foreign file (lfs + API)
2750         $LFS setstripe --foreign=none --flags 0xda08 \
2751                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2752                 error "$DIR/$tdir/${tfile}2: create failed"
2753
2754         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2755                 grep "lfm_magic:.*0x0BD70BD0" ||
2756                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2757         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2758         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2759                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2760         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2761                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2762         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2763                 grep "lfm_flags:.*0x0000DA08" ||
2764                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2765         $LFS getstripe $DIR/$tdir/${tfile}2 |
2766                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2767                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2768
2769         # modify striping should fail
2770         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2771                 error "$DIR/$tdir/$tfile: setstripe should fail"
2772         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2773                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2774
2775         # R/W should fail
2776         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2777         cat $DIR/$tdir/${tfile}2 &&
2778                 error "$DIR/$tdir/${tfile}2: read should fail"
2779         cat /etc/passwd > $DIR/$tdir/$tfile &&
2780                 error "$DIR/$tdir/$tfile: write should fail"
2781         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2782                 error "$DIR/$tdir/${tfile}2: write should fail"
2783
2784         # chmod should work
2785         chmod 222 $DIR/$tdir/$tfile ||
2786                 error "$DIR/$tdir/$tfile: chmod failed"
2787         chmod 222 $DIR/$tdir/${tfile}2 ||
2788                 error "$DIR/$tdir/${tfile}2: chmod failed"
2789
2790         # chown should work
2791         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2792                 error "$DIR/$tdir/$tfile: chown failed"
2793         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2794                 error "$DIR/$tdir/${tfile}2: chown failed"
2795
2796         # rename should work
2797         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2798                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2799         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2800                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2801
2802         #remove foreign file
2803         rm $DIR/$tdir/${tfile}.new ||
2804                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2805         rm $DIR/$tdir/${tfile}2.new ||
2806                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2807 }
2808 run_test 27J "basic ops on file with foreign LOV"
2809
2810 test_27K() {
2811         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2812                 skip "Need MDS version newer than 2.12.49"
2813
2814         test_mkdir $DIR/$tdir
2815         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2816         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2817
2818         # create foreign dir (raw way)
2819         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2820                 error "create_foreign_dir FAILED"
2821
2822         # verify foreign dir (raw way)
2823         parse_foreign_dir -d $DIR/$tdir/$tdir |
2824                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2825                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2826         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2827                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2828         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2829                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2830         parse_foreign_dir -d $DIR/$tdir/$tdir |
2831                 grep "lmv_foreign_flags: 55813$" ||
2832                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2833         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2834                 grep "lmv_foreign_value: 0x" |
2835                 sed 's/lmv_foreign_value: 0x//')
2836         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2837                 sed 's/ //g')
2838         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2839
2840         # create foreign dir (lfs + API)
2841         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2842                 $DIR/$tdir/${tdir}2 ||
2843                 error "$DIR/$tdir/${tdir}2: create failed"
2844
2845         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2846                 grep "lfm_magic:.*0x0CD50CD0" ||
2847                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2848         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2849         # - sizeof(lfm_type) - sizeof(lfm_flags)
2850         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2851                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2852         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2853                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2854         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2855                 grep "lfm_flags:.*0x0000DA05" ||
2856                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2857         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2858                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2859                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2860
2861         # file create in dir should fail
2862         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2863         touch $DIR/$tdir/${tdir}2/$tfile &&
2864                 "$DIR/${tdir}2: file create should fail"
2865
2866         # chmod should work
2867         chmod 777 $DIR/$tdir/$tdir ||
2868                 error "$DIR/$tdir: chmod failed"
2869         chmod 777 $DIR/$tdir/${tdir}2 ||
2870                 error "$DIR/${tdir}2: chmod failed"
2871
2872         # chown should work
2873         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2874                 error "$DIR/$tdir: chown failed"
2875         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2876                 error "$DIR/${tdir}2: chown failed"
2877
2878         # rename should work
2879         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2880                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2881         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2882                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2883
2884         #remove foreign dir
2885         rmdir $DIR/$tdir/${tdir}.new ||
2886                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2887         rmdir $DIR/$tdir/${tdir}2.new ||
2888                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2889 }
2890 run_test 27K "basic ops on dir with foreign LMV"
2891
2892 test_27L() {
2893         remote_mds_nodsh && skip "remote MDS with nodsh"
2894
2895         local POOL=${POOL:-$TESTNAME}
2896
2897         pool_add $POOL || error "pool_add failed"
2898
2899         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2900                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2901                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2902 }
2903 run_test 27L "lfs pool_list gives correct pool name"
2904
2905 test_27M() {
2906         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2907                 skip "Need MDS version >= than 2.12.57"
2908         remote_mds_nodsh && skip "remote MDS with nodsh"
2909         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2910
2911         test_mkdir $DIR/$tdir
2912
2913         # Set default striping on directory
2914         $LFS setstripe -C 4 $DIR/$tdir
2915
2916         echo 1 > $DIR/$tdir/${tfile}.1
2917         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2918         local setcount=4
2919         [ $count -eq $setcount ] ||
2920                 error "(1) stripe count $count, should be $setcount"
2921
2922         # Capture existing append_stripe_count setting for restore
2923         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2924         local mdts=$(comma_list $(mdts_nodes))
2925         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2926
2927         local appendcount=$orig_count
2928         echo 1 >> $DIR/$tdir/${tfile}.2_append
2929         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2930         [ $count -eq $appendcount ] ||
2931                 error "(2)stripe count $count, should be $appendcount for append"
2932
2933         # Disable O_APPEND striping, verify it works
2934         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2935
2936         # Should now get the default striping, which is 4
2937         setcount=4
2938         echo 1 >> $DIR/$tdir/${tfile}.3_append
2939         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2940         [ $count -eq $setcount ] ||
2941                 error "(3) stripe count $count, should be $setcount"
2942
2943         # Try changing the stripe count for append files
2944         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2945
2946         # Append striping is now 2 (directory default is still 4)
2947         appendcount=2
2948         echo 1 >> $DIR/$tdir/${tfile}.4_append
2949         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2950         [ $count -eq $appendcount ] ||
2951                 error "(4) stripe count $count, should be $appendcount for append"
2952
2953         # Test append stripe count of -1
2954         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2955         appendcount=$OSTCOUNT
2956         echo 1 >> $DIR/$tdir/${tfile}.5
2957         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2958         [ $count -eq $appendcount ] ||
2959                 error "(5) stripe count $count, should be $appendcount for append"
2960
2961         # Set append striping back to default of 1
2962         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2963
2964         # Try a new default striping, PFL + DOM
2965         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2966
2967         # Create normal DOM file, DOM returns stripe count == 0
2968         setcount=0
2969         touch $DIR/$tdir/${tfile}.6
2970         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2971         [ $count -eq $setcount ] ||
2972                 error "(6) stripe count $count, should be $setcount"
2973
2974         # Show
2975         appendcount=1
2976         echo 1 >> $DIR/$tdir/${tfile}.7_append
2977         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2978         [ $count -eq $appendcount ] ||
2979                 error "(7) stripe count $count, should be $appendcount for append"
2980
2981         # Clean up DOM layout
2982         $LFS setstripe -d $DIR/$tdir
2983
2984         # Now test that append striping works when layout is from root
2985         $LFS setstripe -c 2 $MOUNT
2986         # Make a special directory for this
2987         mkdir $DIR/${tdir}/${tdir}.2
2988         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2989
2990         # Verify for normal file
2991         setcount=2
2992         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2993         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2994         [ $count -eq $setcount ] ||
2995                 error "(8) stripe count $count, should be $setcount"
2996
2997         appendcount=1
2998         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2999         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3000         [ $count -eq $appendcount ] ||
3001                 error "(9) stripe count $count, should be $appendcount for append"
3002
3003         # Now test O_APPEND striping with pools
3004         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3005         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3006
3007         # Create the pool
3008         pool_add $TESTNAME || error "pool creation failed"
3009         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3010
3011         echo 1 >> $DIR/$tdir/${tfile}.10_append
3012
3013         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3014         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3015
3016         # Check that count is still correct
3017         appendcount=1
3018         echo 1 >> $DIR/$tdir/${tfile}.11_append
3019         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3020         [ $count -eq $appendcount ] ||
3021                 error "(11) stripe count $count, should be $appendcount for append"
3022
3023         # Disable O_APPEND stripe count, verify pool works separately
3024         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3025
3026         echo 1 >> $DIR/$tdir/${tfile}.12_append
3027
3028         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3029         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3030
3031         # Remove pool setting, verify it's not applied
3032         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3033
3034         echo 1 >> $DIR/$tdir/${tfile}.13_append
3035
3036         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3037         [ "$pool" = "" ] || error "(13) pool found: $pool"
3038 }
3039 run_test 27M "test O_APPEND striping"
3040
3041 test_27N() {
3042         combined_mgs_mds && skip "needs separate MGS/MDT"
3043
3044         pool_add $TESTNAME || error "pool_add failed"
3045         do_facet mgs "$LCTL pool_list $FSNAME" |
3046                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3047                 error "lctl pool_list on MGS failed"
3048 }
3049 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3050
3051 clean_foreign_symlink() {
3052         trap 0
3053         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3054         for i in $DIR/$tdir/* ; do
3055                 $LFS unlink_foreign $i || true
3056         done
3057 }
3058
3059 test_27O() {
3060         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3061                 skip "Need MDS version newer than 2.12.51"
3062
3063         test_mkdir $DIR/$tdir
3064         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3065         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3066
3067         trap clean_foreign_symlink EXIT
3068
3069         # enable foreign_symlink behaviour
3070         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3071
3072         # foreign symlink LOV format is a partial path by default
3073
3074         # create foreign file (lfs + API)
3075         $LFS setstripe --foreign=symlink --flags 0xda05 \
3076                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3077                 error "$DIR/$tdir/${tfile}: create failed"
3078
3079         $LFS getstripe -v $DIR/$tdir/${tfile} |
3080                 grep "lfm_magic:.*0x0BD70BD0" ||
3081                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3082         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3083                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3084         $LFS getstripe -v $DIR/$tdir/${tfile} |
3085                 grep "lfm_flags:.*0x0000DA05" ||
3086                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3087         $LFS getstripe $DIR/$tdir/${tfile} |
3088                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3089                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3090
3091         # modify striping should fail
3092         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3093                 error "$DIR/$tdir/$tfile: setstripe should fail"
3094
3095         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3096         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3097         cat /etc/passwd > $DIR/$tdir/$tfile &&
3098                 error "$DIR/$tdir/$tfile: write should fail"
3099
3100         # rename should succeed
3101         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3102                 error "$DIR/$tdir/$tfile: rename has failed"
3103
3104         #remove foreign_symlink file should fail
3105         rm $DIR/$tdir/${tfile}.new &&
3106                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3107
3108         #test fake symlink
3109         mkdir /tmp/${uuid1} ||
3110                 error "/tmp/${uuid1}: mkdir has failed"
3111         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3112                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3113         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3114         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3115                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3116         #read should succeed now
3117         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3118                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3119         #write should succeed now
3120         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3121                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3122         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3123                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3124         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3125                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3126
3127         #check that getstripe still works
3128         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3129                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3130
3131         # chmod should still succeed
3132         chmod 644 $DIR/$tdir/${tfile}.new ||
3133                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3134
3135         # chown should still succeed
3136         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3137                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3138
3139         # rename should still succeed
3140         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3141                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3142
3143         #remove foreign_symlink file should still fail
3144         rm $DIR/$tdir/${tfile} &&
3145                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3146
3147         #use special ioctl() to unlink foreign_symlink file
3148         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3149                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3150
3151 }
3152 run_test 27O "basic ops on foreign file of symlink type"
3153
3154 test_27P() {
3155         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3156                 skip "Need MDS version newer than 2.12.49"
3157
3158         test_mkdir $DIR/$tdir
3159         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3160         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3161
3162         trap clean_foreign_symlink EXIT
3163
3164         # enable foreign_symlink behaviour
3165         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3166
3167         # foreign symlink LMV format is a partial path by default
3168
3169         # create foreign dir (lfs + API)
3170         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3171                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3172                 error "$DIR/$tdir/${tdir}: create failed"
3173
3174         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3175                 grep "lfm_magic:.*0x0CD50CD0" ||
3176                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3177         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3178                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3179         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3180                 grep "lfm_flags:.*0x0000DA05" ||
3181                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3182         $LFS getdirstripe $DIR/$tdir/${tdir} |
3183                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3184                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3185
3186         # file create in dir should fail
3187         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3188         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3189
3190         # rename should succeed
3191         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3192                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3193
3194         #remove foreign_symlink dir should fail
3195         rmdir $DIR/$tdir/${tdir}.new &&
3196                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3197
3198         #test fake symlink
3199         mkdir -p /tmp/${uuid1}/${uuid2} ||
3200                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3201         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3202                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3203         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3204         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3205                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3206         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3207                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3208
3209         #check that getstripe fails now that foreign_symlink enabled
3210         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3211                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3212
3213         # file create in dir should work now
3214         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3215                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3216         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3217                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3218         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3219                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3220
3221         # chmod should still succeed
3222         chmod 755 $DIR/$tdir/${tdir}.new ||
3223                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3224
3225         # chown should still succeed
3226         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3227                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3228
3229         # rename should still succeed
3230         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3231                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3232
3233         #remove foreign_symlink dir should still fail
3234         rmdir $DIR/$tdir/${tdir} &&
3235                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3236
3237         #use special ioctl() to unlink foreign_symlink file
3238         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3239                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3240
3241         #created file should still exist
3242         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3243                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3244         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3245                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3246 }
3247 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3248
3249 # createtest also checks that device nodes are created and
3250 # then visible correctly (#2091)
3251 test_28() { # bug 2091
3252         test_mkdir $DIR/d28
3253         $CREATETEST $DIR/d28/ct || error "createtest failed"
3254 }
3255 run_test 28 "create/mknod/mkdir with bad file types ============"
3256
3257 test_29() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3259
3260         sync; sleep 1; sync # flush out any dirty pages from previous tests
3261         cancel_lru_locks
3262         test_mkdir $DIR/d29
3263         touch $DIR/d29/foo
3264         log 'first d29'
3265         ls -l $DIR/d29
3266
3267         declare -i LOCKCOUNTORIG=0
3268         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3269                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3270         done
3271         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3272
3273         declare -i LOCKUNUSEDCOUNTORIG=0
3274         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3275                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3276         done
3277
3278         log 'second d29'
3279         ls -l $DIR/d29
3280         log 'done'
3281
3282         declare -i LOCKCOUNTCURRENT=0
3283         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3284                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3285         done
3286
3287         declare -i LOCKUNUSEDCOUNTCURRENT=0
3288         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3289                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3290         done
3291
3292         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3293                 $LCTL set_param -n ldlm.dump_namespaces ""
3294                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3295                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3296                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3297                 return 2
3298         fi
3299         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3300                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3301                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3302                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3303                 return 3
3304         fi
3305 }
3306 run_test 29 "IT_GETATTR regression  ============================"
3307
3308 test_30a() { # was test_30
3309         cp $(which ls) $DIR || cp /bin/ls $DIR
3310         $DIR/ls / || error "Can't execute binary from lustre"
3311         rm $DIR/ls
3312 }
3313 run_test 30a "execute binary from Lustre (execve) =============="
3314
3315 test_30b() {
3316         cp `which ls` $DIR || cp /bin/ls $DIR
3317         chmod go+rx $DIR/ls
3318         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3319         rm $DIR/ls
3320 }
3321 run_test 30b "execute binary from Lustre as non-root ==========="
3322
3323 test_30c() { # b=22376
3324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3325
3326         cp $(which ls) $DIR || cp /bin/ls $DIR
3327         chmod a-rw $DIR/ls
3328         cancel_lru_locks mdc
3329         cancel_lru_locks osc
3330         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3331         rm -f $DIR/ls
3332 }
3333 run_test 30c "execute binary from Lustre without read perms ===="
3334
3335 test_30d() {
3336         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3337
3338         for i in {1..10}; do
3339                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3340                 local PID=$!
3341                 sleep 1
3342                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3343                 wait $PID || error "executing dd from Lustre failed"
3344                 rm -f $DIR/$tfile
3345         done
3346
3347         rm -f $DIR/dd
3348 }
3349 run_test 30d "execute binary from Lustre while clear locks"
3350
3351 test_31a() {
3352         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3353         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3354 }
3355 run_test 31a "open-unlink file =================================="
3356
3357 test_31b() {
3358         touch $DIR/f31 || error "touch $DIR/f31 failed"
3359         ln $DIR/f31 $DIR/f31b || error "ln failed"
3360         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3361         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3362 }
3363 run_test 31b "unlink file with multiple links while open ======="
3364
3365 test_31c() {
3366         touch $DIR/f31 || error "touch $DIR/f31 failed"
3367         ln $DIR/f31 $DIR/f31c || error "ln failed"
3368         multiop_bg_pause $DIR/f31 O_uc ||
3369                 error "multiop_bg_pause for $DIR/f31 failed"
3370         MULTIPID=$!
3371         $MULTIOP $DIR/f31c Ouc
3372         kill -USR1 $MULTIPID
3373         wait $MULTIPID
3374 }
3375 run_test 31c "open-unlink file with multiple links ============="
3376
3377 test_31d() {
3378         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3379         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3380 }
3381 run_test 31d "remove of open directory ========================="
3382
3383 test_31e() { # bug 2904
3384         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3385 }
3386 run_test 31e "remove of open non-empty directory ==============="
3387
3388 test_31f() { # bug 4554
3389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3390
3391         set -vx
3392         test_mkdir $DIR/d31f
3393         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3394         cp /etc/hosts $DIR/d31f
3395         ls -l $DIR/d31f
3396         $LFS getstripe $DIR/d31f/hosts
3397         multiop_bg_pause $DIR/d31f D_c || return 1
3398         MULTIPID=$!
3399
3400         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3401         test_mkdir $DIR/d31f
3402         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3403         cp /etc/hosts $DIR/d31f
3404         ls -l $DIR/d31f
3405         $LFS getstripe $DIR/d31f/hosts
3406         multiop_bg_pause $DIR/d31f D_c || return 1
3407         MULTIPID2=$!
3408
3409         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3410         wait $MULTIPID || error "first opendir $MULTIPID failed"
3411
3412         sleep 6
3413
3414         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3415         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3416         set +vx
3417 }
3418 run_test 31f "remove of open directory with open-unlink file ==="
3419
3420 test_31g() {
3421         echo "-- cross directory link --"
3422         test_mkdir -c1 $DIR/${tdir}ga
3423         test_mkdir -c1 $DIR/${tdir}gb
3424         touch $DIR/${tdir}ga/f
3425         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3426         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3427         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3428         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3429         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3430 }
3431 run_test 31g "cross directory link==============="
3432
3433 test_31h() {
3434         echo "-- cross directory link --"
3435         test_mkdir -c1 $DIR/${tdir}
3436         test_mkdir -c1 $DIR/${tdir}/dir
3437         touch $DIR/${tdir}/f
3438         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3439         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3440         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3441         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3442         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3443 }
3444 run_test 31h "cross directory link under child==============="
3445
3446 test_31i() {
3447         echo "-- cross directory link --"
3448         test_mkdir -c1 $DIR/$tdir
3449         test_mkdir -c1 $DIR/$tdir/dir
3450         touch $DIR/$tdir/dir/f
3451         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3452         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3453         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3454         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3455         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3456 }
3457 run_test 31i "cross directory link under parent==============="
3458
3459 test_31j() {
3460         test_mkdir -c1 -p $DIR/$tdir
3461         test_mkdir -c1 -p $DIR/$tdir/dir1
3462         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3463         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3464         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3465         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3466         return 0
3467 }
3468 run_test 31j "link for directory==============="
3469
3470 test_31k() {
3471         test_mkdir -c1 -p $DIR/$tdir
3472         touch $DIR/$tdir/s
3473         touch $DIR/$tdir/exist
3474         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3475         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3476         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3477         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3478         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3479         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3480         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3481         return 0
3482 }
3483 run_test 31k "link to file: the same, non-existing, dir==============="
3484
3485 test_31m() {
3486         mkdir $DIR/d31m
3487         touch $DIR/d31m/s
3488         mkdir $DIR/d31m2
3489         touch $DIR/d31m2/exist
3490         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3491         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3492         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3493         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3494         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3495         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3496         return 0
3497 }
3498 run_test 31m "link to file: the same, non-existing, dir==============="
3499
3500 test_31n() {
3501         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3502         nlink=$(stat --format=%h $DIR/$tfile)
3503         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3504         local fd=$(free_fd)
3505         local cmd="exec $fd<$DIR/$tfile"
3506         eval $cmd
3507         cmd="exec $fd<&-"
3508         trap "eval $cmd" EXIT
3509         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3510         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3511         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3512         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3513         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3514         eval $cmd
3515 }
3516 run_test 31n "check link count of unlinked file"
3517
3518 link_one() {
3519         local tempfile=$(mktemp $1_XXXXXX)
3520         mlink $tempfile $1 2> /dev/null &&
3521                 echo "$BASHPID: link $tempfile to $1 succeeded"
3522         munlink $tempfile
3523 }
3524
3525 test_31o() { # LU-2901
3526         test_mkdir $DIR/$tdir
3527         for LOOP in $(seq 100); do
3528                 rm -f $DIR/$tdir/$tfile*
3529                 for THREAD in $(seq 8); do
3530                         link_one $DIR/$tdir/$tfile.$LOOP &
3531                 done
3532                 wait
3533                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3534                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3535                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3536                         break || true
3537         done
3538 }
3539 run_test 31o "duplicate hard links with same filename"
3540
3541 test_31p() {
3542         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3543
3544         test_mkdir $DIR/$tdir
3545         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3546         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3547
3548         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3549                 error "open unlink test1 failed"
3550         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3551                 error "open unlink test2 failed"
3552
3553         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3554                 error "test1 still exists"
3555         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3556                 error "test2 still exists"
3557 }
3558 run_test 31p "remove of open striped directory"
3559
3560 test_31q() {
3561         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3562
3563         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3564         index=$($LFS getdirstripe -i $DIR/$tdir)
3565         [ $index -eq 3 ] || error "first stripe index $index != 3"
3566         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3567         [ $index -eq 1 ] || error "second stripe index $index != 1"
3568
3569         # when "-c <stripe_count>" is set, the number of MDTs specified after
3570         # "-i" should equal to the stripe count
3571         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3572 }
3573 run_test 31q "create striped directory on specific MDTs"
3574
3575 cleanup_test32_mount() {
3576         local rc=0
3577         trap 0
3578         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3579         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3580         losetup -d $loopdev || true
3581         rm -rf $DIR/$tdir
3582         return $rc
3583 }
3584
3585 test_32a() {
3586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3587
3588         echo "== more mountpoints and symlinks ================="
3589         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3590         trap cleanup_test32_mount EXIT
3591         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3592         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3593                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3594         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3595                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3596         cleanup_test32_mount
3597 }
3598 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3599
3600 test_32b() {
3601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3602
3603         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3604         trap cleanup_test32_mount EXIT
3605         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3606         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3607                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3608         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3609                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3610         cleanup_test32_mount
3611 }
3612 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3613
3614 test_32c() {
3615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3616
3617         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3618         trap cleanup_test32_mount EXIT
3619         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3620         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3621                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3622         test_mkdir -p $DIR/$tdir/d2/test_dir
3623         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3624                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3625         cleanup_test32_mount
3626 }
3627 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3628
3629 test_32d() {
3630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3631
3632         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3633         trap cleanup_test32_mount EXIT
3634         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3635         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3636                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3637         test_mkdir -p $DIR/$tdir/d2/test_dir
3638         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3639                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3640         cleanup_test32_mount
3641 }
3642 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3643
3644 test_32e() {
3645         rm -fr $DIR/$tdir
3646         test_mkdir -p $DIR/$tdir/tmp
3647         local tmp_dir=$DIR/$tdir/tmp
3648         ln -s $DIR/$tdir $tmp_dir/symlink11
3649         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3650         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3651         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3652 }
3653 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3654
3655 test_32f() {
3656         rm -fr $DIR/$tdir
3657         test_mkdir -p $DIR/$tdir/tmp
3658         local tmp_dir=$DIR/$tdir/tmp
3659         ln -s $DIR/$tdir $tmp_dir/symlink11
3660         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3661         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3662         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3663 }
3664 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3665
3666 test_32g() {
3667         local tmp_dir=$DIR/$tdir/tmp
3668         test_mkdir -p $tmp_dir
3669         test_mkdir $DIR/${tdir}2
3670         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3671         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3672         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3673         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3674         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3675         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3676 }
3677 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3678
3679 test_32h() {
3680         rm -fr $DIR/$tdir $DIR/${tdir}2
3681         tmp_dir=$DIR/$tdir/tmp
3682         test_mkdir -p $tmp_dir
3683         test_mkdir $DIR/${tdir}2
3684         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3685         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3686         ls $tmp_dir/symlink12 || error "listing symlink12"
3687         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3688 }
3689 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3690
3691 test_32i() {
3692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3693
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         touch $DIR/$tdir/test_file
3700         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3701                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3702         cleanup_test32_mount
3703 }
3704 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3705
3706 test_32j() {
3707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3708
3709         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3710         trap cleanup_test32_mount EXIT
3711         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3712         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3713                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3714         touch $DIR/$tdir/test_file
3715         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3716                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3717         cleanup_test32_mount
3718 }
3719 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3720
3721 test_32k() {
3722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3723
3724         rm -fr $DIR/$tdir
3725         trap cleanup_test32_mount EXIT
3726         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3727         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3728                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3729         test_mkdir -p $DIR/$tdir/d2
3730         touch $DIR/$tdir/d2/test_file || error "touch failed"
3731         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3732                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3733         cleanup_test32_mount
3734 }
3735 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3736
3737 test_32l() {
3738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3739
3740         rm -fr $DIR/$tdir
3741         trap cleanup_test32_mount EXIT
3742         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3743         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3744                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3745         test_mkdir -p $DIR/$tdir/d2
3746         touch $DIR/$tdir/d2/test_file || error "touch failed"
3747         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3748                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3749         cleanup_test32_mount
3750 }
3751 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3752
3753 test_32m() {
3754         rm -fr $DIR/d32m
3755         test_mkdir -p $DIR/d32m/tmp
3756         TMP_DIR=$DIR/d32m/tmp
3757         ln -s $DIR $TMP_DIR/symlink11
3758         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3759         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3760                 error "symlink11 not a link"
3761         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3762                 error "symlink01 not a link"
3763 }
3764 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3765
3766 test_32n() {
3767         rm -fr $DIR/d32n
3768         test_mkdir -p $DIR/d32n/tmp
3769         TMP_DIR=$DIR/d32n/tmp
3770         ln -s $DIR $TMP_DIR/symlink11
3771         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3772         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3773         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3774 }
3775 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3776
3777 test_32o() {
3778         touch $DIR/$tfile
3779         test_mkdir -p $DIR/d32o/tmp
3780         TMP_DIR=$DIR/d32o/tmp
3781         ln -s $DIR/$tfile $TMP_DIR/symlink12
3782         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3783         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3784                 error "symlink12 not a link"
3785         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3786         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3787                 error "$DIR/d32o/tmp/symlink12 not file type"
3788         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3789                 error "$DIR/d32o/symlink02 not file type"
3790 }
3791 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3792
3793 test_32p() {
3794         log 32p_1
3795         rm -fr $DIR/d32p
3796         log 32p_2
3797         rm -f $DIR/$tfile
3798         log 32p_3
3799         touch $DIR/$tfile
3800         log 32p_4
3801         test_mkdir -p $DIR/d32p/tmp
3802         log 32p_5
3803         TMP_DIR=$DIR/d32p/tmp
3804         log 32p_6
3805         ln -s $DIR/$tfile $TMP_DIR/symlink12
3806         log 32p_7
3807         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3808         log 32p_8
3809         cat $DIR/d32p/tmp/symlink12 ||
3810                 error "Can't open $DIR/d32p/tmp/symlink12"
3811         log 32p_9
3812         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3813         log 32p_10
3814 }
3815 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3816
3817 test_32q() {
3818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3819
3820         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3821         trap cleanup_test32_mount EXIT
3822         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3823         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3824         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3825                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3826         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3827         cleanup_test32_mount
3828 }
3829 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3830
3831 test_32r() {
3832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3833
3834         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3835         trap cleanup_test32_mount EXIT
3836         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3837         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3838         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3839                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3840         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3841         cleanup_test32_mount
3842 }
3843 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3844
3845 test_33aa() {
3846         rm -f $DIR/$tfile
3847         touch $DIR/$tfile
3848         chmod 444 $DIR/$tfile
3849         chown $RUNAS_ID $DIR/$tfile
3850         log 33_1
3851         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3852         log 33_2
3853 }
3854 run_test 33aa "write file with mode 444 (should return error)"
3855
3856 test_33a() {
3857         rm -fr $DIR/$tdir
3858         test_mkdir $DIR/$tdir
3859         chown $RUNAS_ID $DIR/$tdir
3860         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3861                 error "$RUNAS create $tdir/$tfile failed"
3862         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3863                 error "open RDWR" || true
3864 }
3865 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3866
3867 test_33b() {
3868         rm -fr $DIR/$tdir
3869         test_mkdir $DIR/$tdir
3870         chown $RUNAS_ID $DIR/$tdir
3871         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3872 }
3873 run_test 33b "test open file with malformed flags (No panic)"
3874
3875 test_33c() {
3876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3877         remote_ost_nodsh && skip "remote OST with nodsh"
3878
3879         local ostnum
3880         local ostname
3881         local write_bytes
3882         local all_zeros
3883
3884         all_zeros=:
3885         rm -fr $DIR/$tdir
3886         test_mkdir $DIR/$tdir
3887         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3888
3889         sync
3890         for ostnum in $(seq $OSTCOUNT); do
3891                 # test-framework's OST numbering is one-based, while Lustre's
3892                 # is zero-based
3893                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3894                 # Parsing llobdstat's output sucks; we could grep the /proc
3895                 # path, but that's likely to not be as portable as using the
3896                 # llobdstat utility.  So we parse lctl output instead.
3897                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3898                         obdfilter/$ostname/stats |
3899                         awk '/^write_bytes/ {print $7}' )
3900                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3901                 if (( ${write_bytes:-0} > 0 ))
3902                 then
3903                         all_zeros=false
3904                         break;
3905                 fi
3906         done
3907
3908         $all_zeros || return 0
3909
3910         # Write four bytes
3911         echo foo > $DIR/$tdir/bar
3912         # Really write them
3913         sync
3914
3915         # Total up write_bytes after writing.  We'd better find non-zeros.
3916         for ostnum in $(seq $OSTCOUNT); do
3917                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3918                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3919                         obdfilter/$ostname/stats |
3920                         awk '/^write_bytes/ {print $7}' )
3921                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3922                 if (( ${write_bytes:-0} > 0 ))
3923                 then
3924                         all_zeros=false
3925                         break;
3926                 fi
3927         done
3928
3929         if $all_zeros
3930         then
3931                 for ostnum in $(seq $OSTCOUNT); do
3932                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3933                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3934                         do_facet ost$ostnum lctl get_param -n \
3935                                 obdfilter/$ostname/stats
3936                 done
3937                 error "OST not keeping write_bytes stats (b22312)"
3938         fi
3939 }
3940 run_test 33c "test llobdstat and write_bytes"
3941
3942 test_33d() {
3943         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3945
3946         local MDTIDX=1
3947         local remote_dir=$DIR/$tdir/remote_dir
3948
3949         test_mkdir $DIR/$tdir
3950         $LFS mkdir -i $MDTIDX $remote_dir ||
3951                 error "create remote directory failed"
3952
3953         touch $remote_dir/$tfile
3954         chmod 444 $remote_dir/$tfile
3955         chown $RUNAS_ID $remote_dir/$tfile
3956
3957         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3958
3959         chown $RUNAS_ID $remote_dir
3960         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3961                                         error "create" || true
3962         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3963                                     error "open RDWR" || true
3964         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3965 }
3966 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3967
3968 test_33e() {
3969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3970
3971         mkdir $DIR/$tdir
3972
3973         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3974         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3975         mkdir $DIR/$tdir/local_dir
3976
3977         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3978         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3979         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3980
3981         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3982                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3983
3984         rmdir $DIR/$tdir/* || error "rmdir failed"
3985
3986         umask 777
3987         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3988         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3989         mkdir $DIR/$tdir/local_dir
3990
3991         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3992         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3993         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3994
3995         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3996                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3997
3998         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3999
4000         umask 000
4001         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4002         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4003         mkdir $DIR/$tdir/local_dir
4004
4005         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4006         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4007         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4008
4009         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4010                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4011 }
4012 run_test 33e "mkdir and striped directory should have same mode"
4013
4014 cleanup_33f() {
4015         trap 0
4016         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4017 }
4018
4019 test_33f() {
4020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4021         remote_mds_nodsh && skip "remote MDS with nodsh"
4022
4023         mkdir $DIR/$tdir
4024         chmod go+rwx $DIR/$tdir
4025         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4026         trap cleanup_33f EXIT
4027
4028         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4029                 error "cannot create striped directory"
4030
4031         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4032                 error "cannot create files in striped directory"
4033
4034         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4035                 error "cannot remove files in striped directory"
4036
4037         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4038                 error "cannot remove striped directory"
4039
4040         cleanup_33f
4041 }
4042 run_test 33f "nonroot user can create, access, and remove a striped directory"
4043
4044 test_33g() {
4045         mkdir -p $DIR/$tdir/dir2
4046
4047         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4048         echo $err
4049         [[ $err =~ "exists" ]] || error "Not exists error"
4050 }
4051 run_test 33g "nonroot user create already existing root created file"
4052
4053 test_33h() {
4054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4055         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4056                 skip "Need MDS version at least 2.13.50"
4057
4058         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4059                 error "mkdir $tdir failed"
4060         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4061
4062         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4063         local index2
4064
4065         for fname in $DIR/$tdir/$tfile.bak \
4066                      $DIR/$tdir/$tfile.SAV \
4067                      $DIR/$tdir/$tfile.orig \
4068                      $DIR/$tdir/$tfile~; do
4069                 touch $fname  || error "touch $fname failed"
4070                 index2=$($LFS getstripe -m $fname)
4071                 [ $index -eq $index2 ] ||
4072                         error "$fname MDT index mismatch $index != $index2"
4073         done
4074
4075         local failed=0
4076         for i in {1..250}; do
4077                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4078                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4079                         touch $fname  || error "touch $fname failed"
4080                         index2=$($LFS getstripe -m $fname)
4081                         if [[ $index != $index2 ]]; then
4082                                 failed=$((failed + 1))
4083                                 echo "$fname MDT index mismatch $index != $index2"
4084                         fi
4085                 done
4086         done
4087         echo "$failed MDT index mismatches"
4088         (( failed < 20 )) || error "MDT index mismatch $failed times"
4089
4090 }
4091 run_test 33h "temp file is located on the same MDT as target"
4092
4093 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4094 test_34a() {
4095         rm -f $DIR/f34
4096         $MCREATE $DIR/f34 || error "mcreate failed"
4097         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4098                 error "getstripe failed"
4099         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4100         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4101                 error "getstripe failed"
4102         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4103                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4104 }
4105 run_test 34a "truncate file that has not been opened ==========="
4106
4107 test_34b() {
4108         [ ! -f $DIR/f34 ] && test_34a
4109         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4110                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4111         $OPENFILE -f O_RDONLY $DIR/f34
4112         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4113                 error "getstripe failed"
4114         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4115                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4116 }
4117 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4118
4119 test_34c() {
4120         [ ! -f $DIR/f34 ] && test_34a
4121         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4122                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4123         $OPENFILE -f O_RDWR $DIR/f34
4124         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4125                 error "$LFS getstripe failed"
4126         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4127                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4128 }
4129 run_test 34c "O_RDWR opening file-with-size works =============="
4130
4131 test_34d() {
4132         [ ! -f $DIR/f34 ] && test_34a
4133         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4134                 error "dd failed"
4135         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4136                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4137         rm $DIR/f34
4138 }
4139 run_test 34d "write to sparse file ============================="
4140
4141 test_34e() {
4142         rm -f $DIR/f34e
4143         $MCREATE $DIR/f34e || error "mcreate failed"
4144         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4145         $CHECKSTAT -s 1000 $DIR/f34e ||
4146                 error "Size of $DIR/f34e not equal to 1000 bytes"
4147         $OPENFILE -f O_RDWR $DIR/f34e
4148         $CHECKSTAT -s 1000 $DIR/f34e ||
4149                 error "Size of $DIR/f34e not equal to 1000 bytes"
4150 }
4151 run_test 34e "create objects, some with size and some without =="
4152
4153 test_34f() { # bug 6242, 6243
4154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4155
4156         SIZE34F=48000
4157         rm -f $DIR/f34f
4158         $MCREATE $DIR/f34f || error "mcreate failed"
4159         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4160         dd if=$DIR/f34f of=$TMP/f34f
4161         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4162         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4163         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4164         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4165         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4166 }
4167 run_test 34f "read from a file with no objects until EOF ======="
4168
4169 test_34g() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171
4172         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4173                 error "dd failed"
4174         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4175         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4176                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4177         cancel_lru_locks osc
4178         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4179                 error "wrong size after lock cancel"
4180
4181         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4182         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4183                 error "expanding truncate failed"
4184         cancel_lru_locks osc
4185         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4186                 error "wrong expanded size after lock cancel"
4187 }
4188 run_test 34g "truncate long file ==============================="
4189
4190 test_34h() {
4191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4192
4193         local gid=10
4194         local sz=1000
4195
4196         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4197         sync # Flush the cache so that multiop below does not block on cache
4198              # flush when getting the group lock
4199         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4200         MULTIPID=$!
4201
4202         # Since just timed wait is not good enough, let's do a sync write
4203         # that way we are sure enough time for a roundtrip + processing
4204         # passed + 2 seconds of extra margin.
4205         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4206         rm $DIR/${tfile}-1
4207         sleep 2
4208
4209         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4210                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4211                 kill -9 $MULTIPID
4212         fi
4213         wait $MULTIPID
4214         local nsz=`stat -c %s $DIR/$tfile`
4215         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4216 }
4217 run_test 34h "ftruncate file under grouplock should not block"
4218
4219 test_35a() {
4220         cp /bin/sh $DIR/f35a
4221         chmod 444 $DIR/f35a
4222         chown $RUNAS_ID $DIR/f35a
4223         $RUNAS $DIR/f35a && error || true
4224         rm $DIR/f35a
4225 }
4226 run_test 35a "exec file with mode 444 (should return and not leak)"
4227
4228 test_36a() {
4229         rm -f $DIR/f36
4230         utime $DIR/f36 || error "utime failed for MDS"
4231 }
4232 run_test 36a "MDS utime check (mknod, utime)"
4233
4234 test_36b() {
4235         echo "" > $DIR/f36
4236         utime $DIR/f36 || error "utime failed for OST"
4237 }
4238 run_test 36b "OST utime check (open, utime)"
4239
4240 test_36c() {
4241         rm -f $DIR/d36/f36
4242         test_mkdir $DIR/d36
4243         chown $RUNAS_ID $DIR/d36
4244         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4245 }
4246 run_test 36c "non-root MDS utime check (mknod, utime)"
4247
4248 test_36d() {
4249         [ ! -d $DIR/d36 ] && test_36c
4250         echo "" > $DIR/d36/f36
4251         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4252 }
4253 run_test 36d "non-root OST utime check (open, utime)"
4254
4255 test_36e() {
4256         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4257
4258         test_mkdir $DIR/$tdir
4259         touch $DIR/$tdir/$tfile
4260         $RUNAS utime $DIR/$tdir/$tfile &&
4261                 error "utime worked, expected failure" || true
4262 }
4263 run_test 36e "utime on non-owned file (should return error)"
4264
4265 subr_36fh() {
4266         local fl="$1"
4267         local LANG_SAVE=$LANG
4268         local LC_LANG_SAVE=$LC_LANG
4269         export LANG=C LC_LANG=C # for date language
4270
4271         DATESTR="Dec 20  2000"
4272         test_mkdir $DIR/$tdir
4273         lctl set_param fail_loc=$fl
4274         date; date +%s
4275         cp /etc/hosts $DIR/$tdir/$tfile
4276         sync & # write RPC generated with "current" inode timestamp, but delayed
4277         sleep 1
4278         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4279         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4280         cancel_lru_locks $OSC
4281         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4282         date; date +%s
4283         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4284                 echo "BEFORE: $LS_BEFORE" && \
4285                 echo "AFTER : $LS_AFTER" && \
4286                 echo "WANT  : $DATESTR" && \
4287                 error "$DIR/$tdir/$tfile timestamps changed" || true
4288
4289         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4290 }
4291
4292 test_36f() {
4293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4294
4295         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4296         subr_36fh "0x80000214"
4297 }
4298 run_test 36f "utime on file racing with OST BRW write =========="
4299
4300 test_36g() {
4301         remote_ost_nodsh && skip "remote OST with nodsh"
4302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4303         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4304                 skip "Need MDS version at least 2.12.51"
4305
4306         local fmd_max_age
4307         local fmd
4308         local facet="ost1"
4309         local tgt="obdfilter"
4310
4311         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4312
4313         test_mkdir $DIR/$tdir
4314         fmd_max_age=$(do_facet $facet \
4315                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4316                 head -n 1")
4317
4318         echo "FMD max age: ${fmd_max_age}s"
4319         touch $DIR/$tdir/$tfile
4320         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4321                 gawk '{cnt=cnt+$1}  END{print cnt}')
4322         echo "FMD before: $fmd"
4323         [[ $fmd == 0 ]] &&
4324                 error "FMD wasn't create by touch"
4325         sleep $((fmd_max_age + 12))
4326         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4327                 gawk '{cnt=cnt+$1}  END{print cnt}')
4328         echo "FMD after: $fmd"
4329         [[ $fmd == 0 ]] ||
4330                 error "FMD wasn't expired by ping"
4331 }
4332 run_test 36g "FMD cache expiry ====================="
4333
4334 test_36h() {
4335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4336
4337         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4338         subr_36fh "0x80000227"
4339 }
4340 run_test 36h "utime on file racing with OST BRW write =========="
4341
4342 test_36i() {
4343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4344
4345         test_mkdir $DIR/$tdir
4346         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4347
4348         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4349         local new_mtime=$((mtime + 200))
4350
4351         #change Modify time of striped dir
4352         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4353                         error "change mtime failed"
4354
4355         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4356
4357         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4358 }
4359 run_test 36i "change mtime on striped directory"
4360
4361 # test_37 - duplicate with tests 32q 32r
4362
4363 test_38() {
4364         local file=$DIR/$tfile
4365         touch $file
4366         openfile -f O_DIRECTORY $file
4367         local RC=$?
4368         local ENOTDIR=20
4369         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4370         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4371 }
4372 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4373
4374 test_39a() { # was test_39
4375         touch $DIR/$tfile
4376         touch $DIR/${tfile}2
4377 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4378 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4379 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4380         sleep 2
4381         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4382         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4383                 echo "mtime"
4384                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4385                 echo "atime"
4386                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4387                 echo "ctime"
4388                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4389                 error "O_TRUNC didn't change timestamps"
4390         fi
4391 }
4392 run_test 39a "mtime changed on create"
4393
4394 test_39b() {
4395         test_mkdir -c1 $DIR/$tdir
4396         cp -p /etc/passwd $DIR/$tdir/fopen
4397         cp -p /etc/passwd $DIR/$tdir/flink
4398         cp -p /etc/passwd $DIR/$tdir/funlink
4399         cp -p /etc/passwd $DIR/$tdir/frename
4400         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4401
4402         sleep 1
4403         echo "aaaaaa" >> $DIR/$tdir/fopen
4404         echo "aaaaaa" >> $DIR/$tdir/flink
4405         echo "aaaaaa" >> $DIR/$tdir/funlink
4406         echo "aaaaaa" >> $DIR/$tdir/frename
4407
4408         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4409         local link_new=`stat -c %Y $DIR/$tdir/flink`
4410         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4411         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4412
4413         cat $DIR/$tdir/fopen > /dev/null
4414         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4415         rm -f $DIR/$tdir/funlink2
4416         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4417
4418         for (( i=0; i < 2; i++ )) ; do
4419                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4420                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4421                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4422                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4423
4424                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4425                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4426                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4427                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4428
4429                 cancel_lru_locks $OSC
4430                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4431         done
4432 }
4433 run_test 39b "mtime change on open, link, unlink, rename  ======"
4434
4435 # this should be set to past
4436 TEST_39_MTIME=`date -d "1 year ago" +%s`
4437
4438 # bug 11063
4439 test_39c() {
4440         touch $DIR1/$tfile
4441         sleep 2
4442         local mtime0=`stat -c %Y $DIR1/$tfile`
4443
4444         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4445         local mtime1=`stat -c %Y $DIR1/$tfile`
4446         [ "$mtime1" = $TEST_39_MTIME ] || \
4447                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4448
4449         local d1=`date +%s`
4450         echo hello >> $DIR1/$tfile
4451         local d2=`date +%s`
4452         local mtime2=`stat -c %Y $DIR1/$tfile`
4453         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4454                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4455
4456         mv $DIR1/$tfile $DIR1/$tfile-1
4457
4458         for (( i=0; i < 2; i++ )) ; do
4459                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4460                 [ "$mtime2" = "$mtime3" ] || \
4461                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4462
4463                 cancel_lru_locks $OSC
4464                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4465         done
4466 }
4467 run_test 39c "mtime change on rename ==========================="
4468
4469 # bug 21114
4470 test_39d() {
4471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4472
4473         touch $DIR1/$tfile
4474         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4475
4476         for (( i=0; i < 2; i++ )) ; do
4477                 local mtime=`stat -c %Y $DIR1/$tfile`
4478                 [ $mtime = $TEST_39_MTIME ] || \
4479                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4480
4481                 cancel_lru_locks $OSC
4482                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4483         done
4484 }
4485 run_test 39d "create, utime, stat =============================="
4486
4487 # bug 21114
4488 test_39e() {
4489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4490
4491         touch $DIR1/$tfile
4492         local mtime1=`stat -c %Y $DIR1/$tfile`
4493
4494         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4495
4496         for (( i=0; i < 2; i++ )) ; do
4497                 local mtime2=`stat -c %Y $DIR1/$tfile`
4498                 [ $mtime2 = $TEST_39_MTIME ] || \
4499                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4500
4501                 cancel_lru_locks $OSC
4502                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4503         done
4504 }
4505 run_test 39e "create, stat, utime, stat ========================"
4506
4507 # bug 21114
4508 test_39f() {
4509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4510
4511         touch $DIR1/$tfile
4512         mtime1=`stat -c %Y $DIR1/$tfile`
4513
4514         sleep 2
4515         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4516
4517         for (( i=0; i < 2; i++ )) ; do
4518                 local mtime2=`stat -c %Y $DIR1/$tfile`
4519                 [ $mtime2 = $TEST_39_MTIME ] || \
4520                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4521
4522                 cancel_lru_locks $OSC
4523                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4524         done
4525 }
4526 run_test 39f "create, stat, sleep, utime, stat ================="
4527
4528 # bug 11063
4529 test_39g() {
4530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4531
4532         echo hello >> $DIR1/$tfile
4533         local mtime1=`stat -c %Y $DIR1/$tfile`
4534
4535         sleep 2
4536         chmod o+r $DIR1/$tfile
4537
4538         for (( i=0; i < 2; i++ )) ; do
4539                 local mtime2=`stat -c %Y $DIR1/$tfile`
4540                 [ "$mtime1" = "$mtime2" ] || \
4541                         error "lost mtime: $mtime2, should be $mtime1"
4542
4543                 cancel_lru_locks $OSC
4544                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4545         done
4546 }
4547 run_test 39g "write, chmod, stat ==============================="
4548
4549 # bug 11063
4550 test_39h() {
4551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4552
4553         touch $DIR1/$tfile
4554         sleep 1
4555
4556         local d1=`date`
4557         echo hello >> $DIR1/$tfile
4558         local mtime1=`stat -c %Y $DIR1/$tfile`
4559
4560         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4561         local d2=`date`
4562         if [ "$d1" != "$d2" ]; then
4563                 echo "write and touch not within one second"
4564         else
4565                 for (( i=0; i < 2; i++ )) ; do
4566                         local mtime2=`stat -c %Y $DIR1/$tfile`
4567                         [ "$mtime2" = $TEST_39_MTIME ] || \
4568                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4569
4570                         cancel_lru_locks $OSC
4571                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4572                 done
4573         fi
4574 }
4575 run_test 39h "write, utime within one second, stat ============="
4576
4577 test_39i() {
4578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4579
4580         touch $DIR1/$tfile
4581         sleep 1
4582
4583         echo hello >> $DIR1/$tfile
4584         local mtime1=`stat -c %Y $DIR1/$tfile`
4585
4586         mv $DIR1/$tfile $DIR1/$tfile-1
4587
4588         for (( i=0; i < 2; i++ )) ; do
4589                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4590
4591                 [ "$mtime1" = "$mtime2" ] || \
4592                         error "lost mtime: $mtime2, should be $mtime1"
4593
4594                 cancel_lru_locks $OSC
4595                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4596         done
4597 }
4598 run_test 39i "write, rename, stat =============================="
4599
4600 test_39j() {
4601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4602
4603         start_full_debug_logging
4604         touch $DIR1/$tfile
4605         sleep 1
4606
4607         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4608         lctl set_param fail_loc=0x80000412
4609         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4610                 error "multiop failed"
4611         local multipid=$!
4612         local mtime1=`stat -c %Y $DIR1/$tfile`
4613
4614         mv $DIR1/$tfile $DIR1/$tfile-1
4615
4616         kill -USR1 $multipid
4617         wait $multipid || error "multiop close failed"
4618
4619         for (( i=0; i < 2; i++ )) ; do
4620                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4621                 [ "$mtime1" = "$mtime2" ] ||
4622                         error "mtime is lost on close: $mtime2, " \
4623                               "should be $mtime1"
4624
4625                 cancel_lru_locks
4626                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4627         done
4628         lctl set_param fail_loc=0
4629         stop_full_debug_logging
4630 }
4631 run_test 39j "write, rename, close, stat ======================="
4632
4633 test_39k() {
4634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4635
4636         touch $DIR1/$tfile
4637         sleep 1
4638
4639         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4640         local multipid=$!
4641         local mtime1=`stat -c %Y $DIR1/$tfile`
4642
4643         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4644
4645         kill -USR1 $multipid
4646         wait $multipid || error "multiop close failed"
4647
4648         for (( i=0; i < 2; i++ )) ; do
4649                 local mtime2=`stat -c %Y $DIR1/$tfile`
4650
4651                 [ "$mtime2" = $TEST_39_MTIME ] || \
4652                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4653
4654                 cancel_lru_locks
4655                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4656         done
4657 }
4658 run_test 39k "write, utime, close, stat ========================"
4659
4660 # this should be set to future
4661 TEST_39_ATIME=`date -d "1 year" +%s`
4662
4663 test_39l() {
4664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4665         remote_mds_nodsh && skip "remote MDS with nodsh"
4666
4667         local atime_diff=$(do_facet $SINGLEMDS \
4668                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4669         rm -rf $DIR/$tdir
4670         mkdir -p $DIR/$tdir
4671
4672         # test setting directory atime to future
4673         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4674         local atime=$(stat -c %X $DIR/$tdir)
4675         [ "$atime" = $TEST_39_ATIME ] ||
4676                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4677
4678         # test setting directory atime from future to now
4679         local now=$(date +%s)
4680         touch -a -d @$now $DIR/$tdir
4681
4682         atime=$(stat -c %X $DIR/$tdir)
4683         [ "$atime" -eq "$now"  ] ||
4684                 error "atime is not updated from future: $atime, $now"
4685
4686         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4687         sleep 3
4688
4689         # test setting directory atime when now > dir atime + atime_diff
4690         local d1=$(date +%s)
4691         ls $DIR/$tdir
4692         local d2=$(date +%s)
4693         cancel_lru_locks mdc
4694         atime=$(stat -c %X $DIR/$tdir)
4695         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4696                 error "atime is not updated  : $atime, should be $d2"
4697
4698         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4699         sleep 3
4700
4701         # test not setting directory atime when now < dir atime + atime_diff
4702         ls $DIR/$tdir
4703         cancel_lru_locks mdc
4704         atime=$(stat -c %X $DIR/$tdir)
4705         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4706                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4707
4708         do_facet $SINGLEMDS \
4709                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4710 }
4711 run_test 39l "directory atime update ==========================="
4712
4713 test_39m() {
4714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4715
4716         touch $DIR1/$tfile
4717         sleep 2
4718         local far_past_mtime=$(date -d "May 29 1953" +%s)
4719         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4720
4721         touch -m -d @$far_past_mtime $DIR1/$tfile
4722         touch -a -d @$far_past_atime $DIR1/$tfile
4723
4724         for (( i=0; i < 2; i++ )) ; do
4725                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4726                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4727                         error "atime or mtime set incorrectly"
4728
4729                 cancel_lru_locks $OSC
4730                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4731         done
4732 }
4733 run_test 39m "test atime and mtime before 1970"
4734
4735 test_39n() { # LU-3832
4736         remote_mds_nodsh && skip "remote MDS with nodsh"
4737
4738         local atime_diff=$(do_facet $SINGLEMDS \
4739                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4740         local atime0
4741         local atime1
4742         local atime2
4743
4744         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4745
4746         rm -rf $DIR/$tfile
4747         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4748         atime0=$(stat -c %X $DIR/$tfile)
4749
4750         sleep 5
4751         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4752         atime1=$(stat -c %X $DIR/$tfile)
4753
4754         sleep 5
4755         cancel_lru_locks mdc
4756         cancel_lru_locks osc
4757         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4758         atime2=$(stat -c %X $DIR/$tfile)
4759
4760         do_facet $SINGLEMDS \
4761                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4762
4763         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4764         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4765 }
4766 run_test 39n "check that O_NOATIME is honored"
4767
4768 test_39o() {
4769         TESTDIR=$DIR/$tdir/$tfile
4770         [ -e $TESTDIR ] && rm -rf $TESTDIR
4771         mkdir -p $TESTDIR
4772         cd $TESTDIR
4773         links1=2
4774         ls
4775         mkdir a b
4776         ls
4777         links2=$(stat -c %h .)
4778         [ $(($links1 + 2)) != $links2 ] &&
4779                 error "wrong links count $(($links1 + 2)) != $links2"
4780         rmdir b
4781         links3=$(stat -c %h .)
4782         [ $(($links1 + 1)) != $links3 ] &&
4783                 error "wrong links count $links1 != $links3"
4784         return 0
4785 }
4786 run_test 39o "directory cached attributes updated after create"
4787
4788 test_39p() {
4789         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4790
4791         local MDTIDX=1
4792         TESTDIR=$DIR/$tdir/$tdir
4793         [ -e $TESTDIR ] && rm -rf $TESTDIR
4794         test_mkdir -p $TESTDIR
4795         cd $TESTDIR
4796         links1=2
4797         ls
4798         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4799         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4800         ls
4801         links2=$(stat -c %h .)
4802         [ $(($links1 + 2)) != $links2 ] &&
4803                 error "wrong links count $(($links1 + 2)) != $links2"
4804         rmdir remote_dir2
4805         links3=$(stat -c %h .)
4806         [ $(($links1 + 1)) != $links3 ] &&
4807                 error "wrong links count $links1 != $links3"
4808         return 0
4809 }
4810 run_test 39p "remote directory cached attributes updated after create ========"
4811
4812 test_39r() {
4813         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4814                 skip "no atime update on old OST"
4815         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4816                 skip_env "ldiskfs only test"
4817         fi
4818
4819         local saved_adiff
4820         saved_adiff=$(do_facet ost1 \
4821                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4822         stack_trap "do_facet ost1 \
4823                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4824
4825         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4826
4827         $LFS setstripe -i 0 $DIR/$tfile
4828         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4829                 error "can't write initial file"
4830         cancel_lru_locks osc
4831
4832         # exceed atime_diff and access file
4833         sleep 6
4834         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4835                 error "can't udpate atime"
4836
4837         local atime_cli=$(stat -c %X $DIR/$tfile)
4838         echo "client atime: $atime_cli"
4839         # allow atime update to be written to device
4840         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4841         sleep 5
4842
4843         local ostdev=$(ostdevname 1)
4844         local fid=($(lfs getstripe -y $DIR/$tfile |
4845                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4846         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4847         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4848
4849         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4850         local atime_ost=$(do_facet ost1 "$cmd" |&
4851                           awk -F'[: ]' '/atime:/ { print $4 }')
4852         (( atime_cli == atime_ost )) ||
4853                 error "atime on client $atime_cli != ost $atime_ost"
4854 }
4855 run_test 39r "lazy atime update on OST"
4856
4857 test_39q() { # LU-8041
4858         local testdir=$DIR/$tdir
4859         mkdir -p $testdir
4860         multiop_bg_pause $testdir D_c || error "multiop failed"
4861         local multipid=$!
4862         cancel_lru_locks mdc
4863         kill -USR1 $multipid
4864         local atime=$(stat -c %X $testdir)
4865         [ "$atime" -ne 0 ] || error "atime is zero"
4866 }
4867 run_test 39q "close won't zero out atime"
4868
4869 test_40() {
4870         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4871         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4872                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4873         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4874                 error "$tfile is not 4096 bytes in size"
4875 }
4876 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4877
4878 test_41() {
4879         # bug 1553
4880         small_write $DIR/f41 18
4881 }
4882 run_test 41 "test small file write + fstat ====================="
4883
4884 count_ost_writes() {
4885         lctl get_param -n ${OSC}.*.stats |
4886                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4887                         END { printf("%0.0f", writes) }'
4888 }
4889
4890 # decent default
4891 WRITEBACK_SAVE=500
4892 DIRTY_RATIO_SAVE=40
4893 MAX_DIRTY_RATIO=50
4894 BG_DIRTY_RATIO_SAVE=10
4895 MAX_BG_DIRTY_RATIO=25
4896
4897 start_writeback() {
4898         trap 0
4899         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4900         # dirty_ratio, dirty_background_ratio
4901         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4902                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4903                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4904                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4905         else
4906                 # if file not here, we are a 2.4 kernel
4907                 kill -CONT `pidof kupdated`
4908         fi
4909 }
4910
4911 stop_writeback() {
4912         # setup the trap first, so someone cannot exit the test at the
4913         # exact wrong time and mess up a machine
4914         trap start_writeback EXIT
4915         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4916         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4917                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4918                 sysctl -w vm.dirty_writeback_centisecs=0
4919                 sysctl -w vm.dirty_writeback_centisecs=0
4920                 # save and increase /proc/sys/vm/dirty_ratio
4921                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4922                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4923                 # save and increase /proc/sys/vm/dirty_background_ratio
4924                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4925                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4926         else
4927                 # if file not here, we are a 2.4 kernel
4928                 kill -STOP `pidof kupdated`
4929         fi
4930 }
4931
4932 # ensure that all stripes have some grant before we test client-side cache
4933 setup_test42() {
4934         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4935                 dd if=/dev/zero of=$i bs=4k count=1
4936                 rm $i
4937         done
4938 }
4939
4940 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4941 # file truncation, and file removal.
4942 test_42a() {
4943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4944
4945         setup_test42
4946         cancel_lru_locks $OSC
4947         stop_writeback
4948         sync; sleep 1; sync # just to be safe
4949         BEFOREWRITES=`count_ost_writes`
4950         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4951         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4952         AFTERWRITES=`count_ost_writes`
4953         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4954                 error "$BEFOREWRITES < $AFTERWRITES"
4955         start_writeback
4956 }
4957 run_test 42a "ensure that we don't flush on close"
4958
4959 test_42b() {
4960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4961
4962         setup_test42
4963         cancel_lru_locks $OSC
4964         stop_writeback
4965         sync
4966         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4967         BEFOREWRITES=$(count_ost_writes)
4968         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4969         AFTERWRITES=$(count_ost_writes)
4970         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4971                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4972         fi
4973         BEFOREWRITES=$(count_ost_writes)
4974         sync || error "sync: $?"
4975         AFTERWRITES=$(count_ost_writes)
4976         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4977                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4978         fi
4979         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4980         start_writeback
4981         return 0
4982 }
4983 run_test 42b "test destroy of file with cached dirty data ======"
4984
4985 # if these tests just want to test the effect of truncation,
4986 # they have to be very careful.  consider:
4987 # - the first open gets a {0,EOF}PR lock
4988 # - the first write conflicts and gets a {0, count-1}PW
4989 # - the rest of the writes are under {count,EOF}PW
4990 # - the open for truncate tries to match a {0,EOF}PR
4991 #   for the filesize and cancels the PWs.
4992 # any number of fixes (don't get {0,EOF} on open, match
4993 # composite locks, do smarter file size management) fix
4994 # this, but for now we want these tests to verify that
4995 # the cancellation with truncate intent works, so we
4996 # start the file with a full-file pw lock to match against
4997 # until the truncate.
4998 trunc_test() {
4999         test=$1
5000         file=$DIR/$test
5001         offset=$2
5002         cancel_lru_locks $OSC
5003         stop_writeback
5004         # prime the file with 0,EOF PW to match
5005         touch $file
5006         $TRUNCATE $file 0
5007         sync; sync
5008         # now the real test..
5009         dd if=/dev/zero of=$file bs=1024 count=100
5010         BEFOREWRITES=`count_ost_writes`
5011         $TRUNCATE $file $offset
5012         cancel_lru_locks $OSC
5013         AFTERWRITES=`count_ost_writes`
5014         start_writeback
5015 }
5016
5017 test_42c() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         trunc_test 42c 1024
5021         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5022                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5023         rm $file
5024 }
5025 run_test 42c "test partial truncate of file with cached dirty data"
5026
5027 test_42d() {
5028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5029
5030         trunc_test 42d 0
5031         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5032                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5033         rm $file
5034 }
5035 run_test 42d "test complete truncate of file with cached dirty data"
5036
5037 test_42e() { # bug22074
5038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5039
5040         local TDIR=$DIR/${tdir}e
5041         local pages=16 # hardcoded 16 pages, don't change it.
5042         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5043         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5044         local max_dirty_mb
5045         local warmup_files
5046
5047         test_mkdir $DIR/${tdir}e
5048         $LFS setstripe -c 1 $TDIR
5049         createmany -o $TDIR/f $files
5050
5051         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5052
5053         # we assume that with $OSTCOUNT files, at least one of them will
5054         # be allocated on OST0.
5055         warmup_files=$((OSTCOUNT * max_dirty_mb))
5056         createmany -o $TDIR/w $warmup_files
5057
5058         # write a large amount of data into one file and sync, to get good
5059         # avail_grant number from OST.
5060         for ((i=0; i<$warmup_files; i++)); do
5061                 idx=$($LFS getstripe -i $TDIR/w$i)
5062                 [ $idx -ne 0 ] && continue
5063                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5064                 break
5065         done
5066         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5067         sync
5068         $LCTL get_param $proc_osc0/cur_dirty_bytes
5069         $LCTL get_param $proc_osc0/cur_grant_bytes
5070
5071         # create as much dirty pages as we can while not to trigger the actual
5072         # RPCs directly. but depends on the env, VFS may trigger flush during this
5073         # period, hopefully we are good.
5074         for ((i=0; i<$warmup_files; i++)); do
5075                 idx=$($LFS getstripe -i $TDIR/w$i)
5076                 [ $idx -ne 0 ] && continue
5077                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5078         done
5079         $LCTL get_param $proc_osc0/cur_dirty_bytes
5080         $LCTL get_param $proc_osc0/cur_grant_bytes
5081
5082         # perform the real test
5083         $LCTL set_param $proc_osc0/rpc_stats 0
5084         for ((;i<$files; i++)); do
5085                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5086                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5087         done
5088         sync
5089         $LCTL get_param $proc_osc0/rpc_stats
5090
5091         local percent=0
5092         local have_ppr=false
5093         $LCTL get_param $proc_osc0/rpc_stats |
5094                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5095                         # skip lines until we are at the RPC histogram data
5096                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5097                         $have_ppr || continue
5098
5099                         # we only want the percent stat for < 16 pages
5100                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5101
5102                         percent=$((percent + WPCT))
5103                         if [[ $percent -gt 15 ]]; then
5104                                 error "less than 16-pages write RPCs" \
5105                                       "$percent% > 15%"
5106                                 break
5107                         fi
5108                 done
5109         rm -rf $TDIR
5110 }
5111 run_test 42e "verify sub-RPC writes are not done synchronously"
5112
5113 test_43A() { # was test_43
5114         test_mkdir $DIR/$tdir
5115         cp -p /bin/ls $DIR/$tdir/$tfile
5116         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5117         pid=$!
5118         # give multiop a chance to open
5119         sleep 1
5120
5121         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5122         kill -USR1 $pid
5123         # Wait for multiop to exit
5124         wait $pid
5125 }
5126 run_test 43A "execution of file opened for write should return -ETXTBSY"
5127
5128 test_43a() {
5129         test_mkdir $DIR/$tdir
5130         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5131         $DIR/$tdir/sleep 60 &
5132         SLEEP_PID=$!
5133         # Make sure exec of $tdir/sleep wins race with truncate
5134         sleep 1
5135         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5136         kill $SLEEP_PID
5137 }
5138 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5139
5140 test_43b() {
5141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5142
5143         test_mkdir $DIR/$tdir
5144         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5145         $DIR/$tdir/sleep 60 &
5146         SLEEP_PID=$!
5147         # Make sure exec of $tdir/sleep wins race with truncate
5148         sleep 1
5149         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5150         kill $SLEEP_PID
5151 }
5152 run_test 43b "truncate of file being executed should return -ETXTBSY"
5153
5154 test_43c() {
5155         local testdir="$DIR/$tdir"
5156         test_mkdir $testdir
5157         cp $SHELL $testdir/
5158         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5159                 ( cd $testdir && md5sum -c )
5160 }
5161 run_test 43c "md5sum of copy into lustre"
5162
5163 test_44A() { # was test_44
5164         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5165
5166         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5167         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5168 }
5169 run_test 44A "zero length read from a sparse stripe"
5170
5171 test_44a() {
5172         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
5173                 awk '{ print $2 }')
5174         [ -z "$nstripe" ] && skip "can't get stripe info"
5175         [[ $nstripe -gt $OSTCOUNT ]] &&
5176                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5177
5178         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
5179                 awk '{ print $2 }')
5180         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5181                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
5182                         awk '{ print $2 }')
5183         fi
5184
5185         OFFSETS="0 $((stride/2)) $((stride-1))"
5186         for offset in $OFFSETS; do
5187                 for i in $(seq 0 $((nstripe-1))); do
5188                         local GLOBALOFFSETS=""
5189                         # size in Bytes
5190                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5191                         local myfn=$DIR/d44a-$size
5192                         echo "--------writing $myfn at $size"
5193                         ll_sparseness_write $myfn $size ||
5194                                 error "ll_sparseness_write"
5195                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5196                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5197                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5198
5199                         for j in $(seq 0 $((nstripe-1))); do
5200                                 # size in Bytes
5201                                 size=$((((j + $nstripe )*$stride + $offset)))
5202                                 ll_sparseness_write $myfn $size ||
5203                                         error "ll_sparseness_write"
5204                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5205                         done
5206                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5207                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5208                         rm -f $myfn
5209                 done
5210         done
5211 }
5212 run_test 44a "test sparse pwrite ==============================="
5213
5214 dirty_osc_total() {
5215         tot=0
5216         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5217                 tot=$(($tot + $d))
5218         done
5219         echo $tot
5220 }
5221 do_dirty_record() {
5222         before=`dirty_osc_total`
5223         echo executing "\"$*\""
5224         eval $*
5225         after=`dirty_osc_total`
5226         echo before $before, after $after
5227 }
5228 test_45() {
5229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5230
5231         f="$DIR/f45"
5232         # Obtain grants from OST if it supports it
5233         echo blah > ${f}_grant
5234         stop_writeback
5235         sync
5236         do_dirty_record "echo blah > $f"
5237         [[ $before -eq $after ]] && error "write wasn't cached"
5238         do_dirty_record "> $f"
5239         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5240         do_dirty_record "echo blah > $f"
5241         [[ $before -eq $after ]] && error "write wasn't cached"
5242         do_dirty_record "sync"
5243         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5244         do_dirty_record "echo blah > $f"
5245         [[ $before -eq $after ]] && error "write wasn't cached"
5246         do_dirty_record "cancel_lru_locks osc"
5247         [[ $before -gt $after ]] ||
5248                 error "lock cancellation didn't lower dirty count"
5249         start_writeback
5250 }
5251 run_test 45 "osc io page accounting ============================"
5252
5253 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5254 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5255 # objects offset and an assert hit when an rpc was built with 1023's mapped
5256 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5257 test_46() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259
5260         f="$DIR/f46"
5261         stop_writeback
5262         sync
5263         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5264         sync
5265         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5266         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5267         sync
5268         start_writeback
5269 }
5270 run_test 46 "dirtying a previously written page ================"
5271
5272 # test_47 is removed "Device nodes check" is moved to test_28
5273
5274 test_48a() { # bug 2399
5275         [ "$mds1_FSTYPE" = "zfs" ] &&
5276         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5277                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5278
5279         test_mkdir $DIR/$tdir
5280         cd $DIR/$tdir
5281         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5282         test_mkdir $DIR/$tdir
5283         touch foo || error "'touch foo' failed after recreating cwd"
5284         test_mkdir bar
5285         touch .foo || error "'touch .foo' failed after recreating cwd"
5286         test_mkdir .bar
5287         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5288         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5289         cd . || error "'cd .' failed after recreating cwd"
5290         mkdir . && error "'mkdir .' worked after recreating cwd"
5291         rmdir . && error "'rmdir .' worked after recreating cwd"
5292         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5293         cd .. || error "'cd ..' failed after recreating cwd"
5294 }
5295 run_test 48a "Access renamed working dir (should return errors)="
5296
5297 test_48b() { # bug 2399
5298         rm -rf $DIR/$tdir
5299         test_mkdir $DIR/$tdir
5300         cd $DIR/$tdir
5301         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5302         touch foo && error "'touch foo' worked after removing cwd"
5303         mkdir foo && error "'mkdir foo' worked after removing cwd"
5304         touch .foo && error "'touch .foo' worked after removing cwd"
5305         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5306         ls . > /dev/null && error "'ls .' worked after removing cwd"
5307         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5308         mkdir . && error "'mkdir .' worked after removing cwd"
5309         rmdir . && error "'rmdir .' worked after removing cwd"
5310         ln -s . foo && error "'ln -s .' worked after removing cwd"
5311         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5312 }
5313 run_test 48b "Access removed working dir (should return errors)="
5314
5315 test_48c() { # bug 2350
5316         #lctl set_param debug=-1
5317         #set -vx
5318         rm -rf $DIR/$tdir
5319         test_mkdir -p $DIR/$tdir/dir
5320         cd $DIR/$tdir/dir
5321         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5322         $TRACE touch foo && error "touch foo worked after removing cwd"
5323         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5324         touch .foo && error "touch .foo worked after removing cwd"
5325         mkdir .foo && error "mkdir .foo worked after removing cwd"
5326         $TRACE ls . && error "'ls .' worked after removing cwd"
5327         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5328         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5329         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5330         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5331         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5332 }
5333 run_test 48c "Access removed working subdir (should return errors)"
5334
5335 test_48d() { # bug 2350
5336         #lctl set_param debug=-1
5337         #set -vx
5338         rm -rf $DIR/$tdir
5339         test_mkdir -p $DIR/$tdir/dir
5340         cd $DIR/$tdir/dir
5341         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5342         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5343         $TRACE touch foo && error "'touch foo' worked after removing parent"
5344         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5345         touch .foo && error "'touch .foo' worked after removing parent"
5346         mkdir .foo && error "mkdir .foo worked after removing parent"
5347         $TRACE ls . && error "'ls .' worked after removing parent"
5348         $TRACE ls .. && error "'ls ..' worked after removing parent"
5349         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5350         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5351         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5352         true
5353 }
5354 run_test 48d "Access removed parent subdir (should return errors)"
5355
5356 test_48e() { # bug 4134
5357         #lctl set_param debug=-1
5358         #set -vx
5359         rm -rf $DIR/$tdir
5360         test_mkdir -p $DIR/$tdir/dir
5361         cd $DIR/$tdir/dir
5362         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5363         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5364         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5365         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5366         # On a buggy kernel addition of "touch foo" after cd .. will
5367         # produce kernel oops in lookup_hash_it
5368         touch ../foo && error "'cd ..' worked after recreate parent"
5369         cd $DIR
5370         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5371 }
5372 run_test 48e "Access to recreated parent subdir (should return errors)"
5373
5374 test_48f() {
5375         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5376                 skip "need MDS >= 2.13.55"
5377         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5378         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5379                 skip "needs different host for mdt1 mdt2"
5380         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5381
5382         $LFS mkdir -i0 $DIR/$tdir
5383         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5384
5385         for d in sub1 sub2 sub3; do
5386                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5387                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5388                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5389         done
5390
5391         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5392 }
5393 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5394
5395 test_49() { # LU-1030
5396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5397         remote_ost_nodsh && skip "remote OST with nodsh"
5398
5399         # get ost1 size - $FSNAME-OST0000
5400         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5401                 awk '{ print $4 }')
5402         # write 800M at maximum
5403         [[ $ost1_size -lt 2 ]] && ost1_size=2
5404         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5405
5406         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5407         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5408         local dd_pid=$!
5409
5410         # change max_pages_per_rpc while writing the file
5411         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5412         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5413         # loop until dd process exits
5414         while ps ax -opid | grep -wq $dd_pid; do
5415                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5416                 sleep $((RANDOM % 5 + 1))
5417         done
5418         # restore original max_pages_per_rpc
5419         $LCTL set_param $osc1_mppc=$orig_mppc
5420         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5421 }
5422 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5423
5424 test_50() {
5425         # bug 1485
5426         test_mkdir $DIR/$tdir
5427         cd $DIR/$tdir
5428         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5429 }
5430 run_test 50 "special situations: /proc symlinks  ==============="
5431
5432 test_51a() {    # was test_51
5433         # bug 1516 - create an empty entry right after ".." then split dir
5434         test_mkdir -c1 $DIR/$tdir
5435         touch $DIR/$tdir/foo
5436         $MCREATE $DIR/$tdir/bar
5437         rm $DIR/$tdir/foo
5438         createmany -m $DIR/$tdir/longfile 201
5439         FNUM=202
5440         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5441                 $MCREATE $DIR/$tdir/longfile$FNUM
5442                 FNUM=$(($FNUM + 1))
5443                 echo -n "+"
5444         done
5445         echo
5446         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5447 }
5448 run_test 51a "special situations: split htree with empty entry =="
5449
5450 cleanup_print_lfs_df () {
5451         trap 0
5452         $LFS df
5453         $LFS df -i
5454 }
5455
5456 test_51b() {
5457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5458
5459         local dir=$DIR/$tdir
5460         local nrdirs=$((65536 + 100))
5461
5462         # cleanup the directory
5463         rm -fr $dir
5464
5465         test_mkdir -c1 $dir
5466
5467         $LFS df
5468         $LFS df -i
5469         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5470         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5471         [[ $numfree -lt $nrdirs ]] &&
5472                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5473
5474         # need to check free space for the directories as well
5475         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5476         numfree=$(( blkfree / $(fs_inode_ksize) ))
5477         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5478
5479         trap cleanup_print_lfs_df EXIT
5480
5481         # create files
5482         createmany -d $dir/d $nrdirs || {
5483                 unlinkmany $dir/d $nrdirs
5484                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5485         }
5486
5487         # really created :
5488         nrdirs=$(ls -U $dir | wc -l)
5489
5490         # unlink all but 100 subdirectories, then check it still works
5491         local left=100
5492         local delete=$((nrdirs - left))
5493
5494         $LFS df
5495         $LFS df -i
5496
5497         # for ldiskfs the nlink count should be 1, but this is OSD specific
5498         # and so this is listed for informational purposes only
5499         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5500         unlinkmany -d $dir/d $delete ||
5501                 error "unlink of first $delete subdirs failed"
5502
5503         echo "nlink between: $(stat -c %h $dir)"
5504         local found=$(ls -U $dir | wc -l)
5505         [ $found -ne $left ] &&
5506                 error "can't find subdirs: found only $found, expected $left"
5507
5508         unlinkmany -d $dir/d $delete $left ||
5509                 error "unlink of second $left subdirs failed"
5510         # regardless of whether the backing filesystem tracks nlink accurately
5511         # or not, the nlink count shouldn't be more than "." and ".." here
5512         local after=$(stat -c %h $dir)
5513         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5514                 echo "nlink after: $after"
5515
5516         cleanup_print_lfs_df
5517 }
5518 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5519
5520 test_51d() {
5521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5522         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5523
5524         test_mkdir $DIR/$tdir
5525         createmany -o $DIR/$tdir/t- 1000
5526         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5527         for N in $(seq 0 $((OSTCOUNT - 1))); do
5528                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5529                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5530                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5531                         '($1 == '$N') { objs += 1 } \
5532                         END { printf("%0.0f", objs) }')
5533                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5534         done
5535         unlinkmany $DIR/$tdir/t- 1000
5536
5537         NLAST=0
5538         for N in $(seq 1 $((OSTCOUNT - 1))); do
5539                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5540                         error "OST $N has less objects vs OST $NLAST" \
5541                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5542                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5543                         error "OST $N has less objects vs OST $NLAST" \
5544                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5545
5546                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5547                         error "OST $N has less #0 objects vs OST $NLAST" \
5548                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5549                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5550                         error "OST $N has less #0 objects vs OST $NLAST" \
5551                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5552                 NLAST=$N
5553         done
5554         rm -f $TMP/$tfile
5555 }
5556 run_test 51d "check object distribution"
5557
5558 test_51e() {
5559         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5560                 skip_env "ldiskfs only test"
5561         fi
5562
5563         test_mkdir -c1 $DIR/$tdir
5564         test_mkdir -c1 $DIR/$tdir/d0
5565
5566         touch $DIR/$tdir/d0/foo
5567         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5568                 error "file exceed 65000 nlink limit!"
5569         unlinkmany $DIR/$tdir/d0/f- 65001
5570         return 0
5571 }
5572 run_test 51e "check file nlink limit"
5573
5574 test_51f() {
5575         test_mkdir $DIR/$tdir
5576
5577         local max=100000
5578         local ulimit_old=$(ulimit -n)
5579         local spare=20 # number of spare fd's for scripts/libraries, etc.
5580         local mdt=$($LFS getstripe -m $DIR/$tdir)
5581         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5582
5583         echo "MDT$mdt numfree=$numfree, max=$max"
5584         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5585         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5586                 while ! ulimit -n $((numfree + spare)); do
5587                         numfree=$((numfree * 3 / 4))
5588                 done
5589                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5590         else
5591                 echo "left ulimit at $ulimit_old"
5592         fi
5593
5594         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5595                 unlinkmany $DIR/$tdir/f $numfree
5596                 error "create+open $numfree files in $DIR/$tdir failed"
5597         }
5598         ulimit -n $ulimit_old
5599
5600         # if createmany exits at 120s there will be fewer than $numfree files
5601         unlinkmany $DIR/$tdir/f $numfree || true
5602 }
5603 run_test 51f "check many open files limit"
5604
5605 test_52a() {
5606         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5607         test_mkdir $DIR/$tdir
5608         touch $DIR/$tdir/foo
5609         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5610         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5611         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5612         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5613         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5614                                         error "link worked"
5615         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5616         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5617         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5618                                                      error "lsattr"
5619         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5620         cp -r $DIR/$tdir $TMP/
5621         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5622 }
5623 run_test 52a "append-only flag test (should return errors)"
5624
5625 test_52b() {
5626         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5627         test_mkdir $DIR/$tdir
5628         touch $DIR/$tdir/foo
5629         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5630         cat test > $DIR/$tdir/foo && error "cat test worked"
5631         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5632         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5633         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5634                                         error "link worked"
5635         echo foo >> $DIR/$tdir/foo && error "echo worked"
5636         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5637         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5638         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5639         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5640                                                         error "lsattr"
5641         chattr -i $DIR/$tdir/foo || error "chattr failed"
5642
5643         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5644 }
5645 run_test 52b "immutable flag test (should return errors) ======="
5646
5647 test_53() {
5648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5649         remote_mds_nodsh && skip "remote MDS with nodsh"
5650         remote_ost_nodsh && skip "remote OST with nodsh"
5651
5652         local param
5653         local param_seq
5654         local ostname
5655         local mds_last
5656         local mds_last_seq
5657         local ost_last
5658         local ost_last_seq
5659         local ost_last_id
5660         local ostnum
5661         local node
5662         local found=false
5663         local support_last_seq=true
5664
5665         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5666                 support_last_seq=false
5667
5668         # only test MDT0000
5669         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5670         local value
5671         for value in $(do_facet $SINGLEMDS \
5672                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5673                 param=$(echo ${value[0]} | cut -d "=" -f1)
5674                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5675
5676                 if $support_last_seq; then
5677                         param_seq=$(echo $param |
5678                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5679                         mds_last_seq=$(do_facet $SINGLEMDS \
5680                                        $LCTL get_param -n $param_seq)
5681                 fi
5682                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5683
5684                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5685                 node=$(facet_active_host ost$((ostnum+1)))
5686                 param="obdfilter.$ostname.last_id"
5687                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5688                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5689                         ost_last_id=$ost_last
5690
5691                         if $support_last_seq; then
5692                                 ost_last_id=$(echo $ost_last |
5693                                               awk -F':' '{print $2}' |
5694                                               sed -e "s/^0x//g")
5695                                 ost_last_seq=$(echo $ost_last |
5696                                                awk -F':' '{print $1}')
5697                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5698                         fi
5699
5700                         if [[ $ost_last_id != $mds_last ]]; then
5701                                 error "$ost_last_id != $mds_last"
5702                         else
5703                                 found=true
5704                                 break
5705                         fi
5706                 done
5707         done
5708         $found || error "can not match last_seq/last_id for $mdtosc"
5709         return 0
5710 }
5711 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5712
5713 test_54a() {
5714         perl -MSocket -e ';' || skip "no Socket perl module installed"
5715
5716         $SOCKETSERVER $DIR/socket ||
5717                 error "$SOCKETSERVER $DIR/socket failed: $?"
5718         $SOCKETCLIENT $DIR/socket ||
5719                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5720         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5721 }
5722 run_test 54a "unix domain socket test =========================="
5723
5724 test_54b() {
5725         f="$DIR/f54b"
5726         mknod $f c 1 3
5727         chmod 0666 $f
5728         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5729 }
5730 run_test 54b "char device works in lustre ======================"
5731
5732 find_loop_dev() {
5733         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5734         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5735         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5736
5737         for i in $(seq 3 7); do
5738                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5739                 LOOPDEV=$LOOPBASE$i
5740                 LOOPNUM=$i
5741                 break
5742         done
5743 }
5744
5745 cleanup_54c() {
5746         local rc=0
5747         loopdev="$DIR/loop54c"
5748
5749         trap 0
5750         $UMOUNT $DIR/$tdir || rc=$?
5751         losetup -d $loopdev || true
5752         losetup -d $LOOPDEV || true
5753         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5754         return $rc
5755 }
5756
5757 test_54c() {
5758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5759
5760         loopdev="$DIR/loop54c"
5761
5762         find_loop_dev
5763         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5764         trap cleanup_54c EXIT
5765         mknod $loopdev b 7 $LOOPNUM
5766         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5767         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5768         losetup $loopdev $DIR/$tfile ||
5769                 error "can't set up $loopdev for $DIR/$tfile"
5770         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5771         test_mkdir $DIR/$tdir
5772         mount -t ext2 $loopdev $DIR/$tdir ||
5773                 error "error mounting $loopdev on $DIR/$tdir"
5774         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5775                 error "dd write"
5776         df $DIR/$tdir
5777         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5778                 error "dd read"
5779         cleanup_54c
5780 }
5781 run_test 54c "block device works in lustre ====================="
5782
5783 test_54d() {
5784         f="$DIR/f54d"
5785         string="aaaaaa"
5786         mknod $f p
5787         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5788 }
5789 run_test 54d "fifo device works in lustre ======================"
5790
5791 test_54e() {
5792         f="$DIR/f54e"
5793         string="aaaaaa"
5794         cp -aL /dev/console $f
5795         echo $string > $f || error "echo $string to $f failed"
5796 }
5797 run_test 54e "console/tty device works in lustre ======================"
5798
5799 test_56a() {
5800         local numfiles=3
5801         local dir=$DIR/$tdir
5802
5803         rm -rf $dir
5804         test_mkdir -p $dir/dir
5805         for i in $(seq $numfiles); do
5806                 touch $dir/file$i
5807                 touch $dir/dir/file$i
5808         done
5809
5810         local numcomp=$($LFS getstripe --component-count $dir)
5811
5812         [[ $numcomp == 0 ]] && numcomp=1
5813
5814         # test lfs getstripe with --recursive
5815         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5816
5817         [[ $filenum -eq $((numfiles * 2)) ]] ||
5818                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5819         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5820         [[ $filenum -eq $numfiles ]] ||
5821                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5822         echo "$LFS getstripe showed obdidx or l_ost_idx"
5823
5824         # test lfs getstripe with file instead of dir
5825         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5826         [[ $filenum -eq 1 ]] ||
5827                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5828         echo "$LFS getstripe file1 passed"
5829
5830         #test lfs getstripe with --verbose
5831         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5832         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5833                 error "$LFS getstripe --verbose $dir: "\
5834                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5835         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5836                 error "$LFS getstripe $dir: showed lmm_magic"
5837
5838         #test lfs getstripe with -v prints lmm_fid
5839         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5840         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5841                 error "$LFS getstripe -v $dir: "\
5842                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5843         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5844                 error "$LFS getstripe $dir: showed lmm_fid by default"
5845         echo "$LFS getstripe --verbose passed"
5846
5847         #check for FID information
5848         local fid1=$($LFS getstripe --fid $dir/file1)
5849         local fid2=$($LFS getstripe --verbose $dir/file1 |
5850                      awk '/lmm_fid: / { print $2; exit; }')
5851         local fid3=$($LFS path2fid $dir/file1)
5852
5853         [ "$fid1" != "$fid2" ] &&
5854                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5855         [ "$fid1" != "$fid3" ] &&
5856                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5857         echo "$LFS getstripe --fid passed"
5858
5859         #test lfs getstripe with --obd
5860         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5861                 error "$LFS getstripe --obd wrong_uuid: should return error"
5862
5863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5864
5865         local ostidx=1
5866         local obduuid=$(ostuuid_from_index $ostidx)
5867         local found=$($LFS getstripe -r --obd $obduuid $dir |
5868                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5869
5870         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5871         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5872                 ((filenum--))
5873         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5874                 ((filenum--))
5875
5876         [[ $found -eq $filenum ]] ||
5877                 error "$LFS getstripe --obd: found $found expect $filenum"
5878         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5879                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5880                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5881                 error "$LFS getstripe --obd: should not show file on other obd"
5882         echo "$LFS getstripe --obd passed"
5883 }
5884 run_test 56a "check $LFS getstripe"
5885
5886 test_56b() {
5887         local dir=$DIR/$tdir
5888         local numdirs=3
5889
5890         test_mkdir $dir
5891         for i in $(seq $numdirs); do
5892                 test_mkdir $dir/dir$i
5893         done
5894
5895         # test lfs getdirstripe default mode is non-recursion, which is
5896         # different from lfs getstripe
5897         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5898
5899         [[ $dircnt -eq 1 ]] ||
5900                 error "$LFS getdirstripe: found $dircnt, not 1"
5901         dircnt=$($LFS getdirstripe --recursive $dir |
5902                 grep -c lmv_stripe_count)
5903         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5904                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5905 }
5906 run_test 56b "check $LFS getdirstripe"
5907
5908 test_56c() {
5909         remote_ost_nodsh && skip "remote OST with nodsh"
5910
5911         local ost_idx=0
5912         local ost_name=$(ostname_from_index $ost_idx)
5913         local old_status=$(ost_dev_status $ost_idx)
5914         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5915
5916         [[ -z "$old_status" ]] ||
5917                 skip_env "OST $ost_name is in $old_status status"
5918
5919         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5920         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5921                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5922         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5923                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5924                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5925         fi
5926
5927         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5928                 error "$LFS df -v showing inactive devices"
5929         sleep_maxage
5930
5931         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5932
5933         [[ "$new_status" =~ "D" ]] ||
5934                 error "$ost_name status is '$new_status', missing 'D'"
5935         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5936                 [[ "$new_status" =~ "N" ]] ||
5937                         error "$ost_name status is '$new_status', missing 'N'"
5938         fi
5939         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5940                 [[ "$new_status" =~ "f" ]] ||
5941                         error "$ost_name status is '$new_status', missing 'f'"
5942         fi
5943
5944         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5945         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5946                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5947         [[ -z "$p" ]] && restore_lustre_params < $p || true
5948         sleep_maxage
5949
5950         new_status=$(ost_dev_status $ost_idx)
5951         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5952                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5953         # can't check 'f' as devices may actually be on flash
5954 }
5955 run_test 56c "check 'lfs df' showing device status"
5956
5957 test_56d() {
5958         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5959         local osts=$($LFS df -v $MOUNT | grep -c OST)
5960
5961         $LFS df $MOUNT
5962
5963         (( mdts == MDSCOUNT )) ||
5964                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5965         (( osts == OSTCOUNT )) ||
5966                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5967 }
5968 run_test 56d "'lfs df -v' prints only configured devices"
5969
5970 NUMFILES=3
5971 NUMDIRS=3
5972 setup_56() {
5973         local local_tdir="$1"
5974         local local_numfiles="$2"
5975         local local_numdirs="$3"
5976         local dir_params="$4"
5977         local dir_stripe_params="$5"
5978
5979         if [ ! -d "$local_tdir" ] ; then
5980                 test_mkdir -p $dir_stripe_params $local_tdir
5981                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5982                 for i in $(seq $local_numfiles) ; do
5983                         touch $local_tdir/file$i
5984                 done
5985                 for i in $(seq $local_numdirs) ; do
5986                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5987                         for j in $(seq $local_numfiles) ; do
5988                                 touch $local_tdir/dir$i/file$j
5989                         done
5990                 done
5991         fi
5992 }
5993
5994 setup_56_special() {
5995         local local_tdir=$1
5996         local local_numfiles=$2
5997         local local_numdirs=$3
5998
5999         setup_56 $local_tdir $local_numfiles $local_numdirs
6000
6001         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6002                 for i in $(seq $local_numfiles) ; do
6003                         mknod $local_tdir/loop${i}b b 7 $i
6004                         mknod $local_tdir/null${i}c c 1 3
6005                         ln -s $local_tdir/file1 $local_tdir/link${i}
6006                 done
6007                 for i in $(seq $local_numdirs) ; do
6008                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6009                         mknod $local_tdir/dir$i/null${i}c c 1 3
6010                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6011                 done
6012         fi
6013 }
6014
6015 test_56g() {
6016         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6017         local expected=$(($NUMDIRS + 2))
6018
6019         setup_56 $dir $NUMFILES $NUMDIRS
6020
6021         # test lfs find with -name
6022         for i in $(seq $NUMFILES) ; do
6023                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6024
6025                 [ $nums -eq $expected ] ||
6026                         error "lfs find -name '*$i' $dir wrong: "\
6027                               "found $nums, expected $expected"
6028         done
6029 }
6030 run_test 56g "check lfs find -name"
6031
6032 test_56h() {
6033         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6034         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6035
6036         setup_56 $dir $NUMFILES $NUMDIRS
6037
6038         # test lfs find with ! -name
6039         for i in $(seq $NUMFILES) ; do
6040                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6041
6042                 [ $nums -eq $expected ] ||
6043                         error "lfs find ! -name '*$i' $dir wrong: "\
6044                               "found $nums, expected $expected"
6045         done
6046 }
6047 run_test 56h "check lfs find ! -name"
6048
6049 test_56i() {
6050         local dir=$DIR/$tdir
6051
6052         test_mkdir $dir
6053
6054         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6055         local out=$($cmd)
6056
6057         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6058 }
6059 run_test 56i "check 'lfs find -ost UUID' skips directories"
6060
6061 test_56j() {
6062         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6063
6064         setup_56_special $dir $NUMFILES $NUMDIRS
6065
6066         local expected=$((NUMDIRS + 1))
6067         local cmd="$LFS find -type d $dir"
6068         local nums=$($cmd | wc -l)
6069
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072 }
6073 run_test 56j "check lfs find -type d"
6074
6075 test_56k() {
6076         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6077
6078         setup_56_special $dir $NUMFILES $NUMDIRS
6079
6080         local expected=$(((NUMDIRS + 1) * NUMFILES))
6081         local cmd="$LFS find -type f $dir"
6082         local nums=$($cmd | wc -l)
6083
6084         [ $nums -eq $expected ] ||
6085                 error "'$cmd' wrong: found $nums, expected $expected"
6086 }
6087 run_test 56k "check lfs find -type f"
6088
6089 test_56l() {
6090         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6091
6092         setup_56_special $dir $NUMFILES $NUMDIRS
6093
6094         local expected=$((NUMDIRS + NUMFILES))
6095         local cmd="$LFS find -type b $dir"
6096         local nums=$($cmd | wc -l)
6097
6098         [ $nums -eq $expected ] ||
6099                 error "'$cmd' wrong: found $nums, expected $expected"
6100 }
6101 run_test 56l "check lfs find -type b"
6102
6103 test_56m() {
6104         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6105
6106         setup_56_special $dir $NUMFILES $NUMDIRS
6107
6108         local expected=$((NUMDIRS + NUMFILES))
6109         local cmd="$LFS find -type c $dir"
6110         local nums=$($cmd | wc -l)
6111         [ $nums -eq $expected ] ||
6112                 error "'$cmd' wrong: found $nums, expected $expected"
6113 }
6114 run_test 56m "check lfs find -type c"
6115
6116 test_56n() {
6117         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6118         setup_56_special $dir $NUMFILES $NUMDIRS
6119
6120         local expected=$((NUMDIRS + NUMFILES))
6121         local cmd="$LFS find -type l $dir"
6122         local nums=$($cmd | wc -l)
6123
6124         [ $nums -eq $expected ] ||
6125                 error "'$cmd' wrong: found $nums, expected $expected"
6126 }
6127 run_test 56n "check lfs find -type l"
6128
6129 test_56o() {
6130         local dir=$DIR/$tdir
6131
6132         setup_56 $dir $NUMFILES $NUMDIRS
6133         utime $dir/file1 > /dev/null || error "utime (1)"
6134         utime $dir/file2 > /dev/null || error "utime (2)"
6135         utime $dir/dir1 > /dev/null || error "utime (3)"
6136         utime $dir/dir2 > /dev/null || error "utime (4)"
6137         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6138         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6139
6140         local expected=4
6141         local nums=$($LFS find -mtime +0 $dir | wc -l)
6142
6143         [ $nums -eq $expected ] ||
6144                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6145
6146         expected=12
6147         cmd="$LFS find -mtime 0 $dir"
6148         nums=$($cmd | wc -l)
6149         [ $nums -eq $expected ] ||
6150                 error "'$cmd' wrong: found $nums, expected $expected"
6151 }
6152 run_test 56o "check lfs find -mtime for old files"
6153
6154 test_56ob() {
6155         local dir=$DIR/$tdir
6156         local expected=1
6157         local count=0
6158
6159         # just to make sure there is something that won't be found
6160         test_mkdir $dir
6161         touch $dir/$tfile.now
6162
6163         for age in year week day hour min; do
6164                 count=$((count + 1))
6165
6166                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6167                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6168                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6169
6170                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6171                 local nums=$($cmd | wc -l)
6172                 [ $nums -eq $expected ] ||
6173                         error "'$cmd' wrong: found $nums, expected $expected"
6174
6175                 cmd="$LFS find $dir -atime $count${age:0:1}"
6176                 nums=$($cmd | wc -l)
6177                 [ $nums -eq $expected ] ||
6178                         error "'$cmd' wrong: found $nums, expected $expected"
6179         done
6180
6181         sleep 2
6182         cmd="$LFS find $dir -ctime +1s -type f"
6183         nums=$($cmd | wc -l)
6184         (( $nums == $count * 2 + 1)) ||
6185                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6186 }
6187 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6188
6189 test_newerXY_base() {
6190         local x=$1
6191         local y=$2
6192         local dir=$DIR/$tdir
6193         local ref
6194         local negref
6195
6196         if [ $y == "t" ]; then
6197                 if [ $x == "b" ]; then
6198                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6199                 else
6200                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6201                 fi
6202         else
6203                 ref=$DIR/$tfile.newer.$x$y
6204                 touch $ref || error "touch $ref failed"
6205         fi
6206
6207         echo "before = $ref"
6208         sleep 2
6209         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6210         sleep 2
6211         if [ $y == "t" ]; then
6212                 if [ $x == "b" ]; then
6213                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6214                 else
6215                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6216                 fi
6217         else
6218                 negref=$DIR/$tfile.negnewer.$x$y
6219                 touch $negref || error "touch $negref failed"
6220         fi
6221
6222         echo "after = $negref"
6223         local cmd="$LFS find $dir -newer$x$y $ref"
6224         local nums=$(eval $cmd | wc -l)
6225         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6226
6227         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6228                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6229
6230         cmd="$LFS find $dir ! -newer$x$y $negref"
6231         nums=$(eval $cmd | wc -l)
6232         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6233                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6234
6235         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6236         nums=$(eval $cmd | wc -l)
6237         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6238                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6239
6240         rm -rf $DIR/*
6241 }
6242
6243 test_56oc() {
6244         test_newerXY_base "a" "a"
6245         test_newerXY_base "a" "m"
6246         test_newerXY_base "a" "c"
6247         test_newerXY_base "m" "a"
6248         test_newerXY_base "m" "m"
6249         test_newerXY_base "m" "c"
6250         test_newerXY_base "c" "a"
6251         test_newerXY_base "c" "m"
6252         test_newerXY_base "c" "c"
6253
6254         [[ -n "$sles_version" ]] &&
6255                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6256
6257         test_newerXY_base "a" "t"
6258         test_newerXY_base "m" "t"
6259         test_newerXY_base "c" "t"
6260
6261         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6262            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6263                 ! btime_supported && echo "btime unsupported" && return 0
6264
6265         test_newerXY_base "b" "b"
6266         test_newerXY_base "b" "t"
6267 }
6268 run_test 56oc "check lfs find -newerXY work"
6269
6270 btime_supported() {
6271         local dir=$DIR/$tdir
6272         local rc
6273
6274         mkdir -p $dir
6275         touch $dir/$tfile
6276         $LFS find $dir -btime -1d -type f
6277         rc=$?
6278         rm -rf $dir
6279         return $rc
6280 }
6281
6282 test_56od() {
6283         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6284                 ! btime_supported && skip "btime unsupported on MDS"
6285
6286         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6287                 ! btime_supported && skip "btime unsupported on clients"
6288
6289         local dir=$DIR/$tdir
6290         local ref=$DIR/$tfile.ref
6291         local negref=$DIR/$tfile.negref
6292
6293         mkdir $dir || error "mkdir $dir failed"
6294         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6295         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6296         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6297         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6298         touch $ref || error "touch $ref failed"
6299         # sleep 3 seconds at least
6300         sleep 3
6301
6302         local before=$(do_facet mds1 date +%s)
6303         local skew=$(($(date +%s) - before + 1))
6304
6305         if (( skew < 0 && skew > -5 )); then
6306                 sleep $((0 - skew + 1))
6307                 skew=0
6308         fi
6309
6310         # Set the dir stripe params to limit files all on MDT0,
6311         # otherwise we need to calc the max clock skew between
6312         # the client and MDTs.
6313         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6314         sleep 2
6315         touch $negref || error "touch $negref failed"
6316
6317         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6318         local nums=$($cmd | wc -l)
6319         local expected=$(((NUMFILES + 1) * NUMDIRS))
6320
6321         [ $nums -eq $expected ] ||
6322                 error "'$cmd' wrong: found $nums, expected $expected"
6323
6324         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6325         nums=$($cmd | wc -l)
6326         expected=$((NUMFILES + 1))
6327         [ $nums -eq $expected ] ||
6328                 error "'$cmd' wrong: found $nums, expected $expected"
6329
6330         [ $skew -lt 0 ] && return
6331
6332         local after=$(do_facet mds1 date +%s)
6333         local age=$((after - before + 1 + skew))
6334
6335         cmd="$LFS find $dir -btime -${age}s -type f"
6336         nums=$($cmd | wc -l)
6337         expected=$(((NUMFILES + 1) * NUMDIRS))
6338
6339         echo "Clock skew between client and server: $skew, age:$age"
6340         [ $nums -eq $expected ] ||
6341                 error "'$cmd' wrong: found $nums, expected $expected"
6342
6343         expected=$(($NUMDIRS + 1))
6344         cmd="$LFS find $dir -btime -${age}s -type d"
6345         nums=$($cmd | wc -l)
6346         [ $nums -eq $expected ] ||
6347                 error "'$cmd' wrong: found $nums, expected $expected"
6348         rm -f $ref $negref || error "Failed to remove $ref $negref"
6349 }
6350 run_test 56od "check lfs find -btime with units"
6351
6352 test_56p() {
6353         [ $RUNAS_ID -eq $UID ] &&
6354                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6355
6356         local dir=$DIR/$tdir
6357
6358         setup_56 $dir $NUMFILES $NUMDIRS
6359         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6360
6361         local expected=$NUMFILES
6362         local cmd="$LFS find -uid $RUNAS_ID $dir"
6363         local nums=$($cmd | wc -l)
6364
6365         [ $nums -eq $expected ] ||
6366                 error "'$cmd' wrong: found $nums, expected $expected"
6367
6368         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6369         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6370         nums=$($cmd | wc -l)
6371         [ $nums -eq $expected ] ||
6372                 error "'$cmd' wrong: found $nums, expected $expected"
6373 }
6374 run_test 56p "check lfs find -uid and ! -uid"
6375
6376 test_56q() {
6377         [ $RUNAS_ID -eq $UID ] &&
6378                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6379
6380         local dir=$DIR/$tdir
6381
6382         setup_56 $dir $NUMFILES $NUMDIRS
6383         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6384
6385         local expected=$NUMFILES
6386         local cmd="$LFS find -gid $RUNAS_GID $dir"
6387         local nums=$($cmd | wc -l)
6388
6389         [ $nums -eq $expected ] ||
6390                 error "'$cmd' wrong: found $nums, expected $expected"
6391
6392         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6393         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6394         nums=$($cmd | wc -l)
6395         [ $nums -eq $expected ] ||
6396                 error "'$cmd' wrong: found $nums, expected $expected"
6397 }
6398 run_test 56q "check lfs find -gid and ! -gid"
6399
6400 test_56r() {
6401         local dir=$DIR/$tdir
6402
6403         setup_56 $dir $NUMFILES $NUMDIRS
6404
6405         local expected=12
6406         local cmd="$LFS find -size 0 -type f -lazy $dir"
6407         local nums=$($cmd | wc -l)
6408
6409         [ $nums -eq $expected ] ||
6410                 error "'$cmd' wrong: found $nums, expected $expected"
6411         cmd="$LFS find -size 0 -type f $dir"
6412         nums=$($cmd | wc -l)
6413         [ $nums -eq $expected ] ||
6414                 error "'$cmd' wrong: found $nums, expected $expected"
6415
6416         expected=0
6417         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421         cmd="$LFS find ! -size 0 -type f $dir"
6422         nums=$($cmd | wc -l)
6423         [ $nums -eq $expected ] ||
6424                 error "'$cmd' wrong: found $nums, expected $expected"
6425
6426         echo "test" > $dir/$tfile
6427         echo "test2" > $dir/$tfile.2 && sync
6428         expected=1
6429         cmd="$LFS find -size 5 -type f -lazy $dir"
6430         nums=$($cmd | wc -l)
6431         [ $nums -eq $expected ] ||
6432                 error "'$cmd' wrong: found $nums, expected $expected"
6433         cmd="$LFS find -size 5 -type f $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=1
6439         cmd="$LFS find -size +5 -type f -lazy $dir"
6440         nums=$($cmd | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443         cmd="$LFS find -size +5 -type f $dir"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447
6448         expected=2
6449         cmd="$LFS find -size +0 -type f -lazy $dir"
6450         nums=$($cmd | wc -l)
6451         [ $nums -eq $expected ] ||
6452                 error "'$cmd' wrong: found $nums, expected $expected"
6453         cmd="$LFS find -size +0 -type f $dir"
6454         nums=$($cmd | wc -l)
6455         [ $nums -eq $expected ] ||
6456                 error "'$cmd' wrong: found $nums, expected $expected"
6457
6458         expected=2
6459         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6460         nums=$($cmd | wc -l)
6461         [ $nums -eq $expected ] ||
6462                 error "'$cmd' wrong: found $nums, expected $expected"
6463         cmd="$LFS find ! -size -5 -type f $dir"
6464         nums=$($cmd | wc -l)
6465         [ $nums -eq $expected ] ||
6466                 error "'$cmd' wrong: found $nums, expected $expected"
6467
6468         expected=12
6469         cmd="$LFS find -size -5 -type f -lazy $dir"
6470         nums=$($cmd | wc -l)
6471         [ $nums -eq $expected ] ||
6472                 error "'$cmd' wrong: found $nums, expected $expected"
6473         cmd="$LFS find -size -5 -type f $dir"
6474         nums=$($cmd | wc -l)
6475         [ $nums -eq $expected ] ||
6476                 error "'$cmd' wrong: found $nums, expected $expected"
6477 }
6478 run_test 56r "check lfs find -size works"
6479
6480 test_56ra_sub() {
6481         local expected=$1
6482         local glimpses=$2
6483         local cmd="$3"
6484
6485         cancel_lru_locks $OSC
6486
6487         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6488         local nums=$($cmd | wc -l)
6489
6490         [ $nums -eq $expected ] ||
6491                 error "'$cmd' wrong: found $nums, expected $expected"
6492
6493         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6494
6495         if (( rpcs_before + glimpses != rpcs_after )); then
6496                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6497                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6498
6499                 if [[ $glimpses == 0 ]]; then
6500                         error "'$cmd' should not send glimpse RPCs to OST"
6501                 else
6502                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6503                 fi
6504         fi
6505 }
6506
6507 test_56ra() {
6508         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6509                 skip "MDS < 2.12.58 doesn't return LSOM data"
6510         local dir=$DIR/$tdir
6511         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6512
6513         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6514
6515         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6516         $LCTL set_param -n llite.*.statahead_agl=0
6517         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6518
6519         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6520         # open and close all files to ensure LSOM is updated
6521         cancel_lru_locks $OSC
6522         find $dir -type f | xargs cat > /dev/null
6523
6524         #   expect_found  glimpse_rpcs  command_to_run
6525         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6526         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6527         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6528         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6529
6530         echo "test" > $dir/$tfile
6531         echo "test2" > $dir/$tfile.2 && sync
6532         cancel_lru_locks $OSC
6533         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6534
6535         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6536         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6537         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6538         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6539
6540         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6541         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6542         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6543         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6544         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6545         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6546 }
6547 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6548
6549 test_56rb() {
6550         local dir=$DIR/$tdir
6551         local tmp=$TMP/$tfile.log
6552         local mdt_idx;
6553
6554         test_mkdir -p $dir || error "failed to mkdir $dir"
6555         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6556                 error "failed to setstripe $dir/$tfile"
6557         mdt_idx=$($LFS getdirstripe -i $dir)
6558         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6559
6560         stack_trap "rm -f $tmp" EXIT
6561         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6562         ! grep -q obd_uuid $tmp ||
6563                 error "failed to find --size +100K --ost 0 $dir"
6564         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6565         ! grep -q obd_uuid $tmp ||
6566                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6567 }
6568 run_test 56rb "check lfs find --size --ost/--mdt works"
6569
6570 test_56s() { # LU-611 #LU-9369
6571         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6572
6573         local dir=$DIR/$tdir
6574         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6575
6576         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6577         for i in $(seq $NUMDIRS); do
6578                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6579         done
6580
6581         local expected=$NUMDIRS
6582         local cmd="$LFS find -c $OSTCOUNT $dir"
6583         local nums=$($cmd | wc -l)
6584
6585         [ $nums -eq $expected ] || {
6586                 $LFS getstripe -R $dir
6587                 error "'$cmd' wrong: found $nums, expected $expected"
6588         }
6589
6590         expected=$((NUMDIRS + onestripe))
6591         cmd="$LFS find -stripe-count +0 -type f $dir"
6592         nums=$($cmd | wc -l)
6593         [ $nums -eq $expected ] || {
6594                 $LFS getstripe -R $dir
6595                 error "'$cmd' wrong: found $nums, expected $expected"
6596         }
6597
6598         expected=$onestripe
6599         cmd="$LFS find -stripe-count 1 -type f $dir"
6600         nums=$($cmd | wc -l)
6601         [ $nums -eq $expected ] || {
6602                 $LFS getstripe -R $dir
6603                 error "'$cmd' wrong: found $nums, expected $expected"
6604         }
6605
6606         cmd="$LFS find -stripe-count -2 -type f $dir"
6607         nums=$($cmd | wc -l)
6608         [ $nums -eq $expected ] || {
6609                 $LFS getstripe -R $dir
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611         }
6612
6613         expected=0
6614         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6615         nums=$($cmd | wc -l)
6616         [ $nums -eq $expected ] || {
6617                 $LFS getstripe -R $dir
6618                 error "'$cmd' wrong: found $nums, expected $expected"
6619         }
6620 }
6621 run_test 56s "check lfs find -stripe-count works"
6622
6623 test_56t() { # LU-611 #LU-9369
6624         local dir=$DIR/$tdir
6625
6626         setup_56 $dir 0 $NUMDIRS
6627         for i in $(seq $NUMDIRS); do
6628                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6629         done
6630
6631         local expected=$NUMDIRS
6632         local cmd="$LFS find -S 8M $dir"
6633         local nums=$($cmd | wc -l)
6634
6635         [ $nums -eq $expected ] || {
6636                 $LFS getstripe -R $dir
6637                 error "'$cmd' wrong: found $nums, expected $expected"
6638         }
6639         rm -rf $dir
6640
6641         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6642
6643         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6644
6645         expected=$(((NUMDIRS + 1) * NUMFILES))
6646         cmd="$LFS find -stripe-size 512k -type f $dir"
6647         nums=$($cmd | wc -l)
6648         [ $nums -eq $expected ] ||
6649                 error "'$cmd' wrong: found $nums, expected $expected"
6650
6651         cmd="$LFS find -stripe-size +320k -type f $dir"
6652         nums=$($cmd | wc -l)
6653         [ $nums -eq $expected ] ||
6654                 error "'$cmd' wrong: found $nums, expected $expected"
6655
6656         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6657         cmd="$LFS find -stripe-size +200k -type f $dir"
6658         nums=$($cmd | wc -l)
6659         [ $nums -eq $expected ] ||
6660                 error "'$cmd' wrong: found $nums, expected $expected"
6661
6662         cmd="$LFS find -stripe-size -640k -type f $dir"
6663         nums=$($cmd | wc -l)
6664         [ $nums -eq $expected ] ||
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666
6667         expected=4
6668         cmd="$LFS find -stripe-size 256k -type f $dir"
6669         nums=$($cmd | wc -l)
6670         [ $nums -eq $expected ] ||
6671                 error "'$cmd' wrong: found $nums, expected $expected"
6672
6673         cmd="$LFS find -stripe-size -320k -type f $dir"
6674         nums=$($cmd | wc -l)
6675         [ $nums -eq $expected ] ||
6676                 error "'$cmd' wrong: found $nums, expected $expected"
6677
6678         expected=0
6679         cmd="$LFS find -stripe-size 1024k -type f $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] ||
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683 }
6684 run_test 56t "check lfs find -stripe-size works"
6685
6686 test_56u() { # LU-611
6687         local dir=$DIR/$tdir
6688
6689         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6690
6691         if [[ $OSTCOUNT -gt 1 ]]; then
6692                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6693                 onestripe=4
6694         else
6695                 onestripe=0
6696         fi
6697
6698         local expected=$(((NUMDIRS + 1) * NUMFILES))
6699         local cmd="$LFS find -stripe-index 0 -type f $dir"
6700         local nums=$($cmd | wc -l)
6701
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704
6705         expected=$onestripe
6706         cmd="$LFS find -stripe-index 1 -type f $dir"
6707         nums=$($cmd | wc -l)
6708         [ $nums -eq $expected ] ||
6709                 error "'$cmd' wrong: found $nums, expected $expected"
6710
6711         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6712         nums=$($cmd | wc -l)
6713         [ $nums -eq $expected ] ||
6714                 error "'$cmd' wrong: found $nums, expected $expected"
6715
6716         expected=0
6717         # This should produce an error and not return any files
6718         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6719         nums=$($cmd 2>/dev/null | wc -l)
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722
6723         if [[ $OSTCOUNT -gt 1 ]]; then
6724                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6725                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6726                 nums=$($cmd | wc -l)
6727                 [ $nums -eq $expected ] ||
6728                         error "'$cmd' wrong: found $nums, expected $expected"
6729         fi
6730 }
6731 run_test 56u "check lfs find -stripe-index works"
6732
6733 test_56v() {
6734         local mdt_idx=0
6735         local dir=$DIR/$tdir
6736
6737         setup_56 $dir $NUMFILES $NUMDIRS
6738
6739         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6740         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6741
6742         for file in $($LFS find -m $UUID $dir); do
6743                 file_midx=$($LFS getstripe -m $file)
6744                 [ $file_midx -eq $mdt_idx ] ||
6745                         error "lfs find -m $UUID != getstripe -m $file_midx"
6746         done
6747 }
6748 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6749
6750 test_56w() {
6751         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6753
6754         local dir=$DIR/$tdir
6755
6756         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6757
6758         local stripe_size=$($LFS getstripe -S -d $dir) ||
6759                 error "$LFS getstripe -S -d $dir failed"
6760         stripe_size=${stripe_size%% *}
6761
6762         local file_size=$((stripe_size * OSTCOUNT))
6763         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6764         local required_space=$((file_num * file_size))
6765         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6766                            head -n1)
6767         [[ $free_space -le $((required_space / 1024)) ]] &&
6768                 skip_env "need $required_space, have $free_space kbytes"
6769
6770         local dd_bs=65536
6771         local dd_count=$((file_size / dd_bs))
6772
6773         # write data into the files
6774         local i
6775         local j
6776         local file
6777
6778         for i in $(seq $NUMFILES); do
6779                 file=$dir/file$i
6780                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6781                         error "write data into $file failed"
6782         done
6783         for i in $(seq $NUMDIRS); do
6784                 for j in $(seq $NUMFILES); do
6785                         file=$dir/dir$i/file$j
6786                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6787                                 error "write data into $file failed"
6788                 done
6789         done
6790
6791         # $LFS_MIGRATE will fail if hard link migration is unsupported
6792         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6793                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6794                         error "creating links to $dir/dir1/file1 failed"
6795         fi
6796
6797         local expected=-1
6798
6799         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6800
6801         # lfs_migrate file
6802         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6803
6804         echo "$cmd"
6805         eval $cmd || error "$cmd failed"
6806
6807         check_stripe_count $dir/file1 $expected
6808
6809         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6810         then
6811                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6812                 # OST 1 if it is on OST 0. This file is small enough to
6813                 # be on only one stripe.
6814                 file=$dir/migr_1_ost
6815                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6816                         error "write data into $file failed"
6817                 local obdidx=$($LFS getstripe -i $file)
6818                 local oldmd5=$(md5sum $file)
6819                 local newobdidx=0
6820
6821                 [[ $obdidx -eq 0 ]] && newobdidx=1
6822                 cmd="$LFS migrate -i $newobdidx $file"
6823                 echo $cmd
6824                 eval $cmd || error "$cmd failed"
6825
6826                 local realobdix=$($LFS getstripe -i $file)
6827                 local newmd5=$(md5sum $file)
6828
6829                 [[ $newobdidx -ne $realobdix ]] &&
6830                         error "new OST is different (was=$obdidx, "\
6831                               "wanted=$newobdidx, got=$realobdix)"
6832                 [[ "$oldmd5" != "$newmd5" ]] &&
6833                         error "md5sum differ: $oldmd5, $newmd5"
6834         fi
6835
6836         # lfs_migrate dir
6837         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6838         echo "$cmd"
6839         eval $cmd || error "$cmd failed"
6840
6841         for j in $(seq $NUMFILES); do
6842                 check_stripe_count $dir/dir1/file$j $expected
6843         done
6844
6845         # lfs_migrate works with lfs find
6846         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6847              $LFS_MIGRATE -y -c $expected"
6848         echo "$cmd"
6849         eval $cmd || error "$cmd failed"
6850
6851         for i in $(seq 2 $NUMFILES); do
6852                 check_stripe_count $dir/file$i $expected
6853         done
6854         for i in $(seq 2 $NUMDIRS); do
6855                 for j in $(seq $NUMFILES); do
6856                 check_stripe_count $dir/dir$i/file$j $expected
6857                 done
6858         done
6859 }
6860 run_test 56w "check lfs_migrate -c stripe_count works"
6861
6862 test_56wb() {
6863         local file1=$DIR/$tdir/file1
6864         local create_pool=false
6865         local initial_pool=$($LFS getstripe -p $DIR)
6866         local pool_list=()
6867         local pool=""
6868
6869         echo -n "Creating test dir..."
6870         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6871         echo "done."
6872
6873         echo -n "Creating test file..."
6874         touch $file1 || error "cannot create file"
6875         echo "done."
6876
6877         echo -n "Detecting existing pools..."
6878         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6879
6880         if [ ${#pool_list[@]} -gt 0 ]; then
6881                 echo "${pool_list[@]}"
6882                 for thispool in "${pool_list[@]}"; do
6883                         if [[ -z "$initial_pool" ||
6884                               "$initial_pool" != "$thispool" ]]; then
6885                                 pool="$thispool"
6886                                 echo "Using existing pool '$pool'"
6887                                 break
6888                         fi
6889                 done
6890         else
6891                 echo "none detected."
6892         fi
6893         if [ -z "$pool" ]; then
6894                 pool=${POOL:-testpool}
6895                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6896                 echo -n "Creating pool '$pool'..."
6897                 create_pool=true
6898                 pool_add $pool &> /dev/null ||
6899                         error "pool_add failed"
6900                 echo "done."
6901
6902                 echo -n "Adding target to pool..."
6903                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6904                         error "pool_add_targets failed"
6905                 echo "done."
6906         fi
6907
6908         echo -n "Setting pool using -p option..."
6909         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6910                 error "migrate failed rc = $?"
6911         echo "done."
6912
6913         echo -n "Verifying test file is in pool after migrating..."
6914         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6915                 error "file was not migrated to pool $pool"
6916         echo "done."
6917
6918         echo -n "Removing test file from pool '$pool'..."
6919         # "lfs migrate $file" won't remove the file from the pool
6920         # until some striping information is changed.
6921         $LFS migrate -c 1 $file1 &> /dev/null ||
6922                 error "cannot remove from pool"
6923         [ "$($LFS getstripe -p $file1)" ] &&
6924                 error "pool still set"
6925         echo "done."
6926
6927         echo -n "Setting pool using --pool option..."
6928         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6929                 error "migrate failed rc = $?"
6930         echo "done."
6931
6932         # Clean up
6933         rm -f $file1
6934         if $create_pool; then
6935                 destroy_test_pools 2> /dev/null ||
6936                         error "destroy test pools failed"
6937         fi
6938 }
6939 run_test 56wb "check lfs_migrate pool support"
6940
6941 test_56wc() {
6942         local file1="$DIR/$tdir/file1"
6943         local parent_ssize
6944         local parent_scount
6945         local cur_ssize
6946         local cur_scount
6947         local orig_ssize
6948
6949         echo -n "Creating test dir..."
6950         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6951         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6952                 error "cannot set stripe by '-S 1M -c 1'"
6953         echo "done"
6954
6955         echo -n "Setting initial stripe for test file..."
6956         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6957                 error "cannot set stripe"
6958         cur_ssize=$($LFS getstripe -S "$file1")
6959         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6960         echo "done."
6961
6962         # File currently set to -S 512K -c 1
6963
6964         # Ensure -c and -S options are rejected when -R is set
6965         echo -n "Verifying incompatible options are detected..."
6966         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6967                 error "incompatible -c and -R options not detected"
6968         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6969                 error "incompatible -S and -R options not detected"
6970         echo "done."
6971
6972         # Ensure unrecognized options are passed through to 'lfs migrate'
6973         echo -n "Verifying -S option is passed through to lfs migrate..."
6974         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6975                 error "migration failed"
6976         cur_ssize=$($LFS getstripe -S "$file1")
6977         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6978         echo "done."
6979
6980         # File currently set to -S 1M -c 1
6981
6982         # Ensure long options are supported
6983         echo -n "Verifying long options supported..."
6984         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6985                 error "long option without argument not supported"
6986         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6987                 error "long option with argument not supported"
6988         cur_ssize=$($LFS getstripe -S "$file1")
6989         [ $cur_ssize -eq 524288 ] ||
6990                 error "migrate --stripe-size $cur_ssize != 524288"
6991         echo "done."
6992
6993         # File currently set to -S 512K -c 1
6994
6995         if [ "$OSTCOUNT" -gt 1 ]; then
6996                 echo -n "Verifying explicit stripe count can be set..."
6997                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6998                         error "migrate failed"
6999                 cur_scount=$($LFS getstripe -c "$file1")
7000                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7001                 echo "done."
7002         fi
7003
7004         # File currently set to -S 512K -c 1 or -S 512K -c 2
7005
7006         # Ensure parent striping is used if -R is set, and no stripe
7007         # count or size is specified
7008         echo -n "Setting stripe for parent directory..."
7009         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7010                 error "cannot set stripe '-S 2M -c 1'"
7011         echo "done."
7012
7013         echo -n "Verifying restripe option uses parent stripe settings..."
7014         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7015         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7016         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7017                 error "migrate failed"
7018         cur_ssize=$($LFS getstripe -S "$file1")
7019         [ $cur_ssize -eq $parent_ssize ] ||
7020                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7021         cur_scount=$($LFS getstripe -c "$file1")
7022         [ $cur_scount -eq $parent_scount ] ||
7023                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7024         echo "done."
7025
7026         # File currently set to -S 1M -c 1
7027
7028         # Ensure striping is preserved if -R is not set, and no stripe
7029         # count or size is specified
7030         echo -n "Verifying striping size preserved when not specified..."
7031         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7032         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7033                 error "cannot set stripe on parent directory"
7034         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7035                 error "migrate failed"
7036         cur_ssize=$($LFS getstripe -S "$file1")
7037         [ $cur_ssize -eq $orig_ssize ] ||
7038                 error "migrate by default $cur_ssize != $orig_ssize"
7039         echo "done."
7040
7041         # Ensure file name properly detected when final option has no argument
7042         echo -n "Verifying file name properly detected..."
7043         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7044                 error "file name interpreted as option argument"
7045         echo "done."
7046
7047         # Clean up
7048         rm -f "$file1"
7049 }
7050 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7051
7052 test_56wd() {
7053         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7054
7055         local file1=$DIR/$tdir/file1
7056
7057         echo -n "Creating test dir..."
7058         test_mkdir $DIR/$tdir || error "cannot create dir"
7059         echo "done."
7060
7061         echo -n "Creating test file..."
7062         touch $file1
7063         echo "done."
7064
7065         # Ensure 'lfs migrate' will fail by using a non-existent option,
7066         # and make sure rsync is not called to recover
7067         echo -n "Make sure --no-rsync option works..."
7068         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7069                 grep -q 'refusing to fall back to rsync' ||
7070                 error "rsync was called with --no-rsync set"
7071         echo "done."
7072
7073         # Ensure rsync is called without trying 'lfs migrate' first
7074         echo -n "Make sure --rsync option works..."
7075         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7076                 grep -q 'falling back to rsync' &&
7077                 error "lfs migrate was called with --rsync set"
7078         echo "done."
7079
7080         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7081         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7082                 grep -q 'at the same time' ||
7083                 error "--rsync and --no-rsync accepted concurrently"
7084         echo "done."
7085
7086         # Clean up
7087         rm -f $file1
7088 }
7089 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7090
7091 test_56we() {
7092         local td=$DIR/$tdir
7093         local tf=$td/$tfile
7094
7095         test_mkdir $td || error "cannot create $td"
7096         touch $tf || error "cannot touch $tf"
7097
7098         echo -n "Make sure --non-direct|-D works..."
7099         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7100                 grep -q "lfs migrate --non-direct" ||
7101                 error "--non-direct option cannot work correctly"
7102         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7103                 grep -q "lfs migrate -D" ||
7104                 error "-D option cannot work correctly"
7105         echo "done."
7106 }
7107 run_test 56we "check lfs_migrate --non-direct|-D support"
7108
7109 test_56x() {
7110         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7111         check_swap_layouts_support
7112
7113         local dir=$DIR/$tdir
7114         local ref1=/etc/passwd
7115         local file1=$dir/file1
7116
7117         test_mkdir $dir || error "creating dir $dir"
7118         $LFS setstripe -c 2 $file1
7119         cp $ref1 $file1
7120         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7121         stripe=$($LFS getstripe -c $file1)
7122         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7123         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7124
7125         # clean up
7126         rm -f $file1
7127 }
7128 run_test 56x "lfs migration support"
7129
7130 test_56xa() {
7131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7132         check_swap_layouts_support
7133
7134         local dir=$DIR/$tdir/$testnum
7135
7136         test_mkdir -p $dir
7137
7138         local ref1=/etc/passwd
7139         local file1=$dir/file1
7140
7141         $LFS setstripe -c 2 $file1
7142         cp $ref1 $file1
7143         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7144
7145         local stripe=$($LFS getstripe -c $file1)
7146
7147         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7148         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7149
7150         # clean up
7151         rm -f $file1
7152 }
7153 run_test 56xa "lfs migration --block support"
7154
7155 check_migrate_links() {
7156         local dir="$1"
7157         local file1="$dir/file1"
7158         local begin="$2"
7159         local count="$3"
7160         local runas="$4"
7161         local total_count=$(($begin + $count - 1))
7162         local symlink_count=10
7163         local uniq_count=10
7164
7165         if [ ! -f "$file1" ]; then
7166                 echo -n "creating initial file..."
7167                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7168                         error "cannot setstripe initial file"
7169                 echo "done"
7170
7171                 echo -n "creating symlinks..."
7172                 for s in $(seq 1 $symlink_count); do
7173                         ln -s "$file1" "$dir/slink$s" ||
7174                                 error "cannot create symlinks"
7175                 done
7176                 echo "done"
7177
7178                 echo -n "creating nonlinked files..."
7179                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7180                         error "cannot create nonlinked files"
7181                 echo "done"
7182         fi
7183
7184         # create hard links
7185         if [ ! -f "$dir/file$total_count" ]; then
7186                 echo -n "creating hard links $begin:$total_count..."
7187                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7188                         /dev/null || error "cannot create hard links"
7189                 echo "done"
7190         fi
7191
7192         echo -n "checking number of hard links listed in xattrs..."
7193         local fid=$($LFS getstripe -F "$file1")
7194         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7195
7196         echo "${#paths[*]}"
7197         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7198                         skip "hard link list has unexpected size, skipping test"
7199         fi
7200         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7201                         error "link names should exceed xattrs size"
7202         fi
7203
7204         echo -n "migrating files..."
7205         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7206         local rc=$?
7207         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7208         echo "done"
7209
7210         # make sure all links have been properly migrated
7211         echo -n "verifying files..."
7212         fid=$($LFS getstripe -F "$file1") ||
7213                 error "cannot get fid for file $file1"
7214         for i in $(seq 2 $total_count); do
7215                 local fid2=$($LFS getstripe -F $dir/file$i)
7216
7217                 [ "$fid2" == "$fid" ] ||
7218                         error "migrated hard link has mismatched FID"
7219         done
7220
7221         # make sure hard links were properly detected, and migration was
7222         # performed only once for the entire link set; nonlinked files should
7223         # also be migrated
7224         local actual=$(grep -c 'done' <<< "$migrate_out")
7225         local expected=$(($uniq_count + 1))
7226
7227         [ "$actual" -eq  "$expected" ] ||
7228                 error "hard links individually migrated ($actual != $expected)"
7229
7230         # make sure the correct number of hard links are present
7231         local hardlinks=$(stat -c '%h' "$file1")
7232
7233         [ $hardlinks -eq $total_count ] ||
7234                 error "num hard links $hardlinks != $total_count"
7235         echo "done"
7236
7237         return 0
7238 }
7239
7240 test_56xb() {
7241         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7242                 skip "Need MDS version at least 2.10.55"
7243
7244         local dir="$DIR/$tdir"
7245
7246         test_mkdir "$dir" || error "cannot create dir $dir"
7247
7248         echo "testing lfs migrate mode when all links fit within xattrs"
7249         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7250
7251         echo "testing rsync mode when all links fit within xattrs"
7252         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7253
7254         echo "testing lfs migrate mode when all links do not fit within xattrs"
7255         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7256
7257         echo "testing rsync mode when all links do not fit within xattrs"
7258         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7259
7260         chown -R $RUNAS_ID $dir
7261         echo "testing non-root lfs migrate mode when not all links are in xattr"
7262         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7263
7264         # clean up
7265         rm -rf $dir
7266 }
7267 run_test 56xb "lfs migration hard link support"
7268
7269 test_56xc() {
7270         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7271
7272         local dir="$DIR/$tdir"
7273
7274         test_mkdir "$dir" || error "cannot create dir $dir"
7275
7276         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7277         echo -n "Setting initial stripe for 20MB test file..."
7278         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7279                 error "cannot setstripe 20MB file"
7280         echo "done"
7281         echo -n "Sizing 20MB test file..."
7282         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7283         echo "done"
7284         echo -n "Verifying small file autostripe count is 1..."
7285         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7286                 error "cannot migrate 20MB file"
7287         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7288                 error "cannot get stripe for $dir/20mb"
7289         [ $stripe_count -eq 1 ] ||
7290                 error "unexpected stripe count $stripe_count for 20MB file"
7291         rm -f "$dir/20mb"
7292         echo "done"
7293
7294         # Test 2: File is small enough to fit within the available space on
7295         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7296         # have at least an additional 1KB for each desired stripe for test 3
7297         echo -n "Setting stripe for 1GB test file..."
7298         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7299         echo "done"
7300         echo -n "Sizing 1GB test file..."
7301         # File size is 1GB + 3KB
7302         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7303         echo "done"
7304
7305         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7306         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7307         if (( avail > 524288 * OSTCOUNT )); then
7308                 echo -n "Migrating 1GB file..."
7309                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7310                         error "cannot migrate 1GB file"
7311                 echo "done"
7312                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7313                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7314                         error "cannot getstripe for 1GB file"
7315                 [ $stripe_count -eq 2 ] ||
7316                         error "unexpected stripe count $stripe_count != 2"
7317                 echo "done"
7318         fi
7319
7320         # Test 3: File is too large to fit within the available space on
7321         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7322         if [ $OSTCOUNT -ge 3 ]; then
7323                 # The required available space is calculated as
7324                 # file size (1GB + 3KB) / OST count (3).
7325                 local kb_per_ost=349526
7326
7327                 echo -n "Migrating 1GB file with limit..."
7328                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7329                         error "cannot migrate 1GB file with limit"
7330                 echo "done"
7331
7332                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7333                 echo -n "Verifying 1GB autostripe count with limited space..."
7334                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7335                         error "unexpected stripe count $stripe_count (min 3)"
7336                 echo "done"
7337         fi
7338
7339         # clean up
7340         rm -rf $dir
7341 }
7342 run_test 56xc "lfs migration autostripe"
7343
7344 test_56xd() {
7345         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7346
7347         local dir=$DIR/$tdir
7348         local f_mgrt=$dir/$tfile.mgrt
7349         local f_yaml=$dir/$tfile.yaml
7350         local f_copy=$dir/$tfile.copy
7351         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7352         local layout_copy="-c 2 -S 2M -i 1"
7353         local yamlfile=$dir/yamlfile
7354         local layout_before;
7355         local layout_after;
7356
7357         test_mkdir "$dir" || error "cannot create dir $dir"
7358         $LFS setstripe $layout_yaml $f_yaml ||
7359                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7360         $LFS getstripe --yaml $f_yaml > $yamlfile
7361         $LFS setstripe $layout_copy $f_copy ||
7362                 error "cannot setstripe $f_copy with layout $layout_copy"
7363         touch $f_mgrt
7364         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7365
7366         # 1. test option --yaml
7367         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7368                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7369         layout_before=$(get_layout_param $f_yaml)
7370         layout_after=$(get_layout_param $f_mgrt)
7371         [ "$layout_after" == "$layout_before" ] ||
7372                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7373
7374         # 2. test option --copy
7375         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7376                 error "cannot migrate $f_mgrt with --copy $f_copy"
7377         layout_before=$(get_layout_param $f_copy)
7378         layout_after=$(get_layout_param $f_mgrt)
7379         [ "$layout_after" == "$layout_before" ] ||
7380                 error "lfs_migrate --copy: $layout_after != $layout_before"
7381 }
7382 run_test 56xd "check lfs_migrate --yaml and --copy support"
7383
7384 test_56xe() {
7385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7386
7387         local dir=$DIR/$tdir
7388         local f_comp=$dir/$tfile
7389         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7390         local layout_before=""
7391         local layout_after=""
7392
7393         test_mkdir "$dir" || error "cannot create dir $dir"
7394         $LFS setstripe $layout $f_comp ||
7395                 error "cannot setstripe $f_comp with layout $layout"
7396         layout_before=$(get_layout_param $f_comp)
7397         dd if=/dev/zero of=$f_comp bs=1M count=4
7398
7399         # 1. migrate a comp layout file by lfs_migrate
7400         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7401         layout_after=$(get_layout_param $f_comp)
7402         [ "$layout_before" == "$layout_after" ] ||
7403                 error "lfs_migrate: $layout_before != $layout_after"
7404
7405         # 2. migrate a comp layout file by lfs migrate
7406         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7407         layout_after=$(get_layout_param $f_comp)
7408         [ "$layout_before" == "$layout_after" ] ||
7409                 error "lfs migrate: $layout_before != $layout_after"
7410 }
7411 run_test 56xe "migrate a composite layout file"
7412
7413 test_56xf() {
7414         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7415
7416         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7417                 skip "Need server version at least 2.13.53"
7418
7419         local dir=$DIR/$tdir
7420         local f_comp=$dir/$tfile
7421         local layout="-E 1M -c1 -E -1 -c2"
7422         local fid_before=""
7423         local fid_after=""
7424
7425         test_mkdir "$dir" || error "cannot create dir $dir"
7426         $LFS setstripe $layout $f_comp ||
7427                 error "cannot setstripe $f_comp with layout $layout"
7428         fid_before=$($LFS getstripe --fid $f_comp)
7429         dd if=/dev/zero of=$f_comp bs=1M count=4
7430
7431         # 1. migrate a comp layout file to a comp layout
7432         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7433         fid_after=$($LFS getstripe --fid $f_comp)
7434         [ "$fid_before" == "$fid_after" ] ||
7435                 error "comp-to-comp migrate: $fid_before != $fid_after"
7436
7437         # 2. migrate a comp layout file to a plain layout
7438         $LFS migrate -c2 $f_comp ||
7439                 error "cannot migrate $f_comp by lfs migrate"
7440         fid_after=$($LFS getstripe --fid $f_comp)
7441         [ "$fid_before" == "$fid_after" ] ||
7442                 error "comp-to-plain migrate: $fid_before != $fid_after"
7443
7444         # 3. migrate a plain layout file to a comp layout
7445         $LFS migrate $layout $f_comp ||
7446                 error "cannot migrate $f_comp by lfs migrate"
7447         fid_after=$($LFS getstripe --fid $f_comp)
7448         [ "$fid_before" == "$fid_after" ] ||
7449                 error "plain-to-comp migrate: $fid_before != $fid_after"
7450 }
7451 run_test 56xf "FID is not lost during migration of a composite layout file"
7452
7453 test_56y() {
7454         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7455                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7456
7457         local res=""
7458         local dir=$DIR/$tdir
7459         local f1=$dir/file1
7460         local f2=$dir/file2
7461
7462         test_mkdir -p $dir || error "creating dir $dir"
7463         touch $f1 || error "creating std file $f1"
7464         $MULTIOP $f2 H2c || error "creating released file $f2"
7465
7466         # a directory can be raid0, so ask only for files
7467         res=$($LFS find $dir -L raid0 -type f | wc -l)
7468         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7469
7470         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7471         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7472
7473         # only files can be released, so no need to force file search
7474         res=$($LFS find $dir -L released)
7475         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7476
7477         res=$($LFS find $dir -type f \! -L released)
7478         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7479 }
7480 run_test 56y "lfs find -L raid0|released"
7481
7482 test_56z() { # LU-4824
7483         # This checks to make sure 'lfs find' continues after errors
7484         # There are two classes of errors that should be caught:
7485         # - If multiple paths are provided, all should be searched even if one
7486         #   errors out
7487         # - If errors are encountered during the search, it should not terminate
7488         #   early
7489         local dir=$DIR/$tdir
7490         local i
7491
7492         test_mkdir $dir
7493         for i in d{0..9}; do
7494                 test_mkdir $dir/$i
7495                 touch $dir/$i/$tfile
7496         done
7497         $LFS find $DIR/non_existent_dir $dir &&
7498                 error "$LFS find did not return an error"
7499         # Make a directory unsearchable. This should NOT be the last entry in
7500         # directory order.  Arbitrarily pick the 6th entry
7501         chmod 700 $($LFS find $dir -type d | sed '6!d')
7502
7503         $RUNAS $LFS find $DIR/non_existent $dir
7504         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7505
7506         # The user should be able to see 10 directories and 9 files
7507         (( count == 19 )) ||
7508                 error "$LFS find found $count != 19 entries after error"
7509 }
7510 run_test 56z "lfs find should continue after an error"
7511
7512 test_56aa() { # LU-5937
7513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7514
7515         local dir=$DIR/$tdir
7516
7517         mkdir $dir
7518         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7519
7520         createmany -o $dir/striped_dir/${tfile}- 1024
7521         local dirs=$($LFS find --size +8k $dir/)
7522
7523         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7524 }
7525 run_test 56aa "lfs find --size under striped dir"
7526
7527 test_56ab() { # LU-10705
7528         test_mkdir $DIR/$tdir
7529         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7530         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7531         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7532         # Flush writes to ensure valid blocks.  Need to be more thorough for
7533         # ZFS, since blocks are not allocated/returned to client immediately.
7534         sync_all_data
7535         wait_zfs_commit ost1 2
7536         cancel_lru_locks osc
7537         ls -ls $DIR/$tdir
7538
7539         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7540
7541         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7542
7543         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7544         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7545
7546         rm -f $DIR/$tdir/$tfile.[123]
7547 }
7548 run_test 56ab "lfs find --blocks"
7549
7550 test_56ba() {
7551         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7552                 skip "Need MDS version at least 2.10.50"
7553
7554         # Create composite files with one component
7555         local dir=$DIR/$tdir
7556
7557         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7558         # Create composite files with three components
7559         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7560         # Create non-composite files
7561         createmany -o $dir/${tfile}- 10
7562
7563         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7564
7565         [[ $nfiles == 10 ]] ||
7566                 error "lfs find -E 1M found $nfiles != 10 files"
7567
7568         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7569         [[ $nfiles == 25 ]] ||
7570                 error "lfs find ! -E 1M found $nfiles != 25 files"
7571
7572         # All files have a component that starts at 0
7573         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7574         [[ $nfiles == 35 ]] ||
7575                 error "lfs find --component-start 0 - $nfiles != 35 files"
7576
7577         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7578         [[ $nfiles == 15 ]] ||
7579                 error "lfs find --component-start 2M - $nfiles != 15 files"
7580
7581         # All files created here have a componenet that does not starts at 2M
7582         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7583         [[ $nfiles == 35 ]] ||
7584                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7585
7586         # Find files with a specified number of components
7587         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7588         [[ $nfiles == 15 ]] ||
7589                 error "lfs find --component-count 3 - $nfiles != 15 files"
7590
7591         # Remember non-composite files have a component count of zero
7592         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7593         [[ $nfiles == 10 ]] ||
7594                 error "lfs find --component-count 0 - $nfiles != 10 files"
7595
7596         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7597         [[ $nfiles == 20 ]] ||
7598                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7599
7600         # All files have a flag called "init"
7601         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7602         [[ $nfiles == 35 ]] ||
7603                 error "lfs find --component-flags init - $nfiles != 35 files"
7604
7605         # Multi-component files will have a component not initialized
7606         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7607         [[ $nfiles == 15 ]] ||
7608                 error "lfs find !--component-flags init - $nfiles != 15 files"
7609
7610         rm -rf $dir
7611
7612 }
7613 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7614
7615 test_56ca() {
7616         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7617                 skip "Need MDS version at least 2.10.57"
7618
7619         local td=$DIR/$tdir
7620         local tf=$td/$tfile
7621         local dir
7622         local nfiles
7623         local cmd
7624         local i
7625         local j
7626
7627         # create mirrored directories and mirrored files
7628         mkdir $td || error "mkdir $td failed"
7629         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7630         createmany -o $tf- 10 || error "create $tf- failed"
7631
7632         for i in $(seq 2); do
7633                 dir=$td/dir$i
7634                 mkdir $dir || error "mkdir $dir failed"
7635                 $LFS mirror create -N$((3 + i)) $dir ||
7636                         error "create mirrored dir $dir failed"
7637                 createmany -o $dir/$tfile- 10 ||
7638                         error "create $dir/$tfile- failed"
7639         done
7640
7641         # change the states of some mirrored files
7642         echo foo > $tf-6
7643         for i in $(seq 2); do
7644                 dir=$td/dir$i
7645                 for j in $(seq 4 9); do
7646                         echo foo > $dir/$tfile-$j
7647                 done
7648         done
7649
7650         # find mirrored files with specific mirror count
7651         cmd="$LFS find --mirror-count 3 --type f $td"
7652         nfiles=$($cmd | wc -l)
7653         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7654
7655         cmd="$LFS find ! --mirror-count 3 --type f $td"
7656         nfiles=$($cmd | wc -l)
7657         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7658
7659         cmd="$LFS find --mirror-count +2 --type f $td"
7660         nfiles=$($cmd | wc -l)
7661         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7662
7663         cmd="$LFS find --mirror-count -6 --type f $td"
7664         nfiles=$($cmd | wc -l)
7665         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7666
7667         # find mirrored files with specific file state
7668         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7669         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7670
7671         cmd="$LFS find --mirror-state=ro --type f $td"
7672         nfiles=$($cmd | wc -l)
7673         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7674
7675         cmd="$LFS find ! --mirror-state=ro --type f $td"
7676         nfiles=$($cmd | wc -l)
7677         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7678
7679         cmd="$LFS find --mirror-state=wp --type f $td"
7680         nfiles=$($cmd | wc -l)
7681         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7682
7683         cmd="$LFS find ! --mirror-state=sp --type f $td"
7684         nfiles=$($cmd | wc -l)
7685         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7686 }
7687 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7688
7689 test_57a() {
7690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7691         # note test will not do anything if MDS is not local
7692         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7693                 skip_env "ldiskfs only test"
7694         fi
7695         remote_mds_nodsh && skip "remote MDS with nodsh"
7696
7697         local MNTDEV="osd*.*MDT*.mntdev"
7698         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7699         [ -z "$DEV" ] && error "can't access $MNTDEV"
7700         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7701                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7702                         error "can't access $DEV"
7703                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7704                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7705                 rm $TMP/t57a.dump
7706         done
7707 }
7708 run_test 57a "verify MDS filesystem created with large inodes =="
7709
7710 test_57b() {
7711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7712         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7713                 skip_env "ldiskfs only test"
7714         fi
7715         remote_mds_nodsh && skip "remote MDS with nodsh"
7716
7717         local dir=$DIR/$tdir
7718         local filecount=100
7719         local file1=$dir/f1
7720         local fileN=$dir/f$filecount
7721
7722         rm -rf $dir || error "removing $dir"
7723         test_mkdir -c1 $dir
7724         local mdtidx=$($LFS getstripe -m $dir)
7725         local mdtname=MDT$(printf %04x $mdtidx)
7726         local facet=mds$((mdtidx + 1))
7727
7728         echo "mcreating $filecount files"
7729         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7730
7731         # verify that files do not have EAs yet
7732         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7733                 error "$file1 has an EA"
7734         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7735                 error "$fileN has an EA"
7736
7737         sync
7738         sleep 1
7739         df $dir  #make sure we get new statfs data
7740         local mdsfree=$(do_facet $facet \
7741                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7742         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7743         local file
7744
7745         echo "opening files to create objects/EAs"
7746         for file in $(seq -f $dir/f%g 1 $filecount); do
7747                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7748                         error "opening $file"
7749         done
7750
7751         # verify that files have EAs now
7752         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7753         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7754
7755         sleep 1  #make sure we get new statfs data
7756         df $dir
7757         local mdsfree2=$(do_facet $facet \
7758                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7759         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7760
7761         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7762                 if [ "$mdsfree" != "$mdsfree2" ]; then
7763                         error "MDC before $mdcfree != after $mdcfree2"
7764                 else
7765                         echo "MDC before $mdcfree != after $mdcfree2"
7766                         echo "unable to confirm if MDS has large inodes"
7767                 fi
7768         fi
7769         rm -rf $dir
7770 }
7771 run_test 57b "default LOV EAs are stored inside large inodes ==="
7772
7773 test_58() {
7774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7775         [ -z "$(which wiretest 2>/dev/null)" ] &&
7776                         skip_env "could not find wiretest"
7777
7778         wiretest
7779 }
7780 run_test 58 "verify cross-platform wire constants =============="
7781
7782 test_59() {
7783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7784
7785         echo "touch 130 files"
7786         createmany -o $DIR/f59- 130
7787         echo "rm 130 files"
7788         unlinkmany $DIR/f59- 130
7789         sync
7790         # wait for commitment of removal
7791         wait_delete_completed
7792 }
7793 run_test 59 "verify cancellation of llog records async ========="
7794
7795 TEST60_HEAD="test_60 run $RANDOM"
7796 test_60a() {
7797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7798         remote_mgs_nodsh && skip "remote MGS with nodsh"
7799         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7800                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7801                         skip_env "missing subtest run-llog.sh"
7802
7803         log "$TEST60_HEAD - from kernel mode"
7804         do_facet mgs "$LCTL dk > /dev/null"
7805         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7806         do_facet mgs $LCTL dk > $TMP/$tfile
7807
7808         # LU-6388: test llog_reader
7809         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7810         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7811         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7812                         skip_env "missing llog_reader"
7813         local fstype=$(facet_fstype mgs)
7814         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7815                 skip_env "Only for ldiskfs or zfs type mgs"
7816
7817         local mntpt=$(facet_mntpt mgs)
7818         local mgsdev=$(mgsdevname 1)
7819         local fid_list
7820         local fid
7821         local rec_list
7822         local rec
7823         local rec_type
7824         local obj_file
7825         local path
7826         local seq
7827         local oid
7828         local pass=true
7829
7830         #get fid and record list
7831         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7832                 tail -n 4))
7833         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7834                 tail -n 4))
7835         #remount mgs as ldiskfs or zfs type
7836         stop mgs || error "stop mgs failed"
7837         mount_fstype mgs || error "remount mgs failed"
7838         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7839                 fid=${fid_list[i]}
7840                 rec=${rec_list[i]}
7841                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7842                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7843                 oid=$((16#$oid))
7844
7845                 case $fstype in
7846                         ldiskfs )
7847                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7848                         zfs )
7849                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7850                 esac
7851                 echo "obj_file is $obj_file"
7852                 do_facet mgs $llog_reader $obj_file
7853
7854                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7855                         awk '{ print $3 }' | sed -e "s/^type=//g")
7856                 if [ $rec_type != $rec ]; then
7857                         echo "FAILED test_60a wrong record type $rec_type," \
7858                               "should be $rec"
7859                         pass=false
7860                         break
7861                 fi
7862
7863                 #check obj path if record type is LLOG_LOGID_MAGIC
7864                 if [ "$rec" == "1064553b" ]; then
7865                         path=$(do_facet mgs $llog_reader $obj_file |
7866                                 grep "path=" | awk '{ print $NF }' |
7867                                 sed -e "s/^path=//g")
7868                         if [ $obj_file != $mntpt/$path ]; then
7869                                 echo "FAILED test_60a wrong obj path" \
7870                                       "$montpt/$path, should be $obj_file"
7871                                 pass=false
7872                                 break
7873                         fi
7874                 fi
7875         done
7876         rm -f $TMP/$tfile
7877         #restart mgs before "error", otherwise it will block the next test
7878         stop mgs || error "stop mgs failed"
7879         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7880         $pass || error "test failed, see FAILED test_60a messages for specifics"
7881 }
7882 run_test 60a "llog_test run from kernel module and test llog_reader"
7883
7884 test_60b() { # bug 6411
7885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7886
7887         dmesg > $DIR/$tfile
7888         LLOG_COUNT=$(do_facet mgs dmesg |
7889                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7890                           /llog_[a-z]*.c:[0-9]/ {
7891                                 if (marker)
7892                                         from_marker++
7893                                 from_begin++
7894                           }
7895                           END {
7896                                 if (marker)
7897                                         print from_marker
7898                                 else
7899                                         print from_begin
7900                           }")
7901
7902         [[ $LLOG_COUNT -gt 120 ]] &&
7903                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7904 }
7905 run_test 60b "limit repeated messages from CERROR/CWARN"
7906
7907 test_60c() {
7908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7909
7910         echo "create 5000 files"
7911         createmany -o $DIR/f60c- 5000
7912 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7913         lctl set_param fail_loc=0x80000137
7914         unlinkmany $DIR/f60c- 5000
7915         lctl set_param fail_loc=0
7916 }
7917 run_test 60c "unlink file when mds full"
7918
7919 test_60d() {
7920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7921
7922         SAVEPRINTK=$(lctl get_param -n printk)
7923         # verify "lctl mark" is even working"
7924         MESSAGE="test message ID $RANDOM $$"
7925         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7926         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7927
7928         lctl set_param printk=0 || error "set lnet.printk failed"
7929         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7930         MESSAGE="new test message ID $RANDOM $$"
7931         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7932         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7933         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7934
7935         lctl set_param -n printk="$SAVEPRINTK"
7936 }
7937 run_test 60d "test printk console message masking"
7938
7939 test_60e() {
7940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7941         remote_mds_nodsh && skip "remote MDS with nodsh"
7942
7943         touch $DIR/$tfile
7944 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7945         do_facet mds1 lctl set_param fail_loc=0x15b
7946         rm $DIR/$tfile
7947 }
7948 run_test 60e "no space while new llog is being created"
7949
7950 test_60g() {
7951         local pid
7952         local i
7953
7954         test_mkdir -c $MDSCOUNT $DIR/$tdir
7955
7956         (
7957                 local index=0
7958                 while true; do
7959                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7960                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7961                                 2>/dev/null
7962                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7963                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7964                         index=$((index + 1))
7965                 done
7966         ) &
7967
7968         pid=$!
7969
7970         for i in {0..100}; do
7971                 # define OBD_FAIL_OSD_TXN_START    0x19a
7972                 local index=$((i % MDSCOUNT + 1))
7973
7974                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7975                         > /dev/null
7976                 sleep 0.01
7977         done
7978
7979         kill -9 $pid
7980
7981         for i in $(seq $MDSCOUNT); do
7982                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7983         done
7984
7985         mkdir $DIR/$tdir/new || error "mkdir failed"
7986         rmdir $DIR/$tdir/new || error "rmdir failed"
7987
7988         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7989                 -t namespace
7990         for i in $(seq $MDSCOUNT); do
7991                 wait_update_facet mds$i "$LCTL get_param -n \
7992                         mdd.$(facet_svc mds$i).lfsck_namespace |
7993                         awk '/^status/ { print \\\$2 }'" "completed"
7994         done
7995
7996         ls -R $DIR/$tdir || error "ls failed"
7997         rm -rf $DIR/$tdir || error "rmdir failed"
7998 }
7999 run_test 60g "transaction abort won't cause MDT hung"
8000
8001 test_60h() {
8002         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8003                 skip "Need MDS version at least 2.12.52"
8004         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8005
8006         local f
8007
8008         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8009         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8010         for fail_loc in 0x80000188 0x80000189; do
8011                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8012                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8013                         error "mkdir $dir-$fail_loc failed"
8014                 for i in {0..10}; do
8015                         # create may fail on missing stripe
8016                         echo $i > $DIR/$tdir-$fail_loc/$i
8017                 done
8018                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8019                         error "getdirstripe $tdir-$fail_loc failed"
8020                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8021                         error "migrate $tdir-$fail_loc failed"
8022                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8023                         error "getdirstripe $tdir-$fail_loc failed"
8024                 pushd $DIR/$tdir-$fail_loc
8025                 for f in *; do
8026                         echo $f | cmp $f - || error "$f data mismatch"
8027                 done
8028                 popd
8029                 rm -rf $DIR/$tdir-$fail_loc
8030         done
8031 }
8032 run_test 60h "striped directory with missing stripes can be accessed"
8033
8034 test_61a() {
8035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8036
8037         f="$DIR/f61"
8038         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8039         cancel_lru_locks osc
8040         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8041         sync
8042 }
8043 run_test 61a "mmap() writes don't make sync hang ================"
8044
8045 test_61b() {
8046         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8047 }
8048 run_test 61b "mmap() of unstriped file is successful"
8049
8050 # bug 2330 - insufficient obd_match error checking causes LBUG
8051 test_62() {
8052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8053
8054         f="$DIR/f62"
8055         echo foo > $f
8056         cancel_lru_locks osc
8057         lctl set_param fail_loc=0x405
8058         cat $f && error "cat succeeded, expect -EIO"
8059         lctl set_param fail_loc=0
8060 }
8061 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8062 # match every page all of the time.
8063 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8064
8065 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8066 # Though this test is irrelevant anymore, it helped to reveal some
8067 # other grant bugs (LU-4482), let's keep it.
8068 test_63a() {   # was test_63
8069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8070
8071         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8072
8073         for i in `seq 10` ; do
8074                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8075                 sleep 5
8076                 kill $!
8077                 sleep 1
8078         done
8079
8080         rm -f $DIR/f63 || true
8081 }
8082 run_test 63a "Verify oig_wait interruption does not crash ======="
8083
8084 # bug 2248 - async write errors didn't return to application on sync
8085 # bug 3677 - async write errors left page locked
8086 test_63b() {
8087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8088
8089         debugsave
8090         lctl set_param debug=-1
8091
8092         # ensure we have a grant to do async writes
8093         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8094         rm $DIR/$tfile
8095
8096         sync    # sync lest earlier test intercept the fail_loc
8097
8098         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8099         lctl set_param fail_loc=0x80000406
8100         $MULTIOP $DIR/$tfile Owy && \
8101                 error "sync didn't return ENOMEM"
8102         sync; sleep 2; sync     # do a real sync this time to flush page
8103         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8104                 error "locked page left in cache after async error" || true
8105         debugrestore
8106 }
8107 run_test 63b "async write errors should be returned to fsync ==="
8108
8109 test_64a () {
8110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8111
8112         lfs df $DIR
8113         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8114 }
8115 run_test 64a "verify filter grant calculations (in kernel) ====="
8116
8117 test_64b () {
8118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8119
8120         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8121 }
8122 run_test 64b "check out-of-space detection on client"
8123
8124 test_64c() {
8125         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8126 }
8127 run_test 64c "verify grant shrink"
8128
8129 import_param() {
8130         local tgt=$1
8131         local param=$2
8132
8133         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8134 }
8135
8136 # this does exactly what osc_request.c:osc_announce_cached() does in
8137 # order to calculate max amount of grants to ask from server
8138 want_grant() {
8139         local tgt=$1
8140
8141         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8142         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8143
8144         ((rpc_in_flight++));
8145         nrpages=$((nrpages * rpc_in_flight))
8146
8147         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8148
8149         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8150
8151         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8152         local undirty=$((nrpages * PAGE_SIZE))
8153
8154         local max_extent_pages
8155         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8156         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8157         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8158         local grant_extent_tax
8159         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8160
8161         undirty=$((undirty + nrextents * grant_extent_tax))
8162
8163         echo $undirty
8164 }
8165
8166 # this is size of unit for grant allocation. It should be equal to
8167 # what tgt_grant.c:tgt_grant_chunk() calculates
8168 grant_chunk() {
8169         local tgt=$1
8170         local max_brw_size
8171         local grant_extent_tax
8172
8173         max_brw_size=$(import_param $tgt max_brw_size)
8174
8175         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8176
8177         echo $(((max_brw_size + grant_extent_tax) * 2))
8178 }
8179
8180 test_64d() {
8181         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8182                 skip "OST < 2.10.55 doesn't limit grants enough"
8183
8184         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8185
8186         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8187                 skip "no grant_param connect flag"
8188
8189         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8190
8191         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8192         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8193
8194
8195         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8196         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8197
8198         $LFS setstripe $DIR/$tfile -i 0 -c 1
8199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8200         ddpid=$!
8201
8202         while kill -0 $ddpid; do
8203                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8204
8205                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8206                         kill $ddpid
8207                         error "cur_grant $cur_grant > $max_cur_granted"
8208                 fi
8209
8210                 sleep 1
8211         done
8212 }
8213 run_test 64d "check grant limit exceed"
8214
8215 check_grants() {
8216         local tgt=$1
8217         local expected=$2
8218         local msg=$3
8219         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8220
8221         ((cur_grants == expected)) ||
8222                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8223 }
8224
8225 round_up_p2() {
8226         echo $((($1 + $2 - 1) & ~($2 - 1)))
8227 }
8228
8229 test_64e() {
8230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8231         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8232                 skip "Need OSS version at least 2.11.56"
8233
8234         # Remount client to reset grant
8235         remount_client $MOUNT || error "failed to remount client"
8236         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8237
8238         local init_grants=$(import_param $osc_tgt initial_grant)
8239
8240         check_grants $osc_tgt $init_grants "init grants"
8241
8242         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8243         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8244         local gbs=$(import_param $osc_tgt grant_block_size)
8245
8246         # write random number of bytes from max_brw_size / 4 to max_brw_size
8247         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8248         # align for direct io
8249         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8250         # round to grant consumption unit
8251         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8252
8253         local grants=$((wb_round_up + extent_tax))
8254
8255         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8256
8257         # define OBD_FAIL_TGT_NO_GRANT 0x725
8258         # make the server not grant more back
8259         do_facet ost1 $LCTL set_param fail_loc=0x725
8260         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8261
8262         do_facet ost1 $LCTL set_param fail_loc=0
8263
8264         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8265
8266         rm -f $DIR/$tfile || error "rm failed"
8267
8268         # Remount client to reset grant
8269         remount_client $MOUNT || error "failed to remount client"
8270         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8271
8272         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8273
8274         # define OBD_FAIL_TGT_NO_GRANT 0x725
8275         # make the server not grant more back
8276         do_facet ost1 $LCTL set_param fail_loc=0x725
8277         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8278         do_facet ost1 $LCTL set_param fail_loc=0
8279
8280         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8281 }
8282 run_test 64e "check grant consumption (no grant allocation)"
8283
8284 test_64f() {
8285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8286
8287         # Remount client to reset grant
8288         remount_client $MOUNT || error "failed to remount client"
8289         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8290
8291         local init_grants=$(import_param $osc_tgt initial_grant)
8292         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8293         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8294         local gbs=$(import_param $osc_tgt grant_block_size)
8295         local chunk=$(grant_chunk $osc_tgt)
8296
8297         # write random number of bytes from max_brw_size / 4 to max_brw_size
8298         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8299         # align for direct io
8300         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8301         # round to grant consumption unit
8302         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8303
8304         local grants=$((wb_round_up + extent_tax))
8305
8306         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8307         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8308                 error "error writing to $DIR/$tfile"
8309
8310         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8311                 "direct io with grant allocation"
8312
8313         rm -f $DIR/$tfile || error "rm failed"
8314
8315         # Remount client to reset grant
8316         remount_client $MOUNT || error "failed to remount client"
8317         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8318
8319         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8320
8321         local cmd="oO_WRONLY:w${write_bytes}_yc"
8322
8323         $MULTIOP $DIR/$tfile $cmd &
8324         MULTIPID=$!
8325         sleep 1
8326
8327         check_grants $osc_tgt $((init_grants - grants)) \
8328                 "buffered io, not write rpc"
8329
8330         kill -USR1 $MULTIPID
8331         wait
8332
8333         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8334                 "buffered io, one RPC"
8335 }
8336 run_test 64f "check grant consumption (with grant allocation)"
8337
8338 # bug 1414 - set/get directories' stripe info
8339 test_65a() {
8340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8341
8342         test_mkdir $DIR/$tdir
8343         touch $DIR/$tdir/f1
8344         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8345 }
8346 run_test 65a "directory with no stripe info"
8347
8348 test_65b() {
8349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8350
8351         test_mkdir $DIR/$tdir
8352         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8353
8354         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8355                                                 error "setstripe"
8356         touch $DIR/$tdir/f2
8357         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8358 }
8359 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8360
8361 test_65c() {
8362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8363         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8364
8365         test_mkdir $DIR/$tdir
8366         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8367
8368         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8369                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8370         touch $DIR/$tdir/f3
8371         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8372 }
8373 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8374
8375 test_65d() {
8376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8377
8378         test_mkdir $DIR/$tdir
8379         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8380         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8381
8382         if [[ $STRIPECOUNT -le 0 ]]; then
8383                 sc=1
8384         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8385                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8386                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8387         else
8388                 sc=$(($STRIPECOUNT - 1))
8389         fi
8390         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8391         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8392         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8393                 error "lverify failed"
8394 }
8395 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8396
8397 test_65e() {
8398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8399
8400         test_mkdir $DIR/$tdir
8401
8402         $LFS setstripe $DIR/$tdir || error "setstripe"
8403         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8404                                         error "no stripe info failed"
8405         touch $DIR/$tdir/f6
8406         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8407 }
8408 run_test 65e "directory setstripe defaults"
8409
8410 test_65f() {
8411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8412
8413         test_mkdir $DIR/${tdir}f
8414         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8415                 error "setstripe succeeded" || true
8416 }
8417 run_test 65f "dir setstripe permission (should return error) ==="
8418
8419 test_65g() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421
8422         test_mkdir $DIR/$tdir
8423         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8424
8425         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8426                 error "setstripe -S failed"
8427         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8428         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8429                 error "delete default stripe failed"
8430 }
8431 run_test 65g "directory setstripe -d"
8432
8433 test_65h() {
8434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8435
8436         test_mkdir $DIR/$tdir
8437         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8438
8439         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8440                 error "setstripe -S failed"
8441         test_mkdir $DIR/$tdir/dd1
8442         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8443                 error "stripe info inherit failed"
8444 }
8445 run_test 65h "directory stripe info inherit ===================="
8446
8447 test_65i() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449
8450         save_layout_restore_at_exit $MOUNT
8451
8452         # bug6367: set non-default striping on root directory
8453         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8454
8455         # bug12836: getstripe on -1 default directory striping
8456         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8457
8458         # bug12836: getstripe -v on -1 default directory striping
8459         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8460
8461         # bug12836: new find on -1 default directory striping
8462         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8463 }
8464 run_test 65i "various tests to set root directory striping"
8465
8466 test_65j() { # bug6367
8467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8468
8469         sync; sleep 1
8470
8471         # if we aren't already remounting for each test, do so for this test
8472         if [ "$I_MOUNTED" = "yes" ]; then
8473                 cleanup || error "failed to unmount"
8474                 setup
8475         fi
8476
8477         save_layout_restore_at_exit $MOUNT
8478
8479         $LFS setstripe -d $MOUNT || error "setstripe failed"
8480 }
8481 run_test 65j "set default striping on root directory (bug 6367)="
8482
8483 cleanup_65k() {
8484         rm -rf $DIR/$tdir
8485         wait_delete_completed
8486         do_facet $SINGLEMDS "lctl set_param -n \
8487                 osp.$ost*MDT0000.max_create_count=$max_count"
8488         do_facet $SINGLEMDS "lctl set_param -n \
8489                 osp.$ost*MDT0000.create_count=$count"
8490         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8491         echo $INACTIVE_OSC "is Activate"
8492
8493         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8494 }
8495
8496 test_65k() { # bug11679
8497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8498         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8499         remote_mds_nodsh && skip "remote MDS with nodsh"
8500
8501         local disable_precreate=true
8502         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8503                 disable_precreate=false
8504
8505         echo "Check OST status: "
8506         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8507                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8508
8509         for OSC in $MDS_OSCS; do
8510                 echo $OSC "is active"
8511                 do_facet $SINGLEMDS lctl --device %$OSC activate
8512         done
8513
8514         for INACTIVE_OSC in $MDS_OSCS; do
8515                 local ost=$(osc_to_ost $INACTIVE_OSC)
8516                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8517                                lov.*md*.target_obd |
8518                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8519
8520                 mkdir -p $DIR/$tdir
8521                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8522                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8523
8524                 echo "Deactivate: " $INACTIVE_OSC
8525                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8526
8527                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8528                               osp.$ost*MDT0000.create_count")
8529                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8530                                   osp.$ost*MDT0000.max_create_count")
8531                 $disable_precreate &&
8532                         do_facet $SINGLEMDS "lctl set_param -n \
8533                                 osp.$ost*MDT0000.max_create_count=0"
8534
8535                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8536                         [ -f $DIR/$tdir/$idx ] && continue
8537                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8538                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8539                                 { cleanup_65k;
8540                                   error "setstripe $idx should succeed"; }
8541                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8542                 done
8543                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8544                 rmdir $DIR/$tdir
8545
8546                 do_facet $SINGLEMDS "lctl set_param -n \
8547                         osp.$ost*MDT0000.max_create_count=$max_count"
8548                 do_facet $SINGLEMDS "lctl set_param -n \
8549                         osp.$ost*MDT0000.create_count=$count"
8550                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8551                 echo $INACTIVE_OSC "is Activate"
8552
8553                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8554         done
8555 }
8556 run_test 65k "validate manual striping works properly with deactivated OSCs"
8557
8558 test_65l() { # bug 12836
8559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8560
8561         test_mkdir -p $DIR/$tdir/test_dir
8562         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8563         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8564 }
8565 run_test 65l "lfs find on -1 stripe dir ========================"
8566
8567 test_65m() {
8568         local layout=$(save_layout $MOUNT)
8569         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8570                 restore_layout $MOUNT $layout
8571                 error "setstripe should fail by non-root users"
8572         }
8573         true
8574 }
8575 run_test 65m "normal user can't set filesystem default stripe"
8576
8577 test_65n() {
8578         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8579         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8580                 skip "Need MDS version at least 2.12.50"
8581         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8582
8583         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8584         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8585         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8586
8587         local root_layout=$(save_layout $MOUNT)
8588         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8589
8590         # new subdirectory under root directory should not inherit
8591         # the default layout from root
8592         local dir1=$MOUNT/$tdir-1
8593         mkdir $dir1 || error "mkdir $dir1 failed"
8594         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8595                 error "$dir1 shouldn't have LOV EA"
8596
8597         # delete the default layout on root directory
8598         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8599
8600         local dir2=$MOUNT/$tdir-2
8601         mkdir $dir2 || error "mkdir $dir2 failed"
8602         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8603                 error "$dir2 shouldn't have LOV EA"
8604
8605         # set a new striping pattern on root directory
8606         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8607         local new_def_stripe_size=$((def_stripe_size * 2))
8608         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8609                 error "set stripe size on $MOUNT failed"
8610
8611         # new file created in $dir2 should inherit the new stripe size from
8612         # the filesystem default
8613         local file2=$dir2/$tfile-2
8614         touch $file2 || error "touch $file2 failed"
8615
8616         local file2_stripe_size=$($LFS getstripe -S $file2)
8617         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8618         {
8619                 echo "file2_stripe_size: '$file2_stripe_size'"
8620                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8621                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8622         }
8623
8624         local dir3=$MOUNT/$tdir-3
8625         mkdir $dir3 || error "mkdir $dir3 failed"
8626         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8627         # the root layout, which is the actual default layout that will be used
8628         # when new files are created in $dir3.
8629         local dir3_layout=$(get_layout_param $dir3)
8630         local root_dir_layout=$(get_layout_param $MOUNT)
8631         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8632         {
8633                 echo "dir3_layout: '$dir3_layout'"
8634                 echo "root_dir_layout: '$root_dir_layout'"
8635                 error "$dir3 should show the default layout from $MOUNT"
8636         }
8637
8638         # set OST pool on root directory
8639         local pool=$TESTNAME
8640         pool_add $pool || error "add $pool failed"
8641         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8642                 error "add targets to $pool failed"
8643
8644         $LFS setstripe -p $pool $MOUNT ||
8645                 error "set OST pool on $MOUNT failed"
8646
8647         # new file created in $dir3 should inherit the pool from
8648         # the filesystem default
8649         local file3=$dir3/$tfile-3
8650         touch $file3 || error "touch $file3 failed"
8651
8652         local file3_pool=$($LFS getstripe -p $file3)
8653         [[ "$file3_pool" = "$pool" ]] ||
8654                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8655
8656         local dir4=$MOUNT/$tdir-4
8657         mkdir $dir4 || error "mkdir $dir4 failed"
8658         local dir4_layout=$(get_layout_param $dir4)
8659         root_dir_layout=$(get_layout_param $MOUNT)
8660         echo "$LFS getstripe -d $dir4"
8661         $LFS getstripe -d $dir4
8662         echo "$LFS getstripe -d $MOUNT"
8663         $LFS getstripe -d $MOUNT
8664         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8665         {
8666                 echo "dir4_layout: '$dir4_layout'"
8667                 echo "root_dir_layout: '$root_dir_layout'"
8668                 error "$dir4 should show the default layout from $MOUNT"
8669         }
8670
8671         # new file created in $dir4 should inherit the pool from
8672         # the filesystem default
8673         local file4=$dir4/$tfile-4
8674         touch $file4 || error "touch $file4 failed"
8675
8676         local file4_pool=$($LFS getstripe -p $file4)
8677         [[ "$file4_pool" = "$pool" ]] ||
8678                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8679
8680         # new subdirectory under non-root directory should inherit
8681         # the default layout from its parent directory
8682         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8683                 error "set directory layout on $dir4 failed"
8684
8685         local dir5=$dir4/$tdir-5
8686         mkdir $dir5 || error "mkdir $dir5 failed"
8687
8688         dir4_layout=$(get_layout_param $dir4)
8689         local dir5_layout=$(get_layout_param $dir5)
8690         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8691         {
8692                 echo "dir4_layout: '$dir4_layout'"
8693                 echo "dir5_layout: '$dir5_layout'"
8694                 error "$dir5 should inherit the default layout from $dir4"
8695         }
8696
8697         # though subdir under ROOT doesn't inherit default layout, but
8698         # its sub dir/file should be created with default layout.
8699         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8700         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8701                 skip "Need MDS version at least 2.12.59"
8702
8703         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8704         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8705         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8706
8707         if [ $default_lmv_hash == "none" ]; then
8708                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8709         else
8710                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8711                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8712         fi
8713
8714         $LFS setdirstripe -D -c 2 $MOUNT ||
8715                 error "setdirstripe -D -c 2 failed"
8716         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8717         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8718         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8719 }
8720 run_test 65n "don't inherit default layout from root for new subdirectories"
8721
8722 # bug 2543 - update blocks count on client
8723 test_66() {
8724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8725
8726         COUNT=${COUNT:-8}
8727         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8728         sync; sync_all_data; sync; sync_all_data
8729         cancel_lru_locks osc
8730         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8731         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8732 }
8733 run_test 66 "update inode blocks count on client ==============="
8734
8735 meminfo() {
8736         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8737 }
8738
8739 swap_used() {
8740         swapon -s | awk '($1 == "'$1'") { print $4 }'
8741 }
8742
8743 # bug5265, obdfilter oa2dentry return -ENOENT
8744 # #define OBD_FAIL_SRV_ENOENT 0x217
8745 test_69() {
8746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8747         remote_ost_nodsh && skip "remote OST with nodsh"
8748
8749         f="$DIR/$tfile"
8750         $LFS setstripe -c 1 -i 0 $f
8751
8752         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8753
8754         do_facet ost1 lctl set_param fail_loc=0x217
8755         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8756         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8757
8758         do_facet ost1 lctl set_param fail_loc=0
8759         $DIRECTIO write $f 0 2 || error "write error"
8760
8761         cancel_lru_locks osc
8762         $DIRECTIO read $f 0 1 || error "read error"
8763
8764         do_facet ost1 lctl set_param fail_loc=0x217
8765         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8766
8767         do_facet ost1 lctl set_param fail_loc=0
8768         rm -f $f
8769 }
8770 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8771
8772 test_71() {
8773         test_mkdir $DIR/$tdir
8774         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8775         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8776 }
8777 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8778
8779 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8781         [ "$RUNAS_ID" = "$UID" ] &&
8782                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8783         # Check that testing environment is properly set up. Skip if not
8784         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8785                 skip_env "User $RUNAS_ID does not exist - skipping"
8786
8787         touch $DIR/$tfile
8788         chmod 777 $DIR/$tfile
8789         chmod ug+s $DIR/$tfile
8790         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8791                 error "$RUNAS dd $DIR/$tfile failed"
8792         # See if we are still setuid/sgid
8793         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8794                 error "S/gid is not dropped on write"
8795         # Now test that MDS is updated too
8796         cancel_lru_locks mdc
8797         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8798                 error "S/gid is not dropped on MDS"
8799         rm -f $DIR/$tfile
8800 }
8801 run_test 72a "Test that remove suid works properly (bug5695) ===="
8802
8803 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8804         local perm
8805
8806         [ "$RUNAS_ID" = "$UID" ] &&
8807                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8808         [ "$RUNAS_ID" -eq 0 ] &&
8809                 skip_env "RUNAS_ID = 0 -- skipping"
8810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8811         # Check that testing environment is properly set up. Skip if not
8812         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8813                 skip_env "User $RUNAS_ID does not exist - skipping"
8814
8815         touch $DIR/${tfile}-f{g,u}
8816         test_mkdir $DIR/${tfile}-dg
8817         test_mkdir $DIR/${tfile}-du
8818         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8819         chmod g+s $DIR/${tfile}-{f,d}g
8820         chmod u+s $DIR/${tfile}-{f,d}u
8821         for perm in 777 2777 4777; do
8822                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8823                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8824                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8825                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8826         done
8827         true
8828 }
8829 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8830
8831 # bug 3462 - multiple simultaneous MDC requests
8832 test_73() {
8833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8834
8835         test_mkdir $DIR/d73-1
8836         test_mkdir $DIR/d73-2
8837         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8838         pid1=$!
8839
8840         lctl set_param fail_loc=0x80000129
8841         $MULTIOP $DIR/d73-1/f73-2 Oc &
8842         sleep 1
8843         lctl set_param fail_loc=0
8844
8845         $MULTIOP $DIR/d73-2/f73-3 Oc &
8846         pid3=$!
8847
8848         kill -USR1 $pid1
8849         wait $pid1 || return 1
8850
8851         sleep 25
8852
8853         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8854         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8855         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8856
8857         rm -rf $DIR/d73-*
8858 }
8859 run_test 73 "multiple MDC requests (should not deadlock)"
8860
8861 test_74a() { # bug 6149, 6184
8862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8863
8864         touch $DIR/f74a
8865         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8866         #
8867         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8868         # will spin in a tight reconnection loop
8869         $LCTL set_param fail_loc=0x8000030e
8870         # get any lock that won't be difficult - lookup works.
8871         ls $DIR/f74a
8872         $LCTL set_param fail_loc=0
8873         rm -f $DIR/f74a
8874         true
8875 }
8876 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8877
8878 test_74b() { # bug 13310
8879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8880
8881         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8882         #
8883         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8884         # will spin in a tight reconnection loop
8885         $LCTL set_param fail_loc=0x8000030e
8886         # get a "difficult" lock
8887         touch $DIR/f74b
8888         $LCTL set_param fail_loc=0
8889         rm -f $DIR/f74b
8890         true
8891 }
8892 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8893
8894 test_74c() {
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896
8897         #define OBD_FAIL_LDLM_NEW_LOCK
8898         $LCTL set_param fail_loc=0x319
8899         touch $DIR/$tfile && error "touch successful"
8900         $LCTL set_param fail_loc=0
8901         true
8902 }
8903 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8904
8905 slab_lic=/sys/kernel/slab/lustre_inode_cache
8906 num_objects() {
8907         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8908         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8909                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8910 }
8911
8912 test_76a() { # Now for b=20433, added originally in b=1443
8913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8914
8915         cancel_lru_locks osc
8916         # there may be some slab objects cached per core
8917         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8918         local before=$(num_objects)
8919         local count=$((512 * cpus))
8920         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8921         local margin=$((count / 10))
8922         if [[ -f $slab_lic/aliases ]]; then
8923                 local aliases=$(cat $slab_lic/aliases)
8924                 (( aliases > 0 )) && margin=$((margin * aliases))
8925         fi
8926
8927         echo "before slab objects: $before"
8928         for i in $(seq $count); do
8929                 touch $DIR/$tfile
8930                 rm -f $DIR/$tfile
8931         done
8932         cancel_lru_locks osc
8933         local after=$(num_objects)
8934         echo "created: $count, after slab objects: $after"
8935         # shared slab counts are not very accurate, allow significant margin
8936         # the main goal is that the cache growth is not permanently > $count
8937         while (( after > before + margin )); do
8938                 sleep 1
8939                 after=$(num_objects)
8940                 wait=$((wait + 1))
8941                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8942                 if (( wait > 60 )); then
8943                         error "inode slab grew from $before+$margin to $after"
8944                 fi
8945         done
8946 }
8947 run_test 76a "confirm clients recycle inodes properly ===="
8948
8949 test_76b() {
8950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8951         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8952
8953         local count=512
8954         local before=$(num_objects)
8955
8956         for i in $(seq $count); do
8957                 mkdir $DIR/$tdir
8958                 rmdir $DIR/$tdir
8959         done
8960
8961         local after=$(num_objects)
8962         local wait=0
8963
8964         while (( after > before )); do
8965                 sleep 1
8966                 after=$(num_objects)
8967                 wait=$((wait + 1))
8968                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8969                 if (( wait > 60 )); then
8970                         error "inode slab grew from $before to $after"
8971                 fi
8972         done
8973
8974         echo "slab objects before: $before, after: $after"
8975 }
8976 run_test 76b "confirm clients recycle directory inodes properly ===="
8977
8978 export ORIG_CSUM=""
8979 set_checksums()
8980 {
8981         # Note: in sptlrpc modes which enable its own bulk checksum, the
8982         # original crc32_le bulk checksum will be automatically disabled,
8983         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8984         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8985         # In this case set_checksums() will not be no-op, because sptlrpc
8986         # bulk checksum will be enabled all through the test.
8987
8988         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8989         lctl set_param -n osc.*.checksums $1
8990         return 0
8991 }
8992
8993 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8994                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8995 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8996                              tr -d [] | head -n1)}
8997 set_checksum_type()
8998 {
8999         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9000         rc=$?
9001         log "set checksum type to $1, rc = $rc"
9002         return $rc
9003 }
9004
9005 get_osc_checksum_type()
9006 {
9007         # arugment 1: OST name, like OST0000
9008         ost=$1
9009         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9010                         sed 's/.*\[\(.*\)\].*/\1/g')
9011         rc=$?
9012         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9013         echo $checksum_type
9014 }
9015
9016 F77_TMP=$TMP/f77-temp
9017 F77SZ=8
9018 setup_f77() {
9019         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9020                 error "error writing to $F77_TMP"
9021 }
9022
9023 test_77a() { # bug 10889
9024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9025         $GSS && skip_env "could not run with gss"
9026
9027         [ ! -f $F77_TMP ] && setup_f77
9028         set_checksums 1
9029         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9030         set_checksums 0
9031         rm -f $DIR/$tfile
9032 }
9033 run_test 77a "normal checksum read/write operation"
9034
9035 test_77b() { # bug 10889
9036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9037         $GSS && skip_env "could not run with gss"
9038
9039         [ ! -f $F77_TMP ] && setup_f77
9040         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9041         $LCTL set_param fail_loc=0x80000409
9042         set_checksums 1
9043
9044         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9045                 error "dd error: $?"
9046         $LCTL set_param fail_loc=0
9047
9048         for algo in $CKSUM_TYPES; do
9049                 cancel_lru_locks osc
9050                 set_checksum_type $algo
9051                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9052                 $LCTL set_param fail_loc=0x80000408
9053                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9054                 $LCTL set_param fail_loc=0
9055         done
9056         set_checksums 0
9057         set_checksum_type $ORIG_CSUM_TYPE
9058         rm -f $DIR/$tfile
9059 }
9060 run_test 77b "checksum error on client write, read"
9061
9062 cleanup_77c() {
9063         trap 0
9064         set_checksums 0
9065         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9066         $check_ost &&
9067                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9068         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9069         $check_ost && [ -n "$ost_file_prefix" ] &&
9070                 do_facet ost1 rm -f ${ost_file_prefix}\*
9071 }
9072
9073 test_77c() {
9074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9075         $GSS && skip_env "could not run with gss"
9076         remote_ost_nodsh && skip "remote OST with nodsh"
9077
9078         local bad1
9079         local osc_file_prefix
9080         local osc_file
9081         local check_ost=false
9082         local ost_file_prefix
9083         local ost_file
9084         local orig_cksum
9085         local dump_cksum
9086         local fid
9087
9088         # ensure corruption will occur on first OSS/OST
9089         $LFS setstripe -i 0 $DIR/$tfile
9090
9091         [ ! -f $F77_TMP ] && setup_f77
9092         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9093                 error "dd write error: $?"
9094         fid=$($LFS path2fid $DIR/$tfile)
9095
9096         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9097         then
9098                 check_ost=true
9099                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9100                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9101         else
9102                 echo "OSS do not support bulk pages dump upon error"
9103         fi
9104
9105         osc_file_prefix=$($LCTL get_param -n debug_path)
9106         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9107
9108         trap cleanup_77c EXIT
9109
9110         set_checksums 1
9111         # enable bulk pages dump upon error on Client
9112         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9113         # enable bulk pages dump upon error on OSS
9114         $check_ost &&
9115                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9116
9117         # flush Client cache to allow next read to reach OSS
9118         cancel_lru_locks osc
9119
9120         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9121         $LCTL set_param fail_loc=0x80000408
9122         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9123         $LCTL set_param fail_loc=0
9124
9125         rm -f $DIR/$tfile
9126
9127         # check cksum dump on Client
9128         osc_file=$(ls ${osc_file_prefix}*)
9129         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9130         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9131         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9132         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9133         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9134                      cksum)
9135         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9136         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9137                 error "dump content does not match on Client"
9138
9139         $check_ost || skip "No need to check cksum dump on OSS"
9140
9141         # check cksum dump on OSS
9142         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9143         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9144         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9145         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9146         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9147                 error "dump content does not match on OSS"
9148
9149         cleanup_77c
9150 }
9151 run_test 77c "checksum error on client read with debug"
9152
9153 test_77d() { # bug 10889
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155         $GSS && skip_env "could not run with gss"
9156
9157         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9158         $LCTL set_param fail_loc=0x80000409
9159         set_checksums 1
9160         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9161                 error "direct write: rc=$?"
9162         $LCTL set_param fail_loc=0
9163         set_checksums 0
9164
9165         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9166         $LCTL set_param fail_loc=0x80000408
9167         set_checksums 1
9168         cancel_lru_locks osc
9169         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9170                 error "direct read: rc=$?"
9171         $LCTL set_param fail_loc=0
9172         set_checksums 0
9173 }
9174 run_test 77d "checksum error on OST direct write, read"
9175
9176 test_77f() { # bug 10889
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178         $GSS && skip_env "could not run with gss"
9179
9180         set_checksums 1
9181         for algo in $CKSUM_TYPES; do
9182                 cancel_lru_locks osc
9183                 set_checksum_type $algo
9184                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9185                 $LCTL set_param fail_loc=0x409
9186                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9187                         error "direct write succeeded"
9188                 $LCTL set_param fail_loc=0
9189         done
9190         set_checksum_type $ORIG_CSUM_TYPE
9191         set_checksums 0
9192 }
9193 run_test 77f "repeat checksum error on write (expect error)"
9194
9195 test_77g() { # bug 10889
9196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9197         $GSS && skip_env "could not run with gss"
9198         remote_ost_nodsh && skip "remote OST with nodsh"
9199
9200         [ ! -f $F77_TMP ] && setup_f77
9201
9202         local file=$DIR/$tfile
9203         stack_trap "rm -f $file" EXIT
9204
9205         $LFS setstripe -c 1 -i 0 $file
9206         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9207         do_facet ost1 lctl set_param fail_loc=0x8000021a
9208         set_checksums 1
9209         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9210                 error "write error: rc=$?"
9211         do_facet ost1 lctl set_param fail_loc=0
9212         set_checksums 0
9213
9214         cancel_lru_locks osc
9215         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9216         do_facet ost1 lctl set_param fail_loc=0x8000021b
9217         set_checksums 1
9218         cmp $F77_TMP $file || error "file compare failed"
9219         do_facet ost1 lctl set_param fail_loc=0
9220         set_checksums 0
9221 }
9222 run_test 77g "checksum error on OST write, read"
9223
9224 test_77k() { # LU-10906
9225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9226         $GSS && skip_env "could not run with gss"
9227
9228         local cksum_param="osc.$FSNAME*.checksums"
9229         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9230         local checksum
9231         local i
9232
9233         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9234         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9235         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9236
9237         for i in 0 1; do
9238                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9239                         error "failed to set checksum=$i on MGS"
9240                 wait_update $HOSTNAME "$get_checksum" $i
9241                 #remount
9242                 echo "remount client, checksum should be $i"
9243                 remount_client $MOUNT || error "failed to remount client"
9244                 checksum=$(eval $get_checksum)
9245                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9246         done
9247         # remove persistent param to avoid races with checksum mountopt below
9248         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9249                 error "failed to delete checksum on MGS"
9250
9251         for opt in "checksum" "nochecksum"; do
9252                 #remount with mount option
9253                 echo "remount client with option $opt, checksum should be $i"
9254                 umount_client $MOUNT || error "failed to umount client"
9255                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9256                         error "failed to mount client with option '$opt'"
9257                 checksum=$(eval $get_checksum)
9258                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9259                 i=$((i - 1))
9260         done
9261
9262         remount_client $MOUNT || error "failed to remount client"
9263 }
9264 run_test 77k "enable/disable checksum correctly"
9265
9266 test_77l() {
9267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9268         $GSS && skip_env "could not run with gss"
9269
9270         set_checksums 1
9271         stack_trap "set_checksums $ORIG_CSUM" EXIT
9272         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9273
9274         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9275
9276         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9277         for algo in $CKSUM_TYPES; do
9278                 set_checksum_type $algo || error "fail to set checksum type $algo"
9279                 osc_algo=$(get_osc_checksum_type OST0000)
9280                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9281
9282                 # no locks, no reqs to let the connection idle
9283                 cancel_lru_locks osc
9284                 lru_resize_disable osc
9285                 wait_osc_import_state client ost1 IDLE
9286
9287                 # ensure ost1 is connected
9288                 stat $DIR/$tfile >/dev/null || error "can't stat"
9289                 wait_osc_import_state client ost1 FULL
9290
9291                 osc_algo=$(get_osc_checksum_type OST0000)
9292                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9293         done
9294         return 0
9295 }
9296 run_test 77l "preferred checksum type is remembered after reconnected"
9297
9298 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9299 rm -f $F77_TMP
9300 unset F77_TMP
9301
9302 cleanup_test_78() {
9303         trap 0
9304         rm -f $DIR/$tfile
9305 }
9306
9307 test_78() { # bug 10901
9308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9309         remote_ost || skip_env "local OST"
9310
9311         NSEQ=5
9312         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9313         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9314         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9315         echo "MemTotal: $MEMTOTAL"
9316
9317         # reserve 256MB of memory for the kernel and other running processes,
9318         # and then take 1/2 of the remaining memory for the read/write buffers.
9319         if [ $MEMTOTAL -gt 512 ] ;then
9320                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9321         else
9322                 # for those poor memory-starved high-end clusters...
9323                 MEMTOTAL=$((MEMTOTAL / 2))
9324         fi
9325         echo "Mem to use for directio: $MEMTOTAL"
9326
9327         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9328         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9329         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9330         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9331                 head -n1)
9332         echo "Smallest OST: $SMALLESTOST"
9333         [[ $SMALLESTOST -lt 10240 ]] &&
9334                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9335
9336         trap cleanup_test_78 EXIT
9337
9338         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9339                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9340
9341         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9342         echo "File size: $F78SIZE"
9343         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9344         for i in $(seq 1 $NSEQ); do
9345                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9346                 echo directIO rdwr round $i of $NSEQ
9347                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9348         done
9349
9350         cleanup_test_78
9351 }
9352 run_test 78 "handle large O_DIRECT writes correctly ============"
9353
9354 test_79() { # bug 12743
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356
9357         wait_delete_completed
9358
9359         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9360         BKFREE=$(calc_osc_kbytes kbytesfree)
9361         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9362
9363         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9364         DFTOTAL=`echo $STRING | cut -d, -f1`
9365         DFUSED=`echo $STRING  | cut -d, -f2`
9366         DFAVAIL=`echo $STRING | cut -d, -f3`
9367         DFFREE=$(($DFTOTAL - $DFUSED))
9368
9369         ALLOWANCE=$((64 * $OSTCOUNT))
9370
9371         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9372            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9373                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9374         fi
9375         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9376            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9377                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9378         fi
9379         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9380            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9381                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9382         fi
9383 }
9384 run_test 79 "df report consistency check ======================="
9385
9386 test_80() { # bug 10718
9387         remote_ost_nodsh && skip "remote OST with nodsh"
9388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9389
9390         # relax strong synchronous semantics for slow backends like ZFS
9391         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9392                 local soc="obdfilter.*.sync_lock_cancel"
9393                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9394
9395                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9396                 if [ -z "$save" ]; then
9397                         soc="obdfilter.*.sync_on_lock_cancel"
9398                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9399                 fi
9400
9401                 if [ "$save" != "never" ]; then
9402                         local hosts=$(comma_list $(osts_nodes))
9403
9404                         do_nodes $hosts $LCTL set_param $soc=never
9405                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9406                 fi
9407         fi
9408
9409         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9410         sync; sleep 1; sync
9411         local before=$(date +%s)
9412         cancel_lru_locks osc
9413         local after=$(date +%s)
9414         local diff=$((after - before))
9415         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9416
9417         rm -f $DIR/$tfile
9418 }
9419 run_test 80 "Page eviction is equally fast at high offsets too"
9420
9421 test_81a() { # LU-456
9422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9423         remote_ost_nodsh && skip "remote OST with nodsh"
9424
9425         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9426         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9427         do_facet ost1 lctl set_param fail_loc=0x80000228
9428
9429         # write should trigger a retry and success
9430         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9431         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9432         RC=$?
9433         if [ $RC -ne 0 ] ; then
9434                 error "write should success, but failed for $RC"
9435         fi
9436 }
9437 run_test 81a "OST should retry write when get -ENOSPC ==============="
9438
9439 test_81b() { # LU-456
9440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9441         remote_ost_nodsh && skip "remote OST with nodsh"
9442
9443         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9444         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9445         do_facet ost1 lctl set_param fail_loc=0x228
9446
9447         # write should retry several times and return -ENOSPC finally
9448         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9449         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9450         RC=$?
9451         ENOSPC=28
9452         if [ $RC -ne $ENOSPC ] ; then
9453                 error "dd should fail for -ENOSPC, but succeed."
9454         fi
9455 }
9456 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9457
9458 test_99() {
9459         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9460
9461         test_mkdir $DIR/$tdir.cvsroot
9462         chown $RUNAS_ID $DIR/$tdir.cvsroot
9463
9464         cd $TMP
9465         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9466
9467         cd /etc/init.d
9468         # some versions of cvs import exit(1) when asked to import links or
9469         # files they can't read.  ignore those files.
9470         local toignore=$(find . -type l -printf '-I %f\n' -o \
9471                          ! -perm /4 -printf '-I %f\n')
9472         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9473                 $tdir.reposname vtag rtag
9474
9475         cd $DIR
9476         test_mkdir $DIR/$tdir.reposname
9477         chown $RUNAS_ID $DIR/$tdir.reposname
9478         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9479
9480         cd $DIR/$tdir.reposname
9481         $RUNAS touch foo99
9482         $RUNAS cvs add -m 'addmsg' foo99
9483         $RUNAS cvs update
9484         $RUNAS cvs commit -m 'nomsg' foo99
9485         rm -fr $DIR/$tdir.cvsroot
9486 }
9487 run_test 99 "cvs strange file/directory operations"
9488
9489 test_100() {
9490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9491         [[ "$NETTYPE" =~ tcp ]] ||
9492                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9493         remote_ost_nodsh && skip "remote OST with nodsh"
9494         remote_mds_nodsh && skip "remote MDS with nodsh"
9495         remote_servers ||
9496                 skip "useless for local single node setup"
9497
9498         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9499                 [ "$PROT" != "tcp" ] && continue
9500                 RPORT=$(echo $REMOTE | cut -d: -f2)
9501                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9502
9503                 rc=0
9504                 LPORT=`echo $LOCAL | cut -d: -f2`
9505                 if [ $LPORT -ge 1024 ]; then
9506                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9507                         netstat -tna
9508                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9509                 fi
9510         done
9511         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9512 }
9513 run_test 100 "check local port using privileged port ==========="
9514
9515 function get_named_value()
9516 {
9517     local tag
9518
9519     tag=$1
9520     while read ;do
9521         line=$REPLY
9522         case $line in
9523         $tag*)
9524             echo $line | sed "s/^$tag[ ]*//"
9525             break
9526             ;;
9527         esac
9528     done
9529 }
9530
9531 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9532                    awk '/^max_cached_mb/ { print $2 }')
9533
9534 cleanup_101a() {
9535         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9536         trap 0
9537 }
9538
9539 test_101a() {
9540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9541
9542         local s
9543         local discard
9544         local nreads=10000
9545         local cache_limit=32
9546
9547         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9548         trap cleanup_101a EXIT
9549         $LCTL set_param -n llite.*.read_ahead_stats 0
9550         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9551
9552         #
9553         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9554         #
9555         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9556         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9557
9558         discard=0
9559         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9560                 get_named_value 'read but discarded' | cut -d" " -f1); do
9561                         discard=$(($discard + $s))
9562         done
9563         cleanup_101a
9564
9565         $LCTL get_param osc.*-osc*.rpc_stats
9566         $LCTL get_param llite.*.read_ahead_stats
9567
9568         # Discard is generally zero, but sometimes a few random reads line up
9569         # and trigger larger readahead, which is wasted & leads to discards.
9570         if [[ $(($discard)) -gt $nreads ]]; then
9571                 error "too many ($discard) discarded pages"
9572         fi
9573         rm -f $DIR/$tfile || true
9574 }
9575 run_test 101a "check read-ahead for random reads"
9576
9577 setup_test101bc() {
9578         test_mkdir $DIR/$tdir
9579         local ssize=$1
9580         local FILE_LENGTH=$2
9581         STRIPE_OFFSET=0
9582
9583         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9584
9585         local list=$(comma_list $(osts_nodes))
9586         set_osd_param $list '' read_cache_enable 0
9587         set_osd_param $list '' writethrough_cache_enable 0
9588
9589         trap cleanup_test101bc EXIT
9590         # prepare the read-ahead file
9591         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9592
9593         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9594                                 count=$FILE_SIZE_MB 2> /dev/null
9595
9596 }
9597
9598 cleanup_test101bc() {
9599         trap 0
9600         rm -rf $DIR/$tdir
9601         rm -f $DIR/$tfile
9602
9603         local list=$(comma_list $(osts_nodes))
9604         set_osd_param $list '' read_cache_enable 1
9605         set_osd_param $list '' writethrough_cache_enable 1
9606 }
9607
9608 calc_total() {
9609         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9610 }
9611
9612 ra_check_101() {
9613         local READ_SIZE=$1
9614         local STRIPE_SIZE=$2
9615         local FILE_LENGTH=$3
9616         local RA_INC=1048576
9617         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9618         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9619                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9620         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9621                         get_named_value 'read but discarded' |
9622                         cut -d" " -f1 | calc_total)
9623         if [[ $DISCARD -gt $discard_limit ]]; then
9624                 $LCTL get_param llite.*.read_ahead_stats
9625                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9626         else
9627                 echo "Read-ahead success for size ${READ_SIZE}"
9628         fi
9629 }
9630
9631 test_101b() {
9632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9633         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9634
9635         local STRIPE_SIZE=1048576
9636         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9637
9638         if [ $SLOW == "yes" ]; then
9639                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9640         else
9641                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9642         fi
9643
9644         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9645
9646         # prepare the read-ahead file
9647         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9648         cancel_lru_locks osc
9649         for BIDX in 2 4 8 16 32 64 128 256
9650         do
9651                 local BSIZE=$((BIDX*4096))
9652                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9653                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9654                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9655                 $LCTL set_param -n llite.*.read_ahead_stats 0
9656                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9657                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9658                 cancel_lru_locks osc
9659                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9660         done
9661         cleanup_test101bc
9662         true
9663 }
9664 run_test 101b "check stride-io mode read-ahead ================="
9665
9666 test_101c() {
9667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9668
9669         local STRIPE_SIZE=1048576
9670         local FILE_LENGTH=$((STRIPE_SIZE*100))
9671         local nreads=10000
9672         local rsize=65536
9673         local osc_rpc_stats
9674
9675         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9676
9677         cancel_lru_locks osc
9678         $LCTL set_param osc.*.rpc_stats 0
9679         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9680         $LCTL get_param osc.*.rpc_stats
9681         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9682                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9683                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9684                 local size
9685
9686                 if [ $lines -le 20 ]; then
9687                         echo "continue debug"
9688                         continue
9689                 fi
9690                 for size in 1 2 4 8; do
9691                         local rpc=$(echo "$stats" |
9692                                     awk '($1 == "'$size':") {print $2; exit; }')
9693                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9694                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9695                 done
9696                 echo "$osc_rpc_stats check passed!"
9697         done
9698         cleanup_test101bc
9699         true
9700 }
9701 run_test 101c "check stripe_size aligned read-ahead ================="
9702
9703 test_101d() {
9704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9705
9706         local file=$DIR/$tfile
9707         local sz_MB=${FILESIZE_101d:-80}
9708         local ra_MB=${READAHEAD_MB:-40}
9709
9710         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9711         [ $free_MB -lt $sz_MB ] &&
9712                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9713
9714         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9715         $LFS setstripe -c -1 $file || error "setstripe failed"
9716
9717         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9718         echo Cancel LRU locks on lustre client to flush the client cache
9719         cancel_lru_locks osc
9720
9721         echo Disable read-ahead
9722         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9723         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9724         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9725         $LCTL get_param -n llite.*.max_read_ahead_mb
9726
9727         echo "Reading the test file $file with read-ahead disabled"
9728         local sz_KB=$((sz_MB * 1024 / 4))
9729         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9730         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9731         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9732                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9733
9734         echo "Cancel LRU locks on lustre client to flush the client cache"
9735         cancel_lru_locks osc
9736         echo Enable read-ahead with ${ra_MB}MB
9737         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9738
9739         echo "Reading the test file $file with read-ahead enabled"
9740         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9741                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9742
9743         echo "read-ahead disabled time read $raOFF"
9744         echo "read-ahead enabled time read $raON"
9745
9746         rm -f $file
9747         wait_delete_completed
9748
9749         # use awk for this check instead of bash because it handles decimals
9750         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9751                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9752 }
9753 run_test 101d "file read with and without read-ahead enabled"
9754
9755 test_101e() {
9756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9757
9758         local file=$DIR/$tfile
9759         local size_KB=500  #KB
9760         local count=100
9761         local bsize=1024
9762
9763         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9764         local need_KB=$((count * size_KB))
9765         [[ $free_KB -le $need_KB ]] &&
9766                 skip_env "Need free space $need_KB, have $free_KB"
9767
9768         echo "Creating $count ${size_KB}K test files"
9769         for ((i = 0; i < $count; i++)); do
9770                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9771         done
9772
9773         echo "Cancel LRU locks on lustre client to flush the client cache"
9774         cancel_lru_locks $OSC
9775
9776         echo "Reset readahead stats"
9777         $LCTL set_param -n llite.*.read_ahead_stats 0
9778
9779         for ((i = 0; i < $count; i++)); do
9780                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9781         done
9782
9783         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9784                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9785
9786         for ((i = 0; i < $count; i++)); do
9787                 rm -rf $file.$i 2>/dev/null
9788         done
9789
9790         #10000 means 20% reads are missing in readahead
9791         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9792 }
9793 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9794
9795 test_101f() {
9796         which iozone || skip_env "no iozone installed"
9797
9798         local old_debug=$($LCTL get_param debug)
9799         old_debug=${old_debug#*=}
9800         $LCTL set_param debug="reada mmap"
9801
9802         # create a test file
9803         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9804
9805         echo Cancel LRU locks on lustre client to flush the client cache
9806         cancel_lru_locks osc
9807
9808         echo Reset readahead stats
9809         $LCTL set_param -n llite.*.read_ahead_stats 0
9810
9811         echo mmap read the file with small block size
9812         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9813                 > /dev/null 2>&1
9814
9815         echo checking missing pages
9816         $LCTL get_param llite.*.read_ahead_stats
9817         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9818                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9819
9820         $LCTL set_param debug="$old_debug"
9821         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9822         rm -f $DIR/$tfile
9823 }
9824 run_test 101f "check mmap read performance"
9825
9826 test_101g_brw_size_test() {
9827         local mb=$1
9828         local pages=$((mb * 1048576 / PAGE_SIZE))
9829         local file=$DIR/$tfile
9830
9831         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9832                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9833         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9834                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9835                         return 2
9836         done
9837
9838         stack_trap "rm -f $file" EXIT
9839         $LCTL set_param -n osc.*.rpc_stats=0
9840
9841         # 10 RPCs should be enough for the test
9842         local count=10
9843         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9844                 { error "dd write ${mb} MB blocks failed"; return 3; }
9845         cancel_lru_locks osc
9846         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9847                 { error "dd write ${mb} MB blocks failed"; return 4; }
9848
9849         # calculate number of full-sized read and write RPCs
9850         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9851                 sed -n '/pages per rpc/,/^$/p' |
9852                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9853                 END { print reads,writes }'))
9854         # allow one extra full-sized read RPC for async readahead
9855         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9856                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9857         [[ ${rpcs[1]} == $count ]] ||
9858                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9859 }
9860
9861 test_101g() {
9862         remote_ost_nodsh && skip "remote OST with nodsh"
9863
9864         local rpcs
9865         local osts=$(get_facets OST)
9866         local list=$(comma_list $(osts_nodes))
9867         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9868         local brw_size="obdfilter.*.brw_size"
9869
9870         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9871
9872         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9873
9874         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9875                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9876                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9877            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9878                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9879                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9880
9881                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9882                         suffix="M"
9883
9884                 if [[ $orig_mb -lt 16 ]]; then
9885                         save_lustre_params $osts "$brw_size" > $p
9886                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9887                                 error "set 16MB RPC size failed"
9888
9889                         echo "remount client to enable new RPC size"
9890                         remount_client $MOUNT || error "remount_client failed"
9891                 fi
9892
9893                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9894                 # should be able to set brw_size=12, but no rpc_stats for that
9895                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9896         fi
9897
9898         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9899
9900         if [[ $orig_mb -lt 16 ]]; then
9901                 restore_lustre_params < $p
9902                 remount_client $MOUNT || error "remount_client restore failed"
9903         fi
9904
9905         rm -f $p $DIR/$tfile
9906 }
9907 run_test 101g "Big bulk(4/16 MiB) readahead"
9908
9909 test_101h() {
9910         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9911
9912         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9913                 error "dd 70M file failed"
9914         echo Cancel LRU locks on lustre client to flush the client cache
9915         cancel_lru_locks osc
9916
9917         echo "Reset readahead stats"
9918         $LCTL set_param -n llite.*.read_ahead_stats 0
9919
9920         echo "Read 10M of data but cross 64M bundary"
9921         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9922         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9923                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9924         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9925         rm -f $p $DIR/$tfile
9926 }
9927 run_test 101h "Readahead should cover current read window"
9928
9929 test_101i() {
9930         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9931                 error "dd 10M file failed"
9932
9933         local max_per_file_mb=$($LCTL get_param -n \
9934                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9935         cancel_lru_locks osc
9936         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9937         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9938                 error "set max_read_ahead_per_file_mb to 1 failed"
9939
9940         echo "Reset readahead stats"
9941         $LCTL set_param llite.*.read_ahead_stats=0
9942
9943         dd if=$DIR/$tfile of=/dev/null bs=2M
9944
9945         $LCTL get_param llite.*.read_ahead_stats
9946         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9947                      awk '/misses/ { print $2 }')
9948         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9949         rm -f $DIR/$tfile
9950 }
9951 run_test 101i "allow current readahead to exceed reservation"
9952
9953 test_101j() {
9954         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9955                 error "setstripe $DIR/$tfile failed"
9956         local file_size=$((1048576 * 16))
9957         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9958         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9959
9960         echo Disable read-ahead
9961         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9962
9963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9964         for blk in $PAGE_SIZE 1048576 $file_size; do
9965                 cancel_lru_locks osc
9966                 echo "Reset readahead stats"
9967                 $LCTL set_param -n llite.*.read_ahead_stats=0
9968                 local count=$(($file_size / $blk))
9969                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9970                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9971                              get_named_value 'failed to fast read' |
9972                              cut -d" " -f1 | calc_total)
9973                 $LCTL get_param -n llite.*.read_ahead_stats
9974                 [ $miss -eq $count ] || error "expected $count got $miss"
9975         done
9976
9977         rm -f $p $DIR/$tfile
9978 }
9979 run_test 101j "A complete read block should be submitted when no RA"
9980
9981 setup_test102() {
9982         test_mkdir $DIR/$tdir
9983         chown $RUNAS_ID $DIR/$tdir
9984         STRIPE_SIZE=65536
9985         STRIPE_OFFSET=1
9986         STRIPE_COUNT=$OSTCOUNT
9987         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9988
9989         trap cleanup_test102 EXIT
9990         cd $DIR
9991         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9992         cd $DIR/$tdir
9993         for num in 1 2 3 4; do
9994                 for count in $(seq 1 $STRIPE_COUNT); do
9995                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9996                                 local size=`expr $STRIPE_SIZE \* $num`
9997                                 local file=file"$num-$idx-$count"
9998                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9999                         done
10000                 done
10001         done
10002
10003         cd $DIR
10004         $1 tar cf $TMP/f102.tar $tdir --xattrs
10005 }
10006
10007 cleanup_test102() {
10008         trap 0
10009         rm -f $TMP/f102.tar
10010         rm -rf $DIR/d0.sanity/d102
10011 }
10012
10013 test_102a() {
10014         [ "$UID" != 0 ] && skip "must run as root"
10015         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10016                 skip_env "must have user_xattr"
10017
10018         [ -z "$(which setfattr 2>/dev/null)" ] &&
10019                 skip_env "could not find setfattr"
10020
10021         local testfile=$DIR/$tfile
10022
10023         touch $testfile
10024         echo "set/get xattr..."
10025         setfattr -n trusted.name1 -v value1 $testfile ||
10026                 error "setfattr -n trusted.name1=value1 $testfile failed"
10027         getfattr -n trusted.name1 $testfile 2> /dev/null |
10028           grep "trusted.name1=.value1" ||
10029                 error "$testfile missing trusted.name1=value1"
10030
10031         setfattr -n user.author1 -v author1 $testfile ||
10032                 error "setfattr -n user.author1=author1 $testfile failed"
10033         getfattr -n user.author1 $testfile 2> /dev/null |
10034           grep "user.author1=.author1" ||
10035                 error "$testfile missing trusted.author1=author1"
10036
10037         echo "listxattr..."
10038         setfattr -n trusted.name2 -v value2 $testfile ||
10039                 error "$testfile unable to set trusted.name2"
10040         setfattr -n trusted.name3 -v value3 $testfile ||
10041                 error "$testfile unable to set trusted.name3"
10042         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10043             grep "trusted.name" | wc -l) -eq 3 ] ||
10044                 error "$testfile missing 3 trusted.name xattrs"
10045
10046         setfattr -n user.author2 -v author2 $testfile ||
10047                 error "$testfile unable to set user.author2"
10048         setfattr -n user.author3 -v author3 $testfile ||
10049                 error "$testfile unable to set user.author3"
10050         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10051             grep "user.author" | wc -l) -eq 3 ] ||
10052                 error "$testfile missing 3 user.author xattrs"
10053
10054         echo "remove xattr..."
10055         setfattr -x trusted.name1 $testfile ||
10056                 error "$testfile error deleting trusted.name1"
10057         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10058                 error "$testfile did not delete trusted.name1 xattr"
10059
10060         setfattr -x user.author1 $testfile ||
10061                 error "$testfile error deleting user.author1"
10062         echo "set lustre special xattr ..."
10063         $LFS setstripe -c1 $testfile
10064         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10065                 awk -F "=" '/trusted.lov/ { print $2 }' )
10066         setfattr -n "trusted.lov" -v $lovea $testfile ||
10067                 error "$testfile doesn't ignore setting trusted.lov again"
10068         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10069                 error "$testfile allow setting invalid trusted.lov"
10070         rm -f $testfile
10071 }
10072 run_test 102a "user xattr test =================================="
10073
10074 check_102b_layout() {
10075         local layout="$*"
10076         local testfile=$DIR/$tfile
10077
10078         echo "test layout '$layout'"
10079         $LFS setstripe $layout $testfile || error "setstripe failed"
10080         $LFS getstripe -y $testfile
10081
10082         echo "get/set/list trusted.lov xattr ..." # b=10930
10083         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10084         [[ "$value" =~ "trusted.lov" ]] ||
10085                 error "can't get trusted.lov from $testfile"
10086         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10087                 error "getstripe failed"
10088
10089         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10090
10091         value=$(cut -d= -f2 <<<$value)
10092         # LU-13168: truncated xattr should fail if short lov_user_md header
10093         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10094                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10095         for len in $lens; do
10096                 echo "setfattr $len $testfile.2"
10097                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10098                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10099         done
10100         local stripe_size=$($LFS getstripe -S $testfile.2)
10101         local stripe_count=$($LFS getstripe -c $testfile.2)
10102         [[ $stripe_size -eq 65536 ]] ||
10103                 error "stripe size $stripe_size != 65536"
10104         [[ $stripe_count -eq $stripe_count_orig ]] ||
10105                 error "stripe count $stripe_count != $stripe_count_orig"
10106         rm $testfile $testfile.2
10107 }
10108
10109 test_102b() {
10110         [ -z "$(which setfattr 2>/dev/null)" ] &&
10111                 skip_env "could not find setfattr"
10112         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10113
10114         # check plain layout
10115         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10116
10117         # and also check composite layout
10118         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10119
10120 }
10121 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10122
10123 test_102c() {
10124         [ -z "$(which setfattr 2>/dev/null)" ] &&
10125                 skip_env "could not find setfattr"
10126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10127
10128         # b10930: get/set/list lustre.lov xattr
10129         echo "get/set/list lustre.lov xattr ..."
10130         test_mkdir $DIR/$tdir
10131         chown $RUNAS_ID $DIR/$tdir
10132         local testfile=$DIR/$tdir/$tfile
10133         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10134                 error "setstripe failed"
10135         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10136                 error "getstripe failed"
10137         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10138         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10139
10140         local testfile2=${testfile}2
10141         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10142                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10143
10144         $RUNAS $MCREATE $testfile2
10145         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10146         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10147         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10148         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10149         [ $stripe_count -eq $STRIPECOUNT ] ||
10150                 error "stripe count $stripe_count != $STRIPECOUNT"
10151 }
10152 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10153
10154 compare_stripe_info1() {
10155         local stripe_index_all_zero=true
10156
10157         for num in 1 2 3 4; do
10158                 for count in $(seq 1 $STRIPE_COUNT); do
10159                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10160                                 local size=$((STRIPE_SIZE * num))
10161                                 local file=file"$num-$offset-$count"
10162                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10163                                 [[ $stripe_size -ne $size ]] &&
10164                                     error "$file: size $stripe_size != $size"
10165                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10166                                 # allow fewer stripes to be created, ORI-601
10167                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10168                                     error "$file: count $stripe_count != $count"
10169                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10170                                 [[ $stripe_index -ne 0 ]] &&
10171                                         stripe_index_all_zero=false
10172                         done
10173                 done
10174         done
10175         $stripe_index_all_zero &&
10176                 error "all files are being extracted starting from OST index 0"
10177         return 0
10178 }
10179
10180 have_xattrs_include() {
10181         tar --help | grep -q xattrs-include &&
10182                 echo --xattrs-include="lustre.*"
10183 }
10184
10185 test_102d() {
10186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10187         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10188
10189         XINC=$(have_xattrs_include)
10190         setup_test102
10191         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10192         cd $DIR/$tdir/$tdir
10193         compare_stripe_info1
10194 }
10195 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10196
10197 test_102f() {
10198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10199         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10200
10201         XINC=$(have_xattrs_include)
10202         setup_test102
10203         test_mkdir $DIR/$tdir.restore
10204         cd $DIR
10205         tar cf - --xattrs $tdir | tar xf - \
10206                 -C $DIR/$tdir.restore --xattrs $XINC
10207         cd $DIR/$tdir.restore/$tdir
10208         compare_stripe_info1
10209 }
10210 run_test 102f "tar copy files, not keep osts"
10211
10212 grow_xattr() {
10213         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10214                 skip "must have user_xattr"
10215         [ -z "$(which setfattr 2>/dev/null)" ] &&
10216                 skip_env "could not find setfattr"
10217         [ -z "$(which getfattr 2>/dev/null)" ] &&
10218                 skip_env "could not find getfattr"
10219
10220         local xsize=${1:-1024}  # in bytes
10221         local file=$DIR/$tfile
10222         local value="$(generate_string $xsize)"
10223         local xbig=trusted.big
10224         local toobig=$2
10225
10226         touch $file
10227         log "save $xbig on $file"
10228         if [ -z "$toobig" ]
10229         then
10230                 setfattr -n $xbig -v $value $file ||
10231                         error "saving $xbig on $file failed"
10232         else
10233                 setfattr -n $xbig -v $value $file &&
10234                         error "saving $xbig on $file succeeded"
10235                 return 0
10236         fi
10237
10238         local orig=$(get_xattr_value $xbig $file)
10239         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10240
10241         local xsml=trusted.sml
10242         log "save $xsml on $file"
10243         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10244
10245         local new=$(get_xattr_value $xbig $file)
10246         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10247
10248         log "grow $xsml on $file"
10249         setfattr -n $xsml -v "$value" $file ||
10250                 error "growing $xsml on $file failed"
10251
10252         new=$(get_xattr_value $xbig $file)
10253         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10254         log "$xbig still valid after growing $xsml"
10255
10256         rm -f $file
10257 }
10258
10259 test_102h() { # bug 15777
10260         grow_xattr 1024
10261 }
10262 run_test 102h "grow xattr from inside inode to external block"
10263
10264 test_102ha() {
10265         large_xattr_enabled || skip_env "ea_inode feature disabled"
10266
10267         echo "setting xattr of max xattr size: $(max_xattr_size)"
10268         grow_xattr $(max_xattr_size)
10269
10270         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10271         echo "This should fail:"
10272         grow_xattr $(($(max_xattr_size) + 10)) 1
10273 }
10274 run_test 102ha "grow xattr from inside inode to external inode"
10275
10276 test_102i() { # bug 17038
10277         [ -z "$(which getfattr 2>/dev/null)" ] &&
10278                 skip "could not find getfattr"
10279
10280         touch $DIR/$tfile
10281         ln -s $DIR/$tfile $DIR/${tfile}link
10282         getfattr -n trusted.lov $DIR/$tfile ||
10283                 error "lgetxattr on $DIR/$tfile failed"
10284         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10285                 grep -i "no such attr" ||
10286                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10287         rm -f $DIR/$tfile $DIR/${tfile}link
10288 }
10289 run_test 102i "lgetxattr test on symbolic link ============"
10290
10291 test_102j() {
10292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10294
10295         XINC=$(have_xattrs_include)
10296         setup_test102 "$RUNAS"
10297         chown $RUNAS_ID $DIR/$tdir
10298         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10299         cd $DIR/$tdir/$tdir
10300         compare_stripe_info1 "$RUNAS"
10301 }
10302 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10303
10304 test_102k() {
10305         [ -z "$(which setfattr 2>/dev/null)" ] &&
10306                 skip "could not find setfattr"
10307
10308         touch $DIR/$tfile
10309         # b22187 just check that does not crash for regular file.
10310         setfattr -n trusted.lov $DIR/$tfile
10311         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10312         local test_kdir=$DIR/$tdir
10313         test_mkdir $test_kdir
10314         local default_size=$($LFS getstripe -S $test_kdir)
10315         local default_count=$($LFS getstripe -c $test_kdir)
10316         local default_offset=$($LFS getstripe -i $test_kdir)
10317         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10318                 error 'dir setstripe failed'
10319         setfattr -n trusted.lov $test_kdir
10320         local stripe_size=$($LFS getstripe -S $test_kdir)
10321         local stripe_count=$($LFS getstripe -c $test_kdir)
10322         local stripe_offset=$($LFS getstripe -i $test_kdir)
10323         [ $stripe_size -eq $default_size ] ||
10324                 error "stripe size $stripe_size != $default_size"
10325         [ $stripe_count -eq $default_count ] ||
10326                 error "stripe count $stripe_count != $default_count"
10327         [ $stripe_offset -eq $default_offset ] ||
10328                 error "stripe offset $stripe_offset != $default_offset"
10329         rm -rf $DIR/$tfile $test_kdir
10330 }
10331 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10332
10333 test_102l() {
10334         [ -z "$(which getfattr 2>/dev/null)" ] &&
10335                 skip "could not find getfattr"
10336
10337         # LU-532 trusted. xattr is invisible to non-root
10338         local testfile=$DIR/$tfile
10339
10340         touch $testfile
10341
10342         echo "listxattr as user..."
10343         chown $RUNAS_ID $testfile
10344         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10345             grep -q "trusted" &&
10346                 error "$testfile trusted xattrs are user visible"
10347
10348         return 0;
10349 }
10350 run_test 102l "listxattr size test =================================="
10351
10352 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10353         local path=$DIR/$tfile
10354         touch $path
10355
10356         listxattr_size_check $path || error "listattr_size_check $path failed"
10357 }
10358 run_test 102m "Ensure listxattr fails on small bufffer ========"
10359
10360 cleanup_test102
10361
10362 getxattr() { # getxattr path name
10363         # Return the base64 encoding of the value of xattr name on path.
10364         local path=$1
10365         local name=$2
10366
10367         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10368         # file: $path
10369         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10370         #
10371         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10372
10373         getfattr --absolute-names --encoding=base64 --name=$name $path |
10374                 awk -F= -v name=$name '$1 == name {
10375                         print substr($0, index($0, "=") + 1);
10376         }'
10377 }
10378
10379 test_102n() { # LU-4101 mdt: protect internal xattrs
10380         [ -z "$(which setfattr 2>/dev/null)" ] &&
10381                 skip "could not find setfattr"
10382         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10383         then
10384                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10385         fi
10386
10387         local file0=$DIR/$tfile.0
10388         local file1=$DIR/$tfile.1
10389         local xattr0=$TMP/$tfile.0
10390         local xattr1=$TMP/$tfile.1
10391         local namelist="lov lma lmv link fid version som hsm"
10392         local name
10393         local value
10394
10395         rm -rf $file0 $file1 $xattr0 $xattr1
10396         touch $file0 $file1
10397
10398         # Get 'before' xattrs of $file1.
10399         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10400
10401         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10402                 namelist+=" lfsck_namespace"
10403         for name in $namelist; do
10404                 # Try to copy xattr from $file0 to $file1.
10405                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10406
10407                 setfattr --name=trusted.$name --value="$value" $file1 ||
10408                         error "setxattr 'trusted.$name' failed"
10409
10410                 # Try to set a garbage xattr.
10411                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10412
10413                 if [[ x$name == "xlov" ]]; then
10414                         setfattr --name=trusted.lov --value="$value" $file1 &&
10415                         error "setxattr invalid 'trusted.lov' success"
10416                 else
10417                         setfattr --name=trusted.$name --value="$value" $file1 ||
10418                                 error "setxattr invalid 'trusted.$name' failed"
10419                 fi
10420
10421                 # Try to remove the xattr from $file1. We don't care if this
10422                 # appears to succeed or fail, we just don't want there to be
10423                 # any changes or crashes.
10424                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10425         done
10426
10427         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10428         then
10429                 name="lfsck_ns"
10430                 # Try to copy xattr from $file0 to $file1.
10431                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10432
10433                 setfattr --name=trusted.$name --value="$value" $file1 ||
10434                         error "setxattr 'trusted.$name' failed"
10435
10436                 # Try to set a garbage xattr.
10437                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10438
10439                 setfattr --name=trusted.$name --value="$value" $file1 ||
10440                         error "setxattr 'trusted.$name' failed"
10441
10442                 # Try to remove the xattr from $file1. We don't care if this
10443                 # appears to succeed or fail, we just don't want there to be
10444                 # any changes or crashes.
10445                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10446         fi
10447
10448         # Get 'after' xattrs of file1.
10449         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10450
10451         if ! diff $xattr0 $xattr1; then
10452                 error "before and after xattrs of '$file1' differ"
10453         fi
10454
10455         rm -rf $file0 $file1 $xattr0 $xattr1
10456
10457         return 0
10458 }
10459 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10460
10461 test_102p() { # LU-4703 setxattr did not check ownership
10462         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10463                 skip "MDS needs to be at least 2.5.56"
10464
10465         local testfile=$DIR/$tfile
10466
10467         touch $testfile
10468
10469         echo "setfacl as user..."
10470         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10471         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10472
10473         echo "setfattr as user..."
10474         setfacl -m "u:$RUNAS_ID:---" $testfile
10475         $RUNAS setfattr -x system.posix_acl_access $testfile
10476         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10477 }
10478 run_test 102p "check setxattr(2) correctly fails without permission"
10479
10480 test_102q() {
10481         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10482                 skip "MDS needs to be at least 2.6.92"
10483
10484         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10485 }
10486 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10487
10488 test_102r() {
10489         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10490                 skip "MDS needs to be at least 2.6.93"
10491
10492         touch $DIR/$tfile || error "touch"
10493         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10494         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10495         rm $DIR/$tfile || error "rm"
10496
10497         #normal directory
10498         mkdir -p $DIR/$tdir || error "mkdir"
10499         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10500         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10501         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10502                 error "$testfile error deleting user.author1"
10503         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10504                 grep "user.$(basename $tdir)" &&
10505                 error "$tdir did not delete user.$(basename $tdir)"
10506         rmdir $DIR/$tdir || error "rmdir"
10507
10508         #striped directory
10509         test_mkdir $DIR/$tdir
10510         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10511         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10512         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10513                 error "$testfile error deleting user.author1"
10514         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10515                 grep "user.$(basename $tdir)" &&
10516                 error "$tdir did not delete user.$(basename $tdir)"
10517         rmdir $DIR/$tdir || error "rm striped dir"
10518 }
10519 run_test 102r "set EAs with empty values"
10520
10521 test_102s() {
10522         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10523                 skip "MDS needs to be at least 2.11.52"
10524
10525         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10526
10527         save_lustre_params client "llite.*.xattr_cache" > $save
10528
10529         for cache in 0 1; do
10530                 lctl set_param llite.*.xattr_cache=$cache
10531
10532                 rm -f $DIR/$tfile
10533                 touch $DIR/$tfile || error "touch"
10534                 for prefix in lustre security system trusted user; do
10535                         # Note getxattr() may fail with 'Operation not
10536                         # supported' or 'No such attribute' depending
10537                         # on prefix and cache.
10538                         getfattr -n $prefix.n102s $DIR/$tfile &&
10539                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10540                 done
10541         done
10542
10543         restore_lustre_params < $save
10544 }
10545 run_test 102s "getting nonexistent xattrs should fail"
10546
10547 test_102t() {
10548         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10549                 skip "MDS needs to be at least 2.11.52"
10550
10551         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10552
10553         save_lustre_params client "llite.*.xattr_cache" > $save
10554
10555         for cache in 0 1; do
10556                 lctl set_param llite.*.xattr_cache=$cache
10557
10558                 for buf_size in 0 256; do
10559                         rm -f $DIR/$tfile
10560                         touch $DIR/$tfile || error "touch"
10561                         setfattr -n user.multiop $DIR/$tfile
10562                         $MULTIOP $DIR/$tfile oa$buf_size ||
10563                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10564                 done
10565         done
10566
10567         restore_lustre_params < $save
10568 }
10569 run_test 102t "zero length xattr values handled correctly"
10570
10571 run_acl_subtest()
10572 {
10573     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10574     return $?
10575 }
10576
10577 test_103a() {
10578         [ "$UID" != 0 ] && skip "must run as root"
10579         $GSS && skip_env "could not run under gss"
10580         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10581                 skip_env "must have acl enabled"
10582         [ -z "$(which setfacl 2>/dev/null)" ] &&
10583                 skip_env "could not find setfacl"
10584         remote_mds_nodsh && skip "remote MDS with nodsh"
10585
10586         gpasswd -a daemon bin                           # LU-5641
10587         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10588
10589         declare -a identity_old
10590
10591         for num in $(seq $MDSCOUNT); do
10592                 switch_identity $num true || identity_old[$num]=$?
10593         done
10594
10595         SAVE_UMASK=$(umask)
10596         umask 0022
10597         mkdir -p $DIR/$tdir
10598         cd $DIR/$tdir
10599
10600         echo "performing cp ..."
10601         run_acl_subtest cp || error "run_acl_subtest cp failed"
10602         echo "performing getfacl-noacl..."
10603         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10604         echo "performing misc..."
10605         run_acl_subtest misc || error  "misc test failed"
10606         echo "performing permissions..."
10607         run_acl_subtest permissions || error "permissions failed"
10608         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10609         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10610                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10611                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10612         then
10613                 echo "performing permissions xattr..."
10614                 run_acl_subtest permissions_xattr ||
10615                         error "permissions_xattr failed"
10616         fi
10617         echo "performing setfacl..."
10618         run_acl_subtest setfacl || error  "setfacl test failed"
10619
10620         # inheritance test got from HP
10621         echo "performing inheritance..."
10622         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10623         chmod +x make-tree || error "chmod +x failed"
10624         run_acl_subtest inheritance || error "inheritance test failed"
10625         rm -f make-tree
10626
10627         echo "LU-974 ignore umask when acl is enabled..."
10628         run_acl_subtest 974 || error "LU-974 umask test failed"
10629         if [ $MDSCOUNT -ge 2 ]; then
10630                 run_acl_subtest 974_remote ||
10631                         error "LU-974 umask test failed under remote dir"
10632         fi
10633
10634         echo "LU-2561 newly created file is same size as directory..."
10635         if [ "$mds1_FSTYPE" != "zfs" ]; then
10636                 run_acl_subtest 2561 || error "LU-2561 test failed"
10637         else
10638                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10639         fi
10640
10641         run_acl_subtest 4924 || error "LU-4924 test failed"
10642
10643         cd $SAVE_PWD
10644         umask $SAVE_UMASK
10645
10646         for num in $(seq $MDSCOUNT); do
10647                 if [ "${identity_old[$num]}" = 1 ]; then
10648                         switch_identity $num false || identity_old[$num]=$?
10649                 fi
10650         done
10651 }
10652 run_test 103a "acl test"
10653
10654 test_103b() {
10655         declare -a pids
10656         local U
10657
10658         for U in {0..511}; do
10659                 {
10660                 local O=$(printf "%04o" $U)
10661
10662                 umask $(printf "%04o" $((511 ^ $O)))
10663                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10664                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10665
10666                 (( $S == ($O & 0666) )) ||
10667                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10668
10669                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10670                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10671                 (( $S == ($O & 0666) )) ||
10672                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10673
10674                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10675                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10676                 (( $S == ($O & 0666) )) ||
10677                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10678                 rm -f $DIR/$tfile.[smp]$0
10679                 } &
10680                 local pid=$!
10681
10682                 # limit the concurrently running threads to 64. LU-11878
10683                 local idx=$((U % 64))
10684                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10685                 pids[idx]=$pid
10686         done
10687         wait
10688 }
10689 run_test 103b "umask lfs setstripe"
10690
10691 test_103c() {
10692         mkdir -p $DIR/$tdir
10693         cp -rp $DIR/$tdir $DIR/$tdir.bak
10694
10695         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10696                 error "$DIR/$tdir shouldn't contain default ACL"
10697         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10698                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10699         true
10700 }
10701 run_test 103c "'cp -rp' won't set empty acl"
10702
10703 test_103e() {
10704         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10705                 skip "MDS needs to be at least 2.13.59"
10706
10707         mkdir -p $DIR/$tdir
10708         # one default ACL will be created for the file owner
10709         for U in {2..256}; do
10710                 setfacl -m default:user:$U:rwx $DIR/$tdir
10711                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10712                 touch $DIR/$tdir/$tfile.$U ||
10713                         error "failed to create $tfile.$U with $numacl ACLs"
10714         done
10715 }
10716 run_test 103e "inheritance of big amount of default ACLs"
10717
10718 test_104a() {
10719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10720
10721         touch $DIR/$tfile
10722         lfs df || error "lfs df failed"
10723         lfs df -ih || error "lfs df -ih failed"
10724         lfs df -h $DIR || error "lfs df -h $DIR failed"
10725         lfs df -i $DIR || error "lfs df -i $DIR failed"
10726         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10727         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10728
10729         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10730         lctl --device %$OSC deactivate
10731         lfs df || error "lfs df with deactivated OSC failed"
10732         lctl --device %$OSC activate
10733         # wait the osc back to normal
10734         wait_osc_import_ready client ost
10735
10736         lfs df || error "lfs df with reactivated OSC failed"
10737         rm -f $DIR/$tfile
10738 }
10739 run_test 104a "lfs df [-ih] [path] test ========================="
10740
10741 test_104b() {
10742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10743         [ $RUNAS_ID -eq $UID ] &&
10744                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10745
10746         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10747                         grep "Permission denied" | wc -l)))
10748         if [ $denied_cnt -ne 0 ]; then
10749                 error "lfs check servers test failed"
10750         fi
10751 }
10752 run_test 104b "$RUNAS lfs check servers test ===================="
10753
10754 test_105a() {
10755         # doesn't work on 2.4 kernels
10756         touch $DIR/$tfile
10757         if $(flock_is_enabled); then
10758                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10759         else
10760                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10761         fi
10762         rm -f $DIR/$tfile
10763 }
10764 run_test 105a "flock when mounted without -o flock test ========"
10765
10766 test_105b() {
10767         touch $DIR/$tfile
10768         if $(flock_is_enabled); then
10769                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10770         else
10771                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10772         fi
10773         rm -f $DIR/$tfile
10774 }
10775 run_test 105b "fcntl when mounted without -o flock test ========"
10776
10777 test_105c() {
10778         touch $DIR/$tfile
10779         if $(flock_is_enabled); then
10780                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10781         else
10782                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10783         fi
10784         rm -f $DIR/$tfile
10785 }
10786 run_test 105c "lockf when mounted without -o flock test"
10787
10788 test_105d() { # bug 15924
10789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10790
10791         test_mkdir $DIR/$tdir
10792         flock_is_enabled || skip_env "mount w/o flock enabled"
10793         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10794         $LCTL set_param fail_loc=0x80000315
10795         flocks_test 2 $DIR/$tdir
10796 }
10797 run_test 105d "flock race (should not freeze) ========"
10798
10799 test_105e() { # bug 22660 && 22040
10800         flock_is_enabled || skip_env "mount w/o flock enabled"
10801
10802         touch $DIR/$tfile
10803         flocks_test 3 $DIR/$tfile
10804 }
10805 run_test 105e "Two conflicting flocks from same process"
10806
10807 test_106() { #bug 10921
10808         test_mkdir $DIR/$tdir
10809         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10810         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10811 }
10812 run_test 106 "attempt exec of dir followed by chown of that dir"
10813
10814 test_107() {
10815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10816
10817         CDIR=`pwd`
10818         local file=core
10819
10820         cd $DIR
10821         rm -f $file
10822
10823         local save_pattern=$(sysctl -n kernel.core_pattern)
10824         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10825         sysctl -w kernel.core_pattern=$file
10826         sysctl -w kernel.core_uses_pid=0
10827
10828         ulimit -c unlimited
10829         sleep 60 &
10830         SLEEPPID=$!
10831
10832         sleep 1
10833
10834         kill -s 11 $SLEEPPID
10835         wait $SLEEPPID
10836         if [ -e $file ]; then
10837                 size=`stat -c%s $file`
10838                 [ $size -eq 0 ] && error "Fail to create core file $file"
10839         else
10840                 error "Fail to create core file $file"
10841         fi
10842         rm -f $file
10843         sysctl -w kernel.core_pattern=$save_pattern
10844         sysctl -w kernel.core_uses_pid=$save_uses_pid
10845         cd $CDIR
10846 }
10847 run_test 107 "Coredump on SIG"
10848
10849 test_110() {
10850         test_mkdir $DIR/$tdir
10851         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10852         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10853                 error "mkdir with 256 char should fail, but did not"
10854         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10855                 error "create with 255 char failed"
10856         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10857                 error "create with 256 char should fail, but did not"
10858
10859         ls -l $DIR/$tdir
10860         rm -rf $DIR/$tdir
10861 }
10862 run_test 110 "filename length checking"
10863
10864 #
10865 # Purpose: To verify dynamic thread (OSS) creation.
10866 #
10867 test_115() {
10868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10869         remote_ost_nodsh && skip "remote OST with nodsh"
10870
10871         # Lustre does not stop service threads once they are started.
10872         # Reset number of running threads to default.
10873         stopall
10874         setupall
10875
10876         local OSTIO_pre
10877         local save_params="$TMP/sanity-$TESTNAME.parameters"
10878
10879         # Get ll_ost_io count before I/O
10880         OSTIO_pre=$(do_facet ost1 \
10881                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10882         # Exit if lustre is not running (ll_ost_io not running).
10883         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10884
10885         echo "Starting with $OSTIO_pre threads"
10886         local thread_max=$((OSTIO_pre * 2))
10887         local rpc_in_flight=$((thread_max * 2))
10888         # Number of I/O Process proposed to be started.
10889         local nfiles
10890         local facets=$(get_facets OST)
10891
10892         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10893         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10894
10895         # Set in_flight to $rpc_in_flight
10896         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10897                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10898         nfiles=${rpc_in_flight}
10899         # Set ost thread_max to $thread_max
10900         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10901
10902         # 5 Minutes should be sufficient for max number of OSS
10903         # threads(thread_max) to be created.
10904         local timeout=300
10905
10906         # Start I/O.
10907         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10908         test_mkdir $DIR/$tdir
10909         for i in $(seq $nfiles); do
10910                 local file=$DIR/$tdir/${tfile}-$i
10911                 $LFS setstripe -c -1 -i 0 $file
10912                 ($WTL $file $timeout)&
10913         done
10914
10915         # I/O Started - Wait for thread_started to reach thread_max or report
10916         # error if thread_started is more than thread_max.
10917         echo "Waiting for thread_started to reach thread_max"
10918         local thread_started=0
10919         local end_time=$((SECONDS + timeout))
10920
10921         while [ $SECONDS -le $end_time ] ; do
10922                 echo -n "."
10923                 # Get ost i/o thread_started count.
10924                 thread_started=$(do_facet ost1 \
10925                         "$LCTL get_param \
10926                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10927                 # Break out if thread_started is equal/greater than thread_max
10928                 if [[ $thread_started -ge $thread_max ]]; then
10929                         echo ll_ost_io thread_started $thread_started, \
10930                                 equal/greater than thread_max $thread_max
10931                         break
10932                 fi
10933                 sleep 1
10934         done
10935
10936         # Cleanup - We have the numbers, Kill i/o jobs if running.
10937         jobcount=($(jobs -p))
10938         for i in $(seq 0 $((${#jobcount[@]}-1)))
10939         do
10940                 kill -9 ${jobcount[$i]}
10941                 if [ $? -ne 0 ] ; then
10942                         echo Warning: \
10943                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10944                 fi
10945         done
10946
10947         # Cleanup files left by WTL binary.
10948         for i in $(seq $nfiles); do
10949                 local file=$DIR/$tdir/${tfile}-$i
10950                 rm -rf $file
10951                 if [ $? -ne 0 ] ; then
10952                         echo "Warning: Failed to delete file $file"
10953                 fi
10954         done
10955
10956         restore_lustre_params <$save_params
10957         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10958
10959         # Error out if no new thread has started or Thread started is greater
10960         # than thread max.
10961         if [[ $thread_started -le $OSTIO_pre ||
10962                         $thread_started -gt $thread_max ]]; then
10963                 error "ll_ost_io: thread_started $thread_started" \
10964                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10965                       "No new thread started or thread started greater " \
10966                       "than thread_max."
10967         fi
10968 }
10969 run_test 115 "verify dynamic thread creation===================="
10970
10971 free_min_max () {
10972         wait_delete_completed
10973         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10974         echo "OST kbytes available: ${AVAIL[@]}"
10975         MAXV=${AVAIL[0]}
10976         MAXI=0
10977         MINV=${AVAIL[0]}
10978         MINI=0
10979         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10980                 #echo OST $i: ${AVAIL[i]}kb
10981                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10982                         MAXV=${AVAIL[i]}
10983                         MAXI=$i
10984                 fi
10985                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10986                         MINV=${AVAIL[i]}
10987                         MINI=$i
10988                 fi
10989         done
10990         echo "Min free space: OST $MINI: $MINV"
10991         echo "Max free space: OST $MAXI: $MAXV"
10992 }
10993
10994 test_116a() { # was previously test_116()
10995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10997         remote_mds_nodsh && skip "remote MDS with nodsh"
10998
10999         echo -n "Free space priority "
11000         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11001                 head -n1
11002         declare -a AVAIL
11003         free_min_max
11004
11005         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11006         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11007         trap simple_cleanup_common EXIT
11008
11009         # Check if we need to generate uneven OSTs
11010         test_mkdir -p $DIR/$tdir/OST${MINI}
11011         local FILL=$((MINV / 4))
11012         local DIFF=$((MAXV - MINV))
11013         local DIFF2=$((DIFF * 100 / MINV))
11014
11015         local threshold=$(do_facet $SINGLEMDS \
11016                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11017         threshold=${threshold%%%}
11018         echo -n "Check for uneven OSTs: "
11019         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11020
11021         if [[ $DIFF2 -gt $threshold ]]; then
11022                 echo "ok"
11023                 echo "Don't need to fill OST$MINI"
11024         else
11025                 # generate uneven OSTs. Write 2% over the QOS threshold value
11026                 echo "no"
11027                 DIFF=$((threshold - DIFF2 + 2))
11028                 DIFF2=$((MINV * DIFF / 100))
11029                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11030                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11031                         error "setstripe failed"
11032                 DIFF=$((DIFF2 / 2048))
11033                 i=0
11034                 while [ $i -lt $DIFF ]; do
11035                         i=$((i + 1))
11036                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11037                                 bs=2M count=1 2>/dev/null
11038                         echo -n .
11039                 done
11040                 echo .
11041                 sync
11042                 sleep_maxage
11043                 free_min_max
11044         fi
11045
11046         DIFF=$((MAXV - MINV))
11047         DIFF2=$((DIFF * 100 / MINV))
11048         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11049         if [ $DIFF2 -gt $threshold ]; then
11050                 echo "ok"
11051         else
11052                 echo "failed - QOS mode won't be used"
11053                 simple_cleanup_common
11054                 skip "QOS imbalance criteria not met"
11055         fi
11056
11057         MINI1=$MINI
11058         MINV1=$MINV
11059         MAXI1=$MAXI
11060         MAXV1=$MAXV
11061
11062         # now fill using QOS
11063         $LFS setstripe -c 1 $DIR/$tdir
11064         FILL=$((FILL / 200))
11065         if [ $FILL -gt 600 ]; then
11066                 FILL=600
11067         fi
11068         echo "writing $FILL files to QOS-assigned OSTs"
11069         i=0
11070         while [ $i -lt $FILL ]; do
11071                 i=$((i + 1))
11072                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11073                         count=1 2>/dev/null
11074                 echo -n .
11075         done
11076         echo "wrote $i 200k files"
11077         sync
11078         sleep_maxage
11079
11080         echo "Note: free space may not be updated, so measurements might be off"
11081         free_min_max
11082         DIFF2=$((MAXV - MINV))
11083         echo "free space delta: orig $DIFF final $DIFF2"
11084         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11085         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11086         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11087         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11088         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11089         if [[ $DIFF -gt 0 ]]; then
11090                 FILL=$((DIFF2 * 100 / DIFF - 100))
11091                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11092         fi
11093
11094         # Figure out which files were written where
11095         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11096                awk '/'$MINI1': / {print $2; exit}')
11097         echo $UUID
11098         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11099         echo "$MINC files created on smaller OST $MINI1"
11100         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11101                awk '/'$MAXI1': / {print $2; exit}')
11102         echo $UUID
11103         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11104         echo "$MAXC files created on larger OST $MAXI1"
11105         if [[ $MINC -gt 0 ]]; then
11106                 FILL=$((MAXC * 100 / MINC - 100))
11107                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11108         fi
11109         [[ $MAXC -gt $MINC ]] ||
11110                 error_ignore LU-9 "stripe QOS didn't balance free space"
11111         simple_cleanup_common
11112 }
11113 run_test 116a "stripe QOS: free space balance ==================="
11114
11115 test_116b() { # LU-2093
11116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11117         remote_mds_nodsh && skip "remote MDS with nodsh"
11118
11119 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11120         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11121                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11122         [ -z "$old_rr" ] && skip "no QOS"
11123         do_facet $SINGLEMDS lctl set_param \
11124                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11125         mkdir -p $DIR/$tdir
11126         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11127         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11128         do_facet $SINGLEMDS lctl set_param fail_loc=0
11129         rm -rf $DIR/$tdir
11130         do_facet $SINGLEMDS lctl set_param \
11131                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11132 }
11133 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11134
11135 test_117() # bug 10891
11136 {
11137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11138
11139         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11140         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11141         lctl set_param fail_loc=0x21e
11142         > $DIR/$tfile || error "truncate failed"
11143         lctl set_param fail_loc=0
11144         echo "Truncate succeeded."
11145         rm -f $DIR/$tfile
11146 }
11147 run_test 117 "verify osd extend =========="
11148
11149 NO_SLOW_RESENDCOUNT=4
11150 export OLD_RESENDCOUNT=""
11151 set_resend_count () {
11152         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11153         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11154         lctl set_param -n $PROC_RESENDCOUNT $1
11155         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11156 }
11157
11158 # for reduce test_118* time (b=14842)
11159 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11160
11161 # Reset async IO behavior after error case
11162 reset_async() {
11163         FILE=$DIR/reset_async
11164
11165         # Ensure all OSCs are cleared
11166         $LFS setstripe -c -1 $FILE
11167         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11168         sync
11169         rm $FILE
11170 }
11171
11172 test_118a() #bug 11710
11173 {
11174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11175
11176         reset_async
11177
11178         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11179         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11180         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11181
11182         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11183                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11184                 return 1;
11185         fi
11186         rm -f $DIR/$tfile
11187 }
11188 run_test 118a "verify O_SYNC works =========="
11189
11190 test_118b()
11191 {
11192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11193         remote_ost_nodsh && skip "remote OST with nodsh"
11194
11195         reset_async
11196
11197         #define OBD_FAIL_SRV_ENOENT 0x217
11198         set_nodes_failloc "$(osts_nodes)" 0x217
11199         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11200         RC=$?
11201         set_nodes_failloc "$(osts_nodes)" 0
11202         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11203         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11204                     grep -c writeback)
11205
11206         if [[ $RC -eq 0 ]]; then
11207                 error "Must return error due to dropped pages, rc=$RC"
11208                 return 1;
11209         fi
11210
11211         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11212                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11213                 return 1;
11214         fi
11215
11216         echo "Dirty pages not leaked on ENOENT"
11217
11218         # Due to the above error the OSC will issue all RPCs syncronously
11219         # until a subsequent RPC completes successfully without error.
11220         $MULTIOP $DIR/$tfile Ow4096yc
11221         rm -f $DIR/$tfile
11222
11223         return 0
11224 }
11225 run_test 118b "Reclaim dirty pages on fatal error =========="
11226
11227 test_118c()
11228 {
11229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11230
11231         # for 118c, restore the original resend count, LU-1940
11232         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11233                                 set_resend_count $OLD_RESENDCOUNT
11234         remote_ost_nodsh && skip "remote OST with nodsh"
11235
11236         reset_async
11237
11238         #define OBD_FAIL_OST_EROFS               0x216
11239         set_nodes_failloc "$(osts_nodes)" 0x216
11240
11241         # multiop should block due to fsync until pages are written
11242         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11243         MULTIPID=$!
11244         sleep 1
11245
11246         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11247                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11248         fi
11249
11250         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11251                     grep -c writeback)
11252         if [[ $WRITEBACK -eq 0 ]]; then
11253                 error "No page in writeback, writeback=$WRITEBACK"
11254         fi
11255
11256         set_nodes_failloc "$(osts_nodes)" 0
11257         wait $MULTIPID
11258         RC=$?
11259         if [[ $RC -ne 0 ]]; then
11260                 error "Multiop fsync failed, rc=$RC"
11261         fi
11262
11263         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11264         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11265                     grep -c writeback)
11266         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11267                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11268         fi
11269
11270         rm -f $DIR/$tfile
11271         echo "Dirty pages flushed via fsync on EROFS"
11272         return 0
11273 }
11274 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11275
11276 # continue to use small resend count to reduce test_118* time (b=14842)
11277 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11278
11279 test_118d()
11280 {
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282         remote_ost_nodsh && skip "remote OST with nodsh"
11283
11284         reset_async
11285
11286         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11287         set_nodes_failloc "$(osts_nodes)" 0x214
11288         # multiop should block due to fsync until pages are written
11289         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11290         MULTIPID=$!
11291         sleep 1
11292
11293         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11294                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11295         fi
11296
11297         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11298                     grep -c writeback)
11299         if [[ $WRITEBACK -eq 0 ]]; then
11300                 error "No page in writeback, writeback=$WRITEBACK"
11301         fi
11302
11303         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11304         set_nodes_failloc "$(osts_nodes)" 0
11305
11306         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11307         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11308                     grep -c writeback)
11309         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11310                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11311         fi
11312
11313         rm -f $DIR/$tfile
11314         echo "Dirty pages gaurenteed flushed via fsync"
11315         return 0
11316 }
11317 run_test 118d "Fsync validation inject a delay of the bulk =========="
11318
11319 test_118f() {
11320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11321
11322         reset_async
11323
11324         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11325         lctl set_param fail_loc=0x8000040a
11326
11327         # Should simulate EINVAL error which is fatal
11328         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11329         RC=$?
11330         if [[ $RC -eq 0 ]]; then
11331                 error "Must return error due to dropped pages, rc=$RC"
11332         fi
11333
11334         lctl set_param fail_loc=0x0
11335
11336         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11337         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11338         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11339                     grep -c writeback)
11340         if [[ $LOCKED -ne 0 ]]; then
11341                 error "Locked pages remain in cache, locked=$LOCKED"
11342         fi
11343
11344         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11345                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11346         fi
11347
11348         rm -f $DIR/$tfile
11349         echo "No pages locked after fsync"
11350
11351         reset_async
11352         return 0
11353 }
11354 run_test 118f "Simulate unrecoverable OSC side error =========="
11355
11356 test_118g() {
11357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11358
11359         reset_async
11360
11361         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11362         lctl set_param fail_loc=0x406
11363
11364         # simulate local -ENOMEM
11365         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11366         RC=$?
11367
11368         lctl set_param fail_loc=0
11369         if [[ $RC -eq 0 ]]; then
11370                 error "Must return error due to dropped pages, rc=$RC"
11371         fi
11372
11373         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11374         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11375         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11376                         grep -c writeback)
11377         if [[ $LOCKED -ne 0 ]]; then
11378                 error "Locked pages remain in cache, locked=$LOCKED"
11379         fi
11380
11381         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11382                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11383         fi
11384
11385         rm -f $DIR/$tfile
11386         echo "No pages locked after fsync"
11387
11388         reset_async
11389         return 0
11390 }
11391 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11392
11393 test_118h() {
11394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11395         remote_ost_nodsh && skip "remote OST with nodsh"
11396
11397         reset_async
11398
11399         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11400         set_nodes_failloc "$(osts_nodes)" 0x20e
11401         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11402         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11403         RC=$?
11404
11405         set_nodes_failloc "$(osts_nodes)" 0
11406         if [[ $RC -eq 0 ]]; then
11407                 error "Must return error due to dropped pages, rc=$RC"
11408         fi
11409
11410         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11411         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11412         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11413                     grep -c writeback)
11414         if [[ $LOCKED -ne 0 ]]; then
11415                 error "Locked pages remain in cache, locked=$LOCKED"
11416         fi
11417
11418         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11419                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11420         fi
11421
11422         rm -f $DIR/$tfile
11423         echo "No pages locked after fsync"
11424
11425         return 0
11426 }
11427 run_test 118h "Verify timeout in handling recoverables errors  =========="
11428
11429 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11430
11431 test_118i() {
11432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11433         remote_ost_nodsh && skip "remote OST with nodsh"
11434
11435         reset_async
11436
11437         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11438         set_nodes_failloc "$(osts_nodes)" 0x20e
11439
11440         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11441         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11442         PID=$!
11443         sleep 5
11444         set_nodes_failloc "$(osts_nodes)" 0
11445
11446         wait $PID
11447         RC=$?
11448         if [[ $RC -ne 0 ]]; then
11449                 error "got error, but should be not, rc=$RC"
11450         fi
11451
11452         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11453         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11454         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11455         if [[ $LOCKED -ne 0 ]]; then
11456                 error "Locked pages remain in cache, locked=$LOCKED"
11457         fi
11458
11459         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11460                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11461         fi
11462
11463         rm -f $DIR/$tfile
11464         echo "No pages locked after fsync"
11465
11466         return 0
11467 }
11468 run_test 118i "Fix error before timeout in recoverable error  =========="
11469
11470 [ "$SLOW" = "no" ] && set_resend_count 4
11471
11472 test_118j() {
11473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11474         remote_ost_nodsh && skip "remote OST with nodsh"
11475
11476         reset_async
11477
11478         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11479         set_nodes_failloc "$(osts_nodes)" 0x220
11480
11481         # return -EIO from OST
11482         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11483         RC=$?
11484         set_nodes_failloc "$(osts_nodes)" 0x0
11485         if [[ $RC -eq 0 ]]; then
11486                 error "Must return error due to dropped pages, rc=$RC"
11487         fi
11488
11489         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11490         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11491         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11492         if [[ $LOCKED -ne 0 ]]; then
11493                 error "Locked pages remain in cache, locked=$LOCKED"
11494         fi
11495
11496         # in recoverable error on OST we want resend and stay until it finished
11497         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11498                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11499         fi
11500
11501         rm -f $DIR/$tfile
11502         echo "No pages locked after fsync"
11503
11504         return 0
11505 }
11506 run_test 118j "Simulate unrecoverable OST side error =========="
11507
11508 test_118k()
11509 {
11510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11511         remote_ost_nodsh && skip "remote OSTs with nodsh"
11512
11513         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11514         set_nodes_failloc "$(osts_nodes)" 0x20e
11515         test_mkdir $DIR/$tdir
11516
11517         for ((i=0;i<10;i++)); do
11518                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11519                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11520                 SLEEPPID=$!
11521                 sleep 0.500s
11522                 kill $SLEEPPID
11523                 wait $SLEEPPID
11524         done
11525
11526         set_nodes_failloc "$(osts_nodes)" 0
11527         rm -rf $DIR/$tdir
11528 }
11529 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11530
11531 test_118l() # LU-646
11532 {
11533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11534
11535         test_mkdir $DIR/$tdir
11536         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11537         rm -rf $DIR/$tdir
11538 }
11539 run_test 118l "fsync dir"
11540
11541 test_118m() # LU-3066
11542 {
11543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11544
11545         test_mkdir $DIR/$tdir
11546         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11547         rm -rf $DIR/$tdir
11548 }
11549 run_test 118m "fdatasync dir ========="
11550
11551 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11552
11553 test_118n()
11554 {
11555         local begin
11556         local end
11557
11558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11559         remote_ost_nodsh && skip "remote OSTs with nodsh"
11560
11561         # Sleep to avoid a cached response.
11562         #define OBD_STATFS_CACHE_SECONDS 1
11563         sleep 2
11564
11565         # Inject a 10 second delay in the OST_STATFS handler.
11566         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11567         set_nodes_failloc "$(osts_nodes)" 0x242
11568
11569         begin=$SECONDS
11570         stat --file-system $MOUNT > /dev/null
11571         end=$SECONDS
11572
11573         set_nodes_failloc "$(osts_nodes)" 0
11574
11575         if ((end - begin > 20)); then
11576             error "statfs took $((end - begin)) seconds, expected 10"
11577         fi
11578 }
11579 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11580
11581 test_119a() # bug 11737
11582 {
11583         BSIZE=$((512 * 1024))
11584         directio write $DIR/$tfile 0 1 $BSIZE
11585         # We ask to read two blocks, which is more than a file size.
11586         # directio will indicate an error when requested and actual
11587         # sizes aren't equeal (a normal situation in this case) and
11588         # print actual read amount.
11589         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11590         if [ "$NOB" != "$BSIZE" ]; then
11591                 error "read $NOB bytes instead of $BSIZE"
11592         fi
11593         rm -f $DIR/$tfile
11594 }
11595 run_test 119a "Short directIO read must return actual read amount"
11596
11597 test_119b() # bug 11737
11598 {
11599         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11600
11601         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11602         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11603         sync
11604         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11605                 error "direct read failed"
11606         rm -f $DIR/$tfile
11607 }
11608 run_test 119b "Sparse directIO read must return actual read amount"
11609
11610 test_119c() # bug 13099
11611 {
11612         BSIZE=1048576
11613         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11614         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11615         rm -f $DIR/$tfile
11616 }
11617 run_test 119c "Testing for direct read hitting hole"
11618
11619 test_119d() # bug 15950
11620 {
11621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11622
11623         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11624         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11625         BSIZE=1048576
11626         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11627         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11628         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11629         lctl set_param fail_loc=0x40d
11630         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11631         pid_dio=$!
11632         sleep 1
11633         cat $DIR/$tfile > /dev/null &
11634         lctl set_param fail_loc=0
11635         pid_reads=$!
11636         wait $pid_dio
11637         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11638         sleep 2
11639         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11640         error "the read rpcs have not completed in 2s"
11641         rm -f $DIR/$tfile
11642         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11643 }
11644 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11645
11646 test_120a() {
11647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11648         remote_mds_nodsh && skip "remote MDS with nodsh"
11649         test_mkdir -i0 -c1 $DIR/$tdir
11650         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11651                 skip_env "no early lock cancel on server"
11652
11653         lru_resize_disable mdc
11654         lru_resize_disable osc
11655         cancel_lru_locks mdc
11656         # asynchronous object destroy at MDT could cause bl ast to client
11657         cancel_lru_locks osc
11658
11659         stat $DIR/$tdir > /dev/null
11660         can1=$(do_facet mds1 \
11661                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11662                awk '/ldlm_cancel/ {print $2}')
11663         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11664                awk '/ldlm_bl_callback/ {print $2}')
11665         test_mkdir -i0 -c1 $DIR/$tdir/d1
11666         can2=$(do_facet mds1 \
11667                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11668                awk '/ldlm_cancel/ {print $2}')
11669         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11670                awk '/ldlm_bl_callback/ {print $2}')
11671         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11672         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11673         lru_resize_enable mdc
11674         lru_resize_enable osc
11675 }
11676 run_test 120a "Early Lock Cancel: mkdir test"
11677
11678 test_120b() {
11679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11680         remote_mds_nodsh && skip "remote MDS with nodsh"
11681         test_mkdir $DIR/$tdir
11682         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11683                 skip_env "no early lock cancel on server"
11684
11685         lru_resize_disable mdc
11686         lru_resize_disable osc
11687         cancel_lru_locks mdc
11688         stat $DIR/$tdir > /dev/null
11689         can1=$(do_facet $SINGLEMDS \
11690                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11691                awk '/ldlm_cancel/ {print $2}')
11692         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11693                awk '/ldlm_bl_callback/ {print $2}')
11694         touch $DIR/$tdir/f1
11695         can2=$(do_facet $SINGLEMDS \
11696                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11697                awk '/ldlm_cancel/ {print $2}')
11698         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11699                awk '/ldlm_bl_callback/ {print $2}')
11700         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11701         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11702         lru_resize_enable mdc
11703         lru_resize_enable osc
11704 }
11705 run_test 120b "Early Lock Cancel: create test"
11706
11707 test_120c() {
11708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11709         remote_mds_nodsh && skip "remote MDS with nodsh"
11710         test_mkdir -i0 -c1 $DIR/$tdir
11711         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11712                 skip "no early lock cancel on server"
11713
11714         lru_resize_disable mdc
11715         lru_resize_disable osc
11716         test_mkdir -i0 -c1 $DIR/$tdir/d1
11717         test_mkdir -i0 -c1 $DIR/$tdir/d2
11718         touch $DIR/$tdir/d1/f1
11719         cancel_lru_locks mdc
11720         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11721         can1=$(do_facet mds1 \
11722                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11723                awk '/ldlm_cancel/ {print $2}')
11724         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11725                awk '/ldlm_bl_callback/ {print $2}')
11726         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11727         can2=$(do_facet mds1 \
11728                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11729                awk '/ldlm_cancel/ {print $2}')
11730         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11731                awk '/ldlm_bl_callback/ {print $2}')
11732         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11733         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11734         lru_resize_enable mdc
11735         lru_resize_enable osc
11736 }
11737 run_test 120c "Early Lock Cancel: link test"
11738
11739 test_120d() {
11740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11741         remote_mds_nodsh && skip "remote MDS with nodsh"
11742         test_mkdir -i0 -c1 $DIR/$tdir
11743         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11744                 skip_env "no early lock cancel on server"
11745
11746         lru_resize_disable mdc
11747         lru_resize_disable osc
11748         touch $DIR/$tdir
11749         cancel_lru_locks mdc
11750         stat $DIR/$tdir > /dev/null
11751         can1=$(do_facet mds1 \
11752                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11753                awk '/ldlm_cancel/ {print $2}')
11754         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11755                awk '/ldlm_bl_callback/ {print $2}')
11756         chmod a+x $DIR/$tdir
11757         can2=$(do_facet mds1 \
11758                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11759                awk '/ldlm_cancel/ {print $2}')
11760         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11761                awk '/ldlm_bl_callback/ {print $2}')
11762         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11763         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11764         lru_resize_enable mdc
11765         lru_resize_enable osc
11766 }
11767 run_test 120d "Early Lock Cancel: setattr test"
11768
11769 test_120e() {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11772                 skip_env "no early lock cancel on server"
11773         remote_mds_nodsh && skip "remote MDS with nodsh"
11774
11775         local dlmtrace_set=false
11776
11777         test_mkdir -i0 -c1 $DIR/$tdir
11778         lru_resize_disable mdc
11779         lru_resize_disable osc
11780         ! $LCTL get_param debug | grep -q dlmtrace &&
11781                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11782         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11783         cancel_lru_locks mdc
11784         cancel_lru_locks osc
11785         dd if=$DIR/$tdir/f1 of=/dev/null
11786         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11787         # XXX client can not do early lock cancel of OST lock
11788         # during unlink (LU-4206), so cancel osc lock now.
11789         sleep 2
11790         cancel_lru_locks osc
11791         can1=$(do_facet mds1 \
11792                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11793                awk '/ldlm_cancel/ {print $2}')
11794         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11795                awk '/ldlm_bl_callback/ {print $2}')
11796         unlink $DIR/$tdir/f1
11797         sleep 5
11798         can2=$(do_facet mds1 \
11799                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11800                awk '/ldlm_cancel/ {print $2}')
11801         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11802                awk '/ldlm_bl_callback/ {print $2}')
11803         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11804                 $LCTL dk $TMP/cancel.debug.txt
11805         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11806                 $LCTL dk $TMP/blocking.debug.txt
11807         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11808         lru_resize_enable mdc
11809         lru_resize_enable osc
11810 }
11811 run_test 120e "Early Lock Cancel: unlink test"
11812
11813 test_120f() {
11814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11815         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11816                 skip_env "no early lock cancel on server"
11817         remote_mds_nodsh && skip "remote MDS with nodsh"
11818
11819         test_mkdir -i0 -c1 $DIR/$tdir
11820         lru_resize_disable mdc
11821         lru_resize_disable osc
11822         test_mkdir -i0 -c1 $DIR/$tdir/d1
11823         test_mkdir -i0 -c1 $DIR/$tdir/d2
11824         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11825         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11826         cancel_lru_locks mdc
11827         cancel_lru_locks osc
11828         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11829         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11830         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11831         # XXX client can not do early lock cancel of OST lock
11832         # during rename (LU-4206), so cancel osc lock now.
11833         sleep 2
11834         cancel_lru_locks osc
11835         can1=$(do_facet mds1 \
11836                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11837                awk '/ldlm_cancel/ {print $2}')
11838         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11839                awk '/ldlm_bl_callback/ {print $2}')
11840         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11841         sleep 5
11842         can2=$(do_facet mds1 \
11843                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11844                awk '/ldlm_cancel/ {print $2}')
11845         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11846                awk '/ldlm_bl_callback/ {print $2}')
11847         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11848         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11849         lru_resize_enable mdc
11850         lru_resize_enable osc
11851 }
11852 run_test 120f "Early Lock Cancel: rename test"
11853
11854 test_120g() {
11855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11856         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11857                 skip_env "no early lock cancel on server"
11858         remote_mds_nodsh && skip "remote MDS with nodsh"
11859
11860         lru_resize_disable mdc
11861         lru_resize_disable osc
11862         count=10000
11863         echo create $count files
11864         test_mkdir $DIR/$tdir
11865         cancel_lru_locks mdc
11866         cancel_lru_locks osc
11867         t0=$(date +%s)
11868
11869         can0=$(do_facet $SINGLEMDS \
11870                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11871                awk '/ldlm_cancel/ {print $2}')
11872         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11873                awk '/ldlm_bl_callback/ {print $2}')
11874         createmany -o $DIR/$tdir/f $count
11875         sync
11876         can1=$(do_facet $SINGLEMDS \
11877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11878                awk '/ldlm_cancel/ {print $2}')
11879         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11880                awk '/ldlm_bl_callback/ {print $2}')
11881         t1=$(date +%s)
11882         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11883         echo rm $count files
11884         rm -r $DIR/$tdir
11885         sync
11886         can2=$(do_facet $SINGLEMDS \
11887                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11888                awk '/ldlm_cancel/ {print $2}')
11889         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11890                awk '/ldlm_bl_callback/ {print $2}')
11891         t2=$(date +%s)
11892         echo total: $count removes in $((t2-t1))
11893         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11894         sleep 2
11895         # wait for commitment of removal
11896         lru_resize_enable mdc
11897         lru_resize_enable osc
11898 }
11899 run_test 120g "Early Lock Cancel: performance test"
11900
11901 test_121() { #bug #10589
11902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11903
11904         rm -rf $DIR/$tfile
11905         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11906 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11907         lctl set_param fail_loc=0x310
11908         cancel_lru_locks osc > /dev/null
11909         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11910         lctl set_param fail_loc=0
11911         [[ $reads -eq $writes ]] ||
11912                 error "read $reads blocks, must be $writes blocks"
11913 }
11914 run_test 121 "read cancel race ========="
11915
11916 test_123a_base() { # was test 123, statahead(bug 11401)
11917         local lsx="$1"
11918
11919         SLOWOK=0
11920         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11921                 log "testing UP system. Performance may be lower than expected."
11922                 SLOWOK=1
11923         fi
11924
11925         rm -rf $DIR/$tdir
11926         test_mkdir $DIR/$tdir
11927         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11928         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11929         MULT=10
11930         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11931                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11932
11933                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11934                 lctl set_param -n llite.*.statahead_max 0
11935                 lctl get_param llite.*.statahead_max
11936                 cancel_lru_locks mdc
11937                 cancel_lru_locks osc
11938                 stime=$(date +%s)
11939                 time $lsx $DIR/$tdir | wc -l
11940                 etime=$(date +%s)
11941                 delta=$((etime - stime))
11942                 log "$lsx $i files without statahead: $delta sec"
11943                 lctl set_param llite.*.statahead_max=$max
11944
11945                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11946                         grep "statahead wrong:" | awk '{print $3}')
11947                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11948                 cancel_lru_locks mdc
11949                 cancel_lru_locks osc
11950                 stime=$(date +%s)
11951                 time $lsx $DIR/$tdir | wc -l
11952                 etime=$(date +%s)
11953                 delta_sa=$((etime - stime))
11954                 log "$lsx $i files with statahead: $delta_sa sec"
11955                 lctl get_param -n llite.*.statahead_stats
11956                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11957                         grep "statahead wrong:" | awk '{print $3}')
11958
11959                 [[ $swrong -lt $ewrong ]] &&
11960                         log "statahead was stopped, maybe too many locks held!"
11961                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11962
11963                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11964                         max=$(lctl get_param -n llite.*.statahead_max |
11965                                 head -n 1)
11966                         lctl set_param -n llite.*.statahead_max 0
11967                         lctl get_param llite.*.statahead_max
11968                         cancel_lru_locks mdc
11969                         cancel_lru_locks osc
11970                         stime=$(date +%s)
11971                         time $lsx $DIR/$tdir | wc -l
11972                         etime=$(date +%s)
11973                         delta=$((etime - stime))
11974                         log "$lsx $i files again without statahead: $delta sec"
11975                         lctl set_param llite.*.statahead_max=$max
11976                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11977                                 if [  $SLOWOK -eq 0 ]; then
11978                                         error "$lsx $i files is slower with statahead!"
11979                                 else
11980                                         log "$lsx $i files is slower with statahead!"
11981                                 fi
11982                                 break
11983                         fi
11984                 fi
11985
11986                 [ $delta -gt 20 ] && break
11987                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11988                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11989         done
11990         log "$lsx done"
11991
11992         stime=$(date +%s)
11993         rm -r $DIR/$tdir
11994         sync
11995         etime=$(date +%s)
11996         delta=$((etime - stime))
11997         log "rm -r $DIR/$tdir/: $delta seconds"
11998         log "rm done"
11999         lctl get_param -n llite.*.statahead_stats
12000 }
12001
12002 test_123aa() {
12003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12004
12005         test_123a_base "ls -l"
12006 }
12007 run_test 123aa "verify statahead work"
12008
12009 test_123ab() {
12010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12011
12012         statx_supported || skip_env "Test must be statx() syscall supported"
12013
12014         test_123a_base "$STATX -l"
12015 }
12016 run_test 123ab "verify statahead work by using statx"
12017
12018 test_123ac() {
12019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12020
12021         statx_supported || skip_env "Test must be statx() syscall supported"
12022
12023         local rpcs_before
12024         local rpcs_after
12025         local agl_before
12026         local agl_after
12027
12028         cancel_lru_locks $OSC
12029         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12030         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12031                 awk '/agl.total:/ {print $3}')
12032         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12033         test_123a_base "$STATX --cached=always -D"
12034         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12035                 awk '/agl.total:/ {print $3}')
12036         [ $agl_before -eq $agl_after ] ||
12037                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12038         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12039         [ $rpcs_after -eq $rpcs_before ] ||
12040                 error "$STATX should not send glimpse RPCs to $OSC"
12041 }
12042 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12043
12044 test_123b () { # statahead(bug 15027)
12045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12046
12047         test_mkdir $DIR/$tdir
12048         createmany -o $DIR/$tdir/$tfile-%d 1000
12049
12050         cancel_lru_locks mdc
12051         cancel_lru_locks osc
12052
12053 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12054         lctl set_param fail_loc=0x80000803
12055         ls -lR $DIR/$tdir > /dev/null
12056         log "ls done"
12057         lctl set_param fail_loc=0x0
12058         lctl get_param -n llite.*.statahead_stats
12059         rm -r $DIR/$tdir
12060         sync
12061
12062 }
12063 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12064
12065 test_123c() {
12066         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12067
12068         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12069         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12070         touch $DIR/$tdir.1/{1..3}
12071         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12072
12073         remount_client $MOUNT
12074
12075         $MULTIOP $DIR/$tdir.0 Q
12076
12077         # let statahead to complete
12078         ls -l $DIR/$tdir.0 > /dev/null
12079
12080         testid=$(echo $TESTNAME | tr '_' ' ')
12081         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12082                 error "statahead warning" || true
12083 }
12084 run_test 123c "Can not initialize inode warning on DNE statahead"
12085
12086 test_124a() {
12087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12088         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12089                 skip_env "no lru resize on server"
12090
12091         local NR=2000
12092
12093         test_mkdir $DIR/$tdir
12094
12095         log "create $NR files at $DIR/$tdir"
12096         createmany -o $DIR/$tdir/f $NR ||
12097                 error "failed to create $NR files in $DIR/$tdir"
12098
12099         cancel_lru_locks mdc
12100         ls -l $DIR/$tdir > /dev/null
12101
12102         local NSDIR=""
12103         local LRU_SIZE=0
12104         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12105                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12106                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12107                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12108                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12109                         log "NSDIR=$NSDIR"
12110                         log "NS=$(basename $NSDIR)"
12111                         break
12112                 fi
12113         done
12114
12115         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12116                 skip "Not enough cached locks created!"
12117         fi
12118         log "LRU=$LRU_SIZE"
12119
12120         local SLEEP=30
12121
12122         # We know that lru resize allows one client to hold $LIMIT locks
12123         # for 10h. After that locks begin to be killed by client.
12124         local MAX_HRS=10
12125         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12126         log "LIMIT=$LIMIT"
12127         if [ $LIMIT -lt $LRU_SIZE ]; then
12128                 skip "Limit is too small $LIMIT"
12129         fi
12130
12131         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12132         # killing locks. Some time was spent for creating locks. This means
12133         # that up to the moment of sleep finish we must have killed some of
12134         # them (10-100 locks). This depends on how fast ther were created.
12135         # Many of them were touched in almost the same moment and thus will
12136         # be killed in groups.
12137         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12138
12139         # Use $LRU_SIZE_B here to take into account real number of locks
12140         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12141         local LRU_SIZE_B=$LRU_SIZE
12142         log "LVF=$LVF"
12143         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12144         log "OLD_LVF=$OLD_LVF"
12145         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12146
12147         # Let's make sure that we really have some margin. Client checks
12148         # cached locks every 10 sec.
12149         SLEEP=$((SLEEP+20))
12150         log "Sleep ${SLEEP} sec"
12151         local SEC=0
12152         while ((SEC<$SLEEP)); do
12153                 echo -n "..."
12154                 sleep 5
12155                 SEC=$((SEC+5))
12156                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12157                 echo -n "$LRU_SIZE"
12158         done
12159         echo ""
12160         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12161         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12162
12163         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12164                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12165                 unlinkmany $DIR/$tdir/f $NR
12166                 return
12167         }
12168
12169         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12170         log "unlink $NR files at $DIR/$tdir"
12171         unlinkmany $DIR/$tdir/f $NR
12172 }
12173 run_test 124a "lru resize ======================================="
12174
12175 get_max_pool_limit()
12176 {
12177         local limit=$($LCTL get_param \
12178                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12179         local max=0
12180         for l in $limit; do
12181                 if [[ $l -gt $max ]]; then
12182                         max=$l
12183                 fi
12184         done
12185         echo $max
12186 }
12187
12188 test_124b() {
12189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12190         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12191                 skip_env "no lru resize on server"
12192
12193         LIMIT=$(get_max_pool_limit)
12194
12195         NR=$(($(default_lru_size)*20))
12196         if [[ $NR -gt $LIMIT ]]; then
12197                 log "Limit lock number by $LIMIT locks"
12198                 NR=$LIMIT
12199         fi
12200
12201         IFree=$(mdsrate_inodes_available)
12202         if [ $IFree -lt $NR ]; then
12203                 log "Limit lock number by $IFree inodes"
12204                 NR=$IFree
12205         fi
12206
12207         lru_resize_disable mdc
12208         test_mkdir -p $DIR/$tdir/disable_lru_resize
12209
12210         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12211         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12212         cancel_lru_locks mdc
12213         stime=`date +%s`
12214         PID=""
12215         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12216         PID="$PID $!"
12217         sleep 2
12218         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12219         PID="$PID $!"
12220         sleep 2
12221         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12222         PID="$PID $!"
12223         wait $PID
12224         etime=`date +%s`
12225         nolruresize_delta=$((etime-stime))
12226         log "ls -la time: $nolruresize_delta seconds"
12227         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12228         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12229
12230         lru_resize_enable mdc
12231         test_mkdir -p $DIR/$tdir/enable_lru_resize
12232
12233         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12234         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12235         cancel_lru_locks mdc
12236         stime=`date +%s`
12237         PID=""
12238         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12239         PID="$PID $!"
12240         sleep 2
12241         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12242         PID="$PID $!"
12243         sleep 2
12244         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12245         PID="$PID $!"
12246         wait $PID
12247         etime=`date +%s`
12248         lruresize_delta=$((etime-stime))
12249         log "ls -la time: $lruresize_delta seconds"
12250         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12251
12252         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12253                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12254         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12255                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12256         else
12257                 log "lru resize performs the same with no lru resize"
12258         fi
12259         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12260 }
12261 run_test 124b "lru resize (performance test) ======================="
12262
12263 test_124c() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12266                 skip_env "no lru resize on server"
12267
12268         # cache ununsed locks on client
12269         local nr=100
12270         cancel_lru_locks mdc
12271         test_mkdir $DIR/$tdir
12272         createmany -o $DIR/$tdir/f $nr ||
12273                 error "failed to create $nr files in $DIR/$tdir"
12274         ls -l $DIR/$tdir > /dev/null
12275
12276         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12277         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12278         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12279         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12280         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12281
12282         # set lru_max_age to 1 sec
12283         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12284         echo "sleep $((recalc_p * 2)) seconds..."
12285         sleep $((recalc_p * 2))
12286
12287         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12288         # restore lru_max_age
12289         $LCTL set_param -n $nsdir.lru_max_age $max_age
12290         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12291         unlinkmany $DIR/$tdir/f $nr
12292 }
12293 run_test 124c "LRUR cancel very aged locks"
12294
12295 test_124d() {
12296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12297         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12298                 skip_env "no lru resize on server"
12299
12300         # cache ununsed locks on client
12301         local nr=100
12302
12303         lru_resize_disable mdc
12304         stack_trap "lru_resize_enable mdc" EXIT
12305
12306         cancel_lru_locks mdc
12307
12308         # asynchronous object destroy at MDT could cause bl ast to client
12309         test_mkdir $DIR/$tdir
12310         createmany -o $DIR/$tdir/f $nr ||
12311                 error "failed to create $nr files in $DIR/$tdir"
12312         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12313
12314         ls -l $DIR/$tdir > /dev/null
12315
12316         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12317         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12318         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12319         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12320
12321         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12322
12323         # set lru_max_age to 1 sec
12324         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12325         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12326
12327         echo "sleep $((recalc_p * 2)) seconds..."
12328         sleep $((recalc_p * 2))
12329
12330         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12331
12332         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12333 }
12334 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12335
12336 test_125() { # 13358
12337         $LCTL get_param -n llite.*.client_type | grep -q local ||
12338                 skip "must run as local client"
12339         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12340                 skip_env "must have acl enabled"
12341         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12342
12343         test_mkdir $DIR/$tdir
12344         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12345         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12346         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12347 }
12348 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12349
12350 test_126() { # bug 12829/13455
12351         $GSS && skip_env "must run as gss disabled"
12352         $LCTL get_param -n llite.*.client_type | grep -q local ||
12353                 skip "must run as local client"
12354         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12355
12356         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12357         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12358         rm -f $DIR/$tfile
12359         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12360 }
12361 run_test 126 "check that the fsgid provided by the client is taken into account"
12362
12363 test_127a() { # bug 15521
12364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12365         local name count samp unit min max sum sumsq
12366
12367         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12368         echo "stats before reset"
12369         $LCTL get_param osc.*.stats
12370         $LCTL set_param osc.*.stats=0
12371         local fsize=$((2048 * 1024))
12372
12373         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12374         cancel_lru_locks osc
12375         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12376
12377         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12378         stack_trap "rm -f $TMP/$tfile.tmp"
12379         while read name count samp unit min max sum sumsq; do
12380                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12381                 [ ! $min ] && error "Missing min value for $name proc entry"
12382                 eval $name=$count || error "Wrong proc format"
12383
12384                 case $name in
12385                 read_bytes|write_bytes)
12386                         [[ "$unit" =~ "bytes" ]] ||
12387                                 error "unit is not 'bytes': $unit"
12388                         (( $min >= 4096 )) || error "min is too small: $min"
12389                         (( $min <= $fsize )) || error "min is too big: $min"
12390                         (( $max >= 4096 )) || error "max is too small: $max"
12391                         (( $max <= $fsize )) || error "max is too big: $max"
12392                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12393                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12394                                 error "sumsquare is too small: $sumsq"
12395                         (( $sumsq <= $fsize * $fsize )) ||
12396                                 error "sumsquare is too big: $sumsq"
12397                         ;;
12398                 ost_read|ost_write)
12399                         [[ "$unit" =~ "usec" ]] ||
12400                                 error "unit is not 'usec': $unit"
12401                         ;;
12402                 *)      ;;
12403                 esac
12404         done < $DIR/$tfile.tmp
12405
12406         #check that we actually got some stats
12407         [ "$read_bytes" ] || error "Missing read_bytes stats"
12408         [ "$write_bytes" ] || error "Missing write_bytes stats"
12409         [ "$read_bytes" != 0 ] || error "no read done"
12410         [ "$write_bytes" != 0 ] || error "no write done"
12411 }
12412 run_test 127a "verify the client stats are sane"
12413
12414 test_127b() { # bug LU-333
12415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12416         local name count samp unit min max sum sumsq
12417
12418         echo "stats before reset"
12419         $LCTL get_param llite.*.stats
12420         $LCTL set_param llite.*.stats=0
12421
12422         # perform 2 reads and writes so MAX is different from SUM.
12423         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12424         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12425         cancel_lru_locks osc
12426         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12427         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12428
12429         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12430         stack_trap "rm -f $TMP/$tfile.tmp"
12431         while read name count samp unit min max sum sumsq; do
12432                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12433                 eval $name=$count || error "Wrong proc format"
12434
12435                 case $name in
12436                 read_bytes|write_bytes)
12437                         [[ "$unit" =~ "bytes" ]] ||
12438                                 error "unit is not 'bytes': $unit"
12439                         (( $count == 2 )) || error "count is not 2: $count"
12440                         (( $min == $PAGE_SIZE )) ||
12441                                 error "min is not $PAGE_SIZE: $min"
12442                         (( $max == $PAGE_SIZE )) ||
12443                                 error "max is not $PAGE_SIZE: $max"
12444                         (( $sum == $PAGE_SIZE * 2 )) ||
12445                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12446                         ;;
12447                 read|write)
12448                         [[ "$unit" =~ "usec" ]] ||
12449                                 error "unit is not 'usec': $unit"
12450                         ;;
12451                 *)      ;;
12452                 esac
12453         done < $TMP/$tfile.tmp
12454
12455         #check that we actually got some stats
12456         [ "$read_bytes" ] || error "Missing read_bytes stats"
12457         [ "$write_bytes" ] || error "Missing write_bytes stats"
12458         [ "$read_bytes" != 0 ] || error "no read done"
12459         [ "$write_bytes" != 0 ] || error "no write done"
12460 }
12461 run_test 127b "verify the llite client stats are sane"
12462
12463 test_127c() { # LU-12394
12464         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12465         local size
12466         local bsize
12467         local reads
12468         local writes
12469         local count
12470
12471         $LCTL set_param llite.*.extents_stats=1
12472         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12473
12474         # Use two stripes so there is enough space in default config
12475         $LFS setstripe -c 2 $DIR/$tfile
12476
12477         # Extent stats start at 0-4K and go in power of two buckets
12478         # LL_HIST_START = 12 --> 2^12 = 4K
12479         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12480         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12481         # small configs
12482         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12483                 do
12484                 # Write and read, 2x each, second time at a non-zero offset
12485                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12486                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12487                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12488                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12489                 rm -f $DIR/$tfile
12490         done
12491
12492         $LCTL get_param llite.*.extents_stats
12493
12494         count=2
12495         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12496                 do
12497                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12498                                 grep -m 1 $bsize)
12499                 reads=$(echo $bucket | awk '{print $5}')
12500                 writes=$(echo $bucket | awk '{print $9}')
12501                 [ "$reads" -eq $count ] ||
12502                         error "$reads reads in < $bsize bucket, expect $count"
12503                 [ "$writes" -eq $count ] ||
12504                         error "$writes writes in < $bsize bucket, expect $count"
12505         done
12506
12507         # Test mmap write and read
12508         $LCTL set_param llite.*.extents_stats=c
12509         size=512
12510         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12511         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12512         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12513
12514         $LCTL get_param llite.*.extents_stats
12515
12516         count=$(((size*1024) / PAGE_SIZE))
12517
12518         bsize=$((2 * PAGE_SIZE / 1024))K
12519
12520         bucket=$($LCTL get_param -n llite.*.extents_stats |
12521                         grep -m 1 $bsize)
12522         reads=$(echo $bucket | awk '{print $5}')
12523         writes=$(echo $bucket | awk '{print $9}')
12524         # mmap writes fault in the page first, creating an additonal read
12525         [ "$reads" -eq $((2 * count)) ] ||
12526                 error "$reads reads in < $bsize bucket, expect $count"
12527         [ "$writes" -eq $count ] ||
12528                 error "$writes writes in < $bsize bucket, expect $count"
12529 }
12530 run_test 127c "test llite extent stats with regular & mmap i/o"
12531
12532 test_128() { # bug 15212
12533         touch $DIR/$tfile
12534         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12535                 find $DIR/$tfile
12536                 find $DIR/$tfile
12537         EOF
12538
12539         result=$(grep error $TMP/$tfile.log)
12540         rm -f $DIR/$tfile $TMP/$tfile.log
12541         [ -z "$result" ] ||
12542                 error "consecutive find's under interactive lfs failed"
12543 }
12544 run_test 128 "interactive lfs for 2 consecutive find's"
12545
12546 set_dir_limits () {
12547         local mntdev
12548         local canondev
12549         local node
12550
12551         local ldproc=/proc/fs/ldiskfs
12552         local facets=$(get_facets MDS)
12553
12554         for facet in ${facets//,/ }; do
12555                 canondev=$(ldiskfs_canon \
12556                            *.$(convert_facet2label $facet).mntdev $facet)
12557                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12558                         ldproc=/sys/fs/ldiskfs
12559                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12560                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12561         done
12562 }
12563
12564 check_mds_dmesg() {
12565         local facets=$(get_facets MDS)
12566         for facet in ${facets//,/ }; do
12567                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12568         done
12569         return 1
12570 }
12571
12572 test_129() {
12573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12574         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12575                 skip "Need MDS version with at least 2.5.56"
12576         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12577                 skip_env "ldiskfs only test"
12578         fi
12579         remote_mds_nodsh && skip "remote MDS with nodsh"
12580
12581         local ENOSPC=28
12582         local has_warning=false
12583
12584         rm -rf $DIR/$tdir
12585         mkdir -p $DIR/$tdir
12586
12587         # block size of mds1
12588         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12589         set_dir_limits $maxsize $((maxsize * 6 / 8))
12590         stack_trap "set_dir_limits 0 0"
12591         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12592         local dirsize=$(stat -c%s "$DIR/$tdir")
12593         local nfiles=0
12594         while (( $dirsize <= $maxsize )); do
12595                 $MCREATE $DIR/$tdir/file_base_$nfiles
12596                 rc=$?
12597                 # check two errors:
12598                 # ENOSPC for ext4 max_dir_size, which has been used since
12599                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12600                 if (( rc == ENOSPC )); then
12601                         set_dir_limits 0 0
12602                         echo "rc=$rc returned as expected after $nfiles files"
12603
12604                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12605                                 error "create failed w/o dir size limit"
12606
12607                         # messages may be rate limited if test is run repeatedly
12608                         check_mds_dmesg '"is approaching max"' ||
12609                                 echo "warning message should be output"
12610                         check_mds_dmesg '"has reached max"' ||
12611                                 echo "reached message should be output"
12612
12613                         dirsize=$(stat -c%s "$DIR/$tdir")
12614
12615                         [[ $dirsize -ge $maxsize ]] && return 0
12616                         error "dirsize $dirsize < $maxsize after $nfiles files"
12617                 elif (( rc != 0 )); then
12618                         break
12619                 fi
12620                 nfiles=$((nfiles + 1))
12621                 dirsize=$(stat -c%s "$DIR/$tdir")
12622         done
12623
12624         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12625 }
12626 run_test 129 "test directory size limit ========================"
12627
12628 OLDIFS="$IFS"
12629 cleanup_130() {
12630         trap 0
12631         IFS="$OLDIFS"
12632 }
12633
12634 test_130a() {
12635         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12636         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12637
12638         trap cleanup_130 EXIT RETURN
12639
12640         local fm_file=$DIR/$tfile
12641         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12642         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12643                 error "dd failed for $fm_file"
12644
12645         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12646         filefrag -ves $fm_file
12647         RC=$?
12648         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12649                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12650         [ $RC != 0 ] && error "filefrag $fm_file failed"
12651
12652         filefrag_op=$(filefrag -ve -k $fm_file |
12653                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12654         lun=$($LFS getstripe -i $fm_file)
12655
12656         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12657         IFS=$'\n'
12658         tot_len=0
12659         for line in $filefrag_op
12660         do
12661                 frag_lun=`echo $line | cut -d: -f5`
12662                 ext_len=`echo $line | cut -d: -f4`
12663                 if (( $frag_lun != $lun )); then
12664                         cleanup_130
12665                         error "FIEMAP on 1-stripe file($fm_file) failed"
12666                         return
12667                 fi
12668                 (( tot_len += ext_len ))
12669         done
12670
12671         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12672                 cleanup_130
12673                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12674                 return
12675         fi
12676
12677         cleanup_130
12678
12679         echo "FIEMAP on single striped file succeeded"
12680 }
12681 run_test 130a "FIEMAP (1-stripe file)"
12682
12683 test_130b() {
12684         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12685
12686         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12687         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12688
12689         trap cleanup_130 EXIT RETURN
12690
12691         local fm_file=$DIR/$tfile
12692         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12693                         error "setstripe on $fm_file"
12694         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12695                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12696
12697         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12698                 error "dd failed on $fm_file"
12699
12700         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12701         filefrag_op=$(filefrag -ve -k $fm_file |
12702                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12703
12704         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12705                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12706
12707         IFS=$'\n'
12708         tot_len=0
12709         num_luns=1
12710         for line in $filefrag_op
12711         do
12712                 frag_lun=$(echo $line | cut -d: -f5 |
12713                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12714                 ext_len=$(echo $line | cut -d: -f4)
12715                 if (( $frag_lun != $last_lun )); then
12716                         if (( tot_len != 1024 )); then
12717                                 cleanup_130
12718                                 error "FIEMAP on $fm_file failed; returned " \
12719                                 "len $tot_len for OST $last_lun instead of 1024"
12720                                 return
12721                         else
12722                                 (( num_luns += 1 ))
12723                                 tot_len=0
12724                         fi
12725                 fi
12726                 (( tot_len += ext_len ))
12727                 last_lun=$frag_lun
12728         done
12729         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12730                 cleanup_130
12731                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12732                         "luns or wrong len for OST $last_lun"
12733                 return
12734         fi
12735
12736         cleanup_130
12737
12738         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12739 }
12740 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12741
12742 test_130c() {
12743         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12744
12745         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12746         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12747
12748         trap cleanup_130 EXIT RETURN
12749
12750         local fm_file=$DIR/$tfile
12751         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12752         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12753                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12754
12755         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12756                         error "dd failed on $fm_file"
12757
12758         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12759         filefrag_op=$(filefrag -ve -k $fm_file |
12760                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12761
12762         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12763                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12764
12765         IFS=$'\n'
12766         tot_len=0
12767         num_luns=1
12768         for line in $filefrag_op
12769         do
12770                 frag_lun=$(echo $line | cut -d: -f5 |
12771                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12772                 ext_len=$(echo $line | cut -d: -f4)
12773                 if (( $frag_lun != $last_lun )); then
12774                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12775                         if (( logical != 512 )); then
12776                                 cleanup_130
12777                                 error "FIEMAP on $fm_file failed; returned " \
12778                                 "logical start for lun $logical instead of 512"
12779                                 return
12780                         fi
12781                         if (( tot_len != 512 )); then
12782                                 cleanup_130
12783                                 error "FIEMAP on $fm_file failed; returned " \
12784                                 "len $tot_len for OST $last_lun instead of 1024"
12785                                 return
12786                         else
12787                                 (( num_luns += 1 ))
12788                                 tot_len=0
12789                         fi
12790                 fi
12791                 (( tot_len += ext_len ))
12792                 last_lun=$frag_lun
12793         done
12794         if (( num_luns != 2 || tot_len != 512 )); then
12795                 cleanup_130
12796                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12797                         "luns or wrong len for OST $last_lun"
12798                 return
12799         fi
12800
12801         cleanup_130
12802
12803         echo "FIEMAP on 2-stripe file with hole succeeded"
12804 }
12805 run_test 130c "FIEMAP (2-stripe file with hole)"
12806
12807 test_130d() {
12808         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12809
12810         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12811         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12812
12813         trap cleanup_130 EXIT RETURN
12814
12815         local fm_file=$DIR/$tfile
12816         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12817                         error "setstripe on $fm_file"
12818         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12819                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12820
12821         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12822         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12823                 error "dd failed on $fm_file"
12824
12825         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12826         filefrag_op=$(filefrag -ve -k $fm_file |
12827                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12828
12829         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12830                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12831
12832         IFS=$'\n'
12833         tot_len=0
12834         num_luns=1
12835         for line in $filefrag_op
12836         do
12837                 frag_lun=$(echo $line | cut -d: -f5 |
12838                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12839                 ext_len=$(echo $line | cut -d: -f4)
12840                 if (( $frag_lun != $last_lun )); then
12841                         if (( tot_len != 1024 )); then
12842                                 cleanup_130
12843                                 error "FIEMAP on $fm_file failed; returned " \
12844                                 "len $tot_len for OST $last_lun instead of 1024"
12845                                 return
12846                         else
12847                                 (( num_luns += 1 ))
12848                                 tot_len=0
12849                         fi
12850                 fi
12851                 (( tot_len += ext_len ))
12852                 last_lun=$frag_lun
12853         done
12854         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12855                 cleanup_130
12856                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12857                         "luns or wrong len for OST $last_lun"
12858                 return
12859         fi
12860
12861         cleanup_130
12862
12863         echo "FIEMAP on N-stripe file succeeded"
12864 }
12865 run_test 130d "FIEMAP (N-stripe file)"
12866
12867 test_130e() {
12868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12869
12870         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12871         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12872
12873         trap cleanup_130 EXIT RETURN
12874
12875         local fm_file=$DIR/$tfile
12876         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12877
12878         NUM_BLKS=512
12879         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12880         for ((i = 0; i < $NUM_BLKS; i++)); do
12881                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12882                         conv=notrunc > /dev/null 2>&1
12883         done
12884
12885         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12886         filefrag_op=$(filefrag -ve -k $fm_file |
12887                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12888
12889         last_lun=$(echo $filefrag_op | cut -d: -f5)
12890
12891         IFS=$'\n'
12892         tot_len=0
12893         num_luns=1
12894         for line in $filefrag_op; do
12895                 frag_lun=$(echo $line | cut -d: -f5)
12896                 ext_len=$(echo $line | cut -d: -f4)
12897                 if [[ "$frag_lun" != "$last_lun" ]]; then
12898                         if (( tot_len != $EXPECTED_LEN )); then
12899                                 cleanup_130
12900                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12901                         else
12902                                 (( num_luns += 1 ))
12903                                 tot_len=0
12904                         fi
12905                 fi
12906                 (( tot_len += ext_len ))
12907                 last_lun=$frag_lun
12908         done
12909         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12910                 cleanup_130
12911                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12912         fi
12913
12914         echo "FIEMAP with continuation calls succeeded"
12915 }
12916 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12917
12918 test_130f() {
12919         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12920         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12921
12922         local fm_file=$DIR/$tfile
12923         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12924                 error "multiop create with lov_delay_create on $fm_file"
12925
12926         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12927         filefrag_extents=$(filefrag -vek $fm_file |
12928                            awk '/extents? found/ { print $2 }')
12929         if [[ "$filefrag_extents" != "0" ]]; then
12930                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
12931         fi
12932
12933         rm -f $fm_file
12934 }
12935 run_test 130f "FIEMAP (unstriped file)"
12936
12937 test_130g() {
12938         local file=$DIR/$tfile
12939         local nr=$((OSTCOUNT * 100))
12940
12941         $LFS setstripe -C $nr $file ||
12942                 error "failed to setstripe -C $nr $file"
12943
12944         dd if=/dev/zero of=$file count=$nr bs=1M
12945         sync
12946         nr=$($LFS getstripe -c $file)
12947
12948         local extents=$(filefrag -v $file |
12949                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
12950
12951         echo "filefrag list $extents extents in file with stripecount $nr"
12952         if (( extents < nr )); then
12953                 $LFS getstripe $file
12954                 filefrag -v $file
12955                 error "filefrag printed $extents < $nr extents"
12956         fi
12957
12958         rm -f $file
12959 }
12960 run_test 130g "FIEMAP (overstripe file)"
12961
12962 # Test for writev/readv
12963 test_131a() {
12964         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12965                 error "writev test failed"
12966         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12967                 error "readv failed"
12968         rm -f $DIR/$tfile
12969 }
12970 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12971
12972 test_131b() {
12973         local fsize=$((524288 + 1048576 + 1572864))
12974         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12975                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12976                         error "append writev test failed"
12977
12978         ((fsize += 1572864 + 1048576))
12979         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12980                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12981                         error "append writev test failed"
12982         rm -f $DIR/$tfile
12983 }
12984 run_test 131b "test append writev"
12985
12986 test_131c() {
12987         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12988         error "NOT PASS"
12989 }
12990 run_test 131c "test read/write on file w/o objects"
12991
12992 test_131d() {
12993         rwv -f $DIR/$tfile -w -n 1 1572864
12994         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12995         if [ "$NOB" != 1572864 ]; then
12996                 error "Short read filed: read $NOB bytes instead of 1572864"
12997         fi
12998         rm -f $DIR/$tfile
12999 }
13000 run_test 131d "test short read"
13001
13002 test_131e() {
13003         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13004         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13005         error "read hitting hole failed"
13006         rm -f $DIR/$tfile
13007 }
13008 run_test 131e "test read hitting hole"
13009
13010 check_stats() {
13011         local facet=$1
13012         local op=$2
13013         local want=${3:-0}
13014         local res
13015
13016         case $facet in
13017         mds*) res=$(do_facet $facet \
13018                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13019                  ;;
13020         ost*) res=$(do_facet $facet \
13021                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13022                  ;;
13023         *) error "Wrong facet '$facet'" ;;
13024         esac
13025         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13026         # if the argument $3 is zero, it means any stat increment is ok.
13027         if [[ $want -gt 0 ]]; then
13028                 local count=$(echo $res | awk '{ print $2 }')
13029                 [[ $count -ne $want ]] &&
13030                         error "The $op counter on $facet is $count, not $want"
13031         fi
13032 }
13033
13034 test_133a() {
13035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13036         remote_ost_nodsh && skip "remote OST with nodsh"
13037         remote_mds_nodsh && skip "remote MDS with nodsh"
13038         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13039                 skip_env "MDS doesn't support rename stats"
13040
13041         local testdir=$DIR/${tdir}/stats_testdir
13042
13043         mkdir -p $DIR/${tdir}
13044
13045         # clear stats.
13046         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13047         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13048
13049         # verify mdt stats first.
13050         mkdir ${testdir} || error "mkdir failed"
13051         check_stats $SINGLEMDS "mkdir" 1
13052         touch ${testdir}/${tfile} || error "touch failed"
13053         check_stats $SINGLEMDS "open" 1
13054         check_stats $SINGLEMDS "close" 1
13055         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13056                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13057                 check_stats $SINGLEMDS "mknod" 2
13058         }
13059         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13060         check_stats $SINGLEMDS "unlink" 1
13061         rm -f ${testdir}/${tfile} || error "file remove failed"
13062         check_stats $SINGLEMDS "unlink" 2
13063
13064         # remove working dir and check mdt stats again.
13065         rmdir ${testdir} || error "rmdir failed"
13066         check_stats $SINGLEMDS "rmdir" 1
13067
13068         local testdir1=$DIR/${tdir}/stats_testdir1
13069         mkdir -p ${testdir}
13070         mkdir -p ${testdir1}
13071         touch ${testdir1}/test1
13072         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13073         check_stats $SINGLEMDS "crossdir_rename" 1
13074
13075         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13076         check_stats $SINGLEMDS "samedir_rename" 1
13077
13078         rm -rf $DIR/${tdir}
13079 }
13080 run_test 133a "Verifying MDT stats ========================================"
13081
13082 test_133b() {
13083         local res
13084
13085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13086         remote_ost_nodsh && skip "remote OST with nodsh"
13087         remote_mds_nodsh && skip "remote MDS with nodsh"
13088
13089         local testdir=$DIR/${tdir}/stats_testdir
13090
13091         mkdir -p ${testdir} || error "mkdir failed"
13092         touch ${testdir}/${tfile} || error "touch failed"
13093         cancel_lru_locks mdc
13094
13095         # clear stats.
13096         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13097         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13098
13099         # extra mdt stats verification.
13100         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13101         check_stats $SINGLEMDS "setattr" 1
13102         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13103         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13104         then            # LU-1740
13105                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13106                 check_stats $SINGLEMDS "getattr" 1
13107         fi
13108         rm -rf $DIR/${tdir}
13109
13110         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13111         # so the check below is not reliable
13112         [ $MDSCOUNT -eq 1 ] || return 0
13113
13114         # Sleep to avoid a cached response.
13115         #define OBD_STATFS_CACHE_SECONDS 1
13116         sleep 2
13117         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13118         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13119         $LFS df || error "lfs failed"
13120         check_stats $SINGLEMDS "statfs" 1
13121
13122         # check aggregated statfs (LU-10018)
13123         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13124                 return 0
13125         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13126                 return 0
13127         sleep 2
13128         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13129         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13130         df $DIR
13131         check_stats $SINGLEMDS "statfs" 1
13132
13133         # We want to check that the client didn't send OST_STATFS to
13134         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13135         # extra care is needed here.
13136         if remote_mds; then
13137                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13138                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13139
13140                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13141                 [ "$res" ] && error "OST got STATFS"
13142         fi
13143
13144         return 0
13145 }
13146 run_test 133b "Verifying extra MDT stats =================================="
13147
13148 test_133c() {
13149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13150         remote_ost_nodsh && skip "remote OST with nodsh"
13151         remote_mds_nodsh && skip "remote MDS with nodsh"
13152
13153         local testdir=$DIR/$tdir/stats_testdir
13154
13155         test_mkdir -p $testdir
13156
13157         # verify obdfilter stats.
13158         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13159         sync
13160         cancel_lru_locks osc
13161         wait_delete_completed
13162
13163         # clear stats.
13164         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13165         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13166
13167         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13168                 error "dd failed"
13169         sync
13170         cancel_lru_locks osc
13171         check_stats ost1 "write" 1
13172
13173         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13174         check_stats ost1 "read" 1
13175
13176         > $testdir/$tfile || error "truncate failed"
13177         check_stats ost1 "punch" 1
13178
13179         rm -f $testdir/$tfile || error "file remove failed"
13180         wait_delete_completed
13181         check_stats ost1 "destroy" 1
13182
13183         rm -rf $DIR/$tdir
13184 }
13185 run_test 133c "Verifying OST stats ========================================"
13186
13187 order_2() {
13188         local value=$1
13189         local orig=$value
13190         local order=1
13191
13192         while [ $value -ge 2 ]; do
13193                 order=$((order*2))
13194                 value=$((value/2))
13195         done
13196
13197         if [ $orig -gt $order ]; then
13198                 order=$((order*2))
13199         fi
13200         echo $order
13201 }
13202
13203 size_in_KMGT() {
13204     local value=$1
13205     local size=('K' 'M' 'G' 'T');
13206     local i=0
13207     local size_string=$value
13208
13209     while [ $value -ge 1024 ]; do
13210         if [ $i -gt 3 ]; then
13211             #T is the biggest unit we get here, if that is bigger,
13212             #just return XXXT
13213             size_string=${value}T
13214             break
13215         fi
13216         value=$((value >> 10))
13217         if [ $value -lt 1024 ]; then
13218             size_string=${value}${size[$i]}
13219             break
13220         fi
13221         i=$((i + 1))
13222     done
13223
13224     echo $size_string
13225 }
13226
13227 get_rename_size() {
13228         local size=$1
13229         local context=${2:-.}
13230         local sample=$(do_facet $SINGLEMDS $LCTL \
13231                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13232                 grep -A1 $context |
13233                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13234         echo $sample
13235 }
13236
13237 test_133d() {
13238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13239         remote_ost_nodsh && skip "remote OST with nodsh"
13240         remote_mds_nodsh && skip "remote MDS with nodsh"
13241         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13242                 skip_env "MDS doesn't support rename stats"
13243
13244         local testdir1=$DIR/${tdir}/stats_testdir1
13245         local testdir2=$DIR/${tdir}/stats_testdir2
13246         mkdir -p $DIR/${tdir}
13247
13248         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13249
13250         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13251         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13252
13253         createmany -o $testdir1/test 512 || error "createmany failed"
13254
13255         # check samedir rename size
13256         mv ${testdir1}/test0 ${testdir1}/test_0
13257
13258         local testdir1_size=$(ls -l $DIR/${tdir} |
13259                 awk '/stats_testdir1/ {print $5}')
13260         local testdir2_size=$(ls -l $DIR/${tdir} |
13261                 awk '/stats_testdir2/ {print $5}')
13262
13263         testdir1_size=$(order_2 $testdir1_size)
13264         testdir2_size=$(order_2 $testdir2_size)
13265
13266         testdir1_size=$(size_in_KMGT $testdir1_size)
13267         testdir2_size=$(size_in_KMGT $testdir2_size)
13268
13269         echo "source rename dir size: ${testdir1_size}"
13270         echo "target rename dir size: ${testdir2_size}"
13271
13272         local cmd="do_facet $SINGLEMDS $LCTL "
13273         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13274
13275         eval $cmd || error "$cmd failed"
13276         local samedir=$($cmd | grep 'same_dir')
13277         local same_sample=$(get_rename_size $testdir1_size)
13278         [ -z "$samedir" ] && error "samedir_rename_size count error"
13279         [[ $same_sample -eq 1 ]] ||
13280                 error "samedir_rename_size error $same_sample"
13281         echo "Check same dir rename stats success"
13282
13283         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13284
13285         # check crossdir rename size
13286         mv ${testdir1}/test_0 ${testdir2}/test_0
13287
13288         testdir1_size=$(ls -l $DIR/${tdir} |
13289                 awk '/stats_testdir1/ {print $5}')
13290         testdir2_size=$(ls -l $DIR/${tdir} |
13291                 awk '/stats_testdir2/ {print $5}')
13292
13293         testdir1_size=$(order_2 $testdir1_size)
13294         testdir2_size=$(order_2 $testdir2_size)
13295
13296         testdir1_size=$(size_in_KMGT $testdir1_size)
13297         testdir2_size=$(size_in_KMGT $testdir2_size)
13298
13299         echo "source rename dir size: ${testdir1_size}"
13300         echo "target rename dir size: ${testdir2_size}"
13301
13302         eval $cmd || error "$cmd failed"
13303         local crossdir=$($cmd | grep 'crossdir')
13304         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13305         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13306         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13307         [[ $src_sample -eq 1 ]] ||
13308                 error "crossdir_rename_size error $src_sample"
13309         [[ $tgt_sample -eq 1 ]] ||
13310                 error "crossdir_rename_size error $tgt_sample"
13311         echo "Check cross dir rename stats success"
13312         rm -rf $DIR/${tdir}
13313 }
13314 run_test 133d "Verifying rename_stats ========================================"
13315
13316 test_133e() {
13317         remote_mds_nodsh && skip "remote MDS with nodsh"
13318         remote_ost_nodsh && skip "remote OST with nodsh"
13319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13320
13321         local testdir=$DIR/${tdir}/stats_testdir
13322         local ctr f0 f1 bs=32768 count=42 sum
13323
13324         mkdir -p ${testdir} || error "mkdir failed"
13325
13326         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13327
13328         for ctr in {write,read}_bytes; do
13329                 sync
13330                 cancel_lru_locks osc
13331
13332                 do_facet ost1 $LCTL set_param -n \
13333                         "obdfilter.*.exports.clear=clear"
13334
13335                 if [ $ctr = write_bytes ]; then
13336                         f0=/dev/zero
13337                         f1=${testdir}/${tfile}
13338                 else
13339                         f0=${testdir}/${tfile}
13340                         f1=/dev/null
13341                 fi
13342
13343                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13344                         error "dd failed"
13345                 sync
13346                 cancel_lru_locks osc
13347
13348                 sum=$(do_facet ost1 $LCTL get_param \
13349                         "obdfilter.*.exports.*.stats" |
13350                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13351                                 $1 == ctr { sum += $7 }
13352                                 END { printf("%0.0f", sum) }')
13353
13354                 if ((sum != bs * count)); then
13355                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13356                 fi
13357         done
13358
13359         rm -rf $DIR/${tdir}
13360 }
13361 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13362
13363 test_133f() {
13364         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13365                 skip "too old lustre for get_param -R ($facet_ver)"
13366
13367         # verifying readability.
13368         $LCTL get_param -R '*' &> /dev/null
13369
13370         # Verifing writability with badarea_io.
13371         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13372                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13373                 error "client badarea_io failed"
13374
13375         # remount the FS in case writes/reads /proc break the FS
13376         cleanup || error "failed to unmount"
13377         setup || error "failed to setup"
13378 }
13379 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13380
13381 test_133g() {
13382         remote_mds_nodsh && skip "remote MDS with nodsh"
13383         remote_ost_nodsh && skip "remote OST with nodsh"
13384
13385         local facet
13386         for facet in mds1 ost1; do
13387                 local facet_ver=$(lustre_version_code $facet)
13388                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13389                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13390                 else
13391                         log "$facet: too old lustre for get_param -R"
13392                 fi
13393                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13394                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13395                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13396                                 xargs badarea_io" ||
13397                                         error "$facet badarea_io failed"
13398                 else
13399                         skip_noexit "$facet: too old lustre for get_param -R"
13400                 fi
13401         done
13402
13403         # remount the FS in case writes/reads /proc break the FS
13404         cleanup || error "failed to unmount"
13405         setup || error "failed to setup"
13406 }
13407 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13408
13409 test_133h() {
13410         remote_mds_nodsh && skip "remote MDS with nodsh"
13411         remote_ost_nodsh && skip "remote OST with nodsh"
13412         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13413                 skip "Need MDS version at least 2.9.54"
13414
13415         local facet
13416         for facet in client mds1 ost1; do
13417                 # Get the list of files that are missing the terminating newline
13418                 local plist=$(do_facet $facet
13419                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13420                 local ent
13421                 for ent in $plist; do
13422                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13423                                 awk -v FS='\v' -v RS='\v\v' \
13424                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13425                                         print FILENAME}'" 2>/dev/null)
13426                         [ -z $missing ] || {
13427                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13428                                 error "file does not end with newline: $facet-$ent"
13429                         }
13430                 done
13431         done
13432 }
13433 run_test 133h "Proc files should end with newlines"
13434
13435 test_134a() {
13436         remote_mds_nodsh && skip "remote MDS with nodsh"
13437         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13438                 skip "Need MDS version at least 2.7.54"
13439
13440         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13441         cancel_lru_locks mdc
13442
13443         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13444         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13445         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13446
13447         local nr=1000
13448         createmany -o $DIR/$tdir/f $nr ||
13449                 error "failed to create $nr files in $DIR/$tdir"
13450         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13451
13452         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13453         do_facet mds1 $LCTL set_param fail_loc=0x327
13454         do_facet mds1 $LCTL set_param fail_val=500
13455         touch $DIR/$tdir/m
13456
13457         echo "sleep 10 seconds ..."
13458         sleep 10
13459         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13460
13461         do_facet mds1 $LCTL set_param fail_loc=0
13462         do_facet mds1 $LCTL set_param fail_val=0
13463         [ $lck_cnt -lt $unused ] ||
13464                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13465
13466         rm $DIR/$tdir/m
13467         unlinkmany $DIR/$tdir/f $nr
13468 }
13469 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13470
13471 test_134b() {
13472         remote_mds_nodsh && skip "remote MDS with nodsh"
13473         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13474                 skip "Need MDS version at least 2.7.54"
13475
13476         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13477         cancel_lru_locks mdc
13478
13479         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13480                         ldlm.lock_reclaim_threshold_mb)
13481         # disable reclaim temporarily
13482         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13483
13484         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13485         do_facet mds1 $LCTL set_param fail_loc=0x328
13486         do_facet mds1 $LCTL set_param fail_val=500
13487
13488         $LCTL set_param debug=+trace
13489
13490         local nr=600
13491         createmany -o $DIR/$tdir/f $nr &
13492         local create_pid=$!
13493
13494         echo "Sleep $TIMEOUT seconds ..."
13495         sleep $TIMEOUT
13496         if ! ps -p $create_pid  > /dev/null 2>&1; then
13497                 do_facet mds1 $LCTL set_param fail_loc=0
13498                 do_facet mds1 $LCTL set_param fail_val=0
13499                 do_facet mds1 $LCTL set_param \
13500                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13501                 error "createmany finished incorrectly!"
13502         fi
13503         do_facet mds1 $LCTL set_param fail_loc=0
13504         do_facet mds1 $LCTL set_param fail_val=0
13505         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13506         wait $create_pid || return 1
13507
13508         unlinkmany $DIR/$tdir/f $nr
13509 }
13510 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13511
13512 test_135() {
13513         remote_mds_nodsh && skip "remote MDS with nodsh"
13514         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13515                 skip "Need MDS version at least 2.13.50"
13516         local fname
13517
13518         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13519
13520 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13521         #set only one record at plain llog
13522         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13523
13524         #fill already existed plain llog each 64767
13525         #wrapping whole catalog
13526         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13527
13528         createmany -o $DIR/$tdir/$tfile_ 64700
13529         for (( i = 0; i < 64700; i = i + 2 ))
13530         do
13531                 rm $DIR/$tdir/$tfile_$i &
13532                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13533                 local pid=$!
13534                 wait $pid
13535         done
13536
13537         #waiting osp synchronization
13538         wait_delete_completed
13539 }
13540 run_test 135 "Race catalog processing"
13541
13542 test_136() {
13543         remote_mds_nodsh && skip "remote MDS with nodsh"
13544         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13545                 skip "Need MDS version at least 2.13.50"
13546         local fname
13547
13548         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13549         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13550         #set only one record at plain llog
13551 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13552         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13553
13554         #fill already existed 2 plain llogs each 64767
13555         #wrapping whole catalog
13556         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13557         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13558         wait_delete_completed
13559
13560         createmany -o $DIR/$tdir/$tfile_ 10
13561         sleep 25
13562
13563         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13564         for (( i = 0; i < 10; i = i + 3 ))
13565         do
13566                 rm $DIR/$tdir/$tfile_$i &
13567                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13568                 local pid=$!
13569                 wait $pid
13570                 sleep 7
13571                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13572         done
13573
13574         #waiting osp synchronization
13575         wait_delete_completed
13576 }
13577 run_test 136 "Race catalog processing 2"
13578
13579 test_140() { #bug-17379
13580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13581
13582         test_mkdir $DIR/$tdir
13583         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13584         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13585
13586         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13587         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13588         local i=0
13589         while i=$((i + 1)); do
13590                 test_mkdir $i
13591                 cd $i || error "Changing to $i"
13592                 ln -s ../stat stat || error "Creating stat symlink"
13593                 # Read the symlink until ELOOP present,
13594                 # not LBUGing the system is considered success,
13595                 # we didn't overrun the stack.
13596                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13597                 if [ $ret -ne 0 ]; then
13598                         if [ $ret -eq 40 ]; then
13599                                 break  # -ELOOP
13600                         else
13601                                 error "Open stat symlink"
13602                                         return
13603                         fi
13604                 fi
13605         done
13606         i=$((i - 1))
13607         echo "The symlink depth = $i"
13608         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13609                 error "Invalid symlink depth"
13610
13611         # Test recursive symlink
13612         ln -s symlink_self symlink_self
13613         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13614         echo "open symlink_self returns $ret"
13615         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13616 }
13617 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13618
13619 test_150a() {
13620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13621
13622         local TF="$TMP/$tfile"
13623
13624         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13625         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13626         cp $TF $DIR/$tfile
13627         cancel_lru_locks $OSC
13628         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13629         remount_client $MOUNT
13630         df -P $MOUNT
13631         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13632
13633         $TRUNCATE $TF 6000
13634         $TRUNCATE $DIR/$tfile 6000
13635         cancel_lru_locks $OSC
13636         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13637
13638         echo "12345" >>$TF
13639         echo "12345" >>$DIR/$tfile
13640         cancel_lru_locks $OSC
13641         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13642
13643         echo "12345" >>$TF
13644         echo "12345" >>$DIR/$tfile
13645         cancel_lru_locks $OSC
13646         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13647 }
13648 run_test 150a "truncate/append tests"
13649
13650 test_150b() {
13651         check_set_fallocate_or_skip
13652
13653         touch $DIR/$tfile
13654         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13655         check_fallocate $DIR/$tfile || error "fallocate failed"
13656 }
13657 run_test 150b "Verify fallocate (prealloc) functionality"
13658
13659 test_150bb() {
13660         check_set_fallocate_or_skip
13661
13662         touch $DIR/$tfile
13663         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13664         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13665         > $DIR/$tfile
13666         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13667         # precomputed md5sum for 20MB of zeroes
13668         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13669         local sum=($(md5sum $DIR/$tfile))
13670
13671         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13672
13673         check_set_fallocate 1
13674
13675         > $DIR/$tfile
13676         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13677         sum=($(md5sum $DIR/$tfile))
13678
13679         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13680 }
13681 run_test 150bb "Verify fallocate modes both zero space"
13682
13683 test_150c() {
13684         check_set_fallocate_or_skip
13685
13686         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13687         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13688         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13689         sync; sync_all_data
13690         cancel_lru_locks $OSC
13691         sleep 5
13692         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13693         want=$((OSTCOUNT * 1048576))
13694
13695         # Must allocate all requested space, not more than 5% extra
13696         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13697                 error "bytes $bytes is not $want"
13698
13699         rm -f $DIR/$tfile
13700         # verify fallocate on PFL file
13701         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13702                 error "Create $DIR/$tfile failed"
13703         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13704                         error "fallocate failed"
13705         sync; sync_all_data
13706         cancel_lru_locks $OSC
13707         sleep 5
13708         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13709         local want=$((1024 * 1048576))
13710
13711         # Must allocate all requested space, not more than 5% extra
13712         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13713                 error "bytes $bytes is not $want"
13714 }
13715 run_test 150c "Verify fallocate Size and Blocks"
13716
13717 test_150d() {
13718         check_set_fallocate_or_skip
13719
13720         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13721         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13722         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13723         sync; sync_all_data
13724         cancel_lru_locks $OSC
13725         sleep 5
13726         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13727         local want=$((OSTCOUNT * 1048576))
13728
13729         # Must allocate all requested space, not more than 5% extra
13730         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13731                 error "bytes $bytes is not $want"
13732 }
13733 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13734
13735 test_150e() {
13736         check_set_fallocate_or_skip
13737
13738         echo "df before:"
13739         $LFS df
13740         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13741         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13742                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13743
13744         # Find OST with Minimum Size
13745         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13746                        sort -un | head -1)
13747
13748         # Get 100MB per OST of the available space to reduce run time
13749         # else 60% of the available space if we are running SLOW tests
13750         if [ $SLOW == "no" ]; then
13751                 local space=$((1024 * 100 * OSTCOUNT))
13752         else
13753                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13754         fi
13755
13756         fallocate -l${space}k $DIR/$tfile ||
13757                 error "fallocate ${space}k $DIR/$tfile failed"
13758         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13759
13760         # get size immediately after fallocate. This should be correctly
13761         # updated
13762         local size=$(stat -c '%s' $DIR/$tfile)
13763         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13764
13765         # Sleep for a while for statfs to get updated. And not pull from cache.
13766         sleep 2
13767
13768         echo "df after fallocate:"
13769         $LFS df
13770
13771         (( size / 1024 == space )) || error "size $size != requested $space"
13772         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13773                 error "used $used < space $space"
13774
13775         rm $DIR/$tfile || error "rm failed"
13776         sync
13777         wait_delete_completed
13778
13779         echo "df after unlink:"
13780         $LFS df
13781 }
13782 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13783
13784 #LU-2902 roc_hit was not able to read all values from lproc
13785 function roc_hit_init() {
13786         local list=$(comma_list $(osts_nodes))
13787         local dir=$DIR/$tdir-check
13788         local file=$dir/$tfile
13789         local BEFORE
13790         local AFTER
13791         local idx
13792
13793         test_mkdir $dir
13794         #use setstripe to do a write to every ost
13795         for i in $(seq 0 $((OSTCOUNT-1))); do
13796                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13797                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13798                 idx=$(printf %04x $i)
13799                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13800                         awk '$1 == "cache_access" {sum += $7}
13801                                 END { printf("%0.0f", sum) }')
13802
13803                 cancel_lru_locks osc
13804                 cat $file >/dev/null
13805
13806                 AFTER=$(get_osd_param $list *OST*$idx stats |
13807                         awk '$1 == "cache_access" {sum += $7}
13808                                 END { printf("%0.0f", sum) }')
13809
13810                 echo BEFORE:$BEFORE AFTER:$AFTER
13811                 if ! let "AFTER - BEFORE == 4"; then
13812                         rm -rf $dir
13813                         error "roc_hit is not safe to use"
13814                 fi
13815                 rm $file
13816         done
13817
13818         rm -rf $dir
13819 }
13820
13821 function roc_hit() {
13822         local list=$(comma_list $(osts_nodes))
13823         echo $(get_osd_param $list '' stats |
13824                 awk '$1 == "cache_hit" {sum += $7}
13825                         END { printf("%0.0f", sum) }')
13826 }
13827
13828 function set_cache() {
13829         local on=1
13830
13831         if [ "$2" == "off" ]; then
13832                 on=0;
13833         fi
13834         local list=$(comma_list $(osts_nodes))
13835         set_osd_param $list '' $1_cache_enable $on
13836
13837         cancel_lru_locks osc
13838 }
13839
13840 test_151() {
13841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13842         remote_ost_nodsh && skip "remote OST with nodsh"
13843
13844         local CPAGES=3
13845         local list=$(comma_list $(osts_nodes))
13846
13847         # check whether obdfilter is cache capable at all
13848         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13849                 skip "not cache-capable obdfilter"
13850         fi
13851
13852         # check cache is enabled on all obdfilters
13853         if get_osd_param $list '' read_cache_enable | grep 0; then
13854                 skip "oss cache is disabled"
13855         fi
13856
13857         set_osd_param $list '' writethrough_cache_enable 1
13858
13859         # check write cache is enabled on all obdfilters
13860         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13861                 skip "oss write cache is NOT enabled"
13862         fi
13863
13864         roc_hit_init
13865
13866         #define OBD_FAIL_OBD_NO_LRU  0x609
13867         do_nodes $list $LCTL set_param fail_loc=0x609
13868
13869         # pages should be in the case right after write
13870         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13871                 error "dd failed"
13872
13873         local BEFORE=$(roc_hit)
13874         cancel_lru_locks osc
13875         cat $DIR/$tfile >/dev/null
13876         local AFTER=$(roc_hit)
13877
13878         do_nodes $list $LCTL set_param fail_loc=0
13879
13880         if ! let "AFTER - BEFORE == CPAGES"; then
13881                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13882         fi
13883
13884         cancel_lru_locks osc
13885         # invalidates OST cache
13886         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13887         set_osd_param $list '' read_cache_enable 0
13888         cat $DIR/$tfile >/dev/null
13889
13890         # now data shouldn't be found in the cache
13891         BEFORE=$(roc_hit)
13892         cancel_lru_locks osc
13893         cat $DIR/$tfile >/dev/null
13894         AFTER=$(roc_hit)
13895         if let "AFTER - BEFORE != 0"; then
13896                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13897         fi
13898
13899         set_osd_param $list '' read_cache_enable 1
13900         rm -f $DIR/$tfile
13901 }
13902 run_test 151 "test cache on oss and controls ==============================="
13903
13904 test_152() {
13905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13906
13907         local TF="$TMP/$tfile"
13908
13909         # simulate ENOMEM during write
13910 #define OBD_FAIL_OST_NOMEM      0x226
13911         lctl set_param fail_loc=0x80000226
13912         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13913         cp $TF $DIR/$tfile
13914         sync || error "sync failed"
13915         lctl set_param fail_loc=0
13916
13917         # discard client's cache
13918         cancel_lru_locks osc
13919
13920         # simulate ENOMEM during read
13921         lctl set_param fail_loc=0x80000226
13922         cmp $TF $DIR/$tfile || error "cmp failed"
13923         lctl set_param fail_loc=0
13924
13925         rm -f $TF
13926 }
13927 run_test 152 "test read/write with enomem ============================"
13928
13929 test_153() {
13930         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13931 }
13932 run_test 153 "test if fdatasync does not crash ======================="
13933
13934 dot_lustre_fid_permission_check() {
13935         local fid=$1
13936         local ffid=$MOUNT/.lustre/fid/$fid
13937         local test_dir=$2
13938
13939         echo "stat fid $fid"
13940         stat $ffid > /dev/null || error "stat $ffid failed."
13941         echo "touch fid $fid"
13942         touch $ffid || error "touch $ffid failed."
13943         echo "write to fid $fid"
13944         cat /etc/hosts > $ffid || error "write $ffid failed."
13945         echo "read fid $fid"
13946         diff /etc/hosts $ffid || error "read $ffid failed."
13947         echo "append write to fid $fid"
13948         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13949         echo "rename fid $fid"
13950         mv $ffid $test_dir/$tfile.1 &&
13951                 error "rename $ffid to $tfile.1 should fail."
13952         touch $test_dir/$tfile.1
13953         mv $test_dir/$tfile.1 $ffid &&
13954                 error "rename $tfile.1 to $ffid should fail."
13955         rm -f $test_dir/$tfile.1
13956         echo "truncate fid $fid"
13957         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13958         echo "link fid $fid"
13959         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13960         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13961                 echo "setfacl fid $fid"
13962                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13963                 echo "getfacl fid $fid"
13964                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13965         fi
13966         echo "unlink fid $fid"
13967         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13968         echo "mknod fid $fid"
13969         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13970
13971         fid=[0xf00000400:0x1:0x0]
13972         ffid=$MOUNT/.lustre/fid/$fid
13973
13974         echo "stat non-exist fid $fid"
13975         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13976         echo "write to non-exist fid $fid"
13977         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13978         echo "link new fid $fid"
13979         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13980
13981         mkdir -p $test_dir/$tdir
13982         touch $test_dir/$tdir/$tfile
13983         fid=$($LFS path2fid $test_dir/$tdir)
13984         rc=$?
13985         [ $rc -ne 0 ] &&
13986                 error "error: could not get fid for $test_dir/$dir/$tfile."
13987
13988         ffid=$MOUNT/.lustre/fid/$fid
13989
13990         echo "ls $fid"
13991         ls $ffid > /dev/null || error "ls $ffid failed."
13992         echo "touch $fid/$tfile.1"
13993         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13994
13995         echo "touch $MOUNT/.lustre/fid/$tfile"
13996         touch $MOUNT/.lustre/fid/$tfile && \
13997                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13998
13999         echo "setxattr to $MOUNT/.lustre/fid"
14000         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14001
14002         echo "listxattr for $MOUNT/.lustre/fid"
14003         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14004
14005         echo "delxattr from $MOUNT/.lustre/fid"
14006         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14007
14008         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14009         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14010                 error "touch invalid fid should fail."
14011
14012         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14013         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14014                 error "touch non-normal fid should fail."
14015
14016         echo "rename $tdir to $MOUNT/.lustre/fid"
14017         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14018                 error "rename to $MOUNT/.lustre/fid should fail."
14019
14020         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14021         then            # LU-3547
14022                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14023                 local new_obf_mode=777
14024
14025                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14026                 chmod $new_obf_mode $DIR/.lustre/fid ||
14027                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14028
14029                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14030                 [ $obf_mode -eq $new_obf_mode ] ||
14031                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14032
14033                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14034                 chmod $old_obf_mode $DIR/.lustre/fid ||
14035                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14036         fi
14037
14038         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14039         fid=$($LFS path2fid $test_dir/$tfile-2)
14040
14041         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14042         then # LU-5424
14043                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14044                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14045                         error "create lov data thru .lustre failed"
14046         fi
14047         echo "cp /etc/passwd $test_dir/$tfile-2"
14048         cp /etc/passwd $test_dir/$tfile-2 ||
14049                 error "copy to $test_dir/$tfile-2 failed."
14050         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14051         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14052                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14053
14054         rm -rf $test_dir/tfile.lnk
14055         rm -rf $test_dir/$tfile-2
14056 }
14057
14058 test_154A() {
14059         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14060                 skip "Need MDS version at least 2.4.1"
14061
14062         local tf=$DIR/$tfile
14063         touch $tf
14064
14065         local fid=$($LFS path2fid $tf)
14066         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14067
14068         # check that we get the same pathname back
14069         local rootpath
14070         local found
14071         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14072                 echo "$rootpath $fid"
14073                 found=$($LFS fid2path $rootpath "$fid")
14074                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14075                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14076         done
14077
14078         # check wrong root path format
14079         rootpath=$MOUNT"_wrong"
14080         found=$($LFS fid2path $rootpath "$fid")
14081         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14082 }
14083 run_test 154A "lfs path2fid and fid2path basic checks"
14084
14085 test_154B() {
14086         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14087                 skip "Need MDS version at least 2.4.1"
14088
14089         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14090         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14091         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14092         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14093
14094         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14095         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14096
14097         # check that we get the same pathname
14098         echo "PFID: $PFID, name: $name"
14099         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14100         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14101         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14102                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14103
14104         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14105 }
14106 run_test 154B "verify the ll_decode_linkea tool"
14107
14108 test_154a() {
14109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14110         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14111         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14112                 skip "Need MDS version at least 2.2.51"
14113         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14114
14115         cp /etc/hosts $DIR/$tfile
14116
14117         fid=$($LFS path2fid $DIR/$tfile)
14118         rc=$?
14119         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14120
14121         dot_lustre_fid_permission_check "$fid" $DIR ||
14122                 error "dot lustre permission check $fid failed"
14123
14124         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14125
14126         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14127
14128         touch $MOUNT/.lustre/file &&
14129                 error "creation is not allowed under .lustre"
14130
14131         mkdir $MOUNT/.lustre/dir &&
14132                 error "mkdir is not allowed under .lustre"
14133
14134         rm -rf $DIR/$tfile
14135 }
14136 run_test 154a "Open-by-FID"
14137
14138 test_154b() {
14139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14140         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14142         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14143                 skip "Need MDS version at least 2.2.51"
14144
14145         local remote_dir=$DIR/$tdir/remote_dir
14146         local MDTIDX=1
14147         local rc=0
14148
14149         mkdir -p $DIR/$tdir
14150         $LFS mkdir -i $MDTIDX $remote_dir ||
14151                 error "create remote directory failed"
14152
14153         cp /etc/hosts $remote_dir/$tfile
14154
14155         fid=$($LFS path2fid $remote_dir/$tfile)
14156         rc=$?
14157         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14158
14159         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14160                 error "dot lustre permission check $fid failed"
14161         rm -rf $DIR/$tdir
14162 }
14163 run_test 154b "Open-by-FID for remote directory"
14164
14165 test_154c() {
14166         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14167                 skip "Need MDS version at least 2.4.1"
14168
14169         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14170         local FID1=$($LFS path2fid $DIR/$tfile.1)
14171         local FID2=$($LFS path2fid $DIR/$tfile.2)
14172         local FID3=$($LFS path2fid $DIR/$tfile.3)
14173
14174         local N=1
14175         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14176                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14177                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14178                 local want=FID$N
14179                 [ "$FID" = "${!want}" ] ||
14180                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14181                 N=$((N + 1))
14182         done
14183
14184         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14185         do
14186                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14187                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14188                 N=$((N + 1))
14189         done
14190 }
14191 run_test 154c "lfs path2fid and fid2path multiple arguments"
14192
14193 test_154d() {
14194         remote_mds_nodsh && skip "remote MDS with nodsh"
14195         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14196                 skip "Need MDS version at least 2.5.53"
14197
14198         if remote_mds; then
14199                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14200         else
14201                 nid="0@lo"
14202         fi
14203         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14204         local fd
14205         local cmd
14206
14207         rm -f $DIR/$tfile
14208         touch $DIR/$tfile
14209
14210         local fid=$($LFS path2fid $DIR/$tfile)
14211         # Open the file
14212         fd=$(free_fd)
14213         cmd="exec $fd<$DIR/$tfile"
14214         eval $cmd
14215         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14216         echo "$fid_list" | grep "$fid"
14217         rc=$?
14218
14219         cmd="exec $fd>/dev/null"
14220         eval $cmd
14221         if [ $rc -ne 0 ]; then
14222                 error "FID $fid not found in open files list $fid_list"
14223         fi
14224 }
14225 run_test 154d "Verify open file fid"
14226
14227 test_154e()
14228 {
14229         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14230                 skip "Need MDS version at least 2.6.50"
14231
14232         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14233                 error ".lustre returned by readdir"
14234         fi
14235 }
14236 run_test 154e ".lustre is not returned by readdir"
14237
14238 test_154f() {
14239         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14240
14241         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14242         test_mkdir -p -c1 $DIR/$tdir/d
14243         # test dirs inherit from its stripe
14244         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14245         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14246         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14247         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14248         touch $DIR/f
14249
14250         # get fid of parents
14251         local FID0=$($LFS path2fid $DIR/$tdir/d)
14252         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14253         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14254         local FID3=$($LFS path2fid $DIR)
14255
14256         # check that path2fid --parents returns expected <parent_fid>/name
14257         # 1) test for a directory (single parent)
14258         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14259         [ "$parent" == "$FID0/foo1" ] ||
14260                 error "expected parent: $FID0/foo1, got: $parent"
14261
14262         # 2) test for a file with nlink > 1 (multiple parents)
14263         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14264         echo "$parent" | grep -F "$FID1/$tfile" ||
14265                 error "$FID1/$tfile not returned in parent list"
14266         echo "$parent" | grep -F "$FID2/link" ||
14267                 error "$FID2/link not returned in parent list"
14268
14269         # 3) get parent by fid
14270         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14271         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14272         echo "$parent" | grep -F "$FID1/$tfile" ||
14273                 error "$FID1/$tfile not returned in parent list (by fid)"
14274         echo "$parent" | grep -F "$FID2/link" ||
14275                 error "$FID2/link not returned in parent list (by fid)"
14276
14277         # 4) test for entry in root directory
14278         parent=$($LFS path2fid --parents $DIR/f)
14279         echo "$parent" | grep -F "$FID3/f" ||
14280                 error "$FID3/f not returned in parent list"
14281
14282         # 5) test it on root directory
14283         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14284                 error "$MOUNT should not have parents"
14285
14286         # enable xattr caching and check that linkea is correctly updated
14287         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14288         save_lustre_params client "llite.*.xattr_cache" > $save
14289         lctl set_param llite.*.xattr_cache 1
14290
14291         # 6.1) linkea update on rename
14292         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14293
14294         # get parents by fid
14295         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14296         # foo1 should no longer be returned in parent list
14297         echo "$parent" | grep -F "$FID1" &&
14298                 error "$FID1 should no longer be in parent list"
14299         # the new path should appear
14300         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14301                 error "$FID2/$tfile.moved is not in parent list"
14302
14303         # 6.2) linkea update on unlink
14304         rm -f $DIR/$tdir/d/foo2/link
14305         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14306         # foo2/link should no longer be returned in parent list
14307         echo "$parent" | grep -F "$FID2/link" &&
14308                 error "$FID2/link should no longer be in parent list"
14309         true
14310
14311         rm -f $DIR/f
14312         restore_lustre_params < $save
14313         rm -f $save
14314 }
14315 run_test 154f "get parent fids by reading link ea"
14316
14317 test_154g()
14318 {
14319         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14320         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14321            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14322                 skip "Need MDS version at least 2.6.92"
14323
14324         mkdir -p $DIR/$tdir
14325         llapi_fid_test -d $DIR/$tdir
14326 }
14327 run_test 154g "various llapi FID tests"
14328
14329 test_155_small_load() {
14330     local temp=$TMP/$tfile
14331     local file=$DIR/$tfile
14332
14333     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14334         error "dd of=$temp bs=6096 count=1 failed"
14335     cp $temp $file
14336     cancel_lru_locks $OSC
14337     cmp $temp $file || error "$temp $file differ"
14338
14339     $TRUNCATE $temp 6000
14340     $TRUNCATE $file 6000
14341     cmp $temp $file || error "$temp $file differ (truncate1)"
14342
14343     echo "12345" >>$temp
14344     echo "12345" >>$file
14345     cmp $temp $file || error "$temp $file differ (append1)"
14346
14347     echo "12345" >>$temp
14348     echo "12345" >>$file
14349     cmp $temp $file || error "$temp $file differ (append2)"
14350
14351     rm -f $temp $file
14352     true
14353 }
14354
14355 test_155_big_load() {
14356         remote_ost_nodsh && skip "remote OST with nodsh"
14357
14358         local temp=$TMP/$tfile
14359         local file=$DIR/$tfile
14360
14361         free_min_max
14362         local cache_size=$(do_facet ost$((MAXI+1)) \
14363                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14364         local large_file_size=$((cache_size * 2))
14365
14366         echo "OSS cache size: $cache_size KB"
14367         echo "Large file size: $large_file_size KB"
14368
14369         [ $MAXV -le $large_file_size ] &&
14370                 skip_env "max available OST size needs > $large_file_size KB"
14371
14372         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14373
14374         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14375                 error "dd of=$temp bs=$large_file_size count=1k failed"
14376         cp $temp $file
14377         ls -lh $temp $file
14378         cancel_lru_locks osc
14379         cmp $temp $file || error "$temp $file differ"
14380
14381         rm -f $temp $file
14382         true
14383 }
14384
14385 save_writethrough() {
14386         local facets=$(get_facets OST)
14387
14388         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14389 }
14390
14391 test_155a() {
14392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14393
14394         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14395
14396         save_writethrough $p
14397
14398         set_cache read on
14399         set_cache writethrough on
14400         test_155_small_load
14401         restore_lustre_params < $p
14402         rm -f $p
14403 }
14404 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14405
14406 test_155b() {
14407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14408
14409         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14410
14411         save_writethrough $p
14412
14413         set_cache read on
14414         set_cache writethrough off
14415         test_155_small_load
14416         restore_lustre_params < $p
14417         rm -f $p
14418 }
14419 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14420
14421 test_155c() {
14422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14423
14424         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14425
14426         save_writethrough $p
14427
14428         set_cache read off
14429         set_cache writethrough on
14430         test_155_small_load
14431         restore_lustre_params < $p
14432         rm -f $p
14433 }
14434 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14435
14436 test_155d() {
14437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14438
14439         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14440
14441         save_writethrough $p
14442
14443         set_cache read off
14444         set_cache writethrough off
14445         test_155_small_load
14446         restore_lustre_params < $p
14447         rm -f $p
14448 }
14449 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14450
14451 test_155e() {
14452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14453
14454         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14455
14456         save_writethrough $p
14457
14458         set_cache read on
14459         set_cache writethrough on
14460         test_155_big_load
14461         restore_lustre_params < $p
14462         rm -f $p
14463 }
14464 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14465
14466 test_155f() {
14467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14468
14469         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14470
14471         save_writethrough $p
14472
14473         set_cache read on
14474         set_cache writethrough off
14475         test_155_big_load
14476         restore_lustre_params < $p
14477         rm -f $p
14478 }
14479 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14480
14481 test_155g() {
14482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14483
14484         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14485
14486         save_writethrough $p
14487
14488         set_cache read off
14489         set_cache writethrough on
14490         test_155_big_load
14491         restore_lustre_params < $p
14492         rm -f $p
14493 }
14494 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14495
14496 test_155h() {
14497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14498
14499         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14500
14501         save_writethrough $p
14502
14503         set_cache read off
14504         set_cache writethrough off
14505         test_155_big_load
14506         restore_lustre_params < $p
14507         rm -f $p
14508 }
14509 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14510
14511 test_156() {
14512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14513         remote_ost_nodsh && skip "remote OST with nodsh"
14514         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14515                 skip "stats not implemented on old servers"
14516         [ "$ost1_FSTYPE" = "zfs" ] &&
14517                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14518
14519         local CPAGES=3
14520         local BEFORE
14521         local AFTER
14522         local file="$DIR/$tfile"
14523         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14524
14525         save_writethrough $p
14526         roc_hit_init
14527
14528         log "Turn on read and write cache"
14529         set_cache read on
14530         set_cache writethrough on
14531
14532         log "Write data and read it back."
14533         log "Read should be satisfied from the cache."
14534         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14535         BEFORE=$(roc_hit)
14536         cancel_lru_locks osc
14537         cat $file >/dev/null
14538         AFTER=$(roc_hit)
14539         if ! let "AFTER - BEFORE == CPAGES"; then
14540                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14541         else
14542                 log "cache hits: before: $BEFORE, after: $AFTER"
14543         fi
14544
14545         log "Read again; it should be satisfied from the cache."
14546         BEFORE=$AFTER
14547         cancel_lru_locks osc
14548         cat $file >/dev/null
14549         AFTER=$(roc_hit)
14550         if ! let "AFTER - BEFORE == CPAGES"; then
14551                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14552         else
14553                 log "cache hits:: before: $BEFORE, after: $AFTER"
14554         fi
14555
14556         log "Turn off the read cache and turn on the write cache"
14557         set_cache read off
14558         set_cache writethrough on
14559
14560         log "Read again; it should be satisfied from the cache."
14561         BEFORE=$(roc_hit)
14562         cancel_lru_locks osc
14563         cat $file >/dev/null
14564         AFTER=$(roc_hit)
14565         if ! let "AFTER - BEFORE == CPAGES"; then
14566                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14567         else
14568                 log "cache hits:: before: $BEFORE, after: $AFTER"
14569         fi
14570
14571         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14572                 # > 2.12.56 uses pagecache if cached
14573                 log "Read again; it should not be satisfied from the cache."
14574                 BEFORE=$AFTER
14575                 cancel_lru_locks osc
14576                 cat $file >/dev/null
14577                 AFTER=$(roc_hit)
14578                 if ! let "AFTER - BEFORE == 0"; then
14579                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14580                 else
14581                         log "cache hits:: before: $BEFORE, after: $AFTER"
14582                 fi
14583         fi
14584
14585         log "Write data and read it back."
14586         log "Read should be satisfied from the cache."
14587         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14588         BEFORE=$(roc_hit)
14589         cancel_lru_locks osc
14590         cat $file >/dev/null
14591         AFTER=$(roc_hit)
14592         if ! let "AFTER - BEFORE == CPAGES"; then
14593                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14594         else
14595                 log "cache hits:: before: $BEFORE, after: $AFTER"
14596         fi
14597
14598         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14599                 # > 2.12.56 uses pagecache if cached
14600                 log "Read again; it should not be satisfied from the cache."
14601                 BEFORE=$AFTER
14602                 cancel_lru_locks osc
14603                 cat $file >/dev/null
14604                 AFTER=$(roc_hit)
14605                 if ! let "AFTER - BEFORE == 0"; then
14606                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14607                 else
14608                         log "cache hits:: before: $BEFORE, after: $AFTER"
14609                 fi
14610         fi
14611
14612         log "Turn off read and write cache"
14613         set_cache read off
14614         set_cache writethrough off
14615
14616         log "Write data and read it back"
14617         log "It should not be satisfied from the cache."
14618         rm -f $file
14619         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14620         cancel_lru_locks osc
14621         BEFORE=$(roc_hit)
14622         cat $file >/dev/null
14623         AFTER=$(roc_hit)
14624         if ! let "AFTER - BEFORE == 0"; then
14625                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14626         else
14627                 log "cache hits:: before: $BEFORE, after: $AFTER"
14628         fi
14629
14630         log "Turn on the read cache and turn off the write cache"
14631         set_cache read on
14632         set_cache writethrough off
14633
14634         log "Write data and read it back"
14635         log "It should not be satisfied from the cache."
14636         rm -f $file
14637         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14638         BEFORE=$(roc_hit)
14639         cancel_lru_locks osc
14640         cat $file >/dev/null
14641         AFTER=$(roc_hit)
14642         if ! let "AFTER - BEFORE == 0"; then
14643                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14644         else
14645                 log "cache hits:: before: $BEFORE, after: $AFTER"
14646         fi
14647
14648         log "Read again; it should be satisfied from the cache."
14649         BEFORE=$(roc_hit)
14650         cancel_lru_locks osc
14651         cat $file >/dev/null
14652         AFTER=$(roc_hit)
14653         if ! let "AFTER - BEFORE == CPAGES"; then
14654                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14655         else
14656                 log "cache hits:: before: $BEFORE, after: $AFTER"
14657         fi
14658
14659         restore_lustre_params < $p
14660         rm -f $p $file
14661 }
14662 run_test 156 "Verification of tunables"
14663
14664 test_160a() {
14665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14666         remote_mds_nodsh && skip "remote MDS with nodsh"
14667         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14668                 skip "Need MDS version at least 2.2.0"
14669
14670         changelog_register || error "changelog_register failed"
14671         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14672         changelog_users $SINGLEMDS | grep -q $cl_user ||
14673                 error "User $cl_user not found in changelog_users"
14674
14675         # change something
14676         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14677         changelog_clear 0 || error "changelog_clear failed"
14678         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14679         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14680         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14681         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14682         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14683         rm $DIR/$tdir/pics/desktop.jpg
14684
14685         changelog_dump | tail -10
14686
14687         echo "verifying changelog mask"
14688         changelog_chmask "-MKDIR"
14689         changelog_chmask "-CLOSE"
14690
14691         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14692         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14693
14694         changelog_chmask "+MKDIR"
14695         changelog_chmask "+CLOSE"
14696
14697         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14698         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14699
14700         changelog_dump | tail -10
14701         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14702         CLOSES=$(changelog_dump | grep -c "CLOSE")
14703         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14704         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14705
14706         # verify contents
14707         echo "verifying target fid"
14708         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14709         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14710         [ "$fidc" == "$fidf" ] ||
14711                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14712         echo "verifying parent fid"
14713         # The FID returned from the Changelog may be the directory shard on
14714         # a different MDT, and not the FID returned by path2fid on the parent.
14715         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14716         # since this is what will matter when recreating this file in the tree.
14717         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14718         local pathp=$($LFS fid2path $MOUNT "$fidp")
14719         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14720                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14721
14722         echo "getting records for $cl_user"
14723         changelog_users $SINGLEMDS
14724         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14725         local nclr=3
14726         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14727                 error "changelog_clear failed"
14728         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14729         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14730         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14731                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14732
14733         local min0_rec=$(changelog_users $SINGLEMDS |
14734                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14735         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14736                           awk '{ print $1; exit; }')
14737
14738         changelog_dump | tail -n 5
14739         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14740         [ $first_rec == $((min0_rec + 1)) ] ||
14741                 error "first index should be $min0_rec + 1 not $first_rec"
14742
14743         # LU-3446 changelog index reset on MDT restart
14744         local cur_rec1=$(changelog_users $SINGLEMDS |
14745                          awk '/^current.index:/ { print $NF }')
14746         changelog_clear 0 ||
14747                 error "clear all changelog records for $cl_user failed"
14748         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14749         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14750                 error "Fail to start $SINGLEMDS"
14751         local cur_rec2=$(changelog_users $SINGLEMDS |
14752                          awk '/^current.index:/ { print $NF }')
14753         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14754         [ $cur_rec1 == $cur_rec2 ] ||
14755                 error "current index should be $cur_rec1 not $cur_rec2"
14756
14757         echo "verifying users from this test are deregistered"
14758         changelog_deregister || error "changelog_deregister failed"
14759         changelog_users $SINGLEMDS | grep -q $cl_user &&
14760                 error "User '$cl_user' still in changelog_users"
14761
14762         # lctl get_param -n mdd.*.changelog_users
14763         # current index: 144
14764         # ID    index (idle seconds)
14765         # cl3   144 (2)
14766         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14767                 # this is the normal case where all users were deregistered
14768                 # make sure no new records are added when no users are present
14769                 local last_rec1=$(changelog_users $SINGLEMDS |
14770                                   awk '/^current.index:/ { print $NF }')
14771                 touch $DIR/$tdir/chloe
14772                 local last_rec2=$(changelog_users $SINGLEMDS |
14773                                   awk '/^current.index:/ { print $NF }')
14774                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14775                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14776         else
14777                 # any changelog users must be leftovers from a previous test
14778                 changelog_users $SINGLEMDS
14779                 echo "other changelog users; can't verify off"
14780         fi
14781 }
14782 run_test 160a "changelog sanity"
14783
14784 test_160b() { # LU-3587
14785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14786         remote_mds_nodsh && skip "remote MDS with nodsh"
14787         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14788                 skip "Need MDS version at least 2.2.0"
14789
14790         changelog_register || error "changelog_register failed"
14791         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14792         changelog_users $SINGLEMDS | grep -q $cl_user ||
14793                 error "User '$cl_user' not found in changelog_users"
14794
14795         local longname1=$(str_repeat a 255)
14796         local longname2=$(str_repeat b 255)
14797
14798         cd $DIR
14799         echo "creating very long named file"
14800         touch $longname1 || error "create of '$longname1' failed"
14801         echo "renaming very long named file"
14802         mv $longname1 $longname2
14803
14804         changelog_dump | grep RENME | tail -n 5
14805         rm -f $longname2
14806 }
14807 run_test 160b "Verify that very long rename doesn't crash in changelog"
14808
14809 test_160c() {
14810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14811         remote_mds_nodsh && skip "remote MDS with nodsh"
14812
14813         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14814                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14815                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14816                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14817
14818         local rc=0
14819
14820         # Registration step
14821         changelog_register || error "changelog_register failed"
14822
14823         rm -rf $DIR/$tdir
14824         mkdir -p $DIR/$tdir
14825         $MCREATE $DIR/$tdir/foo_160c
14826         changelog_chmask "-TRUNC"
14827         $TRUNCATE $DIR/$tdir/foo_160c 200
14828         changelog_chmask "+TRUNC"
14829         $TRUNCATE $DIR/$tdir/foo_160c 199
14830         changelog_dump | tail -n 5
14831         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14832         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14833 }
14834 run_test 160c "verify that changelog log catch the truncate event"
14835
14836 test_160d() {
14837         remote_mds_nodsh && skip "remote MDS with nodsh"
14838         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14840         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14841                 skip "Need MDS version at least 2.7.60"
14842
14843         # Registration step
14844         changelog_register || error "changelog_register failed"
14845
14846         mkdir -p $DIR/$tdir/migrate_dir
14847         changelog_clear 0 || error "changelog_clear failed"
14848
14849         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14850         changelog_dump | tail -n 5
14851         local migrates=$(changelog_dump | grep -c "MIGRT")
14852         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14853 }
14854 run_test 160d "verify that changelog log catch the migrate event"
14855
14856 test_160e() {
14857         remote_mds_nodsh && skip "remote MDS with nodsh"
14858
14859         # Create a user
14860         changelog_register || error "changelog_register failed"
14861
14862         # Delete a future user (expect fail)
14863         local MDT0=$(facet_svc $SINGLEMDS)
14864         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14865         local rc=$?
14866
14867         if [ $rc -eq 0 ]; then
14868                 error "Deleted non-existant user cl77"
14869         elif [ $rc -ne 2 ]; then
14870                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14871         fi
14872
14873         # Clear to a bad index (1 billion should be safe)
14874         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14875         rc=$?
14876
14877         if [ $rc -eq 0 ]; then
14878                 error "Successfully cleared to invalid CL index"
14879         elif [ $rc -ne 22 ]; then
14880                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14881         fi
14882 }
14883 run_test 160e "changelog negative testing (should return errors)"
14884
14885 test_160f() {
14886         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14887         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14888                 skip "Need MDS version at least 2.10.56"
14889
14890         local mdts=$(comma_list $(mdts_nodes))
14891
14892         # Create a user
14893         changelog_register || error "first changelog_register failed"
14894         changelog_register || error "second changelog_register failed"
14895         local cl_users
14896         declare -A cl_user1
14897         declare -A cl_user2
14898         local user_rec1
14899         local user_rec2
14900         local i
14901
14902         # generate some changelog records to accumulate on each MDT
14903         # use fnv1a because created files should be evenly distributed
14904         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14905                 error "test_mkdir $tdir failed"
14906         log "$(date +%s): creating first files"
14907         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14908                 error "create $DIR/$tdir/$tfile failed"
14909
14910         # check changelogs have been generated
14911         local start=$SECONDS
14912         local idle_time=$((MDSCOUNT * 5 + 5))
14913         local nbcl=$(changelog_dump | wc -l)
14914         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14915
14916         for param in "changelog_max_idle_time=$idle_time" \
14917                      "changelog_gc=1" \
14918                      "changelog_min_gc_interval=2" \
14919                      "changelog_min_free_cat_entries=3"; do
14920                 local MDT0=$(facet_svc $SINGLEMDS)
14921                 local var="${param%=*}"
14922                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14923
14924                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14925                 do_nodes $mdts $LCTL set_param mdd.*.$param
14926         done
14927
14928         # force cl_user2 to be idle (1st part), but also cancel the
14929         # cl_user1 records so that it is not evicted later in the test.
14930         local sleep1=$((idle_time / 2))
14931         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14932         sleep $sleep1
14933
14934         # simulate changelog catalog almost full
14935         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14936         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14937
14938         for i in $(seq $MDSCOUNT); do
14939                 cl_users=(${CL_USERS[mds$i]})
14940                 cl_user1[mds$i]="${cl_users[0]}"
14941                 cl_user2[mds$i]="${cl_users[1]}"
14942
14943                 [ -n "${cl_user1[mds$i]}" ] ||
14944                         error "mds$i: no user registered"
14945                 [ -n "${cl_user2[mds$i]}" ] ||
14946                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14947
14948                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14949                 [ -n "$user_rec1" ] ||
14950                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14951                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14952                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14953                 [ -n "$user_rec2" ] ||
14954                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14955                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14956                      "$user_rec1 + 2 == $user_rec2"
14957                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14958                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14959                               "$user_rec1 + 2, but is $user_rec2"
14960                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14961                 [ -n "$user_rec2" ] ||
14962                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14963                 [ $user_rec1 == $user_rec2 ] ||
14964                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14965                               "$user_rec1, but is $user_rec2"
14966         done
14967
14968         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14969         local sleep2=$((idle_time - (SECONDS - start) + 1))
14970         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14971         sleep $sleep2
14972
14973         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14974         # cl_user1 should be OK because it recently processed records.
14975         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14976         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14977                 error "create $DIR/$tdir/${tfile}b failed"
14978
14979         # ensure gc thread is done
14980         for i in $(mdts_nodes); do
14981                 wait_update $i \
14982                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14983                         error "$i: GC-thread not done"
14984         done
14985
14986         local first_rec
14987         for i in $(seq $MDSCOUNT); do
14988                 # check cl_user1 still registered
14989                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14990                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14991                 # check cl_user2 unregistered
14992                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14993                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14994
14995                 # check changelogs are present and starting at $user_rec1 + 1
14996                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14997                 [ -n "$user_rec1" ] ||
14998                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14999                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15000                             awk '{ print $1; exit; }')
15001
15002                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15003                 [ $((user_rec1 + 1)) == $first_rec ] ||
15004                         error "mds$i: first index should be $user_rec1 + 1, " \
15005                               "but is $first_rec"
15006         done
15007 }
15008 run_test 160f "changelog garbage collect (timestamped users)"
15009
15010 test_160g() {
15011         remote_mds_nodsh && skip "remote MDS with nodsh"
15012         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15013                 skip "Need MDS version at least 2.10.56"
15014
15015         local mdts=$(comma_list $(mdts_nodes))
15016
15017         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15018         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15019
15020         # Create a user
15021         changelog_register || error "first changelog_register failed"
15022         changelog_register || error "second changelog_register failed"
15023         local cl_users
15024         declare -A cl_user1
15025         declare -A cl_user2
15026         local user_rec1
15027         local user_rec2
15028         local i
15029
15030         # generate some changelog records to accumulate on each MDT
15031         # use fnv1a because created files should be evenly distributed
15032         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15033                 error "mkdir $tdir failed"
15034         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15035                 error "create $DIR/$tdir/$tfile failed"
15036
15037         # check changelogs have been generated
15038         local nbcl=$(changelog_dump | wc -l)
15039         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15040
15041         # reduce the max_idle_indexes value to make sure we exceed it
15042         max_ndx=$((nbcl / 2 - 1))
15043
15044         for param in "changelog_max_idle_indexes=$max_ndx" \
15045                      "changelog_gc=1" \
15046                      "changelog_min_gc_interval=2" \
15047                      "changelog_min_free_cat_entries=3"; do
15048                 local MDT0=$(facet_svc $SINGLEMDS)
15049                 local var="${param%=*}"
15050                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15051
15052                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15053                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15054                         error "unable to set mdd.*.$param"
15055         done
15056
15057         # simulate changelog catalog almost full
15058         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15059         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
15060
15061         for i in $(seq $MDSCOUNT); do
15062                 cl_users=(${CL_USERS[mds$i]})
15063                 cl_user1[mds$i]="${cl_users[0]}"
15064                 cl_user2[mds$i]="${cl_users[1]}"
15065
15066                 [ -n "${cl_user1[mds$i]}" ] ||
15067                         error "mds$i: no user registered"
15068                 [ -n "${cl_user2[mds$i]}" ] ||
15069                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15070
15071                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15072                 [ -n "$user_rec1" ] ||
15073                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15074                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15075                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15076                 [ -n "$user_rec2" ] ||
15077                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15078                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15079                      "$user_rec1 + 2 == $user_rec2"
15080                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15081                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15082                               "$user_rec1 + 2, but is $user_rec2"
15083                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15084                 [ -n "$user_rec2" ] ||
15085                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15086                 [ $user_rec1 == $user_rec2 ] ||
15087                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15088                               "$user_rec1, but is $user_rec2"
15089         done
15090
15091         # ensure we are past the previous changelog_min_gc_interval set above
15092         sleep 2
15093
15094         # generate one more changelog to trigger fail_loc
15095         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15096                 error "create $DIR/$tdir/${tfile}bis failed"
15097
15098         # ensure gc thread is done
15099         for i in $(mdts_nodes); do
15100                 wait_update $i \
15101                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15102                         error "$i: GC-thread not done"
15103         done
15104
15105         local first_rec
15106         for i in $(seq $MDSCOUNT); do
15107                 # check cl_user1 still registered
15108                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15109                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15110                 # check cl_user2 unregistered
15111                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15112                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15113
15114                 # check changelogs are present and starting at $user_rec1 + 1
15115                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15116                 [ -n "$user_rec1" ] ||
15117                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15118                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15119                             awk '{ print $1; exit; }')
15120
15121                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15122                 [ $((user_rec1 + 1)) == $first_rec ] ||
15123                         error "mds$i: first index should be $user_rec1 + 1, " \
15124                               "but is $first_rec"
15125         done
15126 }
15127 run_test 160g "changelog garbage collect (old users)"
15128
15129 test_160h() {
15130         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15131         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15132                 skip "Need MDS version at least 2.10.56"
15133
15134         local mdts=$(comma_list $(mdts_nodes))
15135
15136         # Create a user
15137         changelog_register || error "first changelog_register failed"
15138         changelog_register || error "second changelog_register failed"
15139         local cl_users
15140         declare -A cl_user1
15141         declare -A cl_user2
15142         local user_rec1
15143         local user_rec2
15144         local i
15145
15146         # generate some changelog records to accumulate on each MDT
15147         # use fnv1a because created files should be evenly distributed
15148         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15149                 error "test_mkdir $tdir failed"
15150         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15151                 error "create $DIR/$tdir/$tfile failed"
15152
15153         # check changelogs have been generated
15154         local nbcl=$(changelog_dump | wc -l)
15155         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15156
15157         for param in "changelog_max_idle_time=10" \
15158                      "changelog_gc=1" \
15159                      "changelog_min_gc_interval=2"; do
15160                 local MDT0=$(facet_svc $SINGLEMDS)
15161                 local var="${param%=*}"
15162                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15163
15164                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15165                 do_nodes $mdts $LCTL set_param mdd.*.$param
15166         done
15167
15168         # force cl_user2 to be idle (1st part)
15169         sleep 9
15170
15171         for i in $(seq $MDSCOUNT); do
15172                 cl_users=(${CL_USERS[mds$i]})
15173                 cl_user1[mds$i]="${cl_users[0]}"
15174                 cl_user2[mds$i]="${cl_users[1]}"
15175
15176                 [ -n "${cl_user1[mds$i]}" ] ||
15177                         error "mds$i: no user registered"
15178                 [ -n "${cl_user2[mds$i]}" ] ||
15179                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15180
15181                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15182                 [ -n "$user_rec1" ] ||
15183                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15184                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15185                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15186                 [ -n "$user_rec2" ] ||
15187                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15188                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15189                      "$user_rec1 + 2 == $user_rec2"
15190                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15191                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15192                               "$user_rec1 + 2, but is $user_rec2"
15193                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15194                 [ -n "$user_rec2" ] ||
15195                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15196                 [ $user_rec1 == $user_rec2 ] ||
15197                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15198                               "$user_rec1, but is $user_rec2"
15199         done
15200
15201         # force cl_user2 to be idle (2nd part) and to reach
15202         # changelog_max_idle_time
15203         sleep 2
15204
15205         # force each GC-thread start and block then
15206         # one per MDT/MDD, set fail_val accordingly
15207         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15208         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15209
15210         # generate more changelogs to trigger fail_loc
15211         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15212                 error "create $DIR/$tdir/${tfile}bis failed"
15213
15214         # stop MDT to stop GC-thread, should be done in back-ground as it will
15215         # block waiting for the thread to be released and exit
15216         declare -A stop_pids
15217         for i in $(seq $MDSCOUNT); do
15218                 stop mds$i &
15219                 stop_pids[mds$i]=$!
15220         done
15221
15222         for i in $(mdts_nodes); do
15223                 local facet
15224                 local nb=0
15225                 local facets=$(facets_up_on_host $i)
15226
15227                 for facet in ${facets//,/ }; do
15228                         if [[ $facet == mds* ]]; then
15229                                 nb=$((nb + 1))
15230                         fi
15231                 done
15232                 # ensure each MDS's gc threads are still present and all in "R"
15233                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15234                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15235                         error "$i: expected $nb GC-thread"
15236                 wait_update $i \
15237                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15238                         "R" 20 ||
15239                         error "$i: GC-thread not found in R-state"
15240                 # check umounts of each MDT on MDS have reached kthread_stop()
15241                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15242                         error "$i: expected $nb umount"
15243                 wait_update $i \
15244                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15245                         error "$i: umount not found in D-state"
15246         done
15247
15248         # release all GC-threads
15249         do_nodes $mdts $LCTL set_param fail_loc=0
15250
15251         # wait for MDT stop to complete
15252         for i in $(seq $MDSCOUNT); do
15253                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15254         done
15255
15256         # XXX
15257         # may try to check if any orphan changelog records are present
15258         # via ldiskfs/zfs and llog_reader...
15259
15260         # re-start/mount MDTs
15261         for i in $(seq $MDSCOUNT); do
15262                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15263                         error "Fail to start mds$i"
15264         done
15265
15266         local first_rec
15267         for i in $(seq $MDSCOUNT); do
15268                 # check cl_user1 still registered
15269                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15270                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15271                 # check cl_user2 unregistered
15272                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15273                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15274
15275                 # check changelogs are present and starting at $user_rec1 + 1
15276                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15277                 [ -n "$user_rec1" ] ||
15278                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15279                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15280                             awk '{ print $1; exit; }')
15281
15282                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15283                 [ $((user_rec1 + 1)) == $first_rec ] ||
15284                         error "mds$i: first index should be $user_rec1 + 1, " \
15285                               "but is $first_rec"
15286         done
15287 }
15288 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15289               "during mount"
15290
15291 test_160i() {
15292
15293         local mdts=$(comma_list $(mdts_nodes))
15294
15295         changelog_register || error "first changelog_register failed"
15296
15297         # generate some changelog records to accumulate on each MDT
15298         # use fnv1a because created files should be evenly distributed
15299         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15300                 error "mkdir $tdir failed"
15301         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15302                 error "create $DIR/$tdir/$tfile failed"
15303
15304         # check changelogs have been generated
15305         local nbcl=$(changelog_dump | wc -l)
15306         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15307
15308         # simulate race between register and unregister
15309         # XXX as fail_loc is set per-MDS, with DNE configs the race
15310         # simulation will only occur for one MDT per MDS and for the
15311         # others the normal race scenario will take place
15312         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15313         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15314         do_nodes $mdts $LCTL set_param fail_val=1
15315
15316         # unregister 1st user
15317         changelog_deregister &
15318         local pid1=$!
15319         # wait some time for deregister work to reach race rdv
15320         sleep 2
15321         # register 2nd user
15322         changelog_register || error "2nd user register failed"
15323
15324         wait $pid1 || error "1st user deregister failed"
15325
15326         local i
15327         local last_rec
15328         declare -A LAST_REC
15329         for i in $(seq $MDSCOUNT); do
15330                 if changelog_users mds$i | grep "^cl"; then
15331                         # make sure new records are added with one user present
15332                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15333                                           awk '/^current.index:/ { print $NF }')
15334                 else
15335                         error "mds$i has no user registered"
15336                 fi
15337         done
15338
15339         # generate more changelog records to accumulate on each MDT
15340         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15341                 error "create $DIR/$tdir/${tfile}bis failed"
15342
15343         for i in $(seq $MDSCOUNT); do
15344                 last_rec=$(changelog_users $SINGLEMDS |
15345                            awk '/^current.index:/ { print $NF }')
15346                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15347                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15348                         error "changelogs are off on mds$i"
15349         done
15350 }
15351 run_test 160i "changelog user register/unregister race"
15352
15353 test_160j() {
15354         remote_mds_nodsh && skip "remote MDS with nodsh"
15355         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15356                 skip "Need MDS version at least 2.12.56"
15357
15358         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15359         stack_trap "umount $MOUNT2" EXIT
15360
15361         changelog_register || error "first changelog_register failed"
15362         stack_trap "changelog_deregister" EXIT
15363
15364         # generate some changelog
15365         # use fnv1a because created files should be evenly distributed
15366         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15367                 error "mkdir $tdir failed"
15368         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15369                 error "create $DIR/$tdir/${tfile}bis failed"
15370
15371         # open the changelog device
15372         exec 3>/dev/changelog-$FSNAME-MDT0000
15373         stack_trap "exec 3>&-" EXIT
15374         exec 4</dev/changelog-$FSNAME-MDT0000
15375         stack_trap "exec 4<&-" EXIT
15376
15377         # umount the first lustre mount
15378         umount $MOUNT
15379         stack_trap "mount_client $MOUNT" EXIT
15380
15381         # read changelog, which may or may not fail, but should not crash
15382         cat <&4 >/dev/null
15383
15384         # clear changelog
15385         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15386         changelog_users $SINGLEMDS | grep -q $cl_user ||
15387                 error "User $cl_user not found in changelog_users"
15388
15389         printf 'clear:'$cl_user':0' >&3
15390 }
15391 run_test 160j "client can be umounted while its chanangelog is being used"
15392
15393 test_160k() {
15394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15395         remote_mds_nodsh && skip "remote MDS with nodsh"
15396
15397         mkdir -p $DIR/$tdir/1/1
15398
15399         changelog_register || error "changelog_register failed"
15400         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15401
15402         changelog_users $SINGLEMDS | grep -q $cl_user ||
15403                 error "User '$cl_user' not found in changelog_users"
15404 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15405         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15406         rmdir $DIR/$tdir/1/1 & sleep 1
15407         mkdir $DIR/$tdir/2
15408         touch $DIR/$tdir/2/2
15409         rm -rf $DIR/$tdir/2
15410
15411         wait
15412         sleep 4
15413
15414         changelog_dump | grep rmdir || error "rmdir not recorded"
15415
15416         rm -rf $DIR/$tdir
15417         changelog_deregister
15418 }
15419 run_test 160k "Verify that changelog records are not lost"
15420
15421 # Verifies that a file passed as a parameter has recently had an operation
15422 # performed on it that has generated an MTIME changelog which contains the
15423 # correct parent FID. As files might reside on a different MDT from the
15424 # parent directory in DNE configurations, the FIDs are translated to paths
15425 # before being compared, which should be identical
15426 compare_mtime_changelog() {
15427         local file="${1}"
15428         local mdtidx
15429         local mtime
15430         local cl_fid
15431         local pdir
15432         local dir
15433
15434         mdtidx=$($LFS getstripe --mdt-index $file)
15435         mdtidx=$(printf "%04x" $mdtidx)
15436
15437         # Obtain the parent FID from the MTIME changelog
15438         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15439         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15440
15441         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15442         [ -z "$cl_fid" ] && error "parent FID not present"
15443
15444         # Verify that the path for the parent FID is the same as the path for
15445         # the test directory
15446         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15447
15448         dir=$(dirname $1)
15449
15450         [[ "${pdir%/}" == "$dir" ]] ||
15451                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15452 }
15453
15454 test_160l() {
15455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15456
15457         remote_mds_nodsh && skip "remote MDS with nodsh"
15458         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15459                 skip "Need MDS version at least 2.13.55"
15460
15461         local cl_user
15462
15463         changelog_register || error "changelog_register failed"
15464         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15465
15466         changelog_users $SINGLEMDS | grep -q $cl_user ||
15467                 error "User '$cl_user' not found in changelog_users"
15468
15469         # Clear some types so that MTIME changelogs are generated
15470         changelog_chmask "-CREAT"
15471         changelog_chmask "-CLOSE"
15472
15473         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15474
15475         # Test CL_MTIME during setattr
15476         touch $DIR/$tdir/$tfile
15477         compare_mtime_changelog $DIR/$tdir/$tfile
15478
15479         # Test CL_MTIME during close
15480         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15481         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15482 }
15483 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15484
15485 test_161a() {
15486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15487
15488         test_mkdir -c1 $DIR/$tdir
15489         cp /etc/hosts $DIR/$tdir/$tfile
15490         test_mkdir -c1 $DIR/$tdir/foo1
15491         test_mkdir -c1 $DIR/$tdir/foo2
15492         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15493         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15494         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15495         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15496         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15497         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15498                 $LFS fid2path $DIR $FID
15499                 error "bad link ea"
15500         fi
15501         # middle
15502         rm $DIR/$tdir/foo2/zachary
15503         # last
15504         rm $DIR/$tdir/foo2/thor
15505         # first
15506         rm $DIR/$tdir/$tfile
15507         # rename
15508         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15509         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15510                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15511         rm $DIR/$tdir/foo2/maggie
15512
15513         # overflow the EA
15514         local longname=$tfile.avg_len_is_thirty_two_
15515         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15516                 error_noexit 'failed to unlink many hardlinks'" EXIT
15517         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15518                 error "failed to hardlink many files"
15519         links=$($LFS fid2path $DIR $FID | wc -l)
15520         echo -n "${links}/1000 links in link EA"
15521         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15522 }
15523 run_test 161a "link ea sanity"
15524
15525 test_161b() {
15526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15527         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15528
15529         local MDTIDX=1
15530         local remote_dir=$DIR/$tdir/remote_dir
15531
15532         mkdir -p $DIR/$tdir
15533         $LFS mkdir -i $MDTIDX $remote_dir ||
15534                 error "create remote directory failed"
15535
15536         cp /etc/hosts $remote_dir/$tfile
15537         mkdir -p $remote_dir/foo1
15538         mkdir -p $remote_dir/foo2
15539         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15540         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15541         ln $remote_dir/$tfile $remote_dir/foo1/luna
15542         ln $remote_dir/$tfile $remote_dir/foo2/thor
15543
15544         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15545                      tr -d ']')
15546         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15547                 $LFS fid2path $DIR $FID
15548                 error "bad link ea"
15549         fi
15550         # middle
15551         rm $remote_dir/foo2/zachary
15552         # last
15553         rm $remote_dir/foo2/thor
15554         # first
15555         rm $remote_dir/$tfile
15556         # rename
15557         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15558         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15559         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15560                 $LFS fid2path $DIR $FID
15561                 error "bad link rename"
15562         fi
15563         rm $remote_dir/foo2/maggie
15564
15565         # overflow the EA
15566         local longname=filename_avg_len_is_thirty_two_
15567         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15568                 error "failed to hardlink many files"
15569         links=$($LFS fid2path $DIR $FID | wc -l)
15570         echo -n "${links}/1000 links in link EA"
15571         [[ ${links} -gt 60 ]] ||
15572                 error "expected at least 60 links in link EA"
15573         unlinkmany $remote_dir/foo2/$longname 1000 ||
15574         error "failed to unlink many hardlinks"
15575 }
15576 run_test 161b "link ea sanity under remote directory"
15577
15578 test_161c() {
15579         remote_mds_nodsh && skip "remote MDS with nodsh"
15580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15581         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15582                 skip "Need MDS version at least 2.1.5"
15583
15584         # define CLF_RENAME_LAST 0x0001
15585         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15586         changelog_register || error "changelog_register failed"
15587
15588         rm -rf $DIR/$tdir
15589         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15590         touch $DIR/$tdir/foo_161c
15591         touch $DIR/$tdir/bar_161c
15592         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15593         changelog_dump | grep RENME | tail -n 5
15594         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15595         changelog_clear 0 || error "changelog_clear failed"
15596         if [ x$flags != "x0x1" ]; then
15597                 error "flag $flags is not 0x1"
15598         fi
15599
15600         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15601         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15602         touch $DIR/$tdir/foo_161c
15603         touch $DIR/$tdir/bar_161c
15604         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15605         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15606         changelog_dump | grep RENME | tail -n 5
15607         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15608         changelog_clear 0 || error "changelog_clear failed"
15609         if [ x$flags != "x0x0" ]; then
15610                 error "flag $flags is not 0x0"
15611         fi
15612         echo "rename overwrite a target having nlink > 1," \
15613                 "changelog record has flags of $flags"
15614
15615         # rename doesn't overwrite a target (changelog flag 0x0)
15616         touch $DIR/$tdir/foo_161c
15617         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15618         changelog_dump | grep RENME | tail -n 5
15619         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15620         changelog_clear 0 || error "changelog_clear failed"
15621         if [ x$flags != "x0x0" ]; then
15622                 error "flag $flags is not 0x0"
15623         fi
15624         echo "rename doesn't overwrite a target," \
15625                 "changelog record has flags of $flags"
15626
15627         # define CLF_UNLINK_LAST 0x0001
15628         # unlink a file having nlink = 1 (changelog flag 0x1)
15629         rm -f $DIR/$tdir/foo2_161c
15630         changelog_dump | grep UNLNK | tail -n 5
15631         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15632         changelog_clear 0 || error "changelog_clear failed"
15633         if [ x$flags != "x0x1" ]; then
15634                 error "flag $flags is not 0x1"
15635         fi
15636         echo "unlink a file having nlink = 1," \
15637                 "changelog record has flags of $flags"
15638
15639         # unlink a file having nlink > 1 (changelog flag 0x0)
15640         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15641         rm -f $DIR/$tdir/foobar_161c
15642         changelog_dump | grep UNLNK | tail -n 5
15643         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15644         changelog_clear 0 || error "changelog_clear failed"
15645         if [ x$flags != "x0x0" ]; then
15646                 error "flag $flags is not 0x0"
15647         fi
15648         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15649 }
15650 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15651
15652 test_161d() {
15653         remote_mds_nodsh && skip "remote MDS with nodsh"
15654         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15655
15656         local pid
15657         local fid
15658
15659         changelog_register || error "changelog_register failed"
15660
15661         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15662         # interfer with $MOUNT/.lustre/fid/ access
15663         mkdir $DIR/$tdir
15664         [[ $? -eq 0 ]] || error "mkdir failed"
15665
15666         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15667         $LCTL set_param fail_loc=0x8000140c
15668         # 5s pause
15669         $LCTL set_param fail_val=5
15670
15671         # create file
15672         echo foofoo > $DIR/$tdir/$tfile &
15673         pid=$!
15674
15675         # wait for create to be delayed
15676         sleep 2
15677
15678         ps -p $pid
15679         [[ $? -eq 0 ]] || error "create should be blocked"
15680
15681         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15682         stack_trap "rm -f $tempfile"
15683         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15684         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15685         # some delay may occur during ChangeLog publishing and file read just
15686         # above, that could allow file write to happen finally
15687         [[ -s $tempfile ]] && echo "file should be empty"
15688
15689         $LCTL set_param fail_loc=0
15690
15691         wait $pid
15692         [[ $? -eq 0 ]] || error "create failed"
15693 }
15694 run_test 161d "create with concurrent .lustre/fid access"
15695
15696 check_path() {
15697         local expected="$1"
15698         shift
15699         local fid="$2"
15700
15701         local path
15702         path=$($LFS fid2path "$@")
15703         local rc=$?
15704
15705         if [ $rc -ne 0 ]; then
15706                 error "path looked up of '$expected' failed: rc=$rc"
15707         elif [ "$path" != "$expected" ]; then
15708                 error "path looked up '$path' instead of '$expected'"
15709         else
15710                 echo "FID '$fid' resolves to path '$path' as expected"
15711         fi
15712 }
15713
15714 test_162a() { # was test_162
15715         test_mkdir -p -c1 $DIR/$tdir/d2
15716         touch $DIR/$tdir/d2/$tfile
15717         touch $DIR/$tdir/d2/x1
15718         touch $DIR/$tdir/d2/x2
15719         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15720         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15721         # regular file
15722         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15723         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15724
15725         # softlink
15726         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15727         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15728         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15729
15730         # softlink to wrong file
15731         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15732         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15733         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15734
15735         # hardlink
15736         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15737         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15738         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15739         # fid2path dir/fsname should both work
15740         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15741         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15742
15743         # hardlink count: check that there are 2 links
15744         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15745         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15746
15747         # hardlink indexing: remove the first link
15748         rm $DIR/$tdir/d2/p/q/r/hlink
15749         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15750 }
15751 run_test 162a "path lookup sanity"
15752
15753 test_162b() {
15754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15755         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15756
15757         mkdir $DIR/$tdir
15758         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15759                                 error "create striped dir failed"
15760
15761         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15762                                         tail -n 1 | awk '{print $2}')
15763         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15764
15765         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15766         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15767
15768         # regular file
15769         for ((i=0;i<5;i++)); do
15770                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15771                         error "get fid for f$i failed"
15772                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15773
15774                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15775                         error "get fid for d$i failed"
15776                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15777         done
15778
15779         return 0
15780 }
15781 run_test 162b "striped directory path lookup sanity"
15782
15783 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15784 test_162c() {
15785         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15786                 skip "Need MDS version at least 2.7.51"
15787
15788         local lpath=$tdir.local
15789         local rpath=$tdir.remote
15790
15791         test_mkdir $DIR/$lpath
15792         test_mkdir $DIR/$rpath
15793
15794         for ((i = 0; i <= 101; i++)); do
15795                 lpath="$lpath/$i"
15796                 mkdir $DIR/$lpath
15797                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15798                         error "get fid for local directory $DIR/$lpath failed"
15799                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15800
15801                 rpath="$rpath/$i"
15802                 test_mkdir $DIR/$rpath
15803                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15804                         error "get fid for remote directory $DIR/$rpath failed"
15805                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15806         done
15807
15808         return 0
15809 }
15810 run_test 162c "fid2path works with paths 100 or more directories deep"
15811
15812 oalr_event_count() {
15813         local event="${1}"
15814         local trace="${2}"
15815
15816         awk -v name="${FSNAME}-OST0000" \
15817             -v event="${event}" \
15818             '$1 == "TRACE" && $2 == event && $3 == name' \
15819             "${trace}" |
15820         wc -l
15821 }
15822
15823 oalr_expect_event_count() {
15824         local event="${1}"
15825         local trace="${2}"
15826         local expect="${3}"
15827         local count
15828
15829         count=$(oalr_event_count "${event}" "${trace}")
15830         if ((count == expect)); then
15831                 return 0
15832         fi
15833
15834         error_noexit "${event} event count was '${count}', expected ${expect}"
15835         cat "${trace}" >&2
15836         exit 1
15837 }
15838
15839 cleanup_165() {
15840         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15841         stop ost1
15842         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15843 }
15844
15845 setup_165() {
15846         sync # Flush previous IOs so we can count log entries.
15847         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15848         stack_trap cleanup_165 EXIT
15849 }
15850
15851 test_165a() {
15852         local trace="/tmp/${tfile}.trace"
15853         local rc
15854         local count
15855
15856         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15857                 skip "OFD access log unsupported"
15858
15859         setup_165
15860         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15861         sleep 5
15862
15863         do_facet ost1 ofd_access_log_reader --list
15864         stop ost1
15865
15866         do_facet ost1 killall -TERM ofd_access_log_reader
15867         wait
15868         rc=$?
15869
15870         if ((rc != 0)); then
15871                 error "ofd_access_log_reader exited with rc = '${rc}'"
15872         fi
15873
15874         # Parse trace file for discovery events:
15875         oalr_expect_event_count alr_log_add "${trace}" 1
15876         oalr_expect_event_count alr_log_eof "${trace}" 1
15877         oalr_expect_event_count alr_log_free "${trace}" 1
15878 }
15879 run_test 165a "ofd access log discovery"
15880
15881 test_165b() {
15882         local trace="/tmp/${tfile}.trace"
15883         local file="${DIR}/${tfile}"
15884         local pfid1
15885         local pfid2
15886         local -a entry
15887         local rc
15888         local count
15889         local size
15890         local flags
15891
15892         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15893                 skip "OFD access log unsupported"
15894
15895         setup_165
15896         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15897         sleep 5
15898
15899         do_facet ost1 ofd_access_log_reader --list
15900
15901         lfs setstripe -c 1 -i 0 "${file}"
15902         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15903                 error "cannot create '${file}'"
15904
15905         sleep 5
15906         do_facet ost1 killall -TERM ofd_access_log_reader
15907         wait
15908         rc=$?
15909
15910         if ((rc != 0)); then
15911                 error "ofd_access_log_reader exited with rc = '${rc}'"
15912         fi
15913
15914         oalr_expect_event_count alr_log_entry "${trace}" 1
15915
15916         pfid1=$($LFS path2fid "${file}")
15917
15918         # 1     2             3   4    5     6   7    8    9     10
15919         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15920         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15921
15922         echo "entry = '${entry[*]}'" >&2
15923
15924         pfid2=${entry[4]}
15925         if [[ "${pfid1}" != "${pfid2}" ]]; then
15926                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15927         fi
15928
15929         size=${entry[8]}
15930         if ((size != 1048576)); then
15931                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15932         fi
15933
15934         flags=${entry[10]}
15935         if [[ "${flags}" != "w" ]]; then
15936                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15937         fi
15938
15939         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15940         sleep 5
15941
15942         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15943                 error "cannot read '${file}'"
15944         sleep 5
15945
15946         do_facet ost1 killall -TERM ofd_access_log_reader
15947         wait
15948         rc=$?
15949
15950         if ((rc != 0)); then
15951                 error "ofd_access_log_reader exited with rc = '${rc}'"
15952         fi
15953
15954         oalr_expect_event_count alr_log_entry "${trace}" 1
15955
15956         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15957         echo "entry = '${entry[*]}'" >&2
15958
15959         pfid2=${entry[4]}
15960         if [[ "${pfid1}" != "${pfid2}" ]]; then
15961                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15962         fi
15963
15964         size=${entry[8]}
15965         if ((size != 524288)); then
15966                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15967         fi
15968
15969         flags=${entry[10]}
15970         if [[ "${flags}" != "r" ]]; then
15971                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15972         fi
15973 }
15974 run_test 165b "ofd access log entries are produced and consumed"
15975
15976 test_165c() {
15977         local trace="/tmp/${tfile}.trace"
15978         local file="${DIR}/${tdir}/${tfile}"
15979
15980         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15981                 skip "OFD access log unsupported"
15982
15983         test_mkdir "${DIR}/${tdir}"
15984
15985         setup_165
15986         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15987         sleep 5
15988
15989         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15990
15991         # 4096 / 64 = 64. Create twice as many entries.
15992         for ((i = 0; i < 128; i++)); do
15993                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15994                         error "cannot create file"
15995         done
15996
15997         sync
15998
15999         do_facet ost1 killall -TERM ofd_access_log_reader
16000         wait
16001         rc=$?
16002         if ((rc != 0)); then
16003                 error "ofd_access_log_reader exited with rc = '${rc}'"
16004         fi
16005
16006         unlinkmany  "${file}-%d" 128
16007 }
16008 run_test 165c "full ofd access logs do not block IOs"
16009
16010 oal_get_read_count() {
16011         local stats="$1"
16012
16013         # STATS lustre-OST0001 alr_read_count 1
16014
16015         do_facet ost1 cat "${stats}" |
16016         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16017              END { print count; }'
16018 }
16019
16020 oal_expect_read_count() {
16021         local stats="$1"
16022         local count
16023         local expect="$2"
16024
16025         # Ask ofd_access_log_reader to write stats.
16026         do_facet ost1 killall -USR1 ofd_access_log_reader
16027
16028         # Allow some time for things to happen.
16029         sleep 1
16030
16031         count=$(oal_get_read_count "${stats}")
16032         if ((count == expect)); then
16033                 return 0
16034         fi
16035
16036         error_noexit "bad read count, got ${count}, expected ${expect}"
16037         do_facet ost1 cat "${stats}" >&2
16038         exit 1
16039 }
16040
16041 test_165d() {
16042         local stats="/tmp/${tfile}.stats"
16043         local file="${DIR}/${tdir}/${tfile}"
16044         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16045
16046         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16047                 skip "OFD access log unsupported"
16048
16049         test_mkdir "${DIR}/${tdir}"
16050
16051         setup_165
16052         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16053         sleep 5
16054
16055         lfs setstripe -c 1 -i 0 "${file}"
16056
16057         do_facet ost1 lctl set_param "${param}=rw"
16058         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16059                 error "cannot create '${file}'"
16060         oal_expect_read_count "${stats}" 1
16061
16062         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16063                 error "cannot read '${file}'"
16064         oal_expect_read_count "${stats}" 2
16065
16066         do_facet ost1 lctl set_param "${param}=r"
16067         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16068                 error "cannot create '${file}'"
16069         oal_expect_read_count "${stats}" 2
16070
16071         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16072                 error "cannot read '${file}'"
16073         oal_expect_read_count "${stats}" 3
16074
16075         do_facet ost1 lctl set_param "${param}=w"
16076         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16077                 error "cannot create '${file}'"
16078         oal_expect_read_count "${stats}" 4
16079
16080         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16081                 error "cannot read '${file}'"
16082         oal_expect_read_count "${stats}" 4
16083
16084         do_facet ost1 lctl set_param "${param}=0"
16085         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16086                 error "cannot create '${file}'"
16087         oal_expect_read_count "${stats}" 4
16088
16089         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16090                 error "cannot read '${file}'"
16091         oal_expect_read_count "${stats}" 4
16092
16093         do_facet ost1 killall -TERM ofd_access_log_reader
16094         wait
16095         rc=$?
16096         if ((rc != 0)); then
16097                 error "ofd_access_log_reader exited with rc = '${rc}'"
16098         fi
16099 }
16100 run_test 165d "ofd_access_log mask works"
16101
16102 test_165e() {
16103         local stats="/tmp/${tfile}.stats"
16104         local file0="${DIR}/${tdir}-0/${tfile}"
16105         local file1="${DIR}/${tdir}-1/${tfile}"
16106
16107         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16108                 skip "OFD access log unsupported"
16109
16110         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16111
16112         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16113         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16114
16115         lfs setstripe -c 1 -i 0 "${file0}"
16116         lfs setstripe -c 1 -i 0 "${file1}"
16117
16118         setup_165
16119         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16120         sleep 5
16121
16122         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16123                 error "cannot create '${file0}'"
16124         sync
16125         oal_expect_read_count "${stats}" 0
16126
16127         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16128                 error "cannot create '${file1}'"
16129         sync
16130         oal_expect_read_count "${stats}" 1
16131
16132         do_facet ost1 killall -TERM ofd_access_log_reader
16133         wait
16134         rc=$?
16135         if ((rc != 0)); then
16136                 error "ofd_access_log_reader exited with rc = '${rc}'"
16137         fi
16138 }
16139 run_test 165e "ofd_access_log MDT index filter works"
16140
16141 test_165f() {
16142         local trace="/tmp/${tfile}.trace"
16143         local rc
16144         local count
16145
16146         setup_165
16147         do_facet ost1 timeout 60 ofd_access_log_reader \
16148                 --exit-on-close --debug=- --trace=- > "${trace}" &
16149         sleep 5
16150         stop ost1
16151
16152         wait
16153         rc=$?
16154
16155         if ((rc != 0)); then
16156                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16157                 cat "${trace}"
16158                 exit 1
16159         fi
16160 }
16161 run_test 165f "ofd_access_log_reader --exit-on-close works"
16162
16163 test_169() {
16164         # do directio so as not to populate the page cache
16165         log "creating a 10 Mb file"
16166         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16167                 error "multiop failed while creating a file"
16168         log "starting reads"
16169         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16170         log "truncating the file"
16171         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16172                 error "multiop failed while truncating the file"
16173         log "killing dd"
16174         kill %+ || true # reads might have finished
16175         echo "wait until dd is finished"
16176         wait
16177         log "removing the temporary file"
16178         rm -rf $DIR/$tfile || error "tmp file removal failed"
16179 }
16180 run_test 169 "parallel read and truncate should not deadlock"
16181
16182 test_170() {
16183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16184
16185         $LCTL clear     # bug 18514
16186         $LCTL debug_daemon start $TMP/${tfile}_log_good
16187         touch $DIR/$tfile
16188         $LCTL debug_daemon stop
16189         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16190                 error "sed failed to read log_good"
16191
16192         $LCTL debug_daemon start $TMP/${tfile}_log_good
16193         rm -rf $DIR/$tfile
16194         $LCTL debug_daemon stop
16195
16196         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16197                error "lctl df log_bad failed"
16198
16199         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16200         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16201
16202         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16203         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16204
16205         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16206                 error "bad_line good_line1 good_line2 are empty"
16207
16208         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16209         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16210         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16211
16212         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16213         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16214         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16215
16216         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16217                 error "bad_line_new good_line_new are empty"
16218
16219         local expected_good=$((good_line1 + good_line2*2))
16220
16221         rm -f $TMP/${tfile}*
16222         # LU-231, short malformed line may not be counted into bad lines
16223         if [ $bad_line -ne $bad_line_new ] &&
16224                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16225                 error "expected $bad_line bad lines, but got $bad_line_new"
16226                 return 1
16227         fi
16228
16229         if [ $expected_good -ne $good_line_new ]; then
16230                 error "expected $expected_good good lines, but got $good_line_new"
16231                 return 2
16232         fi
16233         true
16234 }
16235 run_test 170 "test lctl df to handle corrupted log ====================="
16236
16237 test_171() { # bug20592
16238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16239
16240         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16241         $LCTL set_param fail_loc=0x50e
16242         $LCTL set_param fail_val=3000
16243         multiop_bg_pause $DIR/$tfile O_s || true
16244         local MULTIPID=$!
16245         kill -USR1 $MULTIPID
16246         # cause log dump
16247         sleep 3
16248         wait $MULTIPID
16249         if dmesg | grep "recursive fault"; then
16250                 error "caught a recursive fault"
16251         fi
16252         $LCTL set_param fail_loc=0
16253         true
16254 }
16255 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16256
16257 # it would be good to share it with obdfilter-survey/iokit-libecho code
16258 setup_obdecho_osc () {
16259         local rc=0
16260         local ost_nid=$1
16261         local obdfilter_name=$2
16262         echo "Creating new osc for $obdfilter_name on $ost_nid"
16263         # make sure we can find loopback nid
16264         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16265
16266         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16267                            ${obdfilter_name}_osc_UUID || rc=2; }
16268         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16269                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16270         return $rc
16271 }
16272
16273 cleanup_obdecho_osc () {
16274         local obdfilter_name=$1
16275         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16276         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16277         return 0
16278 }
16279
16280 obdecho_test() {
16281         local OBD=$1
16282         local node=$2
16283         local pages=${3:-64}
16284         local rc=0
16285         local id
16286
16287         local count=10
16288         local obd_size=$(get_obd_size $node $OBD)
16289         local page_size=$(get_page_size $node)
16290         if [[ -n "$obd_size" ]]; then
16291                 local new_count=$((obd_size / (pages * page_size / 1024)))
16292                 [[ $new_count -ge $count ]] || count=$new_count
16293         fi
16294
16295         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16296         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16297                            rc=2; }
16298         if [ $rc -eq 0 ]; then
16299             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16300             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16301         fi
16302         echo "New object id is $id"
16303         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16304                            rc=4; }
16305         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16306                            "test_brw $count w v $pages $id" || rc=4; }
16307         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16308                            rc=4; }
16309         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16310                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16311         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16312                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16313         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16314         return $rc
16315 }
16316
16317 test_180a() {
16318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16319
16320         if ! [ -d /sys/fs/lustre/echo_client ] &&
16321            ! module_loaded obdecho; then
16322                 load_module obdecho/obdecho &&
16323                         stack_trap "rmmod obdecho" EXIT ||
16324                         error "unable to load obdecho on client"
16325         fi
16326
16327         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16328         local host=$($LCTL get_param -n osc.$osc.import |
16329                      awk '/current_connection:/ { print $2 }' )
16330         local target=$($LCTL get_param -n osc.$osc.import |
16331                        awk '/target:/ { print $2 }' )
16332         target=${target%_UUID}
16333
16334         if [ -n "$target" ]; then
16335                 setup_obdecho_osc $host $target &&
16336                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16337                         { error "obdecho setup failed with $?"; return; }
16338
16339                 obdecho_test ${target}_osc client ||
16340                         error "obdecho_test failed on ${target}_osc"
16341         else
16342                 $LCTL get_param osc.$osc.import
16343                 error "there is no osc.$osc.import target"
16344         fi
16345 }
16346 run_test 180a "test obdecho on osc"
16347
16348 test_180b() {
16349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16350         remote_ost_nodsh && skip "remote OST with nodsh"
16351
16352         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16353                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16354                 error "failed to load module obdecho"
16355
16356         local target=$(do_facet ost1 $LCTL dl |
16357                        awk '/obdfilter/ { print $4; exit; }')
16358
16359         if [ -n "$target" ]; then
16360                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16361         else
16362                 do_facet ost1 $LCTL dl
16363                 error "there is no obdfilter target on ost1"
16364         fi
16365 }
16366 run_test 180b "test obdecho directly on obdfilter"
16367
16368 test_180c() { # LU-2598
16369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16370         remote_ost_nodsh && skip "remote OST with nodsh"
16371         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16372                 skip "Need MDS version at least 2.4.0"
16373
16374         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16375                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16376                 error "failed to load module obdecho"
16377
16378         local target=$(do_facet ost1 $LCTL dl |
16379                        awk '/obdfilter/ { print $4; exit; }')
16380
16381         if [ -n "$target" ]; then
16382                 local pages=16384 # 64MB bulk I/O RPC size
16383
16384                 obdecho_test "$target" ost1 "$pages" ||
16385                         error "obdecho_test with pages=$pages failed with $?"
16386         else
16387                 do_facet ost1 $LCTL dl
16388                 error "there is no obdfilter target on ost1"
16389         fi
16390 }
16391 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16392
16393 test_181() { # bug 22177
16394         test_mkdir $DIR/$tdir
16395         # create enough files to index the directory
16396         createmany -o $DIR/$tdir/foobar 4000
16397         # print attributes for debug purpose
16398         lsattr -d .
16399         # open dir
16400         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16401         MULTIPID=$!
16402         # remove the files & current working dir
16403         unlinkmany $DIR/$tdir/foobar 4000
16404         rmdir $DIR/$tdir
16405         kill -USR1 $MULTIPID
16406         wait $MULTIPID
16407         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16408         return 0
16409 }
16410 run_test 181 "Test open-unlinked dir ========================"
16411
16412 test_182() {
16413         local fcount=1000
16414         local tcount=10
16415
16416         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16417
16418         $LCTL set_param mdc.*.rpc_stats=clear
16419
16420         for (( i = 0; i < $tcount; i++ )) ; do
16421                 mkdir $DIR/$tdir/$i
16422         done
16423
16424         for (( i = 0; i < $tcount; i++ )) ; do
16425                 createmany -o $DIR/$tdir/$i/f- $fcount &
16426         done
16427         wait
16428
16429         for (( i = 0; i < $tcount; i++ )) ; do
16430                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16431         done
16432         wait
16433
16434         $LCTL get_param mdc.*.rpc_stats
16435
16436         rm -rf $DIR/$tdir
16437 }
16438 run_test 182 "Test parallel modify metadata operations ================"
16439
16440 test_183() { # LU-2275
16441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16442         remote_mds_nodsh && skip "remote MDS with nodsh"
16443         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16444                 skip "Need MDS version at least 2.3.56"
16445
16446         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16447         echo aaa > $DIR/$tdir/$tfile
16448
16449 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16450         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16451
16452         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16453         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16454
16455         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16456
16457         # Flush negative dentry cache
16458         touch $DIR/$tdir/$tfile
16459
16460         # We are not checking for any leaked references here, they'll
16461         # become evident next time we do cleanup with module unload.
16462         rm -rf $DIR/$tdir
16463 }
16464 run_test 183 "No crash or request leak in case of strange dispositions ========"
16465
16466 # test suite 184 is for LU-2016, LU-2017
16467 test_184a() {
16468         check_swap_layouts_support
16469
16470         dir0=$DIR/$tdir/$testnum
16471         test_mkdir -p -c1 $dir0
16472         ref1=/etc/passwd
16473         ref2=/etc/group
16474         file1=$dir0/f1
16475         file2=$dir0/f2
16476         $LFS setstripe -c1 $file1
16477         cp $ref1 $file1
16478         $LFS setstripe -c2 $file2
16479         cp $ref2 $file2
16480         gen1=$($LFS getstripe -g $file1)
16481         gen2=$($LFS getstripe -g $file2)
16482
16483         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16484         gen=$($LFS getstripe -g $file1)
16485         [[ $gen1 != $gen ]] ||
16486                 "Layout generation on $file1 does not change"
16487         gen=$($LFS getstripe -g $file2)
16488         [[ $gen2 != $gen ]] ||
16489                 "Layout generation on $file2 does not change"
16490
16491         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16492         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16493
16494         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16495 }
16496 run_test 184a "Basic layout swap"
16497
16498 test_184b() {
16499         check_swap_layouts_support
16500
16501         dir0=$DIR/$tdir/$testnum
16502         mkdir -p $dir0 || error "creating dir $dir0"
16503         file1=$dir0/f1
16504         file2=$dir0/f2
16505         file3=$dir0/f3
16506         dir1=$dir0/d1
16507         dir2=$dir0/d2
16508         mkdir $dir1 $dir2
16509         $LFS setstripe -c1 $file1
16510         $LFS setstripe -c2 $file2
16511         $LFS setstripe -c1 $file3
16512         chown $RUNAS_ID $file3
16513         gen1=$($LFS getstripe -g $file1)
16514         gen2=$($LFS getstripe -g $file2)
16515
16516         $LFS swap_layouts $dir1 $dir2 &&
16517                 error "swap of directories layouts should fail"
16518         $LFS swap_layouts $dir1 $file1 &&
16519                 error "swap of directory and file layouts should fail"
16520         $RUNAS $LFS swap_layouts $file1 $file2 &&
16521                 error "swap of file we cannot write should fail"
16522         $LFS swap_layouts $file1 $file3 &&
16523                 error "swap of file with different owner should fail"
16524         /bin/true # to clear error code
16525 }
16526 run_test 184b "Forbidden layout swap (will generate errors)"
16527
16528 test_184c() {
16529         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16530         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16531         check_swap_layouts_support
16532         check_swap_layout_no_dom $DIR
16533
16534         local dir0=$DIR/$tdir/$testnum
16535         mkdir -p $dir0 || error "creating dir $dir0"
16536
16537         local ref1=$dir0/ref1
16538         local ref2=$dir0/ref2
16539         local file1=$dir0/file1
16540         local file2=$dir0/file2
16541         # create a file large enough for the concurrent test
16542         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16543         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16544         echo "ref file size: ref1($(stat -c %s $ref1))," \
16545              "ref2($(stat -c %s $ref2))"
16546
16547         cp $ref2 $file2
16548         dd if=$ref1 of=$file1 bs=16k &
16549         local DD_PID=$!
16550
16551         # Make sure dd starts to copy file, but wait at most 5 seconds
16552         local loops=0
16553         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16554
16555         $LFS swap_layouts $file1 $file2
16556         local rc=$?
16557         wait $DD_PID
16558         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16559         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16560
16561         # how many bytes copied before swapping layout
16562         local copied=$(stat -c %s $file2)
16563         local remaining=$(stat -c %s $ref1)
16564         remaining=$((remaining - copied))
16565         echo "Copied $copied bytes before swapping layout..."
16566
16567         cmp -n $copied $file1 $ref2 | grep differ &&
16568                 error "Content mismatch [0, $copied) of ref2 and file1"
16569         cmp -n $copied $file2 $ref1 ||
16570                 error "Content mismatch [0, $copied) of ref1 and file2"
16571         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16572                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16573
16574         # clean up
16575         rm -f $ref1 $ref2 $file1 $file2
16576 }
16577 run_test 184c "Concurrent write and layout swap"
16578
16579 test_184d() {
16580         check_swap_layouts_support
16581         check_swap_layout_no_dom $DIR
16582         [ -z "$(which getfattr 2>/dev/null)" ] &&
16583                 skip_env "no getfattr command"
16584
16585         local file1=$DIR/$tdir/$tfile-1
16586         local file2=$DIR/$tdir/$tfile-2
16587         local file3=$DIR/$tdir/$tfile-3
16588         local lovea1
16589         local lovea2
16590
16591         mkdir -p $DIR/$tdir
16592         touch $file1 || error "create $file1 failed"
16593         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16594                 error "create $file2 failed"
16595         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16596                 error "create $file3 failed"
16597         lovea1=$(get_layout_param $file1)
16598
16599         $LFS swap_layouts $file2 $file3 ||
16600                 error "swap $file2 $file3 layouts failed"
16601         $LFS swap_layouts $file1 $file2 ||
16602                 error "swap $file1 $file2 layouts failed"
16603
16604         lovea2=$(get_layout_param $file2)
16605         echo "$lovea1"
16606         echo "$lovea2"
16607         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16608
16609         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16610         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16611 }
16612 run_test 184d "allow stripeless layouts swap"
16613
16614 test_184e() {
16615         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16616                 skip "Need MDS version at least 2.6.94"
16617         check_swap_layouts_support
16618         check_swap_layout_no_dom $DIR
16619         [ -z "$(which getfattr 2>/dev/null)" ] &&
16620                 skip_env "no getfattr command"
16621
16622         local file1=$DIR/$tdir/$tfile-1
16623         local file2=$DIR/$tdir/$tfile-2
16624         local file3=$DIR/$tdir/$tfile-3
16625         local lovea
16626
16627         mkdir -p $DIR/$tdir
16628         touch $file1 || error "create $file1 failed"
16629         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16630                 error "create $file2 failed"
16631         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16632                 error "create $file3 failed"
16633
16634         $LFS swap_layouts $file1 $file2 ||
16635                 error "swap $file1 $file2 layouts failed"
16636
16637         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16638         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16639
16640         echo 123 > $file1 || error "Should be able to write into $file1"
16641
16642         $LFS swap_layouts $file1 $file3 ||
16643                 error "swap $file1 $file3 layouts failed"
16644
16645         echo 123 > $file1 || error "Should be able to write into $file1"
16646
16647         rm -rf $file1 $file2 $file3
16648 }
16649 run_test 184e "Recreate layout after stripeless layout swaps"
16650
16651 test_184f() {
16652         # Create a file with name longer than sizeof(struct stat) ==
16653         # 144 to see if we can get chars from the file name to appear
16654         # in the returned striping. Note that 'f' == 0x66.
16655         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16656
16657         mkdir -p $DIR/$tdir
16658         mcreate $DIR/$tdir/$file
16659         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16660                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16661         fi
16662 }
16663 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16664
16665 test_185() { # LU-2441
16666         # LU-3553 - no volatile file support in old servers
16667         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16668                 skip "Need MDS version at least 2.3.60"
16669
16670         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16671         touch $DIR/$tdir/spoo
16672         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16673         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16674                 error "cannot create/write a volatile file"
16675         [ "$FILESET" == "" ] &&
16676         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16677                 error "FID is still valid after close"
16678
16679         multiop_bg_pause $DIR/$tdir vVw4096_c
16680         local multi_pid=$!
16681
16682         local OLD_IFS=$IFS
16683         IFS=":"
16684         local fidv=($fid)
16685         IFS=$OLD_IFS
16686         # assume that the next FID for this client is sequential, since stdout
16687         # is unfortunately eaten by multiop_bg_pause
16688         local n=$((${fidv[1]} + 1))
16689         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16690         if [ "$FILESET" == "" ]; then
16691                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16692                         error "FID is missing before close"
16693         fi
16694         kill -USR1 $multi_pid
16695         # 1 second delay, so if mtime change we will see it
16696         sleep 1
16697         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16698         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16699 }
16700 run_test 185 "Volatile file support"
16701
16702 function create_check_volatile() {
16703         local idx=$1
16704         local tgt
16705
16706         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16707         local PID=$!
16708         sleep 1
16709         local FID=$(cat /tmp/${tfile}.fid)
16710         [ "$FID" == "" ] && error "can't get FID for volatile"
16711         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16712         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16713         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16714         kill -USR1 $PID
16715         wait
16716         sleep 1
16717         cancel_lru_locks mdc # flush opencache
16718         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16719         return 0
16720 }
16721
16722 test_185a(){
16723         # LU-12516 - volatile creation via .lustre
16724         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16725                 skip "Need MDS version at least 2.3.55"
16726
16727         create_check_volatile 0
16728         [ $MDSCOUNT -lt 2 ] && return 0
16729
16730         # DNE case
16731         create_check_volatile 1
16732
16733         return 0
16734 }
16735 run_test 185a "Volatile file creation in .lustre/fid/"
16736
16737 test_187a() {
16738         remote_mds_nodsh && skip "remote MDS with nodsh"
16739         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16740                 skip "Need MDS version at least 2.3.0"
16741
16742         local dir0=$DIR/$tdir/$testnum
16743         mkdir -p $dir0 || error "creating dir $dir0"
16744
16745         local file=$dir0/file1
16746         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16747         local dv1=$($LFS data_version $file)
16748         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16749         local dv2=$($LFS data_version $file)
16750         [[ $dv1 != $dv2 ]] ||
16751                 error "data version did not change on write $dv1 == $dv2"
16752
16753         # clean up
16754         rm -f $file1
16755 }
16756 run_test 187a "Test data version change"
16757
16758 test_187b() {
16759         remote_mds_nodsh && skip "remote MDS with nodsh"
16760         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16761                 skip "Need MDS version at least 2.3.0"
16762
16763         local dir0=$DIR/$tdir/$testnum
16764         mkdir -p $dir0 || error "creating dir $dir0"
16765
16766         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16767         [[ ${DV[0]} != ${DV[1]} ]] ||
16768                 error "data version did not change on write"\
16769                       " ${DV[0]} == ${DV[1]}"
16770
16771         # clean up
16772         rm -f $file1
16773 }
16774 run_test 187b "Test data version change on volatile file"
16775
16776 test_200() {
16777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16778         remote_mgs_nodsh && skip "remote MGS with nodsh"
16779         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16780
16781         local POOL=${POOL:-cea1}
16782         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16783         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16784         # Pool OST targets
16785         local first_ost=0
16786         local last_ost=$(($OSTCOUNT - 1))
16787         local ost_step=2
16788         local ost_list=$(seq $first_ost $ost_step $last_ost)
16789         local ost_range="$first_ost $last_ost $ost_step"
16790         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16791         local file_dir=$POOL_ROOT/file_tst
16792         local subdir=$test_path/subdir
16793         local rc=0
16794
16795         while : ; do
16796                 # former test_200a test_200b
16797                 pool_add $POOL                          || { rc=$? ; break; }
16798                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16799                 # former test_200c test_200d
16800                 mkdir -p $test_path
16801                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16802                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16803                 mkdir -p $subdir
16804                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16805                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16806                                                         || { rc=$? ; break; }
16807                 # former test_200e test_200f
16808                 local files=$((OSTCOUNT*3))
16809                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16810                                                         || { rc=$? ; break; }
16811                 pool_create_files $POOL $file_dir $files "$ost_list" \
16812                                                         || { rc=$? ; break; }
16813                 # former test_200g test_200h
16814                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16815                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16816
16817                 # former test_201a test_201b test_201c
16818                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16819
16820                 local f=$test_path/$tfile
16821                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16822                 pool_remove $POOL $f                    || { rc=$? ; break; }
16823                 break
16824         done
16825
16826         destroy_test_pools
16827
16828         return $rc
16829 }
16830 run_test 200 "OST pools"
16831
16832 # usage: default_attr <count | size | offset>
16833 default_attr() {
16834         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16835 }
16836
16837 # usage: check_default_stripe_attr
16838 check_default_stripe_attr() {
16839         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16840         case $1 in
16841         --stripe-count|-c)
16842                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16843         --stripe-size|-S)
16844                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16845         --stripe-index|-i)
16846                 EXPECTED=-1;;
16847         *)
16848                 error "unknown getstripe attr '$1'"
16849         esac
16850
16851         [ $ACTUAL == $EXPECTED ] ||
16852                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16853 }
16854
16855 test_204a() {
16856         test_mkdir $DIR/$tdir
16857         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16858
16859         check_default_stripe_attr --stripe-count
16860         check_default_stripe_attr --stripe-size
16861         check_default_stripe_attr --stripe-index
16862 }
16863 run_test 204a "Print default stripe attributes"
16864
16865 test_204b() {
16866         test_mkdir $DIR/$tdir
16867         $LFS setstripe --stripe-count 1 $DIR/$tdir
16868
16869         check_default_stripe_attr --stripe-size
16870         check_default_stripe_attr --stripe-index
16871 }
16872 run_test 204b "Print default stripe size and offset"
16873
16874 test_204c() {
16875         test_mkdir $DIR/$tdir
16876         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16877
16878         check_default_stripe_attr --stripe-count
16879         check_default_stripe_attr --stripe-index
16880 }
16881 run_test 204c "Print default stripe count and offset"
16882
16883 test_204d() {
16884         test_mkdir $DIR/$tdir
16885         $LFS setstripe --stripe-index 0 $DIR/$tdir
16886
16887         check_default_stripe_attr --stripe-count
16888         check_default_stripe_attr --stripe-size
16889 }
16890 run_test 204d "Print default stripe count and size"
16891
16892 test_204e() {
16893         test_mkdir $DIR/$tdir
16894         $LFS setstripe -d $DIR/$tdir
16895
16896         check_default_stripe_attr --stripe-count --raw
16897         check_default_stripe_attr --stripe-size --raw
16898         check_default_stripe_attr --stripe-index --raw
16899 }
16900 run_test 204e "Print raw stripe attributes"
16901
16902 test_204f() {
16903         test_mkdir $DIR/$tdir
16904         $LFS setstripe --stripe-count 1 $DIR/$tdir
16905
16906         check_default_stripe_attr --stripe-size --raw
16907         check_default_stripe_attr --stripe-index --raw
16908 }
16909 run_test 204f "Print raw stripe size and offset"
16910
16911 test_204g() {
16912         test_mkdir $DIR/$tdir
16913         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16914
16915         check_default_stripe_attr --stripe-count --raw
16916         check_default_stripe_attr --stripe-index --raw
16917 }
16918 run_test 204g "Print raw stripe count and offset"
16919
16920 test_204h() {
16921         test_mkdir $DIR/$tdir
16922         $LFS setstripe --stripe-index 0 $DIR/$tdir
16923
16924         check_default_stripe_attr --stripe-count --raw
16925         check_default_stripe_attr --stripe-size --raw
16926 }
16927 run_test 204h "Print raw stripe count and size"
16928
16929 # Figure out which job scheduler is being used, if any,
16930 # or use a fake one
16931 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16932         JOBENV=SLURM_JOB_ID
16933 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16934         JOBENV=LSB_JOBID
16935 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16936         JOBENV=PBS_JOBID
16937 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16938         JOBENV=LOADL_STEP_ID
16939 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16940         JOBENV=JOB_ID
16941 else
16942         $LCTL list_param jobid_name > /dev/null 2>&1
16943         if [ $? -eq 0 ]; then
16944                 JOBENV=nodelocal
16945         else
16946                 JOBENV=FAKE_JOBID
16947         fi
16948 fi
16949 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16950
16951 verify_jobstats() {
16952         local cmd=($1)
16953         shift
16954         local facets="$@"
16955
16956 # we don't really need to clear the stats for this test to work, since each
16957 # command has a unique jobid, but it makes debugging easier if needed.
16958 #       for facet in $facets; do
16959 #               local dev=$(convert_facet2label $facet)
16960 #               # clear old jobstats
16961 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16962 #       done
16963
16964         # use a new JobID for each test, or we might see an old one
16965         [ "$JOBENV" = "FAKE_JOBID" ] &&
16966                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16967
16968         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16969
16970         [ "$JOBENV" = "nodelocal" ] && {
16971                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16972                 $LCTL set_param jobid_name=$FAKE_JOBID
16973                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16974         }
16975
16976         log "Test: ${cmd[*]}"
16977         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16978
16979         if [ $JOBENV = "FAKE_JOBID" ]; then
16980                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16981         else
16982                 ${cmd[*]}
16983         fi
16984
16985         # all files are created on OST0000
16986         for facet in $facets; do
16987                 local stats="*.$(convert_facet2label $facet).job_stats"
16988
16989                 # strip out libtool wrappers for in-tree executables
16990                 if [ $(do_facet $facet lctl get_param $stats |
16991                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16992                         do_facet $facet lctl get_param $stats
16993                         error "No jobstats for $JOBVAL found on $facet::$stats"
16994                 fi
16995         done
16996 }
16997
16998 jobstats_set() {
16999         local new_jobenv=$1
17000
17001         set_persistent_param_and_check client "jobid_var" \
17002                 "$FSNAME.sys.jobid_var" $new_jobenv
17003 }
17004
17005 test_205a() { # Job stats
17006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17007         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17008                 skip "Need MDS version with at least 2.7.1"
17009         remote_mgs_nodsh && skip "remote MGS with nodsh"
17010         remote_mds_nodsh && skip "remote MDS with nodsh"
17011         remote_ost_nodsh && skip "remote OST with nodsh"
17012         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17013                 skip "Server doesn't support jobstats"
17014         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17015
17016         local old_jobenv=$($LCTL get_param -n jobid_var)
17017         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17018
17019         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17020                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17021         else
17022                 stack_trap "do_facet mgs $PERM_CMD \
17023                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17024         fi
17025         changelog_register
17026
17027         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17028                                 mdt.*.job_cleanup_interval | head -n 1)
17029         local new_interval=5
17030         do_facet $SINGLEMDS \
17031                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17032         stack_trap "do_facet $SINGLEMDS \
17033                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17034         local start=$SECONDS
17035
17036         local cmd
17037         # mkdir
17038         cmd="mkdir $DIR/$tdir"
17039         verify_jobstats "$cmd" "$SINGLEMDS"
17040         # rmdir
17041         cmd="rmdir $DIR/$tdir"
17042         verify_jobstats "$cmd" "$SINGLEMDS"
17043         # mkdir on secondary MDT
17044         if [ $MDSCOUNT -gt 1 ]; then
17045                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17046                 verify_jobstats "$cmd" "mds2"
17047         fi
17048         # mknod
17049         cmd="mknod $DIR/$tfile c 1 3"
17050         verify_jobstats "$cmd" "$SINGLEMDS"
17051         # unlink
17052         cmd="rm -f $DIR/$tfile"
17053         verify_jobstats "$cmd" "$SINGLEMDS"
17054         # create all files on OST0000 so verify_jobstats can find OST stats
17055         # open & close
17056         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17057         verify_jobstats "$cmd" "$SINGLEMDS"
17058         # setattr
17059         cmd="touch $DIR/$tfile"
17060         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17061         # write
17062         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17063         verify_jobstats "$cmd" "ost1"
17064         # read
17065         cancel_lru_locks osc
17066         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17067         verify_jobstats "$cmd" "ost1"
17068         # truncate
17069         cmd="$TRUNCATE $DIR/$tfile 0"
17070         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17071         # rename
17072         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17073         verify_jobstats "$cmd" "$SINGLEMDS"
17074         # jobstats expiry - sleep until old stats should be expired
17075         local left=$((new_interval + 5 - (SECONDS - start)))
17076         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17077                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17078                         "0" $left
17079         cmd="mkdir $DIR/$tdir.expire"
17080         verify_jobstats "$cmd" "$SINGLEMDS"
17081         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17082             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17083
17084         # Ensure that jobid are present in changelog (if supported by MDS)
17085         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17086                 changelog_dump | tail -10
17087                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17088                 [ $jobids -eq 9 ] ||
17089                         error "Wrong changelog jobid count $jobids != 9"
17090
17091                 # LU-5862
17092                 JOBENV="disable"
17093                 jobstats_set $JOBENV
17094                 touch $DIR/$tfile
17095                 changelog_dump | grep $tfile
17096                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17097                 [ $jobids -eq 0 ] ||
17098                         error "Unexpected jobids when jobid_var=$JOBENV"
17099         fi
17100
17101         # test '%j' access to environment variable - if supported
17102         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17103                 JOBENV="JOBCOMPLEX"
17104                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17105
17106                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17107         fi
17108
17109         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17110                 JOBENV="JOBCOMPLEX"
17111                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17112
17113                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17114         fi
17115
17116         # test '%j' access to per-session jobid - if supported
17117         if lctl list_param jobid_this_session > /dev/null 2>&1
17118         then
17119                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17120                 lctl set_param jobid_this_session=$USER
17121
17122                 JOBENV="JOBCOMPLEX"
17123                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17124
17125                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17126         fi
17127 }
17128 run_test 205a "Verify job stats"
17129
17130 # LU-13117, LU-13597
17131 test_205b() {
17132         job_stats="mdt.*.job_stats"
17133         $LCTL set_param $job_stats=clear
17134         # Setting jobid_var to USER might not be supported
17135         $LCTL set_param jobid_var=USER || true
17136         $LCTL set_param jobid_name="%e.%u"
17137         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17138         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17139                 grep "job_id:.*foolish" &&
17140                         error "Unexpected jobid found"
17141         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17142                 grep "open:.*min.*max.*sum" ||
17143                         error "wrong job_stats format found"
17144 }
17145 run_test 205b "Verify job stats jobid and output format"
17146
17147 # LU-13733
17148 test_205c() {
17149         $LCTL set_param llite.*.stats=0
17150         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17151         $LCTL get_param llite.*.stats
17152         $LCTL get_param llite.*.stats | grep \
17153                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17154                         error "wrong client stats format found"
17155 }
17156 run_test 205c "Verify client stats format"
17157
17158 # LU-1480, LU-1773 and LU-1657
17159 test_206() {
17160         mkdir -p $DIR/$tdir
17161         $LFS setstripe -c -1 $DIR/$tdir
17162 #define OBD_FAIL_LOV_INIT 0x1403
17163         $LCTL set_param fail_loc=0xa0001403
17164         $LCTL set_param fail_val=1
17165         touch $DIR/$tdir/$tfile || true
17166 }
17167 run_test 206 "fail lov_init_raid0() doesn't lbug"
17168
17169 test_207a() {
17170         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17171         local fsz=`stat -c %s $DIR/$tfile`
17172         cancel_lru_locks mdc
17173
17174         # do not return layout in getattr intent
17175 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17176         $LCTL set_param fail_loc=0x170
17177         local sz=`stat -c %s $DIR/$tfile`
17178
17179         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17180
17181         rm -rf $DIR/$tfile
17182 }
17183 run_test 207a "can refresh layout at glimpse"
17184
17185 test_207b() {
17186         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17187         local cksum=`md5sum $DIR/$tfile`
17188         local fsz=`stat -c %s $DIR/$tfile`
17189         cancel_lru_locks mdc
17190         cancel_lru_locks osc
17191
17192         # do not return layout in getattr intent
17193 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17194         $LCTL set_param fail_loc=0x171
17195
17196         # it will refresh layout after the file is opened but before read issues
17197         echo checksum is "$cksum"
17198         echo "$cksum" |md5sum -c --quiet || error "file differs"
17199
17200         rm -rf $DIR/$tfile
17201 }
17202 run_test 207b "can refresh layout at open"
17203
17204 test_208() {
17205         # FIXME: in this test suite, only RD lease is used. This is okay
17206         # for now as only exclusive open is supported. After generic lease
17207         # is done, this test suite should be revised. - Jinshan
17208
17209         remote_mds_nodsh && skip "remote MDS with nodsh"
17210         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17211                 skip "Need MDS version at least 2.4.52"
17212
17213         echo "==== test 1: verify get lease work"
17214         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17215
17216         echo "==== test 2: verify lease can be broken by upcoming open"
17217         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17218         local PID=$!
17219         sleep 1
17220
17221         $MULTIOP $DIR/$tfile oO_RDONLY:c
17222         kill -USR1 $PID && wait $PID || error "break lease error"
17223
17224         echo "==== test 3: verify lease can't be granted if an open already exists"
17225         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17226         local PID=$!
17227         sleep 1
17228
17229         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17230         kill -USR1 $PID && wait $PID || error "open file error"
17231
17232         echo "==== test 4: lease can sustain over recovery"
17233         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17234         PID=$!
17235         sleep 1
17236
17237         fail mds1
17238
17239         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17240
17241         echo "==== test 5: lease broken can't be regained by replay"
17242         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17243         PID=$!
17244         sleep 1
17245
17246         # open file to break lease and then recovery
17247         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17248         fail mds1
17249
17250         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17251
17252         rm -f $DIR/$tfile
17253 }
17254 run_test 208 "Exclusive open"
17255
17256 test_209() {
17257         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17258                 skip_env "must have disp_stripe"
17259
17260         touch $DIR/$tfile
17261         sync; sleep 5; sync;
17262
17263         echo 3 > /proc/sys/vm/drop_caches
17264         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17265                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17266         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17267
17268         # open/close 500 times
17269         for i in $(seq 500); do
17270                 cat $DIR/$tfile
17271         done
17272
17273         echo 3 > /proc/sys/vm/drop_caches
17274         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17275                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17276         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17277
17278         echo "before: $req_before, after: $req_after"
17279         [ $((req_after - req_before)) -ge 300 ] &&
17280                 error "open/close requests are not freed"
17281         return 0
17282 }
17283 run_test 209 "read-only open/close requests should be freed promptly"
17284
17285 test_210() {
17286         local pid
17287
17288         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17289         pid=$!
17290         sleep 1
17291
17292         $LFS getstripe $DIR/$tfile
17293         kill -USR1 $pid
17294         wait $pid || error "multiop failed"
17295
17296         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17297         pid=$!
17298         sleep 1
17299
17300         $LFS getstripe $DIR/$tfile
17301         kill -USR1 $pid
17302         wait $pid || error "multiop failed"
17303 }
17304 run_test 210 "lfs getstripe does not break leases"
17305
17306 test_212() {
17307         size=`date +%s`
17308         size=$((size % 8192 + 1))
17309         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17310         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17311         rm -f $DIR/f212 $DIR/f212.xyz
17312 }
17313 run_test 212 "Sendfile test ============================================"
17314
17315 test_213() {
17316         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17317         cancel_lru_locks osc
17318         lctl set_param fail_loc=0x8000040f
17319         # generate a read lock
17320         cat $DIR/$tfile > /dev/null
17321         # write to the file, it will try to cancel the above read lock.
17322         cat /etc/hosts >> $DIR/$tfile
17323 }
17324 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17325
17326 test_214() { # for bug 20133
17327         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17328         for (( i=0; i < 340; i++ )) ; do
17329                 touch $DIR/$tdir/d214c/a$i
17330         done
17331
17332         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17333         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17334         ls $DIR/d214c || error "ls $DIR/d214c failed"
17335         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17336         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17337 }
17338 run_test 214 "hash-indexed directory test - bug 20133"
17339
17340 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17341 create_lnet_proc_files() {
17342         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17343 }
17344
17345 # counterpart of create_lnet_proc_files
17346 remove_lnet_proc_files() {
17347         rm -f $TMP/lnet_$1.sys
17348 }
17349
17350 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17351 # 3rd arg as regexp for body
17352 check_lnet_proc_stats() {
17353         local l=$(cat "$TMP/lnet_$1" |wc -l)
17354         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17355
17356         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17357 }
17358
17359 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17360 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17361 # optional and can be regexp for 2nd line (lnet.routes case)
17362 check_lnet_proc_entry() {
17363         local blp=2          # blp stands for 'position of 1st line of body'
17364         [ -z "$5" ] || blp=3 # lnet.routes case
17365
17366         local l=$(cat "$TMP/lnet_$1" |wc -l)
17367         # subtracting one from $blp because the body can be empty
17368         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17369
17370         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17371                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17372
17373         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17374                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17375
17376         # bail out if any unexpected line happened
17377         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17378         [ "$?" != 0 ] || error "$2 misformatted"
17379 }
17380
17381 test_215() { # for bugs 18102, 21079, 21517
17382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17383
17384         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17385         local P='[1-9][0-9]*'           # positive numeric
17386         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17387         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17388         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17389         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17390
17391         local L1 # regexp for 1st line
17392         local L2 # regexp for 2nd line (optional)
17393         local BR # regexp for the rest (body)
17394
17395         # lnet.stats should look as 11 space-separated non-negative numerics
17396         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17397         create_lnet_proc_files "stats"
17398         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17399         remove_lnet_proc_files "stats"
17400
17401         # lnet.routes should look like this:
17402         # Routing disabled/enabled
17403         # net hops priority state router
17404         # where net is a string like tcp0, hops > 0, priority >= 0,
17405         # state is up/down,
17406         # router is a string like 192.168.1.1@tcp2
17407         L1="^Routing (disabled|enabled)$"
17408         L2="^net +hops +priority +state +router$"
17409         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17410         create_lnet_proc_files "routes"
17411         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17412         remove_lnet_proc_files "routes"
17413
17414         # lnet.routers should look like this:
17415         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17416         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17417         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17418         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17419         L1="^ref +rtr_ref +alive +router$"
17420         BR="^$P +$P +(up|down) +$NID$"
17421         create_lnet_proc_files "routers"
17422         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17423         remove_lnet_proc_files "routers"
17424
17425         # lnet.peers should look like this:
17426         # nid refs state last max rtr min tx min queue
17427         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17428         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17429         # numeric (0 or >0 or <0), queue >= 0.
17430         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17431         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17432         create_lnet_proc_files "peers"
17433         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17434         remove_lnet_proc_files "peers"
17435
17436         # lnet.buffers  should look like this:
17437         # pages count credits min
17438         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17439         L1="^pages +count +credits +min$"
17440         BR="^ +$N +$N +$I +$I$"
17441         create_lnet_proc_files "buffers"
17442         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17443         remove_lnet_proc_files "buffers"
17444
17445         # lnet.nis should look like this:
17446         # nid status alive refs peer rtr max tx min
17447         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17448         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17449         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17450         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17451         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17452         create_lnet_proc_files "nis"
17453         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17454         remove_lnet_proc_files "nis"
17455
17456         # can we successfully write to lnet.stats?
17457         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17458 }
17459 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17460
17461 test_216() { # bug 20317
17462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17463         remote_ost_nodsh && skip "remote OST with nodsh"
17464
17465         local node
17466         local facets=$(get_facets OST)
17467         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17468
17469         save_lustre_params client "osc.*.contention_seconds" > $p
17470         save_lustre_params $facets \
17471                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17472         save_lustre_params $facets \
17473                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17474         save_lustre_params $facets \
17475                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17476         clear_stats osc.*.osc_stats
17477
17478         # agressive lockless i/o settings
17479         do_nodes $(comma_list $(osts_nodes)) \
17480                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17481                         ldlm.namespaces.filter-*.contended_locks=0 \
17482                         ldlm.namespaces.filter-*.contention_seconds=60"
17483         lctl set_param -n osc.*.contention_seconds=60
17484
17485         $DIRECTIO write $DIR/$tfile 0 10 4096
17486         $CHECKSTAT -s 40960 $DIR/$tfile
17487
17488         # disable lockless i/o
17489         do_nodes $(comma_list $(osts_nodes)) \
17490                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17491                         ldlm.namespaces.filter-*.contended_locks=32 \
17492                         ldlm.namespaces.filter-*.contention_seconds=0"
17493         lctl set_param -n osc.*.contention_seconds=0
17494         clear_stats osc.*.osc_stats
17495
17496         dd if=/dev/zero of=$DIR/$tfile count=0
17497         $CHECKSTAT -s 0 $DIR/$tfile
17498
17499         restore_lustre_params <$p
17500         rm -f $p
17501         rm $DIR/$tfile
17502 }
17503 run_test 216 "check lockless direct write updates file size and kms correctly"
17504
17505 test_217() { # bug 22430
17506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17507
17508         local node
17509         local nid
17510
17511         for node in $(nodes_list); do
17512                 nid=$(host_nids_address $node $NETTYPE)
17513                 if [[ $nid = *-* ]] ; then
17514                         echo "lctl ping $(h2nettype $nid)"
17515                         lctl ping $(h2nettype $nid)
17516                 else
17517                         echo "skipping $node (no hyphen detected)"
17518                 fi
17519         done
17520 }
17521 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17522
17523 test_218() {
17524        # do directio so as not to populate the page cache
17525        log "creating a 10 Mb file"
17526        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17527        log "starting reads"
17528        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17529        log "truncating the file"
17530        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17531        log "killing dd"
17532        kill %+ || true # reads might have finished
17533        echo "wait until dd is finished"
17534        wait
17535        log "removing the temporary file"
17536        rm -rf $DIR/$tfile || error "tmp file removal failed"
17537 }
17538 run_test 218 "parallel read and truncate should not deadlock"
17539
17540 test_219() {
17541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17542
17543         # write one partial page
17544         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17545         # set no grant so vvp_io_commit_write will do sync write
17546         $LCTL set_param fail_loc=0x411
17547         # write a full page at the end of file
17548         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17549
17550         $LCTL set_param fail_loc=0
17551         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17552         $LCTL set_param fail_loc=0x411
17553         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17554
17555         # LU-4201
17556         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17557         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17558 }
17559 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17560
17561 test_220() { #LU-325
17562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17563         remote_ost_nodsh && skip "remote OST with nodsh"
17564         remote_mds_nodsh && skip "remote MDS with nodsh"
17565         remote_mgs_nodsh && skip "remote MGS with nodsh"
17566
17567         local OSTIDX=0
17568
17569         # create on MDT0000 so the last_id and next_id are correct
17570         mkdir $DIR/$tdir
17571         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17572         OST=${OST%_UUID}
17573
17574         # on the mdt's osc
17575         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17576         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17577                         osp.$mdtosc_proc1.prealloc_last_id)
17578         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17579                         osp.$mdtosc_proc1.prealloc_next_id)
17580
17581         $LFS df -i
17582
17583         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17584         #define OBD_FAIL_OST_ENOINO              0x229
17585         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17586         create_pool $FSNAME.$TESTNAME || return 1
17587         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17588
17589         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17590
17591         MDSOBJS=$((last_id - next_id))
17592         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17593
17594         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17595         echo "OST still has $count kbytes free"
17596
17597         echo "create $MDSOBJS files @next_id..."
17598         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17599
17600         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17601                         osp.$mdtosc_proc1.prealloc_last_id)
17602         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17603                         osp.$mdtosc_proc1.prealloc_next_id)
17604
17605         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17606         $LFS df -i
17607
17608         echo "cleanup..."
17609
17610         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17611         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17612
17613         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17614                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17615         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17616                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17617         echo "unlink $MDSOBJS files @$next_id..."
17618         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17619 }
17620 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17621
17622 test_221() {
17623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17624
17625         dd if=`which date` of=$MOUNT/date oflag=sync
17626         chmod +x $MOUNT/date
17627
17628         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17629         $LCTL set_param fail_loc=0x80001401
17630
17631         $MOUNT/date > /dev/null
17632         rm -f $MOUNT/date
17633 }
17634 run_test 221 "make sure fault and truncate race to not cause OOM"
17635
17636 test_222a () {
17637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17638
17639         rm -rf $DIR/$tdir
17640         test_mkdir $DIR/$tdir
17641         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17642         createmany -o $DIR/$tdir/$tfile 10
17643         cancel_lru_locks mdc
17644         cancel_lru_locks osc
17645         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17646         $LCTL set_param fail_loc=0x31a
17647         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17648         $LCTL set_param fail_loc=0
17649         rm -r $DIR/$tdir
17650 }
17651 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17652
17653 test_222b () {
17654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17655
17656         rm -rf $DIR/$tdir
17657         test_mkdir $DIR/$tdir
17658         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17659         createmany -o $DIR/$tdir/$tfile 10
17660         cancel_lru_locks mdc
17661         cancel_lru_locks osc
17662         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17663         $LCTL set_param fail_loc=0x31a
17664         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17665         $LCTL set_param fail_loc=0
17666 }
17667 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17668
17669 test_223 () {
17670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17671
17672         rm -rf $DIR/$tdir
17673         test_mkdir $DIR/$tdir
17674         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17675         createmany -o $DIR/$tdir/$tfile 10
17676         cancel_lru_locks mdc
17677         cancel_lru_locks osc
17678         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17679         $LCTL set_param fail_loc=0x31b
17680         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17681         $LCTL set_param fail_loc=0
17682         rm -r $DIR/$tdir
17683 }
17684 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17685
17686 test_224a() { # LU-1039, MRP-303
17687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17688
17689         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17690         $LCTL set_param fail_loc=0x508
17691         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17692         $LCTL set_param fail_loc=0
17693         df $DIR
17694 }
17695 run_test 224a "Don't panic on bulk IO failure"
17696
17697 test_224b() { # LU-1039, MRP-303
17698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17699
17700         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17701         cancel_lru_locks osc
17702         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17703         $LCTL set_param fail_loc=0x515
17704         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17705         $LCTL set_param fail_loc=0
17706         df $DIR
17707 }
17708 run_test 224b "Don't panic on bulk IO failure"
17709
17710 test_224c() { # LU-6441
17711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17712         remote_mds_nodsh && skip "remote MDS with nodsh"
17713
17714         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17715         save_writethrough $p
17716         set_cache writethrough on
17717
17718         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17719         local at_max=$($LCTL get_param -n at_max)
17720         local timeout=$($LCTL get_param -n timeout)
17721         local test_at="at_max"
17722         local param_at="$FSNAME.sys.at_max"
17723         local test_timeout="timeout"
17724         local param_timeout="$FSNAME.sys.timeout"
17725
17726         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17727
17728         set_persistent_param_and_check client "$test_at" "$param_at" 0
17729         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17730
17731         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17732         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17733         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17734         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17735         sync
17736         do_facet ost1 "$LCTL set_param fail_loc=0"
17737
17738         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17739         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17740                 $timeout
17741
17742         $LCTL set_param -n $pages_per_rpc
17743         restore_lustre_params < $p
17744         rm -f $p
17745 }
17746 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17747
17748 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17749 test_225a () {
17750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17751         if [ -z ${MDSSURVEY} ]; then
17752                 skip_env "mds-survey not found"
17753         fi
17754         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17755                 skip "Need MDS version at least 2.2.51"
17756
17757         local mds=$(facet_host $SINGLEMDS)
17758         local target=$(do_nodes $mds 'lctl dl' |
17759                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17760
17761         local cmd1="file_count=1000 thrhi=4"
17762         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17763         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17764         local cmd="$cmd1 $cmd2 $cmd3"
17765
17766         rm -f ${TMP}/mds_survey*
17767         echo + $cmd
17768         eval $cmd || error "mds-survey with zero-stripe failed"
17769         cat ${TMP}/mds_survey*
17770         rm -f ${TMP}/mds_survey*
17771 }
17772 run_test 225a "Metadata survey sanity with zero-stripe"
17773
17774 test_225b () {
17775         if [ -z ${MDSSURVEY} ]; then
17776                 skip_env "mds-survey not found"
17777         fi
17778         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17779                 skip "Need MDS version at least 2.2.51"
17780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17781         remote_mds_nodsh && skip "remote MDS with nodsh"
17782         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17783                 skip_env "Need to mount OST to test"
17784         fi
17785
17786         local mds=$(facet_host $SINGLEMDS)
17787         local target=$(do_nodes $mds 'lctl dl' |
17788                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17789
17790         local cmd1="file_count=1000 thrhi=4"
17791         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17792         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17793         local cmd="$cmd1 $cmd2 $cmd3"
17794
17795         rm -f ${TMP}/mds_survey*
17796         echo + $cmd
17797         eval $cmd || error "mds-survey with stripe_count failed"
17798         cat ${TMP}/mds_survey*
17799         rm -f ${TMP}/mds_survey*
17800 }
17801 run_test 225b "Metadata survey sanity with stripe_count = 1"
17802
17803 mcreate_path2fid () {
17804         local mode=$1
17805         local major=$2
17806         local minor=$3
17807         local name=$4
17808         local desc=$5
17809         local path=$DIR/$tdir/$name
17810         local fid
17811         local rc
17812         local fid_path
17813
17814         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17815                 error "cannot create $desc"
17816
17817         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17818         rc=$?
17819         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17820
17821         fid_path=$($LFS fid2path $MOUNT $fid)
17822         rc=$?
17823         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17824
17825         [ "$path" == "$fid_path" ] ||
17826                 error "fid2path returned $fid_path, expected $path"
17827
17828         echo "pass with $path and $fid"
17829 }
17830
17831 test_226a () {
17832         rm -rf $DIR/$tdir
17833         mkdir -p $DIR/$tdir
17834
17835         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17836         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17837         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17838         mcreate_path2fid 0040666 0 0 dir "directory"
17839         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17840         mcreate_path2fid 0100666 0 0 file "regular file"
17841         mcreate_path2fid 0120666 0 0 link "symbolic link"
17842         mcreate_path2fid 0140666 0 0 sock "socket"
17843 }
17844 run_test 226a "call path2fid and fid2path on files of all type"
17845
17846 test_226b () {
17847         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17848
17849         local MDTIDX=1
17850
17851         rm -rf $DIR/$tdir
17852         mkdir -p $DIR/$tdir
17853         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17854                 error "create remote directory failed"
17855         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17856         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17857                                 "character special file (null)"
17858         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17859                                 "character special file (no device)"
17860         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17861         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17862                                 "block special file (loop)"
17863         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17864         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17865         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17866 }
17867 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17868
17869 test_226c () {
17870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17871         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17872                 skip "Need MDS version at least 2.13.55"
17873
17874         local submnt=/mnt/submnt
17875         local srcfile=/etc/passwd
17876         local dstfile=$submnt/passwd
17877         local path
17878         local fid
17879
17880         rm -rf $DIR/$tdir
17881         rm -rf $submnt
17882         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17883                 error "create remote directory failed"
17884         mkdir -p $submnt || error "create $submnt failed"
17885         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17886                 error "mount $submnt failed"
17887         stack_trap "umount $submnt" EXIT
17888
17889         cp $srcfile $dstfile
17890         fid=$($LFS path2fid $dstfile)
17891         path=$($LFS fid2path $submnt "$fid")
17892         [ "$path" = "$dstfile" ] ||
17893                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17894 }
17895 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17896
17897 # LU-1299 Executing or running ldd on a truncated executable does not
17898 # cause an out-of-memory condition.
17899 test_227() {
17900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17901         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17902
17903         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17904         chmod +x $MOUNT/date
17905
17906         $MOUNT/date > /dev/null
17907         ldd $MOUNT/date > /dev/null
17908         rm -f $MOUNT/date
17909 }
17910 run_test 227 "running truncated executable does not cause OOM"
17911
17912 # LU-1512 try to reuse idle OI blocks
17913 test_228a() {
17914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17915         remote_mds_nodsh && skip "remote MDS with nodsh"
17916         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17917
17918         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17919         local myDIR=$DIR/$tdir
17920
17921         mkdir -p $myDIR
17922         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17923         $LCTL set_param fail_loc=0x80001002
17924         createmany -o $myDIR/t- 10000
17925         $LCTL set_param fail_loc=0
17926         # The guard is current the largest FID holder
17927         touch $myDIR/guard
17928         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17929                     tr -d '[')
17930         local IDX=$(($SEQ % 64))
17931
17932         do_facet $SINGLEMDS sync
17933         # Make sure journal flushed.
17934         sleep 6
17935         local blk1=$(do_facet $SINGLEMDS \
17936                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17937                      grep Blockcount | awk '{print $4}')
17938
17939         # Remove old files, some OI blocks will become idle.
17940         unlinkmany $myDIR/t- 10000
17941         # Create new files, idle OI blocks should be reused.
17942         createmany -o $myDIR/t- 2000
17943         do_facet $SINGLEMDS sync
17944         # Make sure journal flushed.
17945         sleep 6
17946         local blk2=$(do_facet $SINGLEMDS \
17947                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17948                      grep Blockcount | awk '{print $4}')
17949
17950         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17951 }
17952 run_test 228a "try to reuse idle OI blocks"
17953
17954 test_228b() {
17955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17956         remote_mds_nodsh && skip "remote MDS with nodsh"
17957         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17958
17959         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17960         local myDIR=$DIR/$tdir
17961
17962         mkdir -p $myDIR
17963         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17964         $LCTL set_param fail_loc=0x80001002
17965         createmany -o $myDIR/t- 10000
17966         $LCTL set_param fail_loc=0
17967         # The guard is current the largest FID holder
17968         touch $myDIR/guard
17969         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17970                     tr -d '[')
17971         local IDX=$(($SEQ % 64))
17972
17973         do_facet $SINGLEMDS sync
17974         # Make sure journal flushed.
17975         sleep 6
17976         local blk1=$(do_facet $SINGLEMDS \
17977                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17978                      grep Blockcount | awk '{print $4}')
17979
17980         # Remove old files, some OI blocks will become idle.
17981         unlinkmany $myDIR/t- 10000
17982
17983         # stop the MDT
17984         stop $SINGLEMDS || error "Fail to stop MDT."
17985         # remount the MDT
17986         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17987
17988         df $MOUNT || error "Fail to df."
17989         # Create new files, idle OI blocks should be reused.
17990         createmany -o $myDIR/t- 2000
17991         do_facet $SINGLEMDS sync
17992         # Make sure journal flushed.
17993         sleep 6
17994         local blk2=$(do_facet $SINGLEMDS \
17995                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17996                      grep Blockcount | awk '{print $4}')
17997
17998         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17999 }
18000 run_test 228b "idle OI blocks can be reused after MDT restart"
18001
18002 #LU-1881
18003 test_228c() {
18004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18005         remote_mds_nodsh && skip "remote MDS with nodsh"
18006         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18007
18008         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18009         local myDIR=$DIR/$tdir
18010
18011         mkdir -p $myDIR
18012         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18013         $LCTL set_param fail_loc=0x80001002
18014         # 20000 files can guarantee there are index nodes in the OI file
18015         createmany -o $myDIR/t- 20000
18016         $LCTL set_param fail_loc=0
18017         # The guard is current the largest FID holder
18018         touch $myDIR/guard
18019         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18020                     tr -d '[')
18021         local IDX=$(($SEQ % 64))
18022
18023         do_facet $SINGLEMDS sync
18024         # Make sure journal flushed.
18025         sleep 6
18026         local blk1=$(do_facet $SINGLEMDS \
18027                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18028                      grep Blockcount | awk '{print $4}')
18029
18030         # Remove old files, some OI blocks will become idle.
18031         unlinkmany $myDIR/t- 20000
18032         rm -f $myDIR/guard
18033         # The OI file should become empty now
18034
18035         # Create new files, idle OI blocks should be reused.
18036         createmany -o $myDIR/t- 2000
18037         do_facet $SINGLEMDS sync
18038         # Make sure journal flushed.
18039         sleep 6
18040         local blk2=$(do_facet $SINGLEMDS \
18041                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18042                      grep Blockcount | awk '{print $4}')
18043
18044         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18045 }
18046 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18047
18048 test_229() { # LU-2482, LU-3448
18049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18050         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18051         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18052                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18053
18054         rm -f $DIR/$tfile
18055
18056         # Create a file with a released layout and stripe count 2.
18057         $MULTIOP $DIR/$tfile H2c ||
18058                 error "failed to create file with released layout"
18059
18060         $LFS getstripe -v $DIR/$tfile
18061
18062         local pattern=$($LFS getstripe -L $DIR/$tfile)
18063         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18064
18065         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18066                 error "getstripe"
18067         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18068         stat $DIR/$tfile || error "failed to stat released file"
18069
18070         chown $RUNAS_ID $DIR/$tfile ||
18071                 error "chown $RUNAS_ID $DIR/$tfile failed"
18072
18073         chgrp $RUNAS_ID $DIR/$tfile ||
18074                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18075
18076         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18077         rm $DIR/$tfile || error "failed to remove released file"
18078 }
18079 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18080
18081 test_230a() {
18082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18083         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18084         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18085                 skip "Need MDS version at least 2.11.52"
18086
18087         local MDTIDX=1
18088
18089         test_mkdir $DIR/$tdir
18090         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18091         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18092         [ $mdt_idx -ne 0 ] &&
18093                 error "create local directory on wrong MDT $mdt_idx"
18094
18095         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18096                         error "create remote directory failed"
18097         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18098         [ $mdt_idx -ne $MDTIDX ] &&
18099                 error "create remote directory on wrong MDT $mdt_idx"
18100
18101         createmany -o $DIR/$tdir/test_230/t- 10 ||
18102                 error "create files on remote directory failed"
18103         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18104         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18105         rm -r $DIR/$tdir || error "unlink remote directory failed"
18106 }
18107 run_test 230a "Create remote directory and files under the remote directory"
18108
18109 test_230b() {
18110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18112         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18113                 skip "Need MDS version at least 2.11.52"
18114
18115         local MDTIDX=1
18116         local mdt_index
18117         local i
18118         local file
18119         local pid
18120         local stripe_count
18121         local migrate_dir=$DIR/$tdir/migrate_dir
18122         local other_dir=$DIR/$tdir/other_dir
18123
18124         test_mkdir $DIR/$tdir
18125         test_mkdir -i0 -c1 $migrate_dir
18126         test_mkdir -i0 -c1 $other_dir
18127         for ((i=0; i<10; i++)); do
18128                 mkdir -p $migrate_dir/dir_${i}
18129                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18130                         error "create files under remote dir failed $i"
18131         done
18132
18133         cp /etc/passwd $migrate_dir/$tfile
18134         cp /etc/passwd $other_dir/$tfile
18135         chattr +SAD $migrate_dir
18136         chattr +SAD $migrate_dir/$tfile
18137
18138         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18139         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18140         local old_dir_mode=$(stat -c%f $migrate_dir)
18141         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18142
18143         mkdir -p $migrate_dir/dir_default_stripe2
18144         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18145         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18146
18147         mkdir -p $other_dir
18148         ln $migrate_dir/$tfile $other_dir/luna
18149         ln $migrate_dir/$tfile $migrate_dir/sofia
18150         ln $other_dir/$tfile $migrate_dir/david
18151         ln -s $migrate_dir/$tfile $other_dir/zachary
18152         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18153         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18154
18155         local len
18156         local lnktgt
18157
18158         # inline symlink
18159         for len in 58 59 60; do
18160                 lnktgt=$(str_repeat 'l' $len)
18161                 touch $migrate_dir/$lnktgt
18162                 ln -s $lnktgt $migrate_dir/${len}char_ln
18163         done
18164
18165         # PATH_MAX
18166         for len in 4094 4095; do
18167                 lnktgt=$(str_repeat 'l' $len)
18168                 ln -s $lnktgt $migrate_dir/${len}char_ln
18169         done
18170
18171         # NAME_MAX
18172         for len in 254 255; do
18173                 touch $migrate_dir/$(str_repeat 'l' $len)
18174         done
18175
18176         $LFS migrate -m $MDTIDX $migrate_dir ||
18177                 error "fails on migrating remote dir to MDT1"
18178
18179         echo "migratate to MDT1, then checking.."
18180         for ((i = 0; i < 10; i++)); do
18181                 for file in $(find $migrate_dir/dir_${i}); do
18182                         mdt_index=$($LFS getstripe -m $file)
18183                         # broken symlink getstripe will fail
18184                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18185                                 error "$file is not on MDT${MDTIDX}"
18186                 done
18187         done
18188
18189         # the multiple link file should still in MDT0
18190         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18191         [ $mdt_index == 0 ] ||
18192                 error "$file is not on MDT${MDTIDX}"
18193
18194         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18195         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18196                 error " expect $old_dir_flag get $new_dir_flag"
18197
18198         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18199         [ "$old_file_flag" = "$new_file_flag" ] ||
18200                 error " expect $old_file_flag get $new_file_flag"
18201
18202         local new_dir_mode=$(stat -c%f $migrate_dir)
18203         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18204                 error "expect mode $old_dir_mode get $new_dir_mode"
18205
18206         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18207         [ "$old_file_mode" = "$new_file_mode" ] ||
18208                 error "expect mode $old_file_mode get $new_file_mode"
18209
18210         diff /etc/passwd $migrate_dir/$tfile ||
18211                 error "$tfile different after migration"
18212
18213         diff /etc/passwd $other_dir/luna ||
18214                 error "luna different after migration"
18215
18216         diff /etc/passwd $migrate_dir/sofia ||
18217                 error "sofia different after migration"
18218
18219         diff /etc/passwd $migrate_dir/david ||
18220                 error "david different after migration"
18221
18222         diff /etc/passwd $other_dir/zachary ||
18223                 error "zachary different after migration"
18224
18225         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18226                 error "${tfile}_ln different after migration"
18227
18228         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18229                 error "${tfile}_ln_other different after migration"
18230
18231         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18232         [ $stripe_count = 2 ] ||
18233                 error "dir strpe_count $d != 2 after migration."
18234
18235         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18236         [ $stripe_count = 2 ] ||
18237                 error "file strpe_count $d != 2 after migration."
18238
18239         #migrate back to MDT0
18240         MDTIDX=0
18241
18242         $LFS migrate -m $MDTIDX $migrate_dir ||
18243                 error "fails on migrating remote dir to MDT0"
18244
18245         echo "migrate back to MDT0, checking.."
18246         for file in $(find $migrate_dir); do
18247                 mdt_index=$($LFS getstripe -m $file)
18248                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18249                         error "$file is not on MDT${MDTIDX}"
18250         done
18251
18252         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18253         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18254                 error " expect $old_dir_flag get $new_dir_flag"
18255
18256         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18257         [ "$old_file_flag" = "$new_file_flag" ] ||
18258                 error " expect $old_file_flag get $new_file_flag"
18259
18260         local new_dir_mode=$(stat -c%f $migrate_dir)
18261         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18262                 error "expect mode $old_dir_mode get $new_dir_mode"
18263
18264         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18265         [ "$old_file_mode" = "$new_file_mode" ] ||
18266                 error "expect mode $old_file_mode get $new_file_mode"
18267
18268         diff /etc/passwd ${migrate_dir}/$tfile ||
18269                 error "$tfile different after migration"
18270
18271         diff /etc/passwd ${other_dir}/luna ||
18272                 error "luna different after migration"
18273
18274         diff /etc/passwd ${migrate_dir}/sofia ||
18275                 error "sofia different after migration"
18276
18277         diff /etc/passwd ${other_dir}/zachary ||
18278                 error "zachary different after migration"
18279
18280         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18281                 error "${tfile}_ln different after migration"
18282
18283         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18284                 error "${tfile}_ln_other different after migration"
18285
18286         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18287         [ $stripe_count = 2 ] ||
18288                 error "dir strpe_count $d != 2 after migration."
18289
18290         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18291         [ $stripe_count = 2 ] ||
18292                 error "file strpe_count $d != 2 after migration."
18293
18294         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18295 }
18296 run_test 230b "migrate directory"
18297
18298 test_230c() {
18299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18301         remote_mds_nodsh && skip "remote MDS with nodsh"
18302         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18303                 skip "Need MDS version at least 2.11.52"
18304
18305         local MDTIDX=1
18306         local total=3
18307         local mdt_index
18308         local file
18309         local migrate_dir=$DIR/$tdir/migrate_dir
18310
18311         #If migrating directory fails in the middle, all entries of
18312         #the directory is still accessiable.
18313         test_mkdir $DIR/$tdir
18314         test_mkdir -i0 -c1 $migrate_dir
18315         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18316         stat $migrate_dir
18317         createmany -o $migrate_dir/f $total ||
18318                 error "create files under ${migrate_dir} failed"
18319
18320         # fail after migrating top dir, and this will fail only once, so the
18321         # first sub file migration will fail (currently f3), others succeed.
18322         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18323         do_facet mds1 lctl set_param fail_loc=0x1801
18324         local t=$(ls $migrate_dir | wc -l)
18325         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18326                 error "migrate should fail"
18327         local u=$(ls $migrate_dir | wc -l)
18328         [ "$u" == "$t" ] || error "$u != $t during migration"
18329
18330         # add new dir/file should succeed
18331         mkdir $migrate_dir/dir ||
18332                 error "mkdir failed under migrating directory"
18333         touch $migrate_dir/file ||
18334                 error "create file failed under migrating directory"
18335
18336         # add file with existing name should fail
18337         for file in $migrate_dir/f*; do
18338                 stat $file > /dev/null || error "stat $file failed"
18339                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18340                         error "open(O_CREAT|O_EXCL) $file should fail"
18341                 $MULTIOP $file m && error "create $file should fail"
18342                 touch $DIR/$tdir/remote_dir/$tfile ||
18343                         error "touch $tfile failed"
18344                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18345                         error "link $file should fail"
18346                 mdt_index=$($LFS getstripe -m $file)
18347                 if [ $mdt_index == 0 ]; then
18348                         # file failed to migrate is not allowed to rename to
18349                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18350                                 error "rename to $file should fail"
18351                 else
18352                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18353                                 error "rename to $file failed"
18354                 fi
18355                 echo hello >> $file || error "write $file failed"
18356         done
18357
18358         # resume migration with different options should fail
18359         $LFS migrate -m 0 $migrate_dir &&
18360                 error "migrate -m 0 $migrate_dir should fail"
18361
18362         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18363                 error "migrate -c 2 $migrate_dir should fail"
18364
18365         # resume migration should succeed
18366         $LFS migrate -m $MDTIDX $migrate_dir ||
18367                 error "migrate $migrate_dir failed"
18368
18369         echo "Finish migration, then checking.."
18370         for file in $(find $migrate_dir); do
18371                 mdt_index=$($LFS getstripe -m $file)
18372                 [ $mdt_index == $MDTIDX ] ||
18373                         error "$file is not on MDT${MDTIDX}"
18374         done
18375
18376         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18377 }
18378 run_test 230c "check directory accessiblity if migration failed"
18379
18380 test_230d() {
18381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18383         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18384                 skip "Need MDS version at least 2.11.52"
18385         # LU-11235
18386         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18387
18388         local migrate_dir=$DIR/$tdir/migrate_dir
18389         local old_index
18390         local new_index
18391         local old_count
18392         local new_count
18393         local new_hash
18394         local mdt_index
18395         local i
18396         local j
18397
18398         old_index=$((RANDOM % MDSCOUNT))
18399         old_count=$((MDSCOUNT - old_index))
18400         new_index=$((RANDOM % MDSCOUNT))
18401         new_count=$((MDSCOUNT - new_index))
18402         new_hash=1 # for all_char
18403
18404         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18405         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18406
18407         test_mkdir $DIR/$tdir
18408         test_mkdir -i $old_index -c $old_count $migrate_dir
18409
18410         for ((i=0; i<100; i++)); do
18411                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18412                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18413                         error "create files under remote dir failed $i"
18414         done
18415
18416         echo -n "Migrate from MDT$old_index "
18417         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18418         echo -n "to MDT$new_index"
18419         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18420         echo
18421
18422         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18423         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18424                 error "migrate remote dir error"
18425
18426         echo "Finish migration, then checking.."
18427         for file in $(find $migrate_dir); do
18428                 mdt_index=$($LFS getstripe -m $file)
18429                 if [ $mdt_index -lt $new_index ] ||
18430                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18431                         error "$file is on MDT$mdt_index"
18432                 fi
18433         done
18434
18435         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18436 }
18437 run_test 230d "check migrate big directory"
18438
18439 test_230e() {
18440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18442         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18443                 skip "Need MDS version at least 2.11.52"
18444
18445         local i
18446         local j
18447         local a_fid
18448         local b_fid
18449
18450         mkdir -p $DIR/$tdir
18451         mkdir $DIR/$tdir/migrate_dir
18452         mkdir $DIR/$tdir/other_dir
18453         touch $DIR/$tdir/migrate_dir/a
18454         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18455         ls $DIR/$tdir/other_dir
18456
18457         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18458                 error "migrate dir fails"
18459
18460         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18461         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18462
18463         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18464         [ $mdt_index == 0 ] || error "a is not on MDT0"
18465
18466         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18467                 error "migrate dir fails"
18468
18469         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18470         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18471
18472         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18473         [ $mdt_index == 1 ] || error "a is not on MDT1"
18474
18475         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18476         [ $mdt_index == 1 ] || error "b is not on MDT1"
18477
18478         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18479         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18480
18481         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18482
18483         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18484 }
18485 run_test 230e "migrate mulitple local link files"
18486
18487 test_230f() {
18488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18489         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18490         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18491                 skip "Need MDS version at least 2.11.52"
18492
18493         local a_fid
18494         local ln_fid
18495
18496         mkdir -p $DIR/$tdir
18497         mkdir $DIR/$tdir/migrate_dir
18498         $LFS mkdir -i1 $DIR/$tdir/other_dir
18499         touch $DIR/$tdir/migrate_dir/a
18500         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18501         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18502         ls $DIR/$tdir/other_dir
18503
18504         # a should be migrated to MDT1, since no other links on MDT0
18505         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18506                 error "#1 migrate dir fails"
18507         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18508         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18509         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18510         [ $mdt_index == 1 ] || error "a is not on MDT1"
18511
18512         # a should stay on MDT1, because it is a mulitple link file
18513         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18514                 error "#2 migrate dir fails"
18515         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18516         [ $mdt_index == 1 ] || error "a is not on MDT1"
18517
18518         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18519                 error "#3 migrate dir fails"
18520
18521         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18522         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18523         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18524
18525         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18526         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18527
18528         # a should be migrated to MDT0, since no other links on MDT1
18529         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18530                 error "#4 migrate dir fails"
18531         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18532         [ $mdt_index == 0 ] || error "a is not on MDT0"
18533
18534         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18535 }
18536 run_test 230f "migrate mulitple remote link files"
18537
18538 test_230g() {
18539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18541         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18542                 skip "Need MDS version at least 2.11.52"
18543
18544         mkdir -p $DIR/$tdir/migrate_dir
18545
18546         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18547                 error "migrating dir to non-exist MDT succeeds"
18548         true
18549 }
18550 run_test 230g "migrate dir to non-exist MDT"
18551
18552 test_230h() {
18553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18555         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18556                 skip "Need MDS version at least 2.11.52"
18557
18558         local mdt_index
18559
18560         mkdir -p $DIR/$tdir/migrate_dir
18561
18562         $LFS migrate -m1 $DIR &&
18563                 error "migrating mountpoint1 should fail"
18564
18565         $LFS migrate -m1 $DIR/$tdir/.. &&
18566                 error "migrating mountpoint2 should fail"
18567
18568         # same as mv
18569         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18570                 error "migrating $tdir/migrate_dir/.. should fail"
18571
18572         true
18573 }
18574 run_test 230h "migrate .. and root"
18575
18576 test_230i() {
18577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18579         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18580                 skip "Need MDS version at least 2.11.52"
18581
18582         mkdir -p $DIR/$tdir/migrate_dir
18583
18584         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18585                 error "migration fails with a tailing slash"
18586
18587         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18588                 error "migration fails with two tailing slashes"
18589 }
18590 run_test 230i "lfs migrate -m tolerates trailing slashes"
18591
18592 test_230j() {
18593         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18594         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18595                 skip "Need MDS version at least 2.11.52"
18596
18597         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18598         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18599                 error "create $tfile failed"
18600         cat /etc/passwd > $DIR/$tdir/$tfile
18601
18602         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18603
18604         cmp /etc/passwd $DIR/$tdir/$tfile ||
18605                 error "DoM file mismatch after migration"
18606 }
18607 run_test 230j "DoM file data not changed after dir migration"
18608
18609 test_230k() {
18610         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18611         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18612                 skip "Need MDS version at least 2.11.56"
18613
18614         local total=20
18615         local files_on_starting_mdt=0
18616
18617         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18618         $LFS getdirstripe $DIR/$tdir
18619         for i in $(seq $total); do
18620                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18621                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18622                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18623         done
18624
18625         echo "$files_on_starting_mdt files on MDT0"
18626
18627         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18628         $LFS getdirstripe $DIR/$tdir
18629
18630         files_on_starting_mdt=0
18631         for i in $(seq $total); do
18632                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18633                         error "file $tfile.$i mismatch after migration"
18634                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18635                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18636         done
18637
18638         echo "$files_on_starting_mdt files on MDT1 after migration"
18639         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18640
18641         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18642         $LFS getdirstripe $DIR/$tdir
18643
18644         files_on_starting_mdt=0
18645         for i in $(seq $total); do
18646                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18647                         error "file $tfile.$i mismatch after 2nd migration"
18648                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18649                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18650         done
18651
18652         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18653         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18654
18655         true
18656 }
18657 run_test 230k "file data not changed after dir migration"
18658
18659 test_230l() {
18660         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18661         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18662                 skip "Need MDS version at least 2.11.56"
18663
18664         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18665         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18666                 error "create files under remote dir failed $i"
18667         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18668 }
18669 run_test 230l "readdir between MDTs won't crash"
18670
18671 test_230m() {
18672         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18673         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18674                 skip "Need MDS version at least 2.11.56"
18675
18676         local MDTIDX=1
18677         local mig_dir=$DIR/$tdir/migrate_dir
18678         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18679         local shortstr="b"
18680         local val
18681
18682         echo "Creating files and dirs with xattrs"
18683         test_mkdir $DIR/$tdir
18684         test_mkdir -i0 -c1 $mig_dir
18685         mkdir $mig_dir/dir
18686         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18687                 error "cannot set xattr attr1 on dir"
18688         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18689                 error "cannot set xattr attr2 on dir"
18690         touch $mig_dir/dir/f0
18691         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18692                 error "cannot set xattr attr1 on file"
18693         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18694                 error "cannot set xattr attr2 on file"
18695         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18696         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18697         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18698         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18699         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18700         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18701         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18702         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18703         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18704
18705         echo "Migrating to MDT1"
18706         $LFS migrate -m $MDTIDX $mig_dir ||
18707                 error "fails on migrating dir to MDT1"
18708
18709         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18710         echo "Checking xattrs"
18711         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18712         [ "$val" = $longstr ] ||
18713                 error "expecting xattr1 $longstr on dir, found $val"
18714         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18715         [ "$val" = $shortstr ] ||
18716                 error "expecting xattr2 $shortstr on dir, found $val"
18717         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18718         [ "$val" = $longstr ] ||
18719                 error "expecting xattr1 $longstr on file, found $val"
18720         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18721         [ "$val" = $shortstr ] ||
18722                 error "expecting xattr2 $shortstr on file, found $val"
18723 }
18724 run_test 230m "xattrs not changed after dir migration"
18725
18726 test_230n() {
18727         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18728         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18729                 skip "Need MDS version at least 2.13.53"
18730
18731         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18732         cat /etc/hosts > $DIR/$tdir/$tfile
18733         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18734         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18735
18736         cmp /etc/hosts $DIR/$tdir/$tfile ||
18737                 error "File data mismatch after migration"
18738 }
18739 run_test 230n "Dir migration with mirrored file"
18740
18741 test_230o() {
18742         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18743         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18744                 skip "Need MDS version at least 2.13.52"
18745
18746         local mdts=$(comma_list $(mdts_nodes))
18747         local timeout=100
18748
18749         local restripe_status
18750         local delta
18751         local i
18752         local j
18753
18754         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18755
18756         # in case "crush" hash type is not set
18757         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18758
18759         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18760                            mdt.*MDT0000.enable_dir_restripe)
18761         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18762         stack_trap "do_nodes $mdts $LCTL set_param \
18763                     mdt.*.enable_dir_restripe=$restripe_status"
18764
18765         mkdir $DIR/$tdir
18766         createmany -m $DIR/$tdir/f 100 ||
18767                 error "create files under remote dir failed $i"
18768         createmany -d $DIR/$tdir/d 100 ||
18769                 error "create dirs under remote dir failed $i"
18770
18771         for i in $(seq 2 $MDSCOUNT); do
18772                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18773                 $LFS setdirstripe -c $i $DIR/$tdir ||
18774                         error "split -c $i $tdir failed"
18775                 wait_update $HOSTNAME \
18776                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18777                         error "dir split not finished"
18778                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18779                         awk '/migrate/ {sum += $2} END { print sum }')
18780                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18781                 # delta is around total_files/stripe_count
18782                 [ $delta -lt $((200 /(i - 1))) ] ||
18783                         error "$delta files migrated"
18784         done
18785 }
18786 run_test 230o "dir split"
18787
18788 test_230p() {
18789         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18790         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18791                 skip "Need MDS version at least 2.13.52"
18792
18793         local mdts=$(comma_list $(mdts_nodes))
18794         local timeout=100
18795
18796         local restripe_status
18797         local delta
18798         local i
18799         local j
18800
18801         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18802
18803         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18804
18805         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18806                            mdt.*MDT0000.enable_dir_restripe)
18807         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18808         stack_trap "do_nodes $mdts $LCTL set_param \
18809                     mdt.*.enable_dir_restripe=$restripe_status"
18810
18811         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18812         createmany -m $DIR/$tdir/f 100 ||
18813                 error "create files under remote dir failed $i"
18814         createmany -d $DIR/$tdir/d 100 ||
18815                 error "create dirs under remote dir failed $i"
18816
18817         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18818                 local mdt_hash="crush"
18819
18820                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18821                 $LFS setdirstripe -c $i $DIR/$tdir ||
18822                         error "split -c $i $tdir failed"
18823                 [ $i -eq 1 ] && mdt_hash="none"
18824                 wait_update $HOSTNAME \
18825                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18826                         error "dir merge not finished"
18827                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18828                         awk '/migrate/ {sum += $2} END { print sum }')
18829                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18830                 # delta is around total_files/stripe_count
18831                 [ $delta -lt $((200 / i)) ] ||
18832                         error "$delta files migrated"
18833         done
18834 }
18835 run_test 230p "dir merge"
18836
18837 test_230q() {
18838         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18839         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18840                 skip "Need MDS version at least 2.13.52"
18841
18842         local mdts=$(comma_list $(mdts_nodes))
18843         local saved_threshold=$(do_facet mds1 \
18844                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18845         local saved_delta=$(do_facet mds1 \
18846                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18847         local threshold=100
18848         local delta=2
18849         local total=0
18850         local stripe_count=0
18851         local stripe_index
18852         local nr_files
18853
18854         # test with fewer files on ZFS
18855         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18856
18857         stack_trap "do_nodes $mdts $LCTL set_param \
18858                     mdt.*.dir_split_count=$saved_threshold"
18859         stack_trap "do_nodes $mdts $LCTL set_param \
18860                     mdt.*.dir_split_delta=$saved_delta"
18861         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18862         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18863         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18864         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18865         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18866         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18867
18868         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18869         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18870
18871         while [ $stripe_count -lt $MDSCOUNT ]; do
18872                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18873                         error "create sub files failed"
18874                 stat $DIR/$tdir > /dev/null
18875                 total=$((total + threshold * 3 / 2))
18876                 stripe_count=$((stripe_count + delta))
18877                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18878
18879                 wait_update $HOSTNAME \
18880                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18881                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18882
18883                 wait_update $HOSTNAME \
18884                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18885                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18886
18887                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18888                            grep -w $stripe_index | wc -l)
18889                 echo "$nr_files files on MDT$stripe_index after split"
18890                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18891                         error "$nr_files files on MDT$stripe_index after split"
18892
18893                 nr_files=$(ls $DIR/$tdir | wc -w)
18894                 [ $nr_files -eq $total ] ||
18895                         error "total sub files $nr_files != $total"
18896         done
18897 }
18898 run_test 230q "dir auto split"
18899
18900 test_230r() {
18901         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18902         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18903         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18904                 skip "Need MDS version at least 2.13.54"
18905
18906         # maximum amount of local locks:
18907         # parent striped dir - 2 locks
18908         # new stripe in parent to migrate to - 1 lock
18909         # source and target - 2 locks
18910         # Total 5 locks for regular file
18911         mkdir -p $DIR/$tdir
18912         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18913         touch $DIR/$tdir/dir1/eee
18914
18915         # create 4 hardlink for 4 more locks
18916         # Total: 9 locks > RS_MAX_LOCKS (8)
18917         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18918         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18919         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18920         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18921         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18922         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18923         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18924         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18925
18926         cancel_lru_locks mdc
18927
18928         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18929                 error "migrate dir fails"
18930
18931         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18932 }
18933 run_test 230r "migrate with too many local locks"
18934
18935 test_231a()
18936 {
18937         # For simplicity this test assumes that max_pages_per_rpc
18938         # is the same across all OSCs
18939         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18940         local bulk_size=$((max_pages * PAGE_SIZE))
18941         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18942                                        head -n 1)
18943
18944         mkdir -p $DIR/$tdir
18945         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18946                 error "failed to set stripe with -S ${brw_size}M option"
18947
18948         # clear the OSC stats
18949         $LCTL set_param osc.*.stats=0 &>/dev/null
18950         stop_writeback
18951
18952         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18953         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18954                 oflag=direct &>/dev/null || error "dd failed"
18955
18956         sync; sleep 1; sync # just to be safe
18957         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18958         if [ x$nrpcs != "x1" ]; then
18959                 $LCTL get_param osc.*.stats
18960                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18961         fi
18962
18963         start_writeback
18964         # Drop the OSC cache, otherwise we will read from it
18965         cancel_lru_locks osc
18966
18967         # clear the OSC stats
18968         $LCTL set_param osc.*.stats=0 &>/dev/null
18969
18970         # Client reads $bulk_size.
18971         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18972                 iflag=direct &>/dev/null || error "dd failed"
18973
18974         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18975         if [ x$nrpcs != "x1" ]; then
18976                 $LCTL get_param osc.*.stats
18977                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18978         fi
18979 }
18980 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18981
18982 test_231b() {
18983         mkdir -p $DIR/$tdir
18984         local i
18985         for i in {0..1023}; do
18986                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18987                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18988                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18989         done
18990         sync
18991 }
18992 run_test 231b "must not assert on fully utilized OST request buffer"
18993
18994 test_232a() {
18995         mkdir -p $DIR/$tdir
18996         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18997
18998         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18999         do_facet ost1 $LCTL set_param fail_loc=0x31c
19000
19001         # ignore dd failure
19002         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19003
19004         do_facet ost1 $LCTL set_param fail_loc=0
19005         umount_client $MOUNT || error "umount failed"
19006         mount_client $MOUNT || error "mount failed"
19007         stop ost1 || error "cannot stop ost1"
19008         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19009 }
19010 run_test 232a "failed lock should not block umount"
19011
19012 test_232b() {
19013         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19014                 skip "Need MDS version at least 2.10.58"
19015
19016         mkdir -p $DIR/$tdir
19017         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19018         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19019         sync
19020         cancel_lru_locks osc
19021
19022         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19023         do_facet ost1 $LCTL set_param fail_loc=0x31c
19024
19025         # ignore failure
19026         $LFS data_version $DIR/$tdir/$tfile || true
19027
19028         do_facet ost1 $LCTL set_param fail_loc=0
19029         umount_client $MOUNT || error "umount failed"
19030         mount_client $MOUNT || error "mount failed"
19031         stop ost1 || error "cannot stop ost1"
19032         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19033 }
19034 run_test 232b "failed data version lock should not block umount"
19035
19036 test_233a() {
19037         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19038                 skip "Need MDS version at least 2.3.64"
19039         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19040
19041         local fid=$($LFS path2fid $MOUNT)
19042
19043         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19044                 error "cannot access $MOUNT using its FID '$fid'"
19045 }
19046 run_test 233a "checking that OBF of the FS root succeeds"
19047
19048 test_233b() {
19049         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19050                 skip "Need MDS version at least 2.5.90"
19051         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19052
19053         local fid=$($LFS path2fid $MOUNT/.lustre)
19054
19055         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19056                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19057
19058         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19059         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19060                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19061 }
19062 run_test 233b "checking that OBF of the FS .lustre succeeds"
19063
19064 test_234() {
19065         local p="$TMP/sanityN-$TESTNAME.parameters"
19066         save_lustre_params client "llite.*.xattr_cache" > $p
19067         lctl set_param llite.*.xattr_cache 1 ||
19068                 skip_env "xattr cache is not supported"
19069
19070         mkdir -p $DIR/$tdir || error "mkdir failed"
19071         touch $DIR/$tdir/$tfile || error "touch failed"
19072         # OBD_FAIL_LLITE_XATTR_ENOMEM
19073         $LCTL set_param fail_loc=0x1405
19074         getfattr -n user.attr $DIR/$tdir/$tfile &&
19075                 error "getfattr should have failed with ENOMEM"
19076         $LCTL set_param fail_loc=0x0
19077         rm -rf $DIR/$tdir
19078
19079         restore_lustre_params < $p
19080         rm -f $p
19081 }
19082 run_test 234 "xattr cache should not crash on ENOMEM"
19083
19084 test_235() {
19085         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19086                 skip "Need MDS version at least 2.4.52"
19087
19088         flock_deadlock $DIR/$tfile
19089         local RC=$?
19090         case $RC in
19091                 0)
19092                 ;;
19093                 124) error "process hangs on a deadlock"
19094                 ;;
19095                 *) error "error executing flock_deadlock $DIR/$tfile"
19096                 ;;
19097         esac
19098 }
19099 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19100
19101 #LU-2935
19102 test_236() {
19103         check_swap_layouts_support
19104
19105         local ref1=/etc/passwd
19106         local ref2=/etc/group
19107         local file1=$DIR/$tdir/f1
19108         local file2=$DIR/$tdir/f2
19109
19110         test_mkdir -c1 $DIR/$tdir
19111         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19112         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19113         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19114         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19115         local fd=$(free_fd)
19116         local cmd="exec $fd<>$file2"
19117         eval $cmd
19118         rm $file2
19119         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19120                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19121         cmd="exec $fd>&-"
19122         eval $cmd
19123         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19124
19125         #cleanup
19126         rm -rf $DIR/$tdir
19127 }
19128 run_test 236 "Layout swap on open unlinked file"
19129
19130 # LU-4659 linkea consistency
19131 test_238() {
19132         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19133                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19134                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19135                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19136
19137         touch $DIR/$tfile
19138         ln $DIR/$tfile $DIR/$tfile.lnk
19139         touch $DIR/$tfile.new
19140         mv $DIR/$tfile.new $DIR/$tfile
19141         local fid1=$($LFS path2fid $DIR/$tfile)
19142         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19143         local path1=$($LFS fid2path $FSNAME "$fid1")
19144         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19145         local path2=$($LFS fid2path $FSNAME "$fid2")
19146         [ $tfile.lnk == $path2 ] ||
19147                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19148         rm -f $DIR/$tfile*
19149 }
19150 run_test 238 "Verify linkea consistency"
19151
19152 test_239A() { # was test_239
19153         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19154                 skip "Need MDS version at least 2.5.60"
19155
19156         local list=$(comma_list $(mdts_nodes))
19157
19158         mkdir -p $DIR/$tdir
19159         createmany -o $DIR/$tdir/f- 5000
19160         unlinkmany $DIR/$tdir/f- 5000
19161         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19162                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19163         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19164                         osp.*MDT*.sync_in_flight" | calc_sum)
19165         [ "$changes" -eq 0 ] || error "$changes not synced"
19166 }
19167 run_test 239A "osp_sync test"
19168
19169 test_239a() { #LU-5297
19170         remote_mds_nodsh && skip "remote MDS with nodsh"
19171
19172         touch $DIR/$tfile
19173         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19174         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19175         chgrp $RUNAS_GID $DIR/$tfile
19176         wait_delete_completed
19177 }
19178 run_test 239a "process invalid osp sync record correctly"
19179
19180 test_239b() { #LU-5297
19181         remote_mds_nodsh && skip "remote MDS with nodsh"
19182
19183         touch $DIR/$tfile1
19184         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19185         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19186         chgrp $RUNAS_GID $DIR/$tfile1
19187         wait_delete_completed
19188         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19189         touch $DIR/$tfile2
19190         chgrp $RUNAS_GID $DIR/$tfile2
19191         wait_delete_completed
19192 }
19193 run_test 239b "process osp sync record with ENOMEM error correctly"
19194
19195 test_240() {
19196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19197         remote_mds_nodsh && skip "remote MDS with nodsh"
19198
19199         mkdir -p $DIR/$tdir
19200
19201         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19202                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19203         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19204                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19205
19206         umount_client $MOUNT || error "umount failed"
19207         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19208         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19209         mount_client $MOUNT || error "failed to mount client"
19210
19211         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19212         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19213 }
19214 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19215
19216 test_241_bio() {
19217         local count=$1
19218         local bsize=$2
19219
19220         for LOOP in $(seq $count); do
19221                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19222                 cancel_lru_locks $OSC || true
19223         done
19224 }
19225
19226 test_241_dio() {
19227         local count=$1
19228         local bsize=$2
19229
19230         for LOOP in $(seq $1); do
19231                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19232                         2>/dev/null
19233         done
19234 }
19235
19236 test_241a() { # was test_241
19237         local bsize=$PAGE_SIZE
19238
19239         (( bsize < 40960 )) && bsize=40960
19240         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19241         ls -la $DIR/$tfile
19242         cancel_lru_locks $OSC
19243         test_241_bio 1000 $bsize &
19244         PID=$!
19245         test_241_dio 1000 $bsize
19246         wait $PID
19247 }
19248 run_test 241a "bio vs dio"
19249
19250 test_241b() {
19251         local bsize=$PAGE_SIZE
19252
19253         (( bsize < 40960 )) && bsize=40960
19254         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19255         ls -la $DIR/$tfile
19256         test_241_dio 1000 $bsize &
19257         PID=$!
19258         test_241_dio 1000 $bsize
19259         wait $PID
19260 }
19261 run_test 241b "dio vs dio"
19262
19263 test_242() {
19264         remote_mds_nodsh && skip "remote MDS with nodsh"
19265
19266         mkdir -p $DIR/$tdir
19267         touch $DIR/$tdir/$tfile
19268
19269         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19270         do_facet mds1 lctl set_param fail_loc=0x105
19271         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19272
19273         do_facet mds1 lctl set_param fail_loc=0
19274         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19275 }
19276 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19277
19278 test_243()
19279 {
19280         test_mkdir $DIR/$tdir
19281         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19282 }
19283 run_test 243 "various group lock tests"
19284
19285 test_244a()
19286 {
19287         test_mkdir $DIR/$tdir
19288         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19289         sendfile_grouplock $DIR/$tdir/$tfile || \
19290                 error "sendfile+grouplock failed"
19291         rm -rf $DIR/$tdir
19292 }
19293 run_test 244a "sendfile with group lock tests"
19294
19295 test_244b()
19296 {
19297         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19298
19299         local threads=50
19300         local size=$((1024*1024))
19301
19302         test_mkdir $DIR/$tdir
19303         for i in $(seq 1 $threads); do
19304                 local file=$DIR/$tdir/file_$((i / 10))
19305                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19306                 local pids[$i]=$!
19307         done
19308         for i in $(seq 1 $threads); do
19309                 wait ${pids[$i]}
19310         done
19311 }
19312 run_test 244b "multi-threaded write with group lock"
19313
19314 test_245() {
19315         local flagname="multi_mod_rpcs"
19316         local connect_data_name="max_mod_rpcs"
19317         local out
19318
19319         # check if multiple modify RPCs flag is set
19320         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19321                 grep "connect_flags:")
19322         echo "$out"
19323
19324         echo "$out" | grep -qw $flagname
19325         if [ $? -ne 0 ]; then
19326                 echo "connect flag $flagname is not set"
19327                 return
19328         fi
19329
19330         # check if multiple modify RPCs data is set
19331         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19332         echo "$out"
19333
19334         echo "$out" | grep -qw $connect_data_name ||
19335                 error "import should have connect data $connect_data_name"
19336 }
19337 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19338
19339 cleanup_247() {
19340         local submount=$1
19341
19342         trap 0
19343         umount_client $submount
19344         rmdir $submount
19345 }
19346
19347 test_247a() {
19348         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19349                 grep -q subtree ||
19350                 skip_env "Fileset feature is not supported"
19351
19352         local submount=${MOUNT}_$tdir
19353
19354         mkdir $MOUNT/$tdir
19355         mkdir -p $submount || error "mkdir $submount failed"
19356         FILESET="$FILESET/$tdir" mount_client $submount ||
19357                 error "mount $submount failed"
19358         trap "cleanup_247 $submount" EXIT
19359         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19360         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19361                 error "read $MOUNT/$tdir/$tfile failed"
19362         cleanup_247 $submount
19363 }
19364 run_test 247a "mount subdir as fileset"
19365
19366 test_247b() {
19367         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19368                 skip_env "Fileset feature is not supported"
19369
19370         local submount=${MOUNT}_$tdir
19371
19372         rm -rf $MOUNT/$tdir
19373         mkdir -p $submount || error "mkdir $submount failed"
19374         SKIP_FILESET=1
19375         FILESET="$FILESET/$tdir" mount_client $submount &&
19376                 error "mount $submount should fail"
19377         rmdir $submount
19378 }
19379 run_test 247b "mount subdir that dose not exist"
19380
19381 test_247c() {
19382         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19383                 skip_env "Fileset feature is not supported"
19384
19385         local submount=${MOUNT}_$tdir
19386
19387         mkdir -p $MOUNT/$tdir/dir1
19388         mkdir -p $submount || error "mkdir $submount failed"
19389         trap "cleanup_247 $submount" EXIT
19390         FILESET="$FILESET/$tdir" mount_client $submount ||
19391                 error "mount $submount failed"
19392         local fid=$($LFS path2fid $MOUNT/)
19393         $LFS fid2path $submount $fid && error "fid2path should fail"
19394         cleanup_247 $submount
19395 }
19396 run_test 247c "running fid2path outside subdirectory root"
19397
19398 test_247d() {
19399         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19400                 skip "Fileset feature is not supported"
19401
19402         local submount=${MOUNT}_$tdir
19403
19404         mkdir -p $MOUNT/$tdir/dir1
19405         mkdir -p $submount || error "mkdir $submount failed"
19406         FILESET="$FILESET/$tdir" mount_client $submount ||
19407                 error "mount $submount failed"
19408         trap "cleanup_247 $submount" EXIT
19409
19410         local td=$submount/dir1
19411         local fid=$($LFS path2fid $td)
19412         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19413
19414         # check that we get the same pathname back
19415         local rootpath
19416         local found
19417         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19418                 echo "$rootpath $fid"
19419                 found=$($LFS fid2path $rootpath "$fid")
19420                 [ -n "found" ] || error "fid2path should succeed"
19421                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19422         done
19423         # check wrong root path format
19424         rootpath=$submount"_wrong"
19425         found=$($LFS fid2path $rootpath "$fid")
19426         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19427
19428         cleanup_247 $submount
19429 }
19430 run_test 247d "running fid2path inside subdirectory root"
19431
19432 # LU-8037
19433 test_247e() {
19434         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19435                 grep -q subtree ||
19436                 skip "Fileset feature is not supported"
19437
19438         local submount=${MOUNT}_$tdir
19439
19440         mkdir $MOUNT/$tdir
19441         mkdir -p $submount || error "mkdir $submount failed"
19442         FILESET="$FILESET/.." mount_client $submount &&
19443                 error "mount $submount should fail"
19444         rmdir $submount
19445 }
19446 run_test 247e "mount .. as fileset"
19447
19448 test_247f() {
19449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19450         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19451                 skip "Need at least version 2.13.52"
19452         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19453                 grep -q subtree ||
19454                 skip "Fileset feature is not supported"
19455
19456         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19457         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19458                 error "mkdir remote failed"
19459         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19460         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19461                 error "mkdir striped failed"
19462         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19463
19464         local submount=${MOUNT}_$tdir
19465
19466         mkdir -p $submount || error "mkdir $submount failed"
19467
19468         local dir
19469         local fileset=$FILESET
19470
19471         for dir in $tdir/remote $tdir/remote/subdir \
19472                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19473                 FILESET="$fileset/$dir" mount_client $submount ||
19474                         error "mount $dir failed"
19475                 umount_client $submount
19476         done
19477 }
19478 run_test 247f "mount striped or remote directory as fileset"
19479
19480 test_248a() {
19481         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19482         [ -z "$fast_read_sav" ] && skip "no fast read support"
19483
19484         # create a large file for fast read verification
19485         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19486
19487         # make sure the file is created correctly
19488         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19489                 { rm -f $DIR/$tfile; skip "file creation error"; }
19490
19491         echo "Test 1: verify that fast read is 4 times faster on cache read"
19492
19493         # small read with fast read enabled
19494         $LCTL set_param -n llite.*.fast_read=1
19495         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19496                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19497                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19498         # small read with fast read disabled
19499         $LCTL set_param -n llite.*.fast_read=0
19500         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19501                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19502                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19503
19504         # verify that fast read is 4 times faster for cache read
19505         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19506                 error_not_in_vm "fast read was not 4 times faster: " \
19507                            "$t_fast vs $t_slow"
19508
19509         echo "Test 2: verify the performance between big and small read"
19510         $LCTL set_param -n llite.*.fast_read=1
19511
19512         # 1k non-cache read
19513         cancel_lru_locks osc
19514         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19515                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19516                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19517
19518         # 1M non-cache read
19519         cancel_lru_locks osc
19520         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19521                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19522                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19523
19524         # verify that big IO is not 4 times faster than small IO
19525         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19526                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19527
19528         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19529         rm -f $DIR/$tfile
19530 }
19531 run_test 248a "fast read verification"
19532
19533 test_248b() {
19534         # Default short_io_bytes=16384, try both smaller and larger sizes.
19535         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19536         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19537         echo "bs=53248 count=113 normal buffered write"
19538         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19539                 error "dd of initial data file failed"
19540         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19541
19542         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19543         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19544                 error "dd with sync normal writes failed"
19545         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19546
19547         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19548         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19549                 error "dd with sync small writes failed"
19550         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19551
19552         cancel_lru_locks osc
19553
19554         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19555         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19556         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19557         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19558                 iflag=direct || error "dd with O_DIRECT small read failed"
19559         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19560         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19561                 error "compare $TMP/$tfile.1 failed"
19562
19563         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19564         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19565
19566         # just to see what the maximum tunable value is, and test parsing
19567         echo "test invalid parameter 2MB"
19568         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19569                 error "too-large short_io_bytes allowed"
19570         echo "test maximum parameter 512KB"
19571         # if we can set a larger short_io_bytes, run test regardless of version
19572         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19573                 # older clients may not allow setting it this large, that's OK
19574                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19575                         skip "Need at least client version 2.13.50"
19576                 error "medium short_io_bytes failed"
19577         fi
19578         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19579         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19580
19581         echo "test large parameter 64KB"
19582         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19583         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19584
19585         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19586         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19587                 error "dd with sync large writes failed"
19588         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19589
19590         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19591         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19592         num=$((113 * 4096 / PAGE_SIZE))
19593         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19594         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19595                 error "dd with O_DIRECT large writes failed"
19596         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19597                 error "compare $DIR/$tfile.3 failed"
19598
19599         cancel_lru_locks osc
19600
19601         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19602         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19603                 error "dd with O_DIRECT large read failed"
19604         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19605                 error "compare $TMP/$tfile.2 failed"
19606
19607         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19608         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19609                 error "dd with O_DIRECT large read failed"
19610         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19611                 error "compare $TMP/$tfile.3 failed"
19612 }
19613 run_test 248b "test short_io read and write for both small and large sizes"
19614
19615 test_249() { # LU-7890
19616         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19617                 skip "Need at least version 2.8.54"
19618
19619         rm -f $DIR/$tfile
19620         $LFS setstripe -c 1 $DIR/$tfile
19621         # Offset 2T == 4k * 512M
19622         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19623                 error "dd to 2T offset failed"
19624 }
19625 run_test 249 "Write above 2T file size"
19626
19627 test_250() {
19628         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19629          && skip "no 16TB file size limit on ZFS"
19630
19631         $LFS setstripe -c 1 $DIR/$tfile
19632         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19633         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19634         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19635         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19636                 conv=notrunc,fsync && error "append succeeded"
19637         return 0
19638 }
19639 run_test 250 "Write above 16T limit"
19640
19641 test_251() {
19642         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19643
19644         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19645         #Skip once - writing the first stripe will succeed
19646         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19647         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19648                 error "short write happened"
19649
19650         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19651         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19652                 error "short read happened"
19653
19654         rm -f $DIR/$tfile
19655 }
19656 run_test 251 "Handling short read and write correctly"
19657
19658 test_252() {
19659         remote_mds_nodsh && skip "remote MDS with nodsh"
19660         remote_ost_nodsh && skip "remote OST with nodsh"
19661         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19662                 skip_env "ldiskfs only test"
19663         fi
19664
19665         local tgt
19666         local dev
19667         local out
19668         local uuid
19669         local num
19670         local gen
19671
19672         # check lr_reader on OST0000
19673         tgt=ost1
19674         dev=$(facet_device $tgt)
19675         out=$(do_facet $tgt $LR_READER $dev)
19676         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19677         echo "$out"
19678         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19679         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19680                 error "Invalid uuid returned by $LR_READER on target $tgt"
19681         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19682
19683         # check lr_reader -c on MDT0000
19684         tgt=mds1
19685         dev=$(facet_device $tgt)
19686         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19687                 skip "$LR_READER does not support additional options"
19688         fi
19689         out=$(do_facet $tgt $LR_READER -c $dev)
19690         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19691         echo "$out"
19692         num=$(echo "$out" | grep -c "mdtlov")
19693         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19694                 error "Invalid number of mdtlov clients returned by $LR_READER"
19695         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19696
19697         # check lr_reader -cr on MDT0000
19698         out=$(do_facet $tgt $LR_READER -cr $dev)
19699         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19700         echo "$out"
19701         echo "$out" | grep -q "^reply_data:$" ||
19702                 error "$LR_READER should have returned 'reply_data' section"
19703         num=$(echo "$out" | grep -c "client_generation")
19704         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19705 }
19706 run_test 252 "check lr_reader tool"
19707
19708 test_253() {
19709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19710         remote_mds_nodsh && skip "remote MDS with nodsh"
19711         remote_mgs_nodsh && skip "remote MGS with nodsh"
19712
19713         local ostidx=0
19714         local rc=0
19715         local ost_name=$(ostname_from_index $ostidx)
19716
19717         # on the mdt's osc
19718         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19719         do_facet $SINGLEMDS $LCTL get_param -n \
19720                 osp.$mdtosc_proc1.reserved_mb_high ||
19721                 skip  "remote MDS does not support reserved_mb_high"
19722
19723         rm -rf $DIR/$tdir
19724         wait_mds_ost_sync
19725         wait_delete_completed
19726         mkdir $DIR/$tdir
19727
19728         pool_add $TESTNAME || error "Pool creation failed"
19729         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19730
19731         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19732                 error "Setstripe failed"
19733
19734         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19735
19736         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19737                     grep "watermarks")
19738         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19739
19740         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19741                         osp.$mdtosc_proc1.prealloc_status)
19742         echo "prealloc_status $oa_status"
19743
19744         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19745                 error "File creation should fail"
19746
19747         #object allocation was stopped, but we still able to append files
19748         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19749                 oflag=append || error "Append failed"
19750
19751         rm -f $DIR/$tdir/$tfile.0
19752
19753         # For this test, we want to delete the files we created to go out of
19754         # space but leave the watermark, so we remain nearly out of space
19755         ost_watermarks_enospc_delete_files $tfile $ostidx
19756
19757         wait_delete_completed
19758
19759         sleep_maxage
19760
19761         for i in $(seq 10 12); do
19762                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19763                         2>/dev/null || error "File creation failed after rm"
19764         done
19765
19766         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19767                         osp.$mdtosc_proc1.prealloc_status)
19768         echo "prealloc_status $oa_status"
19769
19770         if (( oa_status != 0 )); then
19771                 error "Object allocation still disable after rm"
19772         fi
19773 }
19774 run_test 253 "Check object allocation limit"
19775
19776 test_254() {
19777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19778         remote_mds_nodsh && skip "remote MDS with nodsh"
19779         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19780                 skip "MDS does not support changelog_size"
19781
19782         local cl_user
19783         local MDT0=$(facet_svc $SINGLEMDS)
19784
19785         changelog_register || error "changelog_register failed"
19786
19787         changelog_clear 0 || error "changelog_clear failed"
19788
19789         local size1=$(do_facet $SINGLEMDS \
19790                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19791         echo "Changelog size $size1"
19792
19793         rm -rf $DIR/$tdir
19794         $LFS mkdir -i 0 $DIR/$tdir
19795         # change something
19796         mkdir -p $DIR/$tdir/pics/2008/zachy
19797         touch $DIR/$tdir/pics/2008/zachy/timestamp
19798         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19799         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19800         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19801         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19802         rm $DIR/$tdir/pics/desktop.jpg
19803
19804         local size2=$(do_facet $SINGLEMDS \
19805                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19806         echo "Changelog size after work $size2"
19807
19808         (( $size2 > $size1 )) ||
19809                 error "new Changelog size=$size2 less than old size=$size1"
19810 }
19811 run_test 254 "Check changelog size"
19812
19813 ladvise_no_type()
19814 {
19815         local type=$1
19816         local file=$2
19817
19818         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19819                 awk -F: '{print $2}' | grep $type > /dev/null
19820         if [ $? -ne 0 ]; then
19821                 return 0
19822         fi
19823         return 1
19824 }
19825
19826 ladvise_no_ioctl()
19827 {
19828         local file=$1
19829
19830         lfs ladvise -a willread $file > /dev/null 2>&1
19831         if [ $? -eq 0 ]; then
19832                 return 1
19833         fi
19834
19835         lfs ladvise -a willread $file 2>&1 |
19836                 grep "Inappropriate ioctl for device" > /dev/null
19837         if [ $? -eq 0 ]; then
19838                 return 0
19839         fi
19840         return 1
19841 }
19842
19843 percent() {
19844         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19845 }
19846
19847 # run a random read IO workload
19848 # usage: random_read_iops <filename> <filesize> <iosize>
19849 random_read_iops() {
19850         local file=$1
19851         local fsize=$2
19852         local iosize=${3:-4096}
19853
19854         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19855                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19856 }
19857
19858 drop_file_oss_cache() {
19859         local file="$1"
19860         local nodes="$2"
19861
19862         $LFS ladvise -a dontneed $file 2>/dev/null ||
19863                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19864 }
19865
19866 ladvise_willread_performance()
19867 {
19868         local repeat=10
19869         local average_origin=0
19870         local average_cache=0
19871         local average_ladvise=0
19872
19873         for ((i = 1; i <= $repeat; i++)); do
19874                 echo "Iter $i/$repeat: reading without willread hint"
19875                 cancel_lru_locks osc
19876                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19877                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19878                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19879                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19880
19881                 cancel_lru_locks osc
19882                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19883                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19884                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19885
19886                 cancel_lru_locks osc
19887                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19888                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19889                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19890                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19891                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19892         done
19893         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19894         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19895         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19896
19897         speedup_cache=$(percent $average_cache $average_origin)
19898         speedup_ladvise=$(percent $average_ladvise $average_origin)
19899
19900         echo "Average uncached read: $average_origin"
19901         echo "Average speedup with OSS cached read: " \
19902                 "$average_cache = +$speedup_cache%"
19903         echo "Average speedup with ladvise willread: " \
19904                 "$average_ladvise = +$speedup_ladvise%"
19905
19906         local lowest_speedup=20
19907         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19908                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19909                         "got $average_cache%. Skipping ladvise willread check."
19910                 return 0
19911         fi
19912
19913         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19914         # it is still good to run until then to exercise 'ladvise willread'
19915         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19916                 [ "$ost1_FSTYPE" = "zfs" ] &&
19917                 echo "osd-zfs does not support dontneed or drop_caches" &&
19918                 return 0
19919
19920         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19921         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19922                 error_not_in_vm "Speedup with willread is less than " \
19923                         "$lowest_speedup%, got $average_ladvise%"
19924 }
19925
19926 test_255a() {
19927         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19928                 skip "lustre < 2.8.54 does not support ladvise "
19929         remote_ost_nodsh && skip "remote OST with nodsh"
19930
19931         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19932
19933         ladvise_no_type willread $DIR/$tfile &&
19934                 skip "willread ladvise is not supported"
19935
19936         ladvise_no_ioctl $DIR/$tfile &&
19937                 skip "ladvise ioctl is not supported"
19938
19939         local size_mb=100
19940         local size=$((size_mb * 1048576))
19941         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19942                 error "dd to $DIR/$tfile failed"
19943
19944         lfs ladvise -a willread $DIR/$tfile ||
19945                 error "Ladvise failed with no range argument"
19946
19947         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19948                 error "Ladvise failed with no -l or -e argument"
19949
19950         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19951                 error "Ladvise failed with only -e argument"
19952
19953         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19954                 error "Ladvise failed with only -l argument"
19955
19956         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19957                 error "End offset should not be smaller than start offset"
19958
19959         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19960                 error "End offset should not be equal to start offset"
19961
19962         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19963                 error "Ladvise failed with overflowing -s argument"
19964
19965         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19966                 error "Ladvise failed with overflowing -e argument"
19967
19968         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19969                 error "Ladvise failed with overflowing -l argument"
19970
19971         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19972                 error "Ladvise succeeded with conflicting -l and -e arguments"
19973
19974         echo "Synchronous ladvise should wait"
19975         local delay=4
19976 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19977         do_nodes $(comma_list $(osts_nodes)) \
19978                 $LCTL set_param fail_val=$delay fail_loc=0x237
19979
19980         local start_ts=$SECONDS
19981         lfs ladvise -a willread $DIR/$tfile ||
19982                 error "Ladvise failed with no range argument"
19983         local end_ts=$SECONDS
19984         local inteval_ts=$((end_ts - start_ts))
19985
19986         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19987                 error "Synchronous advice didn't wait reply"
19988         fi
19989
19990         echo "Asynchronous ladvise shouldn't wait"
19991         local start_ts=$SECONDS
19992         lfs ladvise -a willread -b $DIR/$tfile ||
19993                 error "Ladvise failed with no range argument"
19994         local end_ts=$SECONDS
19995         local inteval_ts=$((end_ts - start_ts))
19996
19997         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19998                 error "Asynchronous advice blocked"
19999         fi
20000
20001         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20002         ladvise_willread_performance
20003 }
20004 run_test 255a "check 'lfs ladvise -a willread'"
20005
20006 facet_meminfo() {
20007         local facet=$1
20008         local info=$2
20009
20010         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20011 }
20012
20013 test_255b() {
20014         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20015                 skip "lustre < 2.8.54 does not support ladvise "
20016         remote_ost_nodsh && skip "remote OST with nodsh"
20017
20018         lfs setstripe -c 1 -i 0 $DIR/$tfile
20019
20020         ladvise_no_type dontneed $DIR/$tfile &&
20021                 skip "dontneed ladvise is not supported"
20022
20023         ladvise_no_ioctl $DIR/$tfile &&
20024                 skip "ladvise ioctl is not supported"
20025
20026         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20027                 [ "$ost1_FSTYPE" = "zfs" ] &&
20028                 skip "zfs-osd does not support 'ladvise dontneed'"
20029
20030         local size_mb=100
20031         local size=$((size_mb * 1048576))
20032         # In order to prevent disturbance of other processes, only check 3/4
20033         # of the memory usage
20034         local kibibytes=$((size_mb * 1024 * 3 / 4))
20035
20036         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20037                 error "dd to $DIR/$tfile failed"
20038
20039         #force write to complete before dropping OST cache & checking memory
20040         sync
20041
20042         local total=$(facet_meminfo ost1 MemTotal)
20043         echo "Total memory: $total KiB"
20044
20045         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20046         local before_read=$(facet_meminfo ost1 Cached)
20047         echo "Cache used before read: $before_read KiB"
20048
20049         lfs ladvise -a willread $DIR/$tfile ||
20050                 error "Ladvise willread failed"
20051         local after_read=$(facet_meminfo ost1 Cached)
20052         echo "Cache used after read: $after_read KiB"
20053
20054         lfs ladvise -a dontneed $DIR/$tfile ||
20055                 error "Ladvise dontneed again failed"
20056         local no_read=$(facet_meminfo ost1 Cached)
20057         echo "Cache used after dontneed ladvise: $no_read KiB"
20058
20059         if [ $total -lt $((before_read + kibibytes)) ]; then
20060                 echo "Memory is too small, abort checking"
20061                 return 0
20062         fi
20063
20064         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20065                 error "Ladvise willread should use more memory" \
20066                         "than $kibibytes KiB"
20067         fi
20068
20069         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20070                 error "Ladvise dontneed should release more memory" \
20071                         "than $kibibytes KiB"
20072         fi
20073 }
20074 run_test 255b "check 'lfs ladvise -a dontneed'"
20075
20076 test_255c() {
20077         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20078                 skip "lustre < 2.10.50 does not support lockahead"
20079
20080         local count
20081         local new_count
20082         local difference
20083         local i
20084         local rc
20085
20086         test_mkdir -p $DIR/$tdir
20087         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20088
20089         #test 10 returns only success/failure
20090         i=10
20091         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20092         rc=$?
20093         if [ $rc -eq 255 ]; then
20094                 error "Ladvise test${i} failed, ${rc}"
20095         fi
20096
20097         #test 11 counts lock enqueue requests, all others count new locks
20098         i=11
20099         count=$(do_facet ost1 \
20100                 $LCTL get_param -n ost.OSS.ost.stats)
20101         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20102
20103         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20104         rc=$?
20105         if [ $rc -eq 255 ]; then
20106                 error "Ladvise test${i} failed, ${rc}"
20107         fi
20108
20109         new_count=$(do_facet ost1 \
20110                 $LCTL get_param -n ost.OSS.ost.stats)
20111         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20112                    awk '{ print $2 }')
20113
20114         difference="$((new_count - count))"
20115         if [ $difference -ne $rc ]; then
20116                 error "Ladvise test${i}, bad enqueue count, returned " \
20117                       "${rc}, actual ${difference}"
20118         fi
20119
20120         for i in $(seq 12 21); do
20121                 # If we do not do this, we run the risk of having too many
20122                 # locks and starting lock cancellation while we are checking
20123                 # lock counts.
20124                 cancel_lru_locks osc
20125
20126                 count=$($LCTL get_param -n \
20127                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
20128
20129                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20130                 rc=$?
20131                 if [ $rc -eq 255 ]; then
20132                         error "Ladvise test ${i} failed, ${rc}"
20133                 fi
20134
20135                 new_count=$($LCTL get_param -n \
20136                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
20137                 difference="$((new_count - count))"
20138
20139                 # Test 15 output is divided by 100 to map down to valid return
20140                 if [ $i -eq 15 ]; then
20141                         rc="$((rc * 100))"
20142                 fi
20143
20144                 if [ $difference -ne $rc ]; then
20145                         error "Ladvise test ${i}, bad lock count, returned " \
20146                               "${rc}, actual ${difference}"
20147                 fi
20148         done
20149
20150         #test 22 returns only success/failure
20151         i=22
20152         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20153         rc=$?
20154         if [ $rc -eq 255 ]; then
20155                 error "Ladvise test${i} failed, ${rc}"
20156         fi
20157 }
20158 run_test 255c "suite of ladvise lockahead tests"
20159
20160 test_256() {
20161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20162         remote_mds_nodsh && skip "remote MDS with nodsh"
20163         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20164         changelog_users $SINGLEMDS | grep "^cl" &&
20165                 skip "active changelog user"
20166
20167         local cl_user
20168         local cat_sl
20169         local mdt_dev
20170
20171         mdt_dev=$(mdsdevname 1)
20172         echo $mdt_dev
20173
20174         changelog_register || error "changelog_register failed"
20175
20176         rm -rf $DIR/$tdir
20177         mkdir -p $DIR/$tdir
20178
20179         changelog_clear 0 || error "changelog_clear failed"
20180
20181         # change something
20182         touch $DIR/$tdir/{1..10}
20183
20184         # stop the MDT
20185         stop $SINGLEMDS || error "Fail to stop MDT"
20186
20187         # remount the MDT
20188
20189         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20190
20191         #after mount new plainllog is used
20192         touch $DIR/$tdir/{11..19}
20193         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20194         stack_trap "rm -f $tmpfile"
20195         cat_sl=$(do_facet $SINGLEMDS "sync; \
20196                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20197                  llog_reader $tmpfile | grep -c type=1064553b")
20198         do_facet $SINGLEMDS llog_reader $tmpfile
20199
20200         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20201
20202         changelog_clear 0 || error "changelog_clear failed"
20203
20204         cat_sl=$(do_facet $SINGLEMDS "sync; \
20205                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20206                  llog_reader $tmpfile | grep -c type=1064553b")
20207
20208         if (( cat_sl == 2 )); then
20209                 error "Empty plain llog was not deleted from changelog catalog"
20210         elif (( cat_sl != 1 )); then
20211                 error "Active plain llog shouldn't be deleted from catalog"
20212         fi
20213 }
20214 run_test 256 "Check llog delete for empty and not full state"
20215
20216 test_257() {
20217         remote_mds_nodsh && skip "remote MDS with nodsh"
20218         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20219                 skip "Need MDS version at least 2.8.55"
20220
20221         test_mkdir $DIR/$tdir
20222
20223         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20224                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20225         stat $DIR/$tdir
20226
20227 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20228         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20229         local facet=mds$((mdtidx + 1))
20230         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20231         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20232
20233         stop $facet || error "stop MDS failed"
20234         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20235                 error "start MDS fail"
20236         wait_recovery_complete $facet
20237 }
20238 run_test 257 "xattr locks are not lost"
20239
20240 # Verify we take the i_mutex when security requires it
20241 test_258a() {
20242 #define OBD_FAIL_IMUTEX_SEC 0x141c
20243         $LCTL set_param fail_loc=0x141c
20244         touch $DIR/$tfile
20245         chmod u+s $DIR/$tfile
20246         chmod a+rwx $DIR/$tfile
20247         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20248         RC=$?
20249         if [ $RC -ne 0 ]; then
20250                 error "error, failed to take i_mutex, rc=$?"
20251         fi
20252         rm -f $DIR/$tfile
20253 }
20254 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20255
20256 # Verify we do NOT take the i_mutex in the normal case
20257 test_258b() {
20258 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20259         $LCTL set_param fail_loc=0x141d
20260         touch $DIR/$tfile
20261         chmod a+rwx $DIR
20262         chmod a+rw $DIR/$tfile
20263         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20264         RC=$?
20265         if [ $RC -ne 0 ]; then
20266                 error "error, took i_mutex unnecessarily, rc=$?"
20267         fi
20268         rm -f $DIR/$tfile
20269
20270 }
20271 run_test 258b "verify i_mutex security behavior"
20272
20273 test_259() {
20274         local file=$DIR/$tfile
20275         local before
20276         local after
20277
20278         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20279
20280         stack_trap "rm -f $file" EXIT
20281
20282         wait_delete_completed
20283         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20284         echo "before: $before"
20285
20286         $LFS setstripe -i 0 -c 1 $file
20287         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20288         sync_all_data
20289         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20290         echo "after write: $after"
20291
20292 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20293         do_facet ost1 $LCTL set_param fail_loc=0x2301
20294         $TRUNCATE $file 0
20295         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20296         echo "after truncate: $after"
20297
20298         stop ost1
20299         do_facet ost1 $LCTL set_param fail_loc=0
20300         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20301         sleep 2
20302         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20303         echo "after restart: $after"
20304         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20305                 error "missing truncate?"
20306
20307         return 0
20308 }
20309 run_test 259 "crash at delayed truncate"
20310
20311 test_260() {
20312 #define OBD_FAIL_MDC_CLOSE               0x806
20313         $LCTL set_param fail_loc=0x80000806
20314         touch $DIR/$tfile
20315
20316 }
20317 run_test 260 "Check mdc_close fail"
20318
20319 ### Data-on-MDT sanity tests ###
20320 test_270a() {
20321         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20322                 skip "Need MDS version at least 2.10.55 for DoM"
20323
20324         # create DoM file
20325         local dom=$DIR/$tdir/dom_file
20326         local tmp=$DIR/$tdir/tmp_file
20327
20328         mkdir -p $DIR/$tdir
20329
20330         # basic checks for DoM component creation
20331         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20332                 error "Can set MDT layout to non-first entry"
20333
20334         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20335                 error "Can define multiple entries as MDT layout"
20336
20337         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20338
20339         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20340         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20341         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20342
20343         local mdtidx=$($LFS getstripe -m $dom)
20344         local mdtname=MDT$(printf %04x $mdtidx)
20345         local facet=mds$((mdtidx + 1))
20346         local space_check=1
20347
20348         # Skip free space checks with ZFS
20349         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20350
20351         # write
20352         sync
20353         local size_tmp=$((65536 * 3))
20354         local mdtfree1=$(do_facet $facet \
20355                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20356
20357         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20358         # check also direct IO along write
20359         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20360         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20361         sync
20362         cmp $tmp $dom || error "file data is different"
20363         [ $(stat -c%s $dom) == $size_tmp ] ||
20364                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20365         if [ $space_check == 1 ]; then
20366                 local mdtfree2=$(do_facet $facet \
20367                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20368
20369                 # increase in usage from by $size_tmp
20370                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20371                         error "MDT free space wrong after write: " \
20372                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20373         fi
20374
20375         # truncate
20376         local size_dom=10000
20377
20378         $TRUNCATE $dom $size_dom
20379         [ $(stat -c%s $dom) == $size_dom ] ||
20380                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20381         if [ $space_check == 1 ]; then
20382                 mdtfree1=$(do_facet $facet \
20383                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20384                 # decrease in usage from $size_tmp to new $size_dom
20385                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20386                   $(((size_tmp - size_dom) / 1024)) ] ||
20387                         error "MDT free space is wrong after truncate: " \
20388                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20389         fi
20390
20391         # append
20392         cat $tmp >> $dom
20393         sync
20394         size_dom=$((size_dom + size_tmp))
20395         [ $(stat -c%s $dom) == $size_dom ] ||
20396                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20397         if [ $space_check == 1 ]; then
20398                 mdtfree2=$(do_facet $facet \
20399                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20400                 # increase in usage by $size_tmp from previous
20401                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20402                         error "MDT free space is wrong after append: " \
20403                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20404         fi
20405
20406         # delete
20407         rm $dom
20408         if [ $space_check == 1 ]; then
20409                 mdtfree1=$(do_facet $facet \
20410                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20411                 # decrease in usage by $size_dom from previous
20412                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20413                         error "MDT free space is wrong after removal: " \
20414                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20415         fi
20416
20417         # combined striping
20418         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20419                 error "Can't create DoM + OST striping"
20420
20421         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20422         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20423         # check also direct IO along write
20424         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20425         sync
20426         cmp $tmp $dom || error "file data is different"
20427         [ $(stat -c%s $dom) == $size_tmp ] ||
20428                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20429         rm $dom $tmp
20430
20431         return 0
20432 }
20433 run_test 270a "DoM: basic functionality tests"
20434
20435 test_270b() {
20436         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20437                 skip "Need MDS version at least 2.10.55"
20438
20439         local dom=$DIR/$tdir/dom_file
20440         local max_size=1048576
20441
20442         mkdir -p $DIR/$tdir
20443         $LFS setstripe -E $max_size -L mdt $dom
20444
20445         # truncate over the limit
20446         $TRUNCATE $dom $(($max_size + 1)) &&
20447                 error "successful truncate over the maximum size"
20448         # write over the limit
20449         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20450                 error "successful write over the maximum size"
20451         # append over the limit
20452         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20453         echo "12345" >> $dom && error "successful append over the maximum size"
20454         rm $dom
20455
20456         return 0
20457 }
20458 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20459
20460 test_270c() {
20461         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20462                 skip "Need MDS version at least 2.10.55"
20463
20464         mkdir -p $DIR/$tdir
20465         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20466
20467         # check files inherit DoM EA
20468         touch $DIR/$tdir/first
20469         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20470                 error "bad pattern"
20471         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20472                 error "bad stripe count"
20473         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20474                 error "bad stripe size"
20475
20476         # check directory inherits DoM EA and uses it as default
20477         mkdir $DIR/$tdir/subdir
20478         touch $DIR/$tdir/subdir/second
20479         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20480                 error "bad pattern in sub-directory"
20481         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20482                 error "bad stripe count in sub-directory"
20483         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20484                 error "bad stripe size in sub-directory"
20485         return 0
20486 }
20487 run_test 270c "DoM: DoM EA inheritance tests"
20488
20489 test_270d() {
20490         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20491                 skip "Need MDS version at least 2.10.55"
20492
20493         mkdir -p $DIR/$tdir
20494         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20495
20496         # inherit default DoM striping
20497         mkdir $DIR/$tdir/subdir
20498         touch $DIR/$tdir/subdir/f1
20499
20500         # change default directory striping
20501         $LFS setstripe -c 1 $DIR/$tdir/subdir
20502         touch $DIR/$tdir/subdir/f2
20503         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20504                 error "wrong default striping in file 2"
20505         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20506                 error "bad pattern in file 2"
20507         return 0
20508 }
20509 run_test 270d "DoM: change striping from DoM to RAID0"
20510
20511 test_270e() {
20512         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20513                 skip "Need MDS version at least 2.10.55"
20514
20515         mkdir -p $DIR/$tdir/dom
20516         mkdir -p $DIR/$tdir/norm
20517         DOMFILES=20
20518         NORMFILES=10
20519         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20520         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20521
20522         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20523         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20524
20525         # find DoM files by layout
20526         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20527         [ $NUM -eq  $DOMFILES ] ||
20528                 error "lfs find -L: found $NUM, expected $DOMFILES"
20529         echo "Test 1: lfs find 20 DOM files by layout: OK"
20530
20531         # there should be 1 dir with default DOM striping
20532         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20533         [ $NUM -eq  1 ] ||
20534                 error "lfs find -L: found $NUM, expected 1 dir"
20535         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20536
20537         # find DoM files by stripe size
20538         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20539         [ $NUM -eq  $DOMFILES ] ||
20540                 error "lfs find -S: found $NUM, expected $DOMFILES"
20541         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20542
20543         # find files by stripe offset except DoM files
20544         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20545         [ $NUM -eq  $NORMFILES ] ||
20546                 error "lfs find -i: found $NUM, expected $NORMFILES"
20547         echo "Test 5: lfs find no DOM files by stripe index: OK"
20548         return 0
20549 }
20550 run_test 270e "DoM: lfs find with DoM files test"
20551
20552 test_270f() {
20553         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20554                 skip "Need MDS version at least 2.10.55"
20555
20556         local mdtname=${FSNAME}-MDT0000-mdtlov
20557         local dom=$DIR/$tdir/dom_file
20558         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20559                                                 lod.$mdtname.dom_stripesize)
20560         local dom_limit=131072
20561
20562         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20563         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20564                                                 lod.$mdtname.dom_stripesize)
20565         [ ${dom_limit} -eq ${dom_current} ] ||
20566                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20567
20568         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20569         $LFS setstripe -d $DIR/$tdir
20570         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20571                 error "Can't set directory default striping"
20572
20573         # exceed maximum stripe size
20574         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20575                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20576         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20577                 error "Able to create DoM component size more than LOD limit"
20578
20579         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20580         dom_current=$(do_facet mds1 $LCTL get_param -n \
20581                                                 lod.$mdtname.dom_stripesize)
20582         [ 0 -eq ${dom_current} ] ||
20583                 error "Can't set zero DoM stripe limit"
20584         rm $dom
20585
20586         # attempt to create DoM file on server with disabled DoM should
20587         # remove DoM entry from layout and be succeed
20588         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20589                 error "Can't create DoM file (DoM is disabled)"
20590         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20591                 error "File has DoM component while DoM is disabled"
20592         rm $dom
20593
20594         # attempt to create DoM file with only DoM stripe should return error
20595         $LFS setstripe -E $dom_limit -L mdt $dom &&
20596                 error "Able to create DoM-only file while DoM is disabled"
20597
20598         # too low values to be aligned with smallest stripe size 64K
20599         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20600         dom_current=$(do_facet mds1 $LCTL get_param -n \
20601                                                 lod.$mdtname.dom_stripesize)
20602         [ 30000 -eq ${dom_current} ] &&
20603                 error "Can set too small DoM stripe limit"
20604
20605         # 64K is a minimal stripe size in Lustre, expect limit of that size
20606         [ 65536 -eq ${dom_current} ] ||
20607                 error "Limit is not set to 64K but ${dom_current}"
20608
20609         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20610         dom_current=$(do_facet mds1 $LCTL get_param -n \
20611                                                 lod.$mdtname.dom_stripesize)
20612         echo $dom_current
20613         [ 2147483648 -eq ${dom_current} ] &&
20614                 error "Can set too large DoM stripe limit"
20615
20616         do_facet mds1 $LCTL set_param -n \
20617                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20618         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20619                 error "Can't create DoM component size after limit change"
20620         do_facet mds1 $LCTL set_param -n \
20621                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20622         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20623                 error "Can't create DoM file after limit decrease"
20624         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20625                 error "Can create big DoM component after limit decrease"
20626         touch ${dom}_def ||
20627                 error "Can't create file with old default layout"
20628
20629         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20630         return 0
20631 }
20632 run_test 270f "DoM: maximum DoM stripe size checks"
20633
20634 test_270g() {
20635         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20636                 skip "Need MDS version at least 2.13.52"
20637         local dom=$DIR/$tdir/$tfile
20638
20639         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20640         local lodname=${FSNAME}-MDT0000-mdtlov
20641
20642         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20643         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20644         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20645         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20646
20647         local dom_limit=1024
20648         local dom_threshold="50%"
20649
20650         $LFS setstripe -d $DIR/$tdir
20651         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20652                 error "Can't set directory default striping"
20653
20654         do_facet mds1 $LCTL set_param -n \
20655                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20656         # set 0 threshold and create DOM file to change tunable stripesize
20657         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20658         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20659                 error "Failed to create $dom file"
20660         # now tunable dom_cur_stripesize should reach maximum
20661         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20662                                         lod.${lodname}.dom_stripesize_cur_kb)
20663         [[ $dom_current == $dom_limit ]] ||
20664                 error "Current DOM stripesize is not maximum"
20665         rm $dom
20666
20667         # set threshold for further tests
20668         do_facet mds1 $LCTL set_param -n \
20669                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20670         echo "DOM threshold is $dom_threshold free space"
20671         local dom_def
20672         local dom_set
20673         # Spoof bfree to exceed threshold
20674         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20675         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20676         for spfree in 40 20 0 15 30 55; do
20677                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20678                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20679                         error "Failed to create $dom file"
20680                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20681                                         lod.${lodname}.dom_stripesize_cur_kb)
20682                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20683                 [[ $dom_def != $dom_current ]] ||
20684                         error "Default stripe size was not changed"
20685                 if [[ $spfree > 0 ]] ; then
20686                         dom_set=$($LFS getstripe -S $dom)
20687                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20688                                 error "DOM component size is still old"
20689                 else
20690                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20691                                 error "DoM component is set with no free space"
20692                 fi
20693                 rm $dom
20694                 dom_current=$dom_def
20695         done
20696 }
20697 run_test 270g "DoM: default DoM stripe size depends on free space"
20698
20699 test_270h() {
20700         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20701                 skip "Need MDS version at least 2.13.53"
20702
20703         local mdtname=${FSNAME}-MDT0000-mdtlov
20704         local dom=$DIR/$tdir/$tfile
20705         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20706
20707         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20708         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20709
20710         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20711         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20712                 error "can't create OST file"
20713         # mirrored file with DOM entry in the second mirror
20714         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20715                 error "can't create mirror with DoM component"
20716
20717         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20718
20719         # DOM component in the middle and has other enries in the same mirror,
20720         # should succeed but lost DoM component
20721         $LFS setstripe --copy=${dom}_1 $dom ||
20722                 error "Can't create file from OST|DOM mirror layout"
20723         # check new file has no DoM layout after all
20724         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20725                 error "File has DoM component while DoM is disabled"
20726 }
20727 run_test 270h "DoM: DoM stripe removal when disabled on server"
20728
20729 test_271a() {
20730         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20731                 skip "Need MDS version at least 2.10.55"
20732
20733         local dom=$DIR/$tdir/dom
20734
20735         mkdir -p $DIR/$tdir
20736
20737         $LFS setstripe -E 1024K -L mdt $dom
20738
20739         lctl set_param -n mdc.*.stats=clear
20740         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20741         cat $dom > /dev/null
20742         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20743         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20744         ls $dom
20745         rm -f $dom
20746 }
20747 run_test 271a "DoM: data is cached for read after write"
20748
20749 test_271b() {
20750         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20751                 skip "Need MDS version at least 2.10.55"
20752
20753         local dom=$DIR/$tdir/dom
20754
20755         mkdir -p $DIR/$tdir
20756
20757         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20758
20759         lctl set_param -n mdc.*.stats=clear
20760         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20761         cancel_lru_locks mdc
20762         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20763         # second stat to check size is cached on client
20764         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20765         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20766         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20767         rm -f $dom
20768 }
20769 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20770
20771 test_271ba() {
20772         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20773                 skip "Need MDS version at least 2.10.55"
20774
20775         local dom=$DIR/$tdir/dom
20776
20777         mkdir -p $DIR/$tdir
20778
20779         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20780
20781         lctl set_param -n mdc.*.stats=clear
20782         lctl set_param -n osc.*.stats=clear
20783         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20784         cancel_lru_locks mdc
20785         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20786         # second stat to check size is cached on client
20787         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20788         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20789         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20790         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20791         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20792         rm -f $dom
20793 }
20794 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20795
20796
20797 get_mdc_stats() {
20798         local mdtidx=$1
20799         local param=$2
20800         local mdt=MDT$(printf %04x $mdtidx)
20801
20802         if [ -z $param ]; then
20803                 lctl get_param -n mdc.*$mdt*.stats
20804         else
20805                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20806         fi
20807 }
20808
20809 test_271c() {
20810         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20811                 skip "Need MDS version at least 2.10.55"
20812
20813         local dom=$DIR/$tdir/dom
20814
20815         mkdir -p $DIR/$tdir
20816
20817         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20818
20819         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20820         local facet=mds$((mdtidx + 1))
20821
20822         cancel_lru_locks mdc
20823         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20824         createmany -o $dom 1000
20825         lctl set_param -n mdc.*.stats=clear
20826         smalliomany -w $dom 1000 200
20827         get_mdc_stats $mdtidx
20828         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20829         # Each file has 1 open, 1 IO enqueues, total 2000
20830         # but now we have also +1 getxattr for security.capability, total 3000
20831         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20832         unlinkmany $dom 1000
20833
20834         cancel_lru_locks mdc
20835         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20836         createmany -o $dom 1000
20837         lctl set_param -n mdc.*.stats=clear
20838         smalliomany -w $dom 1000 200
20839         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20840         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20841         # for OPEN and IO lock.
20842         [ $((enq - enq_2)) -ge 1000 ] ||
20843                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20844         unlinkmany $dom 1000
20845         return 0
20846 }
20847 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20848
20849 cleanup_271def_tests() {
20850         trap 0
20851         rm -f $1
20852 }
20853
20854 test_271d() {
20855         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20856                 skip "Need MDS version at least 2.10.57"
20857
20858         local dom=$DIR/$tdir/dom
20859         local tmp=$TMP/$tfile
20860         trap "cleanup_271def_tests $tmp" EXIT
20861
20862         mkdir -p $DIR/$tdir
20863
20864         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20865
20866         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20867
20868         cancel_lru_locks mdc
20869         dd if=/dev/urandom of=$tmp bs=1000 count=1
20870         dd if=$tmp of=$dom bs=1000 count=1
20871         cancel_lru_locks mdc
20872
20873         cat /etc/hosts >> $tmp
20874         lctl set_param -n mdc.*.stats=clear
20875
20876         # append data to the same file it should update local page
20877         echo "Append to the same page"
20878         cat /etc/hosts >> $dom
20879         local num=$(get_mdc_stats $mdtidx ost_read)
20880         local ra=$(get_mdc_stats $mdtidx req_active)
20881         local rw=$(get_mdc_stats $mdtidx req_waittime)
20882
20883         [ -z $num ] || error "$num READ RPC occured"
20884         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20885         echo "... DONE"
20886
20887         # compare content
20888         cmp $tmp $dom || error "file miscompare"
20889
20890         cancel_lru_locks mdc
20891         lctl set_param -n mdc.*.stats=clear
20892
20893         echo "Open and read file"
20894         cat $dom > /dev/null
20895         local num=$(get_mdc_stats $mdtidx ost_read)
20896         local ra=$(get_mdc_stats $mdtidx req_active)
20897         local rw=$(get_mdc_stats $mdtidx req_waittime)
20898
20899         [ -z $num ] || error "$num READ RPC occured"
20900         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20901         echo "... DONE"
20902
20903         # compare content
20904         cmp $tmp $dom || error "file miscompare"
20905
20906         return 0
20907 }
20908 run_test 271d "DoM: read on open (1K file in reply buffer)"
20909
20910 test_271f() {
20911         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20912                 skip "Need MDS version at least 2.10.57"
20913
20914         local dom=$DIR/$tdir/dom
20915         local tmp=$TMP/$tfile
20916         trap "cleanup_271def_tests $tmp" EXIT
20917
20918         mkdir -p $DIR/$tdir
20919
20920         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20921
20922         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20923
20924         cancel_lru_locks mdc
20925         dd if=/dev/urandom of=$tmp bs=265000 count=1
20926         dd if=$tmp of=$dom bs=265000 count=1
20927         cancel_lru_locks mdc
20928         cat /etc/hosts >> $tmp
20929         lctl set_param -n mdc.*.stats=clear
20930
20931         echo "Append to the same page"
20932         cat /etc/hosts >> $dom
20933         local num=$(get_mdc_stats $mdtidx ost_read)
20934         local ra=$(get_mdc_stats $mdtidx req_active)
20935         local rw=$(get_mdc_stats $mdtidx req_waittime)
20936
20937         [ -z $num ] || error "$num READ RPC occured"
20938         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20939         echo "... DONE"
20940
20941         # compare content
20942         cmp $tmp $dom || error "file miscompare"
20943
20944         cancel_lru_locks mdc
20945         lctl set_param -n mdc.*.stats=clear
20946
20947         echo "Open and read file"
20948         cat $dom > /dev/null
20949         local num=$(get_mdc_stats $mdtidx ost_read)
20950         local ra=$(get_mdc_stats $mdtidx req_active)
20951         local rw=$(get_mdc_stats $mdtidx req_waittime)
20952
20953         [ -z $num ] && num=0
20954         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20955         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20956         echo "... DONE"
20957
20958         # compare content
20959         cmp $tmp $dom || error "file miscompare"
20960
20961         return 0
20962 }
20963 run_test 271f "DoM: read on open (200K file and read tail)"
20964
20965 test_271g() {
20966         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20967                 skip "Skipping due to old client or server version"
20968
20969         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20970         # to get layout
20971         $CHECKSTAT -t file $DIR1/$tfile
20972
20973         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20974         MULTIOP_PID=$!
20975         sleep 1
20976         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20977         $LCTL set_param fail_loc=0x80000314
20978         rm $DIR1/$tfile || error "Unlink fails"
20979         RC=$?
20980         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20981         [ $RC -eq 0 ] || error "Failed write to stale object"
20982 }
20983 run_test 271g "Discard DoM data vs client flush race"
20984
20985 test_272a() {
20986         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20987                 skip "Need MDS version at least 2.11.50"
20988
20989         local dom=$DIR/$tdir/dom
20990         mkdir -p $DIR/$tdir
20991
20992         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20993         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20994                 error "failed to write data into $dom"
20995         local old_md5=$(md5sum $dom)
20996
20997         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20998                 error "failed to migrate to the same DoM component"
20999
21000         local new_md5=$(md5sum $dom)
21001
21002         [ "$old_md5" == "$new_md5" ] ||
21003                 error "md5sum differ: $old_md5, $new_md5"
21004
21005         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21006                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21007 }
21008 run_test 272a "DoM migration: new layout with the same DOM component"
21009
21010 test_272b() {
21011         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21012                 skip "Need MDS version at least 2.11.50"
21013
21014         local dom=$DIR/$tdir/dom
21015         mkdir -p $DIR/$tdir
21016         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21017
21018         local mdtidx=$($LFS getstripe -m $dom)
21019         local mdtname=MDT$(printf %04x $mdtidx)
21020         local facet=mds$((mdtidx + 1))
21021
21022         local mdtfree1=$(do_facet $facet \
21023                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21024         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21025                 error "failed to write data into $dom"
21026         local old_md5=$(md5sum $dom)
21027         cancel_lru_locks mdc
21028         local mdtfree1=$(do_facet $facet \
21029                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21030
21031         $LFS migrate -c2 $dom ||
21032                 error "failed to migrate to the new composite layout"
21033         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21034                 error "MDT stripe was not removed"
21035
21036         cancel_lru_locks mdc
21037         local new_md5=$(md5sum $dom)
21038         [ "$old_md5" == "$new_md5" ] ||
21039                 error "$old_md5 != $new_md5"
21040
21041         # Skip free space checks with ZFS
21042         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21043                 local mdtfree2=$(do_facet $facet \
21044                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21045                 [ $mdtfree2 -gt $mdtfree1 ] ||
21046                         error "MDT space is not freed after migration"
21047         fi
21048         return 0
21049 }
21050 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21051
21052 test_272c() {
21053         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21054                 skip "Need MDS version at least 2.11.50"
21055
21056         local dom=$DIR/$tdir/$tfile
21057         mkdir -p $DIR/$tdir
21058         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21059
21060         local mdtidx=$($LFS getstripe -m $dom)
21061         local mdtname=MDT$(printf %04x $mdtidx)
21062         local facet=mds$((mdtidx + 1))
21063
21064         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21065                 error "failed to write data into $dom"
21066         local old_md5=$(md5sum $dom)
21067         cancel_lru_locks mdc
21068         local mdtfree1=$(do_facet $facet \
21069                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21070
21071         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21072                 error "failed to migrate to the new composite layout"
21073         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21074                 error "MDT stripe was not removed"
21075
21076         cancel_lru_locks mdc
21077         local new_md5=$(md5sum $dom)
21078         [ "$old_md5" == "$new_md5" ] ||
21079                 error "$old_md5 != $new_md5"
21080
21081         # Skip free space checks with ZFS
21082         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21083                 local mdtfree2=$(do_facet $facet \
21084                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21085                 [ $mdtfree2 -gt $mdtfree1 ] ||
21086                         error "MDS space is not freed after migration"
21087         fi
21088         return 0
21089 }
21090 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21091
21092 test_272d() {
21093         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21094                 skip "Need MDS version at least 2.12.55"
21095
21096         local dom=$DIR/$tdir/$tfile
21097         mkdir -p $DIR/$tdir
21098         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21099
21100         local mdtidx=$($LFS getstripe -m $dom)
21101         local mdtname=MDT$(printf %04x $mdtidx)
21102         local facet=mds$((mdtidx + 1))
21103
21104         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21105                 error "failed to write data into $dom"
21106         local old_md5=$(md5sum $dom)
21107         cancel_lru_locks mdc
21108         local mdtfree1=$(do_facet $facet \
21109                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21110
21111         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21112                 error "failed mirroring to the new composite layout"
21113         $LFS mirror resync $dom ||
21114                 error "failed mirror resync"
21115         $LFS mirror split --mirror-id 1 -d $dom ||
21116                 error "failed mirror split"
21117
21118         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21119                 error "MDT stripe was not removed"
21120
21121         cancel_lru_locks mdc
21122         local new_md5=$(md5sum $dom)
21123         [ "$old_md5" == "$new_md5" ] ||
21124                 error "$old_md5 != $new_md5"
21125
21126         # Skip free space checks with ZFS
21127         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21128                 local mdtfree2=$(do_facet $facet \
21129                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21130                 [ $mdtfree2 -gt $mdtfree1 ] ||
21131                         error "MDS space is not freed after DOM mirror deletion"
21132         fi
21133         return 0
21134 }
21135 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21136
21137 test_272e() {
21138         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21139                 skip "Need MDS version at least 2.12.55"
21140
21141         local dom=$DIR/$tdir/$tfile
21142         mkdir -p $DIR/$tdir
21143         $LFS setstripe -c 2 $dom
21144
21145         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21146                 error "failed to write data into $dom"
21147         local old_md5=$(md5sum $dom)
21148         cancel_lru_locks mdc
21149
21150         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21151                 error "failed mirroring to the DOM layout"
21152         $LFS mirror resync $dom ||
21153                 error "failed mirror resync"
21154         $LFS mirror split --mirror-id 1 -d $dom ||
21155                 error "failed mirror split"
21156
21157         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21158                 error "MDT stripe was not removed"
21159
21160         cancel_lru_locks mdc
21161         local new_md5=$(md5sum $dom)
21162         [ "$old_md5" == "$new_md5" ] ||
21163                 error "$old_md5 != $new_md5"
21164
21165         return 0
21166 }
21167 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21168
21169 test_272f() {
21170         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21171                 skip "Need MDS version at least 2.12.55"
21172
21173         local dom=$DIR/$tdir/$tfile
21174         mkdir -p $DIR/$tdir
21175         $LFS setstripe -c 2 $dom
21176
21177         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21178                 error "failed to write data into $dom"
21179         local old_md5=$(md5sum $dom)
21180         cancel_lru_locks mdc
21181
21182         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21183                 error "failed migrating to the DOM file"
21184
21185         cancel_lru_locks mdc
21186         local new_md5=$(md5sum $dom)
21187         [ "$old_md5" != "$new_md5" ] &&
21188                 error "$old_md5 != $new_md5"
21189
21190         return 0
21191 }
21192 run_test 272f "DoM migration: OST-striped file to DOM file"
21193
21194 test_273a() {
21195         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21196                 skip "Need MDS version at least 2.11.50"
21197
21198         # Layout swap cannot be done if either file has DOM component,
21199         # this will never be supported, migration should be used instead
21200
21201         local dom=$DIR/$tdir/$tfile
21202         mkdir -p $DIR/$tdir
21203
21204         $LFS setstripe -c2 ${dom}_plain
21205         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21206         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21207                 error "can swap layout with DoM component"
21208         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21209                 error "can swap layout with DoM component"
21210
21211         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21212         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21213                 error "can swap layout with DoM component"
21214         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21215                 error "can swap layout with DoM component"
21216         return 0
21217 }
21218 run_test 273a "DoM: layout swapping should fail with DOM"
21219
21220 test_275() {
21221         remote_ost_nodsh && skip "remote OST with nodsh"
21222         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21223                 skip "Need OST version >= 2.10.57"
21224
21225         local file=$DIR/$tfile
21226         local oss
21227
21228         oss=$(comma_list $(osts_nodes))
21229
21230         dd if=/dev/urandom of=$file bs=1M count=2 ||
21231                 error "failed to create a file"
21232         cancel_lru_locks osc
21233
21234         #lock 1
21235         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21236                 error "failed to read a file"
21237
21238 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21239         $LCTL set_param fail_loc=0x8000031f
21240
21241         cancel_lru_locks osc &
21242         sleep 1
21243
21244 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21245         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21246         #IO takes another lock, but matches the PENDING one
21247         #and places it to the IO RPC
21248         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21249                 error "failed to read a file with PENDING lock"
21250 }
21251 run_test 275 "Read on a canceled duplicate lock"
21252
21253 test_276() {
21254         remote_ost_nodsh && skip "remote OST with nodsh"
21255         local pid
21256
21257         do_facet ost1 "(while true; do \
21258                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21259                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21260         pid=$!
21261
21262         for LOOP in $(seq 20); do
21263                 stop ost1
21264                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21265         done
21266         kill -9 $pid
21267         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21268                 rm $TMP/sanity_276_pid"
21269 }
21270 run_test 276 "Race between mount and obd_statfs"
21271
21272 test_277() {
21273         $LCTL set_param ldlm.namespaces.*.lru_size=0
21274         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21275         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21276                         grep ^used_mb | awk '{print $2}')
21277         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21278         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21279                 oflag=direct conv=notrunc
21280         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21281                         grep ^used_mb | awk '{print $2}')
21282         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21283 }
21284 run_test 277 "Direct IO shall drop page cache"
21285
21286 test_278() {
21287         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21288         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21289         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21290                 skip "needs the same host for mdt1 mdt2" && return
21291
21292         local pid1
21293         local pid2
21294
21295 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21296         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21297         stop mds2 &
21298         pid2=$!
21299
21300         stop mds1
21301
21302         echo "Starting MDTs"
21303         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21304         wait $pid2
21305 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21306 #will return NULL
21307         do_facet mds2 $LCTL set_param fail_loc=0
21308
21309         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21310         wait_recovery_complete mds2
21311 }
21312 run_test 278 "Race starting MDS between MDTs stop/start"
21313
21314 test_280() {
21315         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21316                 skip "Need MGS version at least 2.13.52"
21317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21318         combined_mgs_mds || skip "needs combined MGS/MDT"
21319
21320         umount_client $MOUNT
21321 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21322         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21323
21324         mount_client $MOUNT &
21325         sleep 1
21326         stop mgs || error "stop mgs failed"
21327         #for a race mgs would crash
21328         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21329         mount_client $MOUNT || error "mount client failed"
21330 }
21331 run_test 280 "Race between MGS umount and client llog processing"
21332
21333 cleanup_test_300() {
21334         trap 0
21335         umask $SAVE_UMASK
21336 }
21337 test_striped_dir() {
21338         local mdt_index=$1
21339         local stripe_count
21340         local stripe_index
21341
21342         mkdir -p $DIR/$tdir
21343
21344         SAVE_UMASK=$(umask)
21345         trap cleanup_test_300 RETURN EXIT
21346
21347         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21348                                                 $DIR/$tdir/striped_dir ||
21349                 error "set striped dir error"
21350
21351         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21352         [ "$mode" = "755" ] || error "expect 755 got $mode"
21353
21354         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21355                 error "getdirstripe failed"
21356         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21357         if [ "$stripe_count" != "2" ]; then
21358                 error "1:stripe_count is $stripe_count, expect 2"
21359         fi
21360         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21361         if [ "$stripe_count" != "2" ]; then
21362                 error "2:stripe_count is $stripe_count, expect 2"
21363         fi
21364
21365         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21366         if [ "$stripe_index" != "$mdt_index" ]; then
21367                 error "stripe_index is $stripe_index, expect $mdt_index"
21368         fi
21369
21370         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21371                 error "nlink error after create striped dir"
21372
21373         mkdir $DIR/$tdir/striped_dir/a
21374         mkdir $DIR/$tdir/striped_dir/b
21375
21376         stat $DIR/$tdir/striped_dir/a ||
21377                 error "create dir under striped dir failed"
21378         stat $DIR/$tdir/striped_dir/b ||
21379                 error "create dir under striped dir failed"
21380
21381         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21382                 error "nlink error after mkdir"
21383
21384         rmdir $DIR/$tdir/striped_dir/a
21385         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21386                 error "nlink error after rmdir"
21387
21388         rmdir $DIR/$tdir/striped_dir/b
21389         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21390                 error "nlink error after rmdir"
21391
21392         chattr +i $DIR/$tdir/striped_dir
21393         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21394                 error "immutable flags not working under striped dir!"
21395         chattr -i $DIR/$tdir/striped_dir
21396
21397         rmdir $DIR/$tdir/striped_dir ||
21398                 error "rmdir striped dir error"
21399
21400         cleanup_test_300
21401
21402         true
21403 }
21404
21405 test_300a() {
21406         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21407                 skip "skipped for lustre < 2.7.0"
21408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21409         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21410
21411         test_striped_dir 0 || error "failed on striped dir on MDT0"
21412         test_striped_dir 1 || error "failed on striped dir on MDT0"
21413 }
21414 run_test 300a "basic striped dir sanity test"
21415
21416 test_300b() {
21417         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21418                 skip "skipped for lustre < 2.7.0"
21419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21421
21422         local i
21423         local mtime1
21424         local mtime2
21425         local mtime3
21426
21427         test_mkdir $DIR/$tdir || error "mkdir fail"
21428         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21429                 error "set striped dir error"
21430         for i in {0..9}; do
21431                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21432                 sleep 1
21433                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21434                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21435                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21436                 sleep 1
21437                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21438                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21439                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21440         done
21441         true
21442 }
21443 run_test 300b "check ctime/mtime for striped dir"
21444
21445 test_300c() {
21446         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21447                 skip "skipped for lustre < 2.7.0"
21448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21450
21451         local file_count
21452
21453         mkdir -p $DIR/$tdir
21454         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21455                 error "set striped dir error"
21456
21457         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21458                 error "chown striped dir failed"
21459
21460         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21461                 error "create 5k files failed"
21462
21463         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21464
21465         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21466
21467         rm -rf $DIR/$tdir
21468 }
21469 run_test 300c "chown && check ls under striped directory"
21470
21471 test_300d() {
21472         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21473                 skip "skipped for lustre < 2.7.0"
21474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21475         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21476
21477         local stripe_count
21478         local file
21479
21480         mkdir -p $DIR/$tdir
21481         $LFS setstripe -c 2 $DIR/$tdir
21482
21483         #local striped directory
21484         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21485                 error "set striped dir error"
21486         #look at the directories for debug purposes
21487         ls -l $DIR/$tdir
21488         $LFS getdirstripe $DIR/$tdir
21489         ls -l $DIR/$tdir/striped_dir
21490         $LFS getdirstripe $DIR/$tdir/striped_dir
21491         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21492                 error "create 10 files failed"
21493
21494         #remote striped directory
21495         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21496                 error "set striped dir error"
21497         #look at the directories for debug purposes
21498         ls -l $DIR/$tdir
21499         $LFS getdirstripe $DIR/$tdir
21500         ls -l $DIR/$tdir/remote_striped_dir
21501         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21502         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21503                 error "create 10 files failed"
21504
21505         for file in $(find $DIR/$tdir); do
21506                 stripe_count=$($LFS getstripe -c $file)
21507                 [ $stripe_count -eq 2 ] ||
21508                         error "wrong stripe $stripe_count for $file"
21509         done
21510
21511         rm -rf $DIR/$tdir
21512 }
21513 run_test 300d "check default stripe under striped directory"
21514
21515 test_300e() {
21516         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21517                 skip "Need MDS version at least 2.7.55"
21518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21520
21521         local stripe_count
21522         local file
21523
21524         mkdir -p $DIR/$tdir
21525
21526         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21527                 error "set striped dir error"
21528
21529         touch $DIR/$tdir/striped_dir/a
21530         touch $DIR/$tdir/striped_dir/b
21531         touch $DIR/$tdir/striped_dir/c
21532
21533         mkdir $DIR/$tdir/striped_dir/dir_a
21534         mkdir $DIR/$tdir/striped_dir/dir_b
21535         mkdir $DIR/$tdir/striped_dir/dir_c
21536
21537         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21538                 error "set striped adir under striped dir error"
21539
21540         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21541                 error "set striped bdir under striped dir error"
21542
21543         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21544                 error "set striped cdir under striped dir error"
21545
21546         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21547                 error "rename dir under striped dir fails"
21548
21549         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21550                 error "rename dir under different stripes fails"
21551
21552         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21553                 error "rename file under striped dir should succeed"
21554
21555         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21556                 error "rename dir under striped dir should succeed"
21557
21558         rm -rf $DIR/$tdir
21559 }
21560 run_test 300e "check rename under striped directory"
21561
21562 test_300f() {
21563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21565         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21566                 skip "Need MDS version at least 2.7.55"
21567
21568         local stripe_count
21569         local file
21570
21571         rm -rf $DIR/$tdir
21572         mkdir -p $DIR/$tdir
21573
21574         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21575                 error "set striped dir error"
21576
21577         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21578                 error "set striped dir error"
21579
21580         touch $DIR/$tdir/striped_dir/a
21581         mkdir $DIR/$tdir/striped_dir/dir_a
21582         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21583                 error "create striped dir under striped dir fails"
21584
21585         touch $DIR/$tdir/striped_dir1/b
21586         mkdir $DIR/$tdir/striped_dir1/dir_b
21587         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21588                 error "create striped dir under striped dir fails"
21589
21590         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21591                 error "rename dir under different striped dir should fail"
21592
21593         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21594                 error "rename striped dir under diff striped dir should fail"
21595
21596         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21597                 error "rename file under diff striped dirs fails"
21598
21599         rm -rf $DIR/$tdir
21600 }
21601 run_test 300f "check rename cross striped directory"
21602
21603 test_300_check_default_striped_dir()
21604 {
21605         local dirname=$1
21606         local default_count=$2
21607         local default_index=$3
21608         local stripe_count
21609         local stripe_index
21610         local dir_stripe_index
21611         local dir
21612
21613         echo "checking $dirname $default_count $default_index"
21614         $LFS setdirstripe -D -c $default_count -i $default_index \
21615                                 -t all_char $DIR/$tdir/$dirname ||
21616                 error "set default stripe on striped dir error"
21617         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21618         [ $stripe_count -eq $default_count ] ||
21619                 error "expect $default_count get $stripe_count for $dirname"
21620
21621         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21622         [ $stripe_index -eq $default_index ] ||
21623                 error "expect $default_index get $stripe_index for $dirname"
21624
21625         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21626                                                 error "create dirs failed"
21627
21628         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21629         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21630         for dir in $(find $DIR/$tdir/$dirname/*); do
21631                 stripe_count=$($LFS getdirstripe -c $dir)
21632                 [ $stripe_count -eq $default_count ] ||
21633                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21634                 error "stripe count $default_count != $stripe_count for $dir"
21635
21636                 stripe_index=$($LFS getdirstripe -i $dir)
21637                 [ $default_index -eq -1 ] ||
21638                         [ $stripe_index -eq $default_index ] ||
21639                         error "$stripe_index != $default_index for $dir"
21640
21641                 #check default stripe
21642                 stripe_count=$($LFS getdirstripe -D -c $dir)
21643                 [ $stripe_count -eq $default_count ] ||
21644                 error "default count $default_count != $stripe_count for $dir"
21645
21646                 stripe_index=$($LFS getdirstripe -D -i $dir)
21647                 [ $stripe_index -eq $default_index ] ||
21648                 error "default index $default_index != $stripe_index for $dir"
21649         done
21650         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21651 }
21652
21653 test_300g() {
21654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21655         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21656                 skip "Need MDS version at least 2.7.55"
21657
21658         local dir
21659         local stripe_count
21660         local stripe_index
21661
21662         mkdir $DIR/$tdir
21663         mkdir $DIR/$tdir/normal_dir
21664
21665         #Checking when client cache stripe index
21666         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21667         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21668                 error "create striped_dir failed"
21669
21670         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21671                 error "create dir0 fails"
21672         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21673         [ $stripe_index -eq 0 ] ||
21674                 error "dir0 expect index 0 got $stripe_index"
21675
21676         mkdir $DIR/$tdir/striped_dir/dir1 ||
21677                 error "create dir1 fails"
21678         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21679         [ $stripe_index -eq 1 ] ||
21680                 error "dir1 expect index 1 got $stripe_index"
21681
21682         #check default stripe count/stripe index
21683         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21684         test_300_check_default_striped_dir normal_dir 1 0
21685         test_300_check_default_striped_dir normal_dir 2 1
21686         test_300_check_default_striped_dir normal_dir 2 -1
21687
21688         #delete default stripe information
21689         echo "delete default stripeEA"
21690         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21691                 error "set default stripe on striped dir error"
21692
21693         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21694         for dir in $(find $DIR/$tdir/normal_dir/*); do
21695                 stripe_count=$($LFS getdirstripe -c $dir)
21696                 [ $stripe_count -eq 0 ] ||
21697                         error "expect 1 get $stripe_count for $dir"
21698                 stripe_index=$($LFS getdirstripe -i $dir)
21699                 [ $stripe_index -eq 0 ] ||
21700                         error "expect 0 get $stripe_index for $dir"
21701         done
21702 }
21703 run_test 300g "check default striped directory for normal directory"
21704
21705 test_300h() {
21706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21707         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21708                 skip "Need MDS version at least 2.7.55"
21709
21710         local dir
21711         local stripe_count
21712
21713         mkdir $DIR/$tdir
21714         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21715                 error "set striped dir error"
21716
21717         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21718         test_300_check_default_striped_dir striped_dir 1 0
21719         test_300_check_default_striped_dir striped_dir 2 1
21720         test_300_check_default_striped_dir striped_dir 2 -1
21721
21722         #delete default stripe information
21723         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21724                 error "set default stripe on striped dir error"
21725
21726         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21727         for dir in $(find $DIR/$tdir/striped_dir/*); do
21728                 stripe_count=$($LFS getdirstripe -c $dir)
21729                 [ $stripe_count -eq 0 ] ||
21730                         error "expect 1 get $stripe_count for $dir"
21731         done
21732 }
21733 run_test 300h "check default striped directory for striped directory"
21734
21735 test_300i() {
21736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21737         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21738         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21739                 skip "Need MDS version at least 2.7.55"
21740
21741         local stripe_count
21742         local file
21743
21744         mkdir $DIR/$tdir
21745
21746         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21747                 error "set striped dir error"
21748
21749         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21750                 error "create files under striped dir failed"
21751
21752         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21753                 error "set striped hashdir error"
21754
21755         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21756                 error "create dir0 under hash dir failed"
21757         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21758                 error "create dir1 under hash dir failed"
21759
21760         # unfortunately, we need to umount to clear dir layout cache for now
21761         # once we fully implement dir layout, we can drop this
21762         umount_client $MOUNT || error "umount failed"
21763         mount_client $MOUNT || error "mount failed"
21764
21765         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21766         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21767         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21768
21769         #set the stripe to be unknown hash type
21770         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21771         $LCTL set_param fail_loc=0x1901
21772         for ((i = 0; i < 10; i++)); do
21773                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21774                         error "stat f-$i failed"
21775                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21776         done
21777
21778         touch $DIR/$tdir/striped_dir/f0 &&
21779                 error "create under striped dir with unknown hash should fail"
21780
21781         $LCTL set_param fail_loc=0
21782
21783         umount_client $MOUNT || error "umount failed"
21784         mount_client $MOUNT || error "mount failed"
21785
21786         return 0
21787 }
21788 run_test 300i "client handle unknown hash type striped directory"
21789
21790 test_300j() {
21791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21794                 skip "Need MDS version at least 2.7.55"
21795
21796         local stripe_count
21797         local file
21798
21799         mkdir $DIR/$tdir
21800
21801         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21802         $LCTL set_param fail_loc=0x1702
21803         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21804                 error "set striped dir error"
21805
21806         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21807                 error "create files under striped dir failed"
21808
21809         $LCTL set_param fail_loc=0
21810
21811         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21812
21813         return 0
21814 }
21815 run_test 300j "test large update record"
21816
21817 test_300k() {
21818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21819         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21820         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21821                 skip "Need MDS version at least 2.7.55"
21822
21823         # this test needs a huge transaction
21824         local kb
21825         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21826              osd*.$FSNAME-MDT0000.kbytestotal")
21827         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21828
21829         local stripe_count
21830         local file
21831
21832         mkdir $DIR/$tdir
21833
21834         #define OBD_FAIL_LARGE_STRIPE   0x1703
21835         $LCTL set_param fail_loc=0x1703
21836         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21837                 error "set striped dir error"
21838         $LCTL set_param fail_loc=0
21839
21840         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21841                 error "getstripeddir fails"
21842         rm -rf $DIR/$tdir/striped_dir ||
21843                 error "unlink striped dir fails"
21844
21845         return 0
21846 }
21847 run_test 300k "test large striped directory"
21848
21849 test_300l() {
21850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21851         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21852         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21853                 skip "Need MDS version at least 2.7.55"
21854
21855         local stripe_index
21856
21857         test_mkdir -p $DIR/$tdir/striped_dir
21858         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21859                         error "chown $RUNAS_ID failed"
21860         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21861                 error "set default striped dir failed"
21862
21863         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21864         $LCTL set_param fail_loc=0x80000158
21865         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21866
21867         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21868         [ $stripe_index -eq 1 ] ||
21869                 error "expect 1 get $stripe_index for $dir"
21870 }
21871 run_test 300l "non-root user to create dir under striped dir with stale layout"
21872
21873 test_300m() {
21874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21875         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21876         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21877                 skip "Need MDS version at least 2.7.55"
21878
21879         mkdir -p $DIR/$tdir/striped_dir
21880         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21881                 error "set default stripes dir error"
21882
21883         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21884
21885         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21886         [ $stripe_count -eq 0 ] ||
21887                         error "expect 0 get $stripe_count for a"
21888
21889         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21890                 error "set default stripes dir error"
21891
21892         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21893
21894         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21895         [ $stripe_count -eq 0 ] ||
21896                         error "expect 0 get $stripe_count for b"
21897
21898         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21899                 error "set default stripes dir error"
21900
21901         mkdir $DIR/$tdir/striped_dir/c &&
21902                 error "default stripe_index is invalid, mkdir c should fails"
21903
21904         rm -rf $DIR/$tdir || error "rmdir fails"
21905 }
21906 run_test 300m "setstriped directory on single MDT FS"
21907
21908 cleanup_300n() {
21909         local list=$(comma_list $(mdts_nodes))
21910
21911         trap 0
21912         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21913 }
21914
21915 test_300n() {
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21918         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21919                 skip "Need MDS version at least 2.7.55"
21920         remote_mds_nodsh && skip "remote MDS with nodsh"
21921
21922         local stripe_index
21923         local list=$(comma_list $(mdts_nodes))
21924
21925         trap cleanup_300n RETURN EXIT
21926         mkdir -p $DIR/$tdir
21927         chmod 777 $DIR/$tdir
21928         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21929                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21930                 error "create striped dir succeeds with gid=0"
21931
21932         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21933         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21934                 error "create striped dir fails with gid=-1"
21935
21936         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21937         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21938                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21939                 error "set default striped dir succeeds with gid=0"
21940
21941
21942         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21943         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21944                 error "set default striped dir fails with gid=-1"
21945
21946
21947         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21948         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21949                                         error "create test_dir fails"
21950         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21951                                         error "create test_dir1 fails"
21952         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21953                                         error "create test_dir2 fails"
21954         cleanup_300n
21955 }
21956 run_test 300n "non-root user to create dir under striped dir with default EA"
21957
21958 test_300o() {
21959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21960         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21961         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21962                 skip "Need MDS version at least 2.7.55"
21963
21964         local numfree1
21965         local numfree2
21966
21967         mkdir -p $DIR/$tdir
21968
21969         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21970         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21971         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21972                 skip "not enough free inodes $numfree1 $numfree2"
21973         fi
21974
21975         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21976         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21977         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21978                 skip "not enough free space $numfree1 $numfree2"
21979         fi
21980
21981         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21982                 error "setdirstripe fails"
21983
21984         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21985                 error "create dirs fails"
21986
21987         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21988         ls $DIR/$tdir/striped_dir > /dev/null ||
21989                 error "ls striped dir fails"
21990         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21991                 error "unlink big striped dir fails"
21992 }
21993 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21994
21995 test_300p() {
21996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21998         remote_mds_nodsh && skip "remote MDS with nodsh"
21999
22000         mkdir -p $DIR/$tdir
22001
22002         #define OBD_FAIL_OUT_ENOSPC     0x1704
22003         do_facet mds2 lctl set_param fail_loc=0x80001704
22004         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22005                  && error "create striped directory should fail"
22006
22007         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22008
22009         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22010         true
22011 }
22012 run_test 300p "create striped directory without space"
22013
22014 test_300q() {
22015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22017
22018         local fd=$(free_fd)
22019         local cmd="exec $fd<$tdir"
22020         cd $DIR
22021         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22022         eval $cmd
22023         cmd="exec $fd<&-"
22024         trap "eval $cmd" EXIT
22025         cd $tdir || error "cd $tdir fails"
22026         rmdir  ../$tdir || error "rmdir $tdir fails"
22027         mkdir local_dir && error "create dir succeeds"
22028         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22029         eval $cmd
22030         return 0
22031 }
22032 run_test 300q "create remote directory under orphan directory"
22033
22034 test_300r() {
22035         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22036                 skip "Need MDS version at least 2.7.55" && return
22037         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22038
22039         mkdir $DIR/$tdir
22040
22041         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22042                 error "set striped dir error"
22043
22044         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22045                 error "getstripeddir fails"
22046
22047         local stripe_count
22048         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22049                       awk '/lmv_stripe_count:/ { print $2 }')
22050
22051         [ $MDSCOUNT -ne $stripe_count ] &&
22052                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22053
22054         rm -rf $DIR/$tdir/striped_dir ||
22055                 error "unlink striped dir fails"
22056 }
22057 run_test 300r "test -1 striped directory"
22058
22059 test_300s_helper() {
22060         local count=$1
22061
22062         local stripe_dir=$DIR/$tdir/striped_dir.$count
22063
22064         $LFS mkdir -c $count $stripe_dir ||
22065                 error "lfs mkdir -c error"
22066
22067         $LFS getdirstripe $stripe_dir ||
22068                 error "lfs getdirstripe fails"
22069
22070         local stripe_count
22071         stripe_count=$($LFS getdirstripe $stripe_dir |
22072                       awk '/lmv_stripe_count:/ { print $2 }')
22073
22074         [ $count -ne $stripe_count ] &&
22075                 error_noexit "bad stripe count $stripe_count expected $count"
22076
22077         local dupe_stripes
22078         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22079                 awk '/0x/ {count[$1] += 1}; END {
22080                         for (idx in count) {
22081                                 if (count[idx]>1) {
22082                                         print "index " idx " count " count[idx]
22083                                 }
22084                         }
22085                 }')
22086
22087         if [[ -n "$dupe_stripes" ]] ; then
22088                 lfs getdirstripe $stripe_dir
22089                 error_noexit "Dupe MDT above: $dupe_stripes "
22090         fi
22091
22092         rm -rf $stripe_dir ||
22093                 error_noexit "unlink $stripe_dir fails"
22094 }
22095
22096 test_300s() {
22097         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22098                 skip "Need MDS version at least 2.7.55" && return
22099         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22100
22101         mkdir $DIR/$tdir
22102         for count in $(seq 2 $MDSCOUNT); do
22103                 test_300s_helper $count
22104         done
22105 }
22106 run_test 300s "test lfs mkdir -c without -i"
22107
22108
22109 prepare_remote_file() {
22110         mkdir $DIR/$tdir/src_dir ||
22111                 error "create remote source failed"
22112
22113         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22114                  error "cp to remote source failed"
22115         touch $DIR/$tdir/src_dir/a
22116
22117         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22118                 error "create remote target dir failed"
22119
22120         touch $DIR/$tdir/tgt_dir/b
22121
22122         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22123                 error "rename dir cross MDT failed!"
22124
22125         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22126                 error "src_child still exists after rename"
22127
22128         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22129                 error "missing file(a) after rename"
22130
22131         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22132                 error "diff after rename"
22133 }
22134
22135 test_310a() {
22136         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22138
22139         local remote_file=$DIR/$tdir/tgt_dir/b
22140
22141         mkdir -p $DIR/$tdir
22142
22143         prepare_remote_file || error "prepare remote file failed"
22144
22145         #open-unlink file
22146         $OPENUNLINK $remote_file $remote_file ||
22147                 error "openunlink $remote_file failed"
22148         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22149 }
22150 run_test 310a "open unlink remote file"
22151
22152 test_310b() {
22153         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22155
22156         local remote_file=$DIR/$tdir/tgt_dir/b
22157
22158         mkdir -p $DIR/$tdir
22159
22160         prepare_remote_file || error "prepare remote file failed"
22161
22162         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22163         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22164         $CHECKSTAT -t file $remote_file || error "check file failed"
22165 }
22166 run_test 310b "unlink remote file with multiple links while open"
22167
22168 test_310c() {
22169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22170         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22171
22172         local remote_file=$DIR/$tdir/tgt_dir/b
22173
22174         mkdir -p $DIR/$tdir
22175
22176         prepare_remote_file || error "prepare remote file failed"
22177
22178         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22179         multiop_bg_pause $remote_file O_uc ||
22180                         error "mulitop failed for remote file"
22181         MULTIPID=$!
22182         $MULTIOP $DIR/$tfile Ouc
22183         kill -USR1 $MULTIPID
22184         wait $MULTIPID
22185 }
22186 run_test 310c "open-unlink remote file with multiple links"
22187
22188 #LU-4825
22189 test_311() {
22190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22191         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22192         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22193                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22194         remote_mds_nodsh && skip "remote MDS with nodsh"
22195
22196         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22197         local mdts=$(comma_list $(mdts_nodes))
22198
22199         mkdir -p $DIR/$tdir
22200         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22201         createmany -o $DIR/$tdir/$tfile. 1000
22202
22203         # statfs data is not real time, let's just calculate it
22204         old_iused=$((old_iused + 1000))
22205
22206         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22207                         osp.*OST0000*MDT0000.create_count")
22208         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22209                                 osp.*OST0000*MDT0000.max_create_count")
22210         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22211
22212         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22213         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22214         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22215
22216         unlinkmany $DIR/$tdir/$tfile. 1000
22217
22218         do_nodes $mdts "$LCTL set_param -n \
22219                         osp.*OST0000*.max_create_count=$max_count"
22220         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22221                 do_nodes $mdts "$LCTL set_param -n \
22222                                 osp.*OST0000*.create_count=$count"
22223         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22224                         grep "=0" && error "create_count is zero"
22225
22226         local new_iused
22227         for i in $(seq 120); do
22228                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22229                 # system may be too busy to destroy all objs in time, use
22230                 # a somewhat small value to not fail autotest
22231                 [ $((old_iused - new_iused)) -gt 400 ] && break
22232                 sleep 1
22233         done
22234
22235         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22236         [ $((old_iused - new_iused)) -gt 400 ] ||
22237                 error "objs not destroyed after unlink"
22238 }
22239 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22240
22241 zfs_oid_to_objid()
22242 {
22243         local ost=$1
22244         local objid=$2
22245
22246         local vdevdir=$(dirname $(facet_vdevice $ost))
22247         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22248         local zfs_zapid=$(do_facet $ost $cmd |
22249                           grep -w "/O/0/d$((objid%32))" -C 5 |
22250                           awk '/Object/{getline; print $1}')
22251         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22252                           awk "/$objid = /"'{printf $3}')
22253
22254         echo $zfs_objid
22255 }
22256
22257 zfs_object_blksz() {
22258         local ost=$1
22259         local objid=$2
22260
22261         local vdevdir=$(dirname $(facet_vdevice $ost))
22262         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22263         local blksz=$(do_facet $ost $cmd $objid |
22264                       awk '/dblk/{getline; printf $4}')
22265
22266         case "${blksz: -1}" in
22267                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22268                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22269                 *) ;;
22270         esac
22271
22272         echo $blksz
22273 }
22274
22275 test_312() { # LU-4856
22276         remote_ost_nodsh && skip "remote OST with nodsh"
22277         [ "$ost1_FSTYPE" = "zfs" ] ||
22278                 skip_env "the test only applies to zfs"
22279
22280         local max_blksz=$(do_facet ost1 \
22281                           $ZFS get -p recordsize $(facet_device ost1) |
22282                           awk '!/VALUE/{print $3}')
22283
22284         # to make life a little bit easier
22285         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22286         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22287
22288         local tf=$DIR/$tdir/$tfile
22289         touch $tf
22290         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22291
22292         # Get ZFS object id
22293         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22294         # block size change by sequential overwrite
22295         local bs
22296
22297         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22298                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22299
22300                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22301                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22302         done
22303         rm -f $tf
22304
22305         # block size change by sequential append write
22306         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22307         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22308         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22309         local count
22310
22311         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22312                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22313                         oflag=sync conv=notrunc
22314
22315                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22316                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22317                         error "blksz error, actual $blksz, " \
22318                                 "expected: 2 * $count * $PAGE_SIZE"
22319         done
22320         rm -f $tf
22321
22322         # random write
22323         touch $tf
22324         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22325         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22326
22327         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22328         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22329         [ $blksz -eq $PAGE_SIZE ] ||
22330                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22331
22332         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22333         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22334         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22335
22336         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22337         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22338         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22339 }
22340 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22341
22342 test_313() {
22343         remote_ost_nodsh && skip "remote OST with nodsh"
22344
22345         local file=$DIR/$tfile
22346
22347         rm -f $file
22348         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22349
22350         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22351         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22352         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22353                 error "write should failed"
22354         do_facet ost1 "$LCTL set_param fail_loc=0"
22355         rm -f $file
22356 }
22357 run_test 313 "io should fail after last_rcvd update fail"
22358
22359 test_314() {
22360         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22361
22362         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22363         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22364         rm -f $DIR/$tfile
22365         wait_delete_completed
22366         do_facet ost1 "$LCTL set_param fail_loc=0"
22367 }
22368 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22369
22370 test_315() { # LU-618
22371         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22372
22373         local file=$DIR/$tfile
22374         rm -f $file
22375
22376         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22377                 error "multiop file write failed"
22378         $MULTIOP $file oO_RDONLY:r4063232_c &
22379         PID=$!
22380
22381         sleep 2
22382
22383         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22384         kill -USR1 $PID
22385
22386         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22387         rm -f $file
22388 }
22389 run_test 315 "read should be accounted"
22390
22391 test_316() {
22392         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22393         large_xattr_enabled || skip_env "ea_inode feature disabled"
22394
22395         rm -rf $DIR/$tdir/d
22396         mkdir -p $DIR/$tdir/d
22397         chown nobody $DIR/$tdir/d
22398         touch $DIR/$tdir/d/file
22399
22400         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22401 }
22402 run_test 316 "lfs mv"
22403
22404 test_317() {
22405         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22406                 skip "Need MDS version at least 2.11.53"
22407         if [ "$ost1_FSTYPE" == "zfs" ]; then
22408                 skip "LU-10370: no implementation for ZFS"
22409         fi
22410
22411         local trunc_sz
22412         local grant_blk_size
22413
22414         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22415                         awk '/grant_block_size:/ { print $2; exit; }')
22416         #
22417         # Create File of size 5M. Truncate it to below size's and verify
22418         # blocks count.
22419         #
22420         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22421                 error "Create file $DIR/$tfile failed"
22422         stack_trap "rm -f $DIR/$tfile" EXIT
22423
22424         for trunc_sz in 2097152 4097 4000 509 0; do
22425                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22426                         error "truncate $tfile to $trunc_sz failed"
22427                 local sz=$(stat --format=%s $DIR/$tfile)
22428                 local blk=$(stat --format=%b $DIR/$tfile)
22429                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22430                                      grant_blk_size) * 8))
22431
22432                 if [[ $blk -ne $trunc_blk ]]; then
22433                         $(which stat) $DIR/$tfile
22434                         error "Expected Block $trunc_blk got $blk for $tfile"
22435                 fi
22436
22437                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22438                         error "Expected Size $trunc_sz got $sz for $tfile"
22439         done
22440
22441         #
22442         # sparse file test
22443         # Create file with a hole and write actual two blocks. Block count
22444         # must be 16.
22445         #
22446         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22447                 conv=fsync || error "Create file : $DIR/$tfile"
22448
22449         # Calculate the final truncate size.
22450         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22451
22452         #
22453         # truncate to size $trunc_sz bytes. Strip the last block
22454         # The block count must drop to 8
22455         #
22456         $TRUNCATE $DIR/$tfile $trunc_sz ||
22457                 error "truncate $tfile to $trunc_sz failed"
22458
22459         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22460         sz=$(stat --format=%s $DIR/$tfile)
22461         blk=$(stat --format=%b $DIR/$tfile)
22462
22463         if [[ $blk -ne $trunc_bsz ]]; then
22464                 $(which stat) $DIR/$tfile
22465                 error "Expected Block $trunc_bsz got $blk for $tfile"
22466         fi
22467
22468         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22469                 error "Expected Size $trunc_sz got $sz for $tfile"
22470 }
22471 run_test 317 "Verify blocks get correctly update after truncate"
22472
22473 test_318() {
22474         local old_max_active=$($LCTL get_param -n \
22475                             llite.*.max_read_ahead_async_active 2>/dev/null)
22476
22477         $LCTL set_param llite.*.max_read_ahead_async_active=256
22478         local max_active=$($LCTL get_param -n \
22479                            llite.*.max_read_ahead_async_active 2>/dev/null)
22480         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22481
22482         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22483                 error "set max_read_ahead_async_active should succeed"
22484
22485         $LCTL set_param llite.*.max_read_ahead_async_active=512
22486         max_active=$($LCTL get_param -n \
22487                      llite.*.max_read_ahead_async_active 2>/dev/null)
22488         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22489
22490         # restore @max_active
22491         [ $old_max_active -ne 0 ] && $LCTL set_param \
22492                 llite.*.max_read_ahead_async_active=$old_max_active
22493
22494         local old_threshold=$($LCTL get_param -n \
22495                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22496         local max_per_file_mb=$($LCTL get_param -n \
22497                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22498
22499         local invalid=$(($max_per_file_mb + 1))
22500         $LCTL set_param \
22501                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22502                         && error "set $invalid should fail"
22503
22504         local valid=$(($invalid - 1))
22505         $LCTL set_param \
22506                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22507                         error "set $valid should succeed"
22508         local threshold=$($LCTL get_param -n \
22509                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22510         [ $threshold -eq $valid ] || error \
22511                 "expect threshold $valid got $threshold"
22512         $LCTL set_param \
22513                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22514 }
22515 run_test 318 "Verify async readahead tunables"
22516
22517 test_319() {
22518         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22519
22520         local before=$(date +%s)
22521         local evict
22522         local mdir=$DIR/$tdir
22523         local file=$mdir/xxx
22524
22525         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22526         touch $file
22527
22528 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22529         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22530         $LFS mv -m1 $file &
22531
22532         sleep 1
22533         dd if=$file of=/dev/null
22534         wait
22535         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22536           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22537
22538         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22539 }
22540 run_test 319 "lost lease lock on migrate error"
22541
22542 test_398a() { # LU-4198
22543         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22544         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22545
22546         # request a new lock on client
22547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22548
22549         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22550         local lock_count=$($LCTL get_param -n \
22551                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22552         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22553
22554         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22555
22556         # no lock cached, should use lockless IO and not enqueue new lock
22557         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22558         lock_count=$($LCTL get_param -n \
22559                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22560         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22561 }
22562 run_test 398a "direct IO should cancel lock otherwise lockless"
22563
22564 test_398b() { # LU-4198
22565         which fio || skip_env "no fio installed"
22566         $LFS setstripe -c -1 $DIR/$tfile
22567
22568         local size=12
22569         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22570
22571         local njobs=4
22572         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22573         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22574                 --numjobs=$njobs --fallocate=none \
22575                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22576                 --filename=$DIR/$tfile &
22577         bg_pid=$!
22578
22579         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22580         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22581                 --numjobs=$njobs --fallocate=none \
22582                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22583                 --filename=$DIR/$tfile || true
22584         wait $bg_pid
22585
22586         rm -rf $DIR/$tfile
22587 }
22588 run_test 398b "DIO and buffer IO race"
22589
22590 test_398c() { # LU-4198
22591         which fio || skip_env "no fio installed"
22592
22593         saved_debug=$($LCTL get_param -n debug)
22594         $LCTL set_param debug=0
22595
22596         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22597         ((size /= 1024)) # by megabytes
22598         ((size /= 2)) # write half of the OST at most
22599         [ $size -gt 40 ] && size=40 #reduce test time anyway
22600
22601         $LFS setstripe -c 1 $DIR/$tfile
22602
22603         # it seems like ldiskfs reserves more space than necessary if the
22604         # writing blocks are not mapped, so it extends the file firstly
22605         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22606         cancel_lru_locks osc
22607
22608         # clear and verify rpc_stats later
22609         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22610
22611         local njobs=4
22612         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22613         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22614                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22615                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22616                 --filename=$DIR/$tfile
22617         [ $? -eq 0 ] || error "fio write error"
22618
22619         [ $($LCTL get_param -n \
22620          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22621                 error "Locks were requested while doing AIO"
22622
22623         # get the percentage of 1-page I/O
22624         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22625                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22626                 awk '{print $7}')
22627         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22628
22629         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22630         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22631                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22632                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22633                 --filename=$DIR/$tfile
22634         [ $? -eq 0 ] || error "fio mixed read write error"
22635
22636         echo "AIO with large block size ${size}M"
22637         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22638                 --numjobs=1 --fallocate=none --ioengine=libaio \
22639                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22640                 --filename=$DIR/$tfile
22641         [ $? -eq 0 ] || error "fio large block size failed"
22642
22643         rm -rf $DIR/$tfile
22644         $LCTL set_param debug="$saved_debug"
22645 }
22646 run_test 398c "run fio to test AIO"
22647
22648 test_398d() { #  LU-13846
22649         test -f aiocp || skip_env "no aiocp installed"
22650         local aio_file=$DIR/aio_file
22651
22652         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22653
22654         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22655         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22656
22657         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22658
22659         # make sure we don't crash and fail properly
22660         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22661                 error "aio not aligned with PAGE SIZE should fail"
22662
22663         rm -rf $DIR/$tfile $aio_file
22664 }
22665 run_test 398d "run aiocp to verify block size > stripe size"
22666
22667 test_398e() {
22668         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22669         touch $DIR/$tfile.new
22670         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22671 }
22672 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22673
22674 test_fake_rw() {
22675         local read_write=$1
22676         if [ "$read_write" = "write" ]; then
22677                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22678         elif [ "$read_write" = "read" ]; then
22679                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22680         else
22681                 error "argument error"
22682         fi
22683
22684         # turn off debug for performance testing
22685         local saved_debug=$($LCTL get_param -n debug)
22686         $LCTL set_param debug=0
22687
22688         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22689
22690         # get ost1 size - $FSNAME-OST0000
22691         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22692         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22693         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22694
22695         if [ "$read_write" = "read" ]; then
22696                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22697         fi
22698
22699         local start_time=$(date +%s.%N)
22700         $dd_cmd bs=1M count=$blocks oflag=sync ||
22701                 error "real dd $read_write error"
22702         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22703
22704         if [ "$read_write" = "write" ]; then
22705                 rm -f $DIR/$tfile
22706         fi
22707
22708         # define OBD_FAIL_OST_FAKE_RW           0x238
22709         do_facet ost1 $LCTL set_param fail_loc=0x238
22710
22711         local start_time=$(date +%s.%N)
22712         $dd_cmd bs=1M count=$blocks oflag=sync ||
22713                 error "fake dd $read_write error"
22714         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22715
22716         if [ "$read_write" = "write" ]; then
22717                 # verify file size
22718                 cancel_lru_locks osc
22719                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22720                         error "$tfile size not $blocks MB"
22721         fi
22722         do_facet ost1 $LCTL set_param fail_loc=0
22723
22724         echo "fake $read_write $duration_fake vs. normal $read_write" \
22725                 "$duration in seconds"
22726         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22727                 error_not_in_vm "fake write is slower"
22728
22729         $LCTL set_param -n debug="$saved_debug"
22730         rm -f $DIR/$tfile
22731 }
22732 test_399a() { # LU-7655 for OST fake write
22733         remote_ost_nodsh && skip "remote OST with nodsh"
22734
22735         test_fake_rw write
22736 }
22737 run_test 399a "fake write should not be slower than normal write"
22738
22739 test_399b() { # LU-8726 for OST fake read
22740         remote_ost_nodsh && skip "remote OST with nodsh"
22741         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22742                 skip_env "ldiskfs only test"
22743         fi
22744
22745         test_fake_rw read
22746 }
22747 run_test 399b "fake read should not be slower than normal read"
22748
22749 test_400a() { # LU-1606, was conf-sanity test_74
22750         if ! which $CC > /dev/null 2>&1; then
22751                 skip_env "$CC is not installed"
22752         fi
22753
22754         local extra_flags=''
22755         local out=$TMP/$tfile
22756         local prefix=/usr/include/lustre
22757         local prog
22758
22759         # Oleg removes c files in his test rig so test if any c files exist
22760         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22761                 skip_env "Needed c test files are missing"
22762
22763         if ! [[ -d $prefix ]]; then
22764                 # Assume we're running in tree and fixup the include path.
22765                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22766                 extra_flags+=" -L$LUSTRE/utils/.lib"
22767         fi
22768
22769         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22770                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22771                         error "client api broken"
22772         done
22773         rm -f $out
22774 }
22775 run_test 400a "Lustre client api program can compile and link"
22776
22777 test_400b() { # LU-1606, LU-5011
22778         local header
22779         local out=$TMP/$tfile
22780         local prefix=/usr/include/linux/lustre
22781
22782         # We use a hard coded prefix so that this test will not fail
22783         # when run in tree. There are headers in lustre/include/lustre/
22784         # that are not packaged (like lustre_idl.h) and have more
22785         # complicated include dependencies (like config.h and lnet/types.h).
22786         # Since this test about correct packaging we just skip them when
22787         # they don't exist (see below) rather than try to fixup cppflags.
22788
22789         if ! which $CC > /dev/null 2>&1; then
22790                 skip_env "$CC is not installed"
22791         fi
22792
22793         for header in $prefix/*.h; do
22794                 if ! [[ -f "$header" ]]; then
22795                         continue
22796                 fi
22797
22798                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22799                         continue # lustre_ioctl.h is internal header
22800                 fi
22801
22802                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22803                         error "cannot compile '$header'"
22804         done
22805         rm -f $out
22806 }
22807 run_test 400b "packaged headers can be compiled"
22808
22809 test_401a() { #LU-7437
22810         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22811         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22812
22813         #count the number of parameters by "list_param -R"
22814         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22815         #count the number of parameters by listing proc files
22816         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22817         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22818         echo "proc_dirs='$proc_dirs'"
22819         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22820         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22821                       sort -u | wc -l)
22822
22823         [ $params -eq $procs ] ||
22824                 error "found $params parameters vs. $procs proc files"
22825
22826         # test the list_param -D option only returns directories
22827         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22828         #count the number of parameters by listing proc directories
22829         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22830                 sort -u | wc -l)
22831
22832         [ $params -eq $procs ] ||
22833                 error "found $params parameters vs. $procs proc files"
22834 }
22835 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22836
22837 test_401b() {
22838         # jobid_var may not allow arbitrary values, so use jobid_name
22839         # if available
22840         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22841                 local testname=jobid_name tmp='testing%p'
22842         else
22843                 local testname=jobid_var tmp=testing
22844         fi
22845
22846         local save=$($LCTL get_param -n $testname)
22847
22848         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22849                 error "no error returned when setting bad parameters"
22850
22851         local jobid_new=$($LCTL get_param -n foe $testname baz)
22852         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22853
22854         $LCTL set_param -n fog=bam $testname=$save bat=fog
22855         local jobid_old=$($LCTL get_param -n foe $testname bag)
22856         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22857 }
22858 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22859
22860 test_401c() {
22861         # jobid_var may not allow arbitrary values, so use jobid_name
22862         # if available
22863         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22864                 local testname=jobid_name
22865         else
22866                 local testname=jobid_var
22867         fi
22868
22869         local jobid_var_old=$($LCTL get_param -n $testname)
22870         local jobid_var_new
22871
22872         $LCTL set_param $testname= &&
22873                 error "no error returned for 'set_param a='"
22874
22875         jobid_var_new=$($LCTL get_param -n $testname)
22876         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22877                 error "$testname was changed by setting without value"
22878
22879         $LCTL set_param $testname &&
22880                 error "no error returned for 'set_param a'"
22881
22882         jobid_var_new=$($LCTL get_param -n $testname)
22883         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22884                 error "$testname was changed by setting without value"
22885 }
22886 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22887
22888 test_401d() {
22889         # jobid_var may not allow arbitrary values, so use jobid_name
22890         # if available
22891         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22892                 local testname=jobid_name new_value='foo=bar%p'
22893         else
22894                 local testname=jobid_var new_valuie=foo=bar
22895         fi
22896
22897         local jobid_var_old=$($LCTL get_param -n $testname)
22898         local jobid_var_new
22899
22900         $LCTL set_param $testname=$new_value ||
22901                 error "'set_param a=b' did not accept a value containing '='"
22902
22903         jobid_var_new=$($LCTL get_param -n $testname)
22904         [[ "$jobid_var_new" == "$new_value" ]] ||
22905                 error "'set_param a=b' failed on a value containing '='"
22906
22907         # Reset the $testname to test the other format
22908         $LCTL set_param $testname=$jobid_var_old
22909         jobid_var_new=$($LCTL get_param -n $testname)
22910         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22911                 error "failed to reset $testname"
22912
22913         $LCTL set_param $testname $new_value ||
22914                 error "'set_param a b' did not accept a value containing '='"
22915
22916         jobid_var_new=$($LCTL get_param -n $testname)
22917         [[ "$jobid_var_new" == "$new_value" ]] ||
22918                 error "'set_param a b' failed on a value containing '='"
22919
22920         $LCTL set_param $testname $jobid_var_old
22921         jobid_var_new=$($LCTL get_param -n $testname)
22922         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22923                 error "failed to reset $testname"
22924 }
22925 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22926
22927 test_402() {
22928         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22929         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22930                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22931         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22932                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22933                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22934         remote_mds_nodsh && skip "remote MDS with nodsh"
22935
22936         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22937 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22938         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22939         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22940                 echo "Touch failed - OK"
22941 }
22942 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22943
22944 test_403() {
22945         local file1=$DIR/$tfile.1
22946         local file2=$DIR/$tfile.2
22947         local tfile=$TMP/$tfile
22948
22949         rm -f $file1 $file2 $tfile
22950
22951         touch $file1
22952         ln $file1 $file2
22953
22954         # 30 sec OBD_TIMEOUT in ll_getattr()
22955         # right before populating st_nlink
22956         $LCTL set_param fail_loc=0x80001409
22957         stat -c %h $file1 > $tfile &
22958
22959         # create an alias, drop all locks and reclaim the dentry
22960         < $file2
22961         cancel_lru_locks mdc
22962         cancel_lru_locks osc
22963         sysctl -w vm.drop_caches=2
22964
22965         wait
22966
22967         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22968
22969         rm -f $tfile $file1 $file2
22970 }
22971 run_test 403 "i_nlink should not drop to zero due to aliasing"
22972
22973 test_404() { # LU-6601
22974         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22975                 skip "Need server version newer than 2.8.52"
22976         remote_mds_nodsh && skip "remote MDS with nodsh"
22977
22978         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22979                 awk '/osp .*-osc-MDT/ { print $4}')
22980
22981         local osp
22982         for osp in $mosps; do
22983                 echo "Deactivate: " $osp
22984                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22985                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22986                         awk -vp=$osp '$4 == p { print $2 }')
22987                 [ $stat = IN ] || {
22988                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22989                         error "deactivate error"
22990                 }
22991                 echo "Activate: " $osp
22992                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22993                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22994                         awk -vp=$osp '$4 == p { print $2 }')
22995                 [ $stat = UP ] || {
22996                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22997                         error "activate error"
22998                 }
22999         done
23000 }
23001 run_test 404 "validate manual {de}activated works properly for OSPs"
23002
23003 test_405() {
23004         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23005         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23006                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23007                         skip "Layout swap lock is not supported"
23008
23009         check_swap_layouts_support
23010         check_swap_layout_no_dom $DIR
23011
23012         test_mkdir $DIR/$tdir
23013         swap_lock_test -d $DIR/$tdir ||
23014                 error "One layout swap locked test failed"
23015 }
23016 run_test 405 "Various layout swap lock tests"
23017
23018 test_406() {
23019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23020         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23021         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23023         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23024                 skip "Need MDS version at least 2.8.50"
23025
23026         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23027         local test_pool=$TESTNAME
23028
23029         pool_add $test_pool || error "pool_add failed"
23030         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23031                 error "pool_add_targets failed"
23032
23033         save_layout_restore_at_exit $MOUNT
23034
23035         # parent set default stripe count only, child will stripe from both
23036         # parent and fs default
23037         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23038                 error "setstripe $MOUNT failed"
23039         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23040         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23041         for i in $(seq 10); do
23042                 local f=$DIR/$tdir/$tfile.$i
23043                 touch $f || error "touch failed"
23044                 local count=$($LFS getstripe -c $f)
23045                 [ $count -eq $OSTCOUNT ] ||
23046                         error "$f stripe count $count != $OSTCOUNT"
23047                 local offset=$($LFS getstripe -i $f)
23048                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23049                 local size=$($LFS getstripe -S $f)
23050                 [ $size -eq $((def_stripe_size * 2)) ] ||
23051                         error "$f stripe size $size != $((def_stripe_size * 2))"
23052                 local pool=$($LFS getstripe -p $f)
23053                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23054         done
23055
23056         # change fs default striping, delete parent default striping, now child
23057         # will stripe from new fs default striping only
23058         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23059                 error "change $MOUNT default stripe failed"
23060         $LFS setstripe -c 0 $DIR/$tdir ||
23061                 error "delete $tdir default stripe failed"
23062         for i in $(seq 11 20); do
23063                 local f=$DIR/$tdir/$tfile.$i
23064                 touch $f || error "touch $f failed"
23065                 local count=$($LFS getstripe -c $f)
23066                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23067                 local offset=$($LFS getstripe -i $f)
23068                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23069                 local size=$($LFS getstripe -S $f)
23070                 [ $size -eq $def_stripe_size ] ||
23071                         error "$f stripe size $size != $def_stripe_size"
23072                 local pool=$($LFS getstripe -p $f)
23073                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23074         done
23075
23076         unlinkmany $DIR/$tdir/$tfile. 1 20
23077
23078         local f=$DIR/$tdir/$tfile
23079         pool_remove_all_targets $test_pool $f
23080         pool_remove $test_pool $f
23081 }
23082 run_test 406 "DNE support fs default striping"
23083
23084 test_407() {
23085         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23086         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23087                 skip "Need MDS version at least 2.8.55"
23088         remote_mds_nodsh && skip "remote MDS with nodsh"
23089
23090         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23091                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23092         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23093                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23094         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23095
23096         #define OBD_FAIL_DT_TXN_STOP    0x2019
23097         for idx in $(seq $MDSCOUNT); do
23098                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23099         done
23100         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23101         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23102                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23103         true
23104 }
23105 run_test 407 "transaction fail should cause operation fail"
23106
23107 test_408() {
23108         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23109
23110         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23111         lctl set_param fail_loc=0x8000040a
23112         # let ll_prepare_partial_page() fail
23113         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23114
23115         rm -f $DIR/$tfile
23116
23117         # create at least 100 unused inodes so that
23118         # shrink_icache_memory(0) should not return 0
23119         touch $DIR/$tfile-{0..100}
23120         rm -f $DIR/$tfile-{0..100}
23121         sync
23122
23123         echo 2 > /proc/sys/vm/drop_caches
23124 }
23125 run_test 408 "drop_caches should not hang due to page leaks"
23126
23127 test_409()
23128 {
23129         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23130
23131         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23132         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23133         touch $DIR/$tdir/guard || error "(2) Fail to create"
23134
23135         local PREFIX=$(str_repeat 'A' 128)
23136         echo "Create 1K hard links start at $(date)"
23137         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23138                 error "(3) Fail to hard link"
23139
23140         echo "Links count should be right although linkEA overflow"
23141         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23142         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23143         [ $linkcount -eq 1001 ] ||
23144                 error "(5) Unexpected hard links count: $linkcount"
23145
23146         echo "List all links start at $(date)"
23147         ls -l $DIR/$tdir/foo > /dev/null ||
23148                 error "(6) Fail to list $DIR/$tdir/foo"
23149
23150         echo "Unlink hard links start at $(date)"
23151         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23152                 error "(7) Fail to unlink"
23153         echo "Unlink hard links finished at $(date)"
23154 }
23155 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23156
23157 test_410()
23158 {
23159         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23160                 skip "Need client version at least 2.9.59"
23161         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23162                 skip "Need MODULES build"
23163
23164         # Create a file, and stat it from the kernel
23165         local testfile=$DIR/$tfile
23166         touch $testfile
23167
23168         local run_id=$RANDOM
23169         local my_ino=$(stat --format "%i" $testfile)
23170
23171         # Try to insert the module. This will always fail as the
23172         # module is designed to not be inserted.
23173         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23174             &> /dev/null
23175
23176         # Anything but success is a test failure
23177         dmesg | grep -q \
23178             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23179             error "no inode match"
23180 }
23181 run_test 410 "Test inode number returned from kernel thread"
23182
23183 cleanup_test411_cgroup() {
23184         trap 0
23185         rmdir "$1"
23186 }
23187
23188 test_411() {
23189         local cg_basedir=/sys/fs/cgroup/memory
23190         # LU-9966
23191         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23192                 skip "no setup for cgroup"
23193
23194         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23195                 error "test file creation failed"
23196         cancel_lru_locks osc
23197
23198         # Create a very small memory cgroup to force a slab allocation error
23199         local cgdir=$cg_basedir/osc_slab_alloc
23200         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23201         trap "cleanup_test411_cgroup $cgdir" EXIT
23202         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23203         echo 1M > $cgdir/memory.limit_in_bytes
23204
23205         # Should not LBUG, just be killed by oom-killer
23206         # dd will return 0 even allocation failure in some environment.
23207         # So don't check return value
23208         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23209         cleanup_test411_cgroup $cgdir
23210
23211         return 0
23212 }
23213 run_test 411 "Slab allocation error with cgroup does not LBUG"
23214
23215 test_412() {
23216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23217         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23218                 skip "Need server version at least 2.10.55"
23219         fi
23220
23221         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23222                 error "mkdir failed"
23223         $LFS getdirstripe $DIR/$tdir
23224         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23225         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23226                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23227         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23228         [ $stripe_count -eq 2 ] ||
23229                 error "expect 2 get $stripe_count"
23230 }
23231 run_test 412 "mkdir on specific MDTs"
23232
23233 test_qos_mkdir() {
23234         local mkdir_cmd=$1
23235         local stripe_count=$2
23236         local mdts=$(comma_list $(mdts_nodes))
23237
23238         local testdir
23239         local lmv_qos_prio_free
23240         local lmv_qos_threshold_rr
23241         local lmv_qos_maxage
23242         local lod_qos_prio_free
23243         local lod_qos_threshold_rr
23244         local lod_qos_maxage
23245         local count
23246         local i
23247
23248         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23249         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23250         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23251                 head -n1)
23252         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23253         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23254         stack_trap "$LCTL set_param \
23255                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23256         stack_trap "$LCTL set_param \
23257                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23258         stack_trap "$LCTL set_param \
23259                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23260
23261         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23262                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23263         lod_qos_prio_free=${lod_qos_prio_free%%%}
23264         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23265                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23266         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23267         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23268                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23269         stack_trap "do_nodes $mdts $LCTL set_param \
23270                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23271         stack_trap "do_nodes $mdts $LCTL set_param \
23272                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23273                 EXIT
23274         stack_trap "do_nodes $mdts $LCTL set_param \
23275                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23276
23277         echo
23278         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23279
23280         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23281         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23282
23283         testdir=$DIR/$tdir-s$stripe_count/rr
23284
23285         for i in $(seq $((100 * MDSCOUNT))); do
23286                 eval $mkdir_cmd $testdir/subdir$i ||
23287                         error "$mkdir_cmd subdir$i failed"
23288         done
23289
23290         for i in $(seq $MDSCOUNT); do
23291                 count=$($LFS getdirstripe -i $testdir/* |
23292                                 grep ^$((i - 1))$ | wc -l)
23293                 echo "$count directories created on MDT$((i - 1))"
23294                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23295
23296                 if [ $stripe_count -gt 1 ]; then
23297                         count=$($LFS getdirstripe $testdir/* |
23298                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23299                         echo "$count stripes created on MDT$((i - 1))"
23300                         # deviation should < 5% of average
23301                         [ $count -lt $((95 * stripe_count)) ] ||
23302                         [ $count -gt $((105 * stripe_count)) ] &&
23303                                 error "stripes are not evenly distributed"
23304                 fi
23305         done
23306
23307         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23308         do_nodes $mdts $LCTL set_param \
23309                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23310
23311         echo
23312         echo "Check for uneven MDTs: "
23313
23314         local ffree
23315         local bavail
23316         local max
23317         local min
23318         local max_index
23319         local min_index
23320         local tmp
23321
23322         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23323         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23324         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23325
23326         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23327         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23328         max_index=0
23329         min_index=0
23330         for ((i = 1; i < ${#ffree[@]}; i++)); do
23331                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23332                 if [ $tmp -gt $max ]; then
23333                         max=$tmp
23334                         max_index=$i
23335                 fi
23336                 if [ $tmp -lt $min ]; then
23337                         min=$tmp
23338                         min_index=$i
23339                 fi
23340         done
23341
23342         [ ${ffree[min_index]} -eq 0 ] &&
23343                 skip "no free files in MDT$min_index"
23344         [ ${ffree[min_index]} -gt 100000000 ] &&
23345                 skip "too much free files in MDT$min_index"
23346
23347         # Check if we need to generate uneven MDTs
23348         local threshold=50
23349         local diff=$(((max - min) * 100 / min))
23350         local value="$(generate_string 1024)"
23351
23352         while [ $diff -lt $threshold ]; do
23353                 # generate uneven MDTs, create till $threshold% diff
23354                 echo -n "weight diff=$diff% must be > $threshold% ..."
23355                 count=$((${ffree[min_index]} / 10))
23356                 # 50 sec per 10000 files in vm
23357                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23358                         skip "$count files to create"
23359                 echo "Fill MDT$min_index with $count files"
23360                 [ -d $DIR/$tdir-MDT$min_index ] ||
23361                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23362                         error "mkdir $tdir-MDT$min_index failed"
23363                 for i in $(seq $count); do
23364                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23365                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23366                                 error "create f$j_$i failed"
23367                         setfattr -n user.413b -v $value \
23368                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23369                                 error "setfattr f$j_$i failed"
23370                 done
23371
23372                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23373                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23374                 max=$(((${ffree[max_index]} >> 8) * \
23375                         (${bavail[max_index]} * bsize >> 16)))
23376                 min=$(((${ffree[min_index]} >> 8) * \
23377                         (${bavail[min_index]} * bsize >> 16)))
23378                 diff=$(((max - min) * 100 / min))
23379         done
23380
23381         echo "MDT filesfree available: ${ffree[@]}"
23382         echo "MDT blocks available: ${bavail[@]}"
23383         echo "weight diff=$diff%"
23384
23385         echo
23386         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23387
23388         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23389         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23390         # decrease statfs age, so that it can be updated in time
23391         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23392         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23393
23394         sleep 1
23395
23396         testdir=$DIR/$tdir-s$stripe_count/qos
23397
23398         for i in $(seq $((100 * MDSCOUNT))); do
23399                 eval $mkdir_cmd $testdir/subdir$i ||
23400                         error "$mkdir_cmd subdir$i failed"
23401         done
23402
23403         for i in $(seq $MDSCOUNT); do
23404                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23405                         wc -l)
23406                 echo "$count directories created on MDT$((i - 1))"
23407
23408                 if [ $stripe_count -gt 1 ]; then
23409                         count=$($LFS getdirstripe $testdir/* |
23410                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23411                         echo "$count stripes created on MDT$((i - 1))"
23412                 fi
23413         done
23414
23415         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23416         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23417
23418         # D-value should > 10% of averge
23419         [ $((max - min)) -lt 10 ] &&
23420                 error "subdirs shouldn't be evenly distributed"
23421
23422         # ditto
23423         if [ $stripe_count -gt 1 ]; then
23424                 max=$($LFS getdirstripe $testdir/* |
23425                         grep -P "^\s+$max_index\t" | wc -l)
23426                 min=$($LFS getdirstripe $testdir/* |
23427                         grep -P "^\s+$min_index\t" | wc -l)
23428                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23429                         error "stripes shouldn't be evenly distributed"|| true
23430         fi
23431 }
23432
23433 test_413a() {
23434         [ $MDSCOUNT -lt 2 ] &&
23435                 skip "We need at least 2 MDTs for this test"
23436
23437         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23438                 skip "Need server version at least 2.12.52"
23439
23440         local stripe_count
23441
23442         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23443                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23444                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23445                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23446                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23447         done
23448 }
23449 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23450
23451 test_413b() {
23452         [ $MDSCOUNT -lt 2 ] &&
23453                 skip "We need at least 2 MDTs for this test"
23454
23455         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23456                 skip "Need server version at least 2.12.52"
23457
23458         local stripe_count
23459
23460         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23461                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23462                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23463                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23464                 $LFS setdirstripe -D -c $stripe_count \
23465                         $DIR/$tdir-s$stripe_count/rr ||
23466                         error "setdirstripe failed"
23467                 $LFS setdirstripe -D -c $stripe_count \
23468                         $DIR/$tdir-s$stripe_count/qos ||
23469                         error "setdirstripe failed"
23470                 test_qos_mkdir "mkdir" $stripe_count
23471         done
23472 }
23473 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23474
23475 test_414() {
23476 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23477         $LCTL set_param fail_loc=0x80000521
23478         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23479         rm -f $DIR/$tfile
23480 }
23481 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23482
23483 test_415() {
23484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23485         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23486                 skip "Need server version at least 2.11.52"
23487
23488         # LU-11102
23489         local total
23490         local setattr_pid
23491         local start_time
23492         local end_time
23493         local duration
23494
23495         total=500
23496         # this test may be slow on ZFS
23497         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23498
23499         # though this test is designed for striped directory, let's test normal
23500         # directory too since lock is always saved as CoS lock.
23501         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23502         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23503
23504         (
23505                 while true; do
23506                         touch $DIR/$tdir
23507                 done
23508         ) &
23509         setattr_pid=$!
23510
23511         start_time=$(date +%s)
23512         for i in $(seq $total); do
23513                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23514                         > /dev/null
23515         done
23516         end_time=$(date +%s)
23517         duration=$((end_time - start_time))
23518
23519         kill -9 $setattr_pid
23520
23521         echo "rename $total files took $duration sec"
23522         [ $duration -lt 100 ] || error "rename took $duration sec"
23523 }
23524 run_test 415 "lock revoke is not missing"
23525
23526 test_416() {
23527         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23528                 skip "Need server version at least 2.11.55"
23529
23530         # define OBD_FAIL_OSD_TXN_START    0x19a
23531         do_facet mds1 lctl set_param fail_loc=0x19a
23532
23533         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23534
23535         true
23536 }
23537 run_test 416 "transaction start failure won't cause system hung"
23538
23539 cleanup_417() {
23540         trap 0
23541         do_nodes $(comma_list $(mdts_nodes)) \
23542                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23543         do_nodes $(comma_list $(mdts_nodes)) \
23544                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23545         do_nodes $(comma_list $(mdts_nodes)) \
23546                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23547 }
23548
23549 test_417() {
23550         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23551         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23552                 skip "Need MDS version at least 2.11.56"
23553
23554         trap cleanup_417 RETURN EXIT
23555
23556         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23557         do_nodes $(comma_list $(mdts_nodes)) \
23558                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23559         $LFS migrate -m 0 $DIR/$tdir.1 &&
23560                 error "migrate dir $tdir.1 should fail"
23561
23562         do_nodes $(comma_list $(mdts_nodes)) \
23563                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23564         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23565                 error "create remote dir $tdir.2 should fail"
23566
23567         do_nodes $(comma_list $(mdts_nodes)) \
23568                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23569         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23570                 error "create striped dir $tdir.3 should fail"
23571         true
23572 }
23573 run_test 417 "disable remote dir, striped dir and dir migration"
23574
23575 # Checks that the outputs of df [-i] and lfs df [-i] match
23576 #
23577 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23578 check_lfs_df() {
23579         local dir=$2
23580         local inodes
23581         local df_out
23582         local lfs_df_out
23583         local count
23584         local passed=false
23585
23586         # blocks or inodes
23587         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23588
23589         for count in {1..100}; do
23590                 cancel_lru_locks
23591                 sync; sleep 0.2
23592
23593                 # read the lines of interest
23594                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23595                         error "df $inodes $dir | tail -n +2 failed"
23596                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23597                         error "lfs df $inodes $dir | grep summary: failed"
23598
23599                 # skip first substrings of each output as they are different
23600                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23601                 # compare the two outputs
23602                 passed=true
23603                 for i in {1..5}; do
23604                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23605                 done
23606                 $passed && break
23607         done
23608
23609         if ! $passed; then
23610                 df -P $inodes $dir
23611                 echo
23612                 lfs df $inodes $dir
23613                 error "df and lfs df $1 output mismatch: "      \
23614                       "df ${inodes}: ${df_out[*]}, "            \
23615                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23616         fi
23617 }
23618
23619 test_418() {
23620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23621
23622         local dir=$DIR/$tdir
23623         local numfiles=$((RANDOM % 4096 + 2))
23624         local numblocks=$((RANDOM % 256 + 1))
23625
23626         wait_delete_completed
23627         test_mkdir $dir
23628
23629         # check block output
23630         check_lfs_df blocks $dir
23631         # check inode output
23632         check_lfs_df inodes $dir
23633
23634         # create a single file and retest
23635         echo "Creating a single file and testing"
23636         createmany -o $dir/$tfile- 1 &>/dev/null ||
23637                 error "creating 1 file in $dir failed"
23638         check_lfs_df blocks $dir
23639         check_lfs_df inodes $dir
23640
23641         # create a random number of files
23642         echo "Creating $((numfiles - 1)) files and testing"
23643         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23644                 error "creating $((numfiles - 1)) files in $dir failed"
23645
23646         # write a random number of blocks to the first test file
23647         echo "Writing $numblocks 4K blocks and testing"
23648         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23649                 count=$numblocks &>/dev/null ||
23650                 error "dd to $dir/${tfile}-0 failed"
23651
23652         # retest
23653         check_lfs_df blocks $dir
23654         check_lfs_df inodes $dir
23655
23656         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23657                 error "unlinking $numfiles files in $dir failed"
23658 }
23659 run_test 418 "df and lfs df outputs match"
23660
23661 test_419()
23662 {
23663         local dir=$DIR/$tdir
23664
23665         mkdir -p $dir
23666         touch $dir/file
23667
23668         cancel_lru_locks mdc
23669
23670         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23671         $LCTL set_param fail_loc=0x1410
23672         cat $dir/file
23673         $LCTL set_param fail_loc=0
23674         rm -rf $dir
23675 }
23676 run_test 419 "Verify open file by name doesn't crash kernel"
23677
23678 test_420()
23679 {
23680         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23681                 skip "Need MDS version at least 2.12.53"
23682
23683         local SAVE_UMASK=$(umask)
23684         local dir=$DIR/$tdir
23685         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23686
23687         mkdir -p $dir
23688         umask 0000
23689         mkdir -m03777 $dir/testdir
23690         ls -dn $dir/testdir
23691         # Need to remove trailing '.' when SELinux is enabled
23692         local dirperms=$(ls -dn $dir/testdir |
23693                          awk '{ sub(/\.$/, "", $1); print $1}')
23694         [ $dirperms == "drwxrwsrwt" ] ||
23695                 error "incorrect perms on $dir/testdir"
23696
23697         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23698                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23699         ls -n $dir/testdir/testfile
23700         local fileperms=$(ls -n $dir/testdir/testfile |
23701                           awk '{ sub(/\.$/, "", $1); print $1}')
23702         [ $fileperms == "-rwxr-xr-x" ] ||
23703                 error "incorrect perms on $dir/testdir/testfile"
23704
23705         umask $SAVE_UMASK
23706 }
23707 run_test 420 "clear SGID bit on non-directories for non-members"
23708
23709 test_421a() {
23710         local cnt
23711         local fid1
23712         local fid2
23713
23714         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23715                 skip "Need MDS version at least 2.12.54"
23716
23717         test_mkdir $DIR/$tdir
23718         createmany -o $DIR/$tdir/f 3
23719         cnt=$(ls -1 $DIR/$tdir | wc -l)
23720         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23721
23722         fid1=$(lfs path2fid $DIR/$tdir/f1)
23723         fid2=$(lfs path2fid $DIR/$tdir/f2)
23724         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23725
23726         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23727         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23728
23729         cnt=$(ls -1 $DIR/$tdir | wc -l)
23730         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23731
23732         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23733         createmany -o $DIR/$tdir/f 3
23734         cnt=$(ls -1 $DIR/$tdir | wc -l)
23735         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23736
23737         fid1=$(lfs path2fid $DIR/$tdir/f1)
23738         fid2=$(lfs path2fid $DIR/$tdir/f2)
23739         echo "remove using fsname $FSNAME"
23740         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23741
23742         cnt=$(ls -1 $DIR/$tdir | wc -l)
23743         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23744 }
23745 run_test 421a "simple rm by fid"
23746
23747 test_421b() {
23748         local cnt
23749         local FID1
23750         local FID2
23751
23752         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23753                 skip "Need MDS version at least 2.12.54"
23754
23755         test_mkdir $DIR/$tdir
23756         createmany -o $DIR/$tdir/f 3
23757         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23758         MULTIPID=$!
23759
23760         FID1=$(lfs path2fid $DIR/$tdir/f1)
23761         FID2=$(lfs path2fid $DIR/$tdir/f2)
23762         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23763
23764         kill -USR1 $MULTIPID
23765         wait
23766
23767         cnt=$(ls $DIR/$tdir | wc -l)
23768         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23769 }
23770 run_test 421b "rm by fid on open file"
23771
23772 test_421c() {
23773         local cnt
23774         local FIDS
23775
23776         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23777                 skip "Need MDS version at least 2.12.54"
23778
23779         test_mkdir $DIR/$tdir
23780         createmany -o $DIR/$tdir/f 3
23781         touch $DIR/$tdir/$tfile
23782         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23783         cnt=$(ls -1 $DIR/$tdir | wc -l)
23784         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23785
23786         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23787         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23788
23789         cnt=$(ls $DIR/$tdir | wc -l)
23790         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23791 }
23792 run_test 421c "rm by fid against hardlinked files"
23793
23794 test_421d() {
23795         local cnt
23796         local FIDS
23797
23798         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23799                 skip "Need MDS version at least 2.12.54"
23800
23801         test_mkdir $DIR/$tdir
23802         createmany -o $DIR/$tdir/f 4097
23803         cnt=$(ls -1 $DIR/$tdir | wc -l)
23804         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23805
23806         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23807         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23808
23809         cnt=$(ls $DIR/$tdir | wc -l)
23810         rm -rf $DIR/$tdir
23811         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23812 }
23813 run_test 421d "rmfid en masse"
23814
23815 test_421e() {
23816         local cnt
23817         local FID
23818
23819         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23820         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23821                 skip "Need MDS version at least 2.12.54"
23822
23823         mkdir -p $DIR/$tdir
23824         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23825         createmany -o $DIR/$tdir/striped_dir/f 512
23826         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23827         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23828
23829         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23830                 sed "s/[/][^:]*://g")
23831         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23832
23833         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23834         rm -rf $DIR/$tdir
23835         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23836 }
23837 run_test 421e "rmfid in DNE"
23838
23839 test_421f() {
23840         local cnt
23841         local FID
23842
23843         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23844                 skip "Need MDS version at least 2.12.54"
23845
23846         test_mkdir $DIR/$tdir
23847         touch $DIR/$tdir/f
23848         cnt=$(ls -1 $DIR/$tdir | wc -l)
23849         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23850
23851         FID=$(lfs path2fid $DIR/$tdir/f)
23852         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23853         # rmfid should fail
23854         cnt=$(ls -1 $DIR/$tdir | wc -l)
23855         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23856
23857         chmod a+rw $DIR/$tdir
23858         ls -la $DIR/$tdir
23859         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23860         # rmfid should fail
23861         cnt=$(ls -1 $DIR/$tdir | wc -l)
23862         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23863
23864         rm -f $DIR/$tdir/f
23865         $RUNAS touch $DIR/$tdir/f
23866         FID=$(lfs path2fid $DIR/$tdir/f)
23867         echo "rmfid as root"
23868         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23869         cnt=$(ls -1 $DIR/$tdir | wc -l)
23870         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23871
23872         rm -f $DIR/$tdir/f
23873         $RUNAS touch $DIR/$tdir/f
23874         cnt=$(ls -1 $DIR/$tdir | wc -l)
23875         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23876         FID=$(lfs path2fid $DIR/$tdir/f)
23877         # rmfid w/o user_fid2path mount option should fail
23878         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23879         cnt=$(ls -1 $DIR/$tdir | wc -l)
23880         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23881
23882         umount_client $MOUNT || error "failed to umount client"
23883         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23884                 error "failed to mount client'"
23885
23886         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23887         # rmfid should succeed
23888         cnt=$(ls -1 $DIR/$tdir | wc -l)
23889         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23890
23891         # rmfid shouldn't allow to remove files due to dir's permission
23892         chmod a+rwx $DIR/$tdir
23893         touch $DIR/$tdir/f
23894         ls -la $DIR/$tdir
23895         FID=$(lfs path2fid $DIR/$tdir/f)
23896         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23897
23898         umount_client $MOUNT || error "failed to umount client"
23899         mount_client $MOUNT "$MOUNT_OPTS" ||
23900                 error "failed to mount client'"
23901
23902 }
23903 run_test 421f "rmfid checks permissions"
23904
23905 test_421g() {
23906         local cnt
23907         local FIDS
23908
23909         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23910         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23911                 skip "Need MDS version at least 2.12.54"
23912
23913         mkdir -p $DIR/$tdir
23914         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23915         createmany -o $DIR/$tdir/striped_dir/f 512
23916         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23917         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23918
23919         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23920                 sed "s/[/][^:]*://g")
23921
23922         rm -f $DIR/$tdir/striped_dir/f1*
23923         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23924         removed=$((512 - cnt))
23925
23926         # few files have been just removed, so we expect
23927         # rmfid to fail on their fids
23928         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23929         [ $removed != $errors ] && error "$errors != $removed"
23930
23931         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23932         rm -rf $DIR/$tdir
23933         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23934 }
23935 run_test 421g "rmfid to return errors properly"
23936
23937 test_422() {
23938         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23939         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23940         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23941         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23942         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23943
23944         local amc=$(at_max_get client)
23945         local amo=$(at_max_get mds1)
23946         local timeout=`lctl get_param -n timeout`
23947
23948         at_max_set 0 client
23949         at_max_set 0 mds1
23950
23951 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23952         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23953                         fail_val=$(((2*timeout + 10)*1000))
23954         touch $DIR/$tdir/d3/file &
23955         sleep 2
23956 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23957         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23958                         fail_val=$((2*timeout + 5))
23959         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23960         local pid=$!
23961         sleep 1
23962         kill -9 $pid
23963         sleep $((2 * timeout))
23964         echo kill $pid
23965         kill -9 $pid
23966         lctl mark touch
23967         touch $DIR/$tdir/d2/file3
23968         touch $DIR/$tdir/d2/file4
23969         touch $DIR/$tdir/d2/file5
23970
23971         wait
23972         at_max_set $amc client
23973         at_max_set $amo mds1
23974
23975         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23976         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23977                 error "Watchdog is always throttled"
23978 }
23979 run_test 422 "kill a process with RPC in progress"
23980
23981 stat_test() {
23982     df -h $MOUNT &
23983     df -h $MOUNT &
23984     df -h $MOUNT &
23985     df -h $MOUNT &
23986     df -h $MOUNT &
23987     df -h $MOUNT &
23988 }
23989
23990 test_423() {
23991     local _stats
23992     # ensure statfs cache is expired
23993     sleep 2;
23994
23995     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23996     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23997
23998     return 0
23999 }
24000 run_test 423 "statfs should return a right data"
24001
24002 test_424() {
24003 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24004         $LCTL set_param fail_loc=0x80000522
24005         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24006         rm -f $DIR/$tfile
24007 }
24008 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24009
24010 test_425() {
24011         test_mkdir -c -1 $DIR/$tdir
24012         $LFS setstripe -c -1 $DIR/$tdir
24013
24014         lru_resize_disable "" 100
24015         stack_trap "lru_resize_enable" EXIT
24016
24017         sleep 5
24018
24019         for i in $(seq $((MDSCOUNT * 125))); do
24020                 local t=$DIR/$tdir/$tfile_$i
24021
24022                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24023                         error_noexit "Create file $t"
24024         done
24025         stack_trap "rm -rf $DIR/$tdir" EXIT
24026
24027         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24028                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24029                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24030
24031                 [ $lock_count -le $lru_size ] ||
24032                         error "osc lock count $lock_count > lru size $lru_size"
24033         done
24034
24035         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24036                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24037                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24038
24039                 [ $lock_count -le $lru_size ] ||
24040                         error "mdc lock count $lock_count > lru size $lru_size"
24041         done
24042 }
24043 run_test 425 "lock count should not exceed lru size"
24044
24045 test_426() {
24046         splice-test -r $DIR/$tfile
24047         splice-test -rd $DIR/$tfile
24048         splice-test $DIR/$tfile
24049         splice-test -d $DIR/$tfile
24050 }
24051 run_test 426 "splice test on Lustre"
24052
24053 lseek_test_430() {
24054         local offset
24055         local file=$1
24056
24057         # data at [200K, 400K)
24058         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24059                 error "256K->512K dd fails"
24060         # data at [2M, 3M)
24061         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24062                 error "2M->3M dd fails"
24063         # data at [4M, 5M)
24064         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24065                 error "4M->5M dd fails"
24066         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24067         # start at first component hole #1
24068         printf "Seeking hole from 1000 ... "
24069         offset=$(lseek_test -l 1000 $file)
24070         echo $offset
24071         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24072         printf "Seeking data from 1000 ... "
24073         offset=$(lseek_test -d 1000 $file)
24074         echo $offset
24075         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24076
24077         # start at first component data block
24078         printf "Seeking hole from 300000 ... "
24079         offset=$(lseek_test -l 300000 $file)
24080         echo $offset
24081         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24082         printf "Seeking data from 300000 ... "
24083         offset=$(lseek_test -d 300000 $file)
24084         echo $offset
24085         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24086
24087         # start at the first component but beyond end of object size
24088         printf "Seeking hole from 1000000 ... "
24089         offset=$(lseek_test -l 1000000 $file)
24090         echo $offset
24091         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24092         printf "Seeking data from 1000000 ... "
24093         offset=$(lseek_test -d 1000000 $file)
24094         echo $offset
24095         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24096
24097         # start at second component stripe 2 (empty file)
24098         printf "Seeking hole from 1500000 ... "
24099         offset=$(lseek_test -l 1500000 $file)
24100         echo $offset
24101         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24102         printf "Seeking data from 1500000 ... "
24103         offset=$(lseek_test -d 1500000 $file)
24104         echo $offset
24105         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24106
24107         # start at second component stripe 1 (all data)
24108         printf "Seeking hole from 3000000 ... "
24109         offset=$(lseek_test -l 3000000 $file)
24110         echo $offset
24111         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24112         printf "Seeking data from 3000000 ... "
24113         offset=$(lseek_test -d 3000000 $file)
24114         echo $offset
24115         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24116
24117         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24118                 error "2nd dd fails"
24119         echo "Add data block at 640K...1280K"
24120
24121         # start at before new data block, in hole
24122         printf "Seeking hole from 600000 ... "
24123         offset=$(lseek_test -l 600000 $file)
24124         echo $offset
24125         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24126         printf "Seeking data from 600000 ... "
24127         offset=$(lseek_test -d 600000 $file)
24128         echo $offset
24129         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24130
24131         # start at the first component new data block
24132         printf "Seeking hole from 1000000 ... "
24133         offset=$(lseek_test -l 1000000 $file)
24134         echo $offset
24135         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24136         printf "Seeking data from 1000000 ... "
24137         offset=$(lseek_test -d 1000000 $file)
24138         echo $offset
24139         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24140
24141         # start at second component stripe 2, new data
24142         printf "Seeking hole from 1200000 ... "
24143         offset=$(lseek_test -l 1200000 $file)
24144         echo $offset
24145         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24146         printf "Seeking data from 1200000 ... "
24147         offset=$(lseek_test -d 1200000 $file)
24148         echo $offset
24149         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24150
24151         # start beyond file end
24152         printf "Using offset > filesize ... "
24153         lseek_test -l 4000000 $file && error "lseek should fail"
24154         printf "Using offset > filesize ... "
24155         lseek_test -d 4000000 $file && error "lseek should fail"
24156
24157         printf "Done\n\n"
24158 }
24159
24160 test_430a() {
24161         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24162                 skip "MDT does not support SEEK_HOLE"
24163
24164         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24165                 skip "OST does not support SEEK_HOLE"
24166
24167         local file=$DIR/$tdir/$tfile
24168
24169         mkdir -p $DIR/$tdir
24170
24171         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24172         # OST stripe #1 will have continuous data at [1M, 3M)
24173         # OST stripe #2 is empty
24174         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24175         lseek_test_430 $file
24176         rm $file
24177         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24178         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24179         lseek_test_430 $file
24180         rm $file
24181         $LFS setstripe -c2 -S 512K $file
24182         echo "Two stripes, stripe size 512K"
24183         lseek_test_430 $file
24184         rm $file
24185         # FLR with stale mirror
24186         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24187                        -N -c2 -S 1M $file
24188         echo "Mirrored file:"
24189         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24190         echo "Plain 2 stripes 1M"
24191         lseek_test_430 $file
24192         rm $file
24193 }
24194 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24195
24196 test_430b() {
24197         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24198                 skip "OST does not support SEEK_HOLE"
24199
24200         local offset
24201         local file=$DIR/$tdir/$tfile
24202
24203         mkdir -p $DIR/$tdir
24204         # Empty layout lseek should fail
24205         $MCREATE $file
24206         # seek from 0
24207         printf "Seeking hole from 0 ... "
24208         lseek_test -l 0 $file && error "lseek should fail"
24209         printf "Seeking data from 0 ... "
24210         lseek_test -d 0 $file && error "lseek should fail"
24211         rm $file
24212
24213         # 1M-hole file
24214         $LFS setstripe -E 1M -c2 -E eof $file
24215         $TRUNCATE $file 1048576
24216         printf "Seeking hole from 1000000 ... "
24217         offset=$(lseek_test -l 1000000 $file)
24218         echo $offset
24219         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24220         printf "Seeking data from 1000000 ... "
24221         lseek_test -d 1000000 $file && error "lseek should fail"
24222         rm $file
24223
24224         # full component followed by non-inited one
24225         $LFS setstripe -E 1M -c2 -E eof $file
24226         dd if=/dev/urandom of=$file bs=1M count=1
24227         printf "Seeking hole from 1000000 ... "
24228         offset=$(lseek_test -l 1000000 $file)
24229         echo $offset
24230         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24231         printf "Seeking hole from 1048576 ... "
24232         lseek_test -l 1048576 $file && error "lseek should fail"
24233         # init second component and truncate back
24234         echo "123" >> $file
24235         $TRUNCATE $file 1048576
24236         printf "Seeking hole from 1000000 ... "
24237         offset=$(lseek_test -l 1000000 $file)
24238         echo $offset
24239         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24240         printf "Seeking hole from 1048576 ... "
24241         lseek_test -l 1048576 $file && error "lseek should fail"
24242         # boundary checks for big values
24243         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24244         offset=$(lseek_test -d 0 $file.10g)
24245         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24246         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24247         offset=$(lseek_test -d 0 $file.100g)
24248         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24249         return 0
24250 }
24251 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24252
24253 test_430c() {
24254         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24255                 skip "OST does not support SEEK_HOLE"
24256
24257         local file=$DIR/$tdir/$tfile
24258         local start
24259
24260         mkdir -p $DIR/$tdir
24261         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24262
24263         # cp version 8.33+ prefers lseek over fiemap
24264         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24265                 start=$SECONDS
24266                 time cp $file /dev/null
24267                 (( SECONDS - start < 5 )) ||
24268                         error "cp: too long runtime $((SECONDS - start))"
24269
24270         fi
24271         # tar version 1.29+ supports SEEK_HOLE/DATA
24272         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24273                 start=$SECONDS
24274                 time tar cS $file - | cat > /dev/null
24275                 (( SECONDS - start < 5 )) ||
24276                         error "tar: too long runtime $((SECONDS - start))"
24277         fi
24278 }
24279 run_test 430c "lseek: external tools check"
24280
24281 test_431() { # LU-14187
24282         local file=$DIR/$tdir/$tfile
24283
24284         mkdir -p $DIR/$tdir
24285         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24286         dd if=/dev/urandom of=$file bs=4k count=1
24287         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24288         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24289         #define OBD_FAIL_OST_RESTART_IO 0x251
24290         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24291         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24292         cp $file $file.0
24293         cancel_lru_locks
24294         sync_all_data
24295         echo 3 > /proc/sys/vm/drop_caches
24296         diff  $file $file.0 || error "data diff"
24297 }
24298 run_test 431 "Restart transaction for IO"
24299
24300 prep_801() {
24301         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24302         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24303                 skip "Need server version at least 2.9.55"
24304
24305         start_full_debug_logging
24306 }
24307
24308 post_801() {
24309         stop_full_debug_logging
24310 }
24311
24312 barrier_stat() {
24313         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24314                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24315                            awk '/The barrier for/ { print $7 }')
24316                 echo $st
24317         else
24318                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24319                 echo \'$st\'
24320         fi
24321 }
24322
24323 barrier_expired() {
24324         local expired
24325
24326         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24327                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24328                           awk '/will be expired/ { print $7 }')
24329         else
24330                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24331         fi
24332
24333         echo $expired
24334 }
24335
24336 test_801a() {
24337         prep_801
24338
24339         echo "Start barrier_freeze at: $(date)"
24340         #define OBD_FAIL_BARRIER_DELAY          0x2202
24341         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24342         # Do not reduce barrier time - See LU-11873
24343         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24344
24345         sleep 2
24346         local b_status=$(barrier_stat)
24347         echo "Got barrier status at: $(date)"
24348         [ "$b_status" = "'freezing_p1'" ] ||
24349                 error "(1) unexpected barrier status $b_status"
24350
24351         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24352         wait
24353         b_status=$(barrier_stat)
24354         [ "$b_status" = "'frozen'" ] ||
24355                 error "(2) unexpected barrier status $b_status"
24356
24357         local expired=$(barrier_expired)
24358         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24359         sleep $((expired + 3))
24360
24361         b_status=$(barrier_stat)
24362         [ "$b_status" = "'expired'" ] ||
24363                 error "(3) unexpected barrier status $b_status"
24364
24365         # Do not reduce barrier time - See LU-11873
24366         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24367                 error "(4) fail to freeze barrier"
24368
24369         b_status=$(barrier_stat)
24370         [ "$b_status" = "'frozen'" ] ||
24371                 error "(5) unexpected barrier status $b_status"
24372
24373         echo "Start barrier_thaw at: $(date)"
24374         #define OBD_FAIL_BARRIER_DELAY          0x2202
24375         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24376         do_facet mgs $LCTL barrier_thaw $FSNAME &
24377
24378         sleep 2
24379         b_status=$(barrier_stat)
24380         echo "Got barrier status at: $(date)"
24381         [ "$b_status" = "'thawing'" ] ||
24382                 error "(6) unexpected barrier status $b_status"
24383
24384         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24385         wait
24386         b_status=$(barrier_stat)
24387         [ "$b_status" = "'thawed'" ] ||
24388                 error "(7) unexpected barrier status $b_status"
24389
24390         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24391         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24392         do_facet mgs $LCTL barrier_freeze $FSNAME
24393
24394         b_status=$(barrier_stat)
24395         [ "$b_status" = "'failed'" ] ||
24396                 error "(8) unexpected barrier status $b_status"
24397
24398         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24399         do_facet mgs $LCTL barrier_thaw $FSNAME
24400
24401         post_801
24402 }
24403 run_test 801a "write barrier user interfaces and stat machine"
24404
24405 test_801b() {
24406         prep_801
24407
24408         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24409         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24410         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24411         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24412         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24413
24414         cancel_lru_locks mdc
24415
24416         # 180 seconds should be long enough
24417         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24418
24419         local b_status=$(barrier_stat)
24420         [ "$b_status" = "'frozen'" ] ||
24421                 error "(6) unexpected barrier status $b_status"
24422
24423         mkdir $DIR/$tdir/d0/d10 &
24424         mkdir_pid=$!
24425
24426         touch $DIR/$tdir/d1/f13 &
24427         touch_pid=$!
24428
24429         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24430         ln_pid=$!
24431
24432         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24433         mv_pid=$!
24434
24435         rm -f $DIR/$tdir/d4/f12 &
24436         rm_pid=$!
24437
24438         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24439
24440         # To guarantee taht the 'stat' is not blocked
24441         b_status=$(barrier_stat)
24442         [ "$b_status" = "'frozen'" ] ||
24443                 error "(8) unexpected barrier status $b_status"
24444
24445         # let above commands to run at background
24446         sleep 5
24447
24448         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24449         ps -p $touch_pid || error "(10) touch should be blocked"
24450         ps -p $ln_pid || error "(11) link should be blocked"
24451         ps -p $mv_pid || error "(12) rename should be blocked"
24452         ps -p $rm_pid || error "(13) unlink should be blocked"
24453
24454         b_status=$(barrier_stat)
24455         [ "$b_status" = "'frozen'" ] ||
24456                 error "(14) unexpected barrier status $b_status"
24457
24458         do_facet mgs $LCTL barrier_thaw $FSNAME
24459         b_status=$(barrier_stat)
24460         [ "$b_status" = "'thawed'" ] ||
24461                 error "(15) unexpected barrier status $b_status"
24462
24463         wait $mkdir_pid || error "(16) mkdir should succeed"
24464         wait $touch_pid || error "(17) touch should succeed"
24465         wait $ln_pid || error "(18) link should succeed"
24466         wait $mv_pid || error "(19) rename should succeed"
24467         wait $rm_pid || error "(20) unlink should succeed"
24468
24469         post_801
24470 }
24471 run_test 801b "modification will be blocked by write barrier"
24472
24473 test_801c() {
24474         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24475
24476         prep_801
24477
24478         stop mds2 || error "(1) Fail to stop mds2"
24479
24480         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24481
24482         local b_status=$(barrier_stat)
24483         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24484                 do_facet mgs $LCTL barrier_thaw $FSNAME
24485                 error "(2) unexpected barrier status $b_status"
24486         }
24487
24488         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24489                 error "(3) Fail to rescan barrier bitmap"
24490
24491         # Do not reduce barrier time - See LU-11873
24492         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24493
24494         b_status=$(barrier_stat)
24495         [ "$b_status" = "'frozen'" ] ||
24496                 error "(4) unexpected barrier status $b_status"
24497
24498         do_facet mgs $LCTL barrier_thaw $FSNAME
24499         b_status=$(barrier_stat)
24500         [ "$b_status" = "'thawed'" ] ||
24501                 error "(5) unexpected barrier status $b_status"
24502
24503         local devname=$(mdsdevname 2)
24504
24505         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24506
24507         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24508                 error "(7) Fail to rescan barrier bitmap"
24509
24510         post_801
24511 }
24512 run_test 801c "rescan barrier bitmap"
24513
24514 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24515 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24516 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24517 saved_MOUNT_OPTS=$MOUNT_OPTS
24518
24519 cleanup_802a() {
24520         trap 0
24521
24522         stopall
24523         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24524         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24525         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24526         MOUNT_OPTS=$saved_MOUNT_OPTS
24527         setupall
24528 }
24529
24530 test_802a() {
24531         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24532         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24533         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24534                 skip "Need server version at least 2.9.55"
24535
24536         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24537
24538         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24539
24540         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24541                 error "(2) Fail to copy"
24542
24543         trap cleanup_802a EXIT
24544
24545         # sync by force before remount as readonly
24546         sync; sync_all_data; sleep 3; sync_all_data
24547
24548         stopall
24549
24550         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24551         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24552         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24553
24554         echo "Mount the server as read only"
24555         setupall server_only || error "(3) Fail to start servers"
24556
24557         echo "Mount client without ro should fail"
24558         mount_client $MOUNT &&
24559                 error "(4) Mount client without 'ro' should fail"
24560
24561         echo "Mount client with ro should succeed"
24562         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24563         mount_client $MOUNT ||
24564                 error "(5) Mount client with 'ro' should succeed"
24565
24566         echo "Modify should be refused"
24567         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24568
24569         echo "Read should be allowed"
24570         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24571                 error "(7) Read should succeed under ro mode"
24572
24573         cleanup_802a
24574 }
24575 run_test 802a "simulate readonly device"
24576
24577 test_802b() {
24578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24579         remote_mds_nodsh && skip "remote MDS with nodsh"
24580
24581         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24582                 skip "readonly option not available"
24583
24584         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24585
24586         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24587                 error "(2) Fail to copy"
24588
24589         # write back all cached data before setting MDT to readonly
24590         cancel_lru_locks
24591         sync_all_data
24592
24593         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24594         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24595
24596         echo "Modify should be refused"
24597         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24598
24599         echo "Read should be allowed"
24600         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24601                 error "(7) Read should succeed under ro mode"
24602
24603         # disable readonly
24604         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24605 }
24606 run_test 802b "be able to set MDTs to readonly"
24607
24608 test_803a() {
24609         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24610         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24611                 skip "MDS needs to be newer than 2.10.54"
24612
24613         mkdir -p $DIR/$tdir
24614         # Create some objects on all MDTs to trigger related logs objects
24615         for idx in $(seq $MDSCOUNT); do
24616                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24617                         $DIR/$tdir/dir${idx} ||
24618                         error "Fail to create $DIR/$tdir/dir${idx}"
24619         done
24620
24621         sync; sleep 3
24622         wait_delete_completed # ensure old test cleanups are finished
24623         echo "before create:"
24624         $LFS df -i $MOUNT
24625         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24626
24627         for i in {1..10}; do
24628                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24629                         error "Fail to create $DIR/$tdir/foo$i"
24630         done
24631
24632         sync; sleep 3
24633         echo "after create:"
24634         $LFS df -i $MOUNT
24635         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24636
24637         # allow for an llog to be cleaned up during the test
24638         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24639                 error "before ($before_used) + 10 > after ($after_used)"
24640
24641         for i in {1..10}; do
24642                 rm -rf $DIR/$tdir/foo$i ||
24643                         error "Fail to remove $DIR/$tdir/foo$i"
24644         done
24645
24646         sleep 3 # avoid MDT return cached statfs
24647         wait_delete_completed
24648         echo "after unlink:"
24649         $LFS df -i $MOUNT
24650         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24651
24652         # allow for an llog to be created during the test
24653         [ $after_used -le $((before_used + 1)) ] ||
24654                 error "after ($after_used) > before ($before_used) + 1"
24655 }
24656 run_test 803a "verify agent object for remote object"
24657
24658 test_803b() {
24659         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24660         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24661                 skip "MDS needs to be newer than 2.13.56"
24662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24663
24664         for i in $(seq 0 $((MDSCOUNT - 1))); do
24665                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24666         done
24667
24668         local before=0
24669         local after=0
24670
24671         local tmp
24672
24673         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24674         for i in $(seq 0 $((MDSCOUNT - 1))); do
24675                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24676                         awk '/getattr/ { print $2 }')
24677                 before=$((before + tmp))
24678         done
24679         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24680         for i in $(seq 0 $((MDSCOUNT - 1))); do
24681                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24682                         awk '/getattr/ { print $2 }')
24683                 after=$((after + tmp))
24684         done
24685
24686         [ $before -eq $after ] || error "getattr count $before != $after"
24687 }
24688 run_test 803b "remote object can getattr from cache"
24689
24690 test_804() {
24691         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24692         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24693                 skip "MDS needs to be newer than 2.10.54"
24694         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24695
24696         mkdir -p $DIR/$tdir
24697         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24698                 error "Fail to create $DIR/$tdir/dir0"
24699
24700         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24701         local dev=$(mdsdevname 2)
24702
24703         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24704                 grep ${fid} || error "NOT found agent entry for dir0"
24705
24706         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24707                 error "Fail to create $DIR/$tdir/dir1"
24708
24709         touch $DIR/$tdir/dir1/foo0 ||
24710                 error "Fail to create $DIR/$tdir/dir1/foo0"
24711         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24712         local rc=0
24713
24714         for idx in $(seq $MDSCOUNT); do
24715                 dev=$(mdsdevname $idx)
24716                 do_facet mds${idx} \
24717                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24718                         grep ${fid} && rc=$idx
24719         done
24720
24721         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24722                 error "Fail to rename foo0 to foo1"
24723         if [ $rc -eq 0 ]; then
24724                 for idx in $(seq $MDSCOUNT); do
24725                         dev=$(mdsdevname $idx)
24726                         do_facet mds${idx} \
24727                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24728                         grep ${fid} && rc=$idx
24729                 done
24730         fi
24731
24732         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24733                 error "Fail to rename foo1 to foo2"
24734         if [ $rc -eq 0 ]; then
24735                 for idx in $(seq $MDSCOUNT); do
24736                         dev=$(mdsdevname $idx)
24737                         do_facet mds${idx} \
24738                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24739                         grep ${fid} && rc=$idx
24740                 done
24741         fi
24742
24743         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24744
24745         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24746                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24747         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24748                 error "Fail to rename foo2 to foo0"
24749         unlink $DIR/$tdir/dir1/foo0 ||
24750                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24751         rm -rf $DIR/$tdir/dir0 ||
24752                 error "Fail to rm $DIR/$tdir/dir0"
24753
24754         for idx in $(seq $MDSCOUNT); do
24755                 dev=$(mdsdevname $idx)
24756                 rc=0
24757
24758                 stop mds${idx}
24759                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24760                         rc=$?
24761                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24762                         error "mount mds$idx failed"
24763                 df $MOUNT > /dev/null 2>&1
24764
24765                 # e2fsck should not return error
24766                 [ $rc -eq 0 ] ||
24767                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24768         done
24769 }
24770 run_test 804 "verify agent entry for remote entry"
24771
24772 cleanup_805() {
24773         do_facet $SINGLEMDS zfs set quota=$old $fsset
24774         unlinkmany $DIR/$tdir/f- 1000000
24775         trap 0
24776 }
24777
24778 test_805() {
24779         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24780         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24781         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24782                 skip "netfree not implemented before 0.7"
24783         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24784                 skip "Need MDS version at least 2.10.57"
24785
24786         local fsset
24787         local freekb
24788         local usedkb
24789         local old
24790         local quota
24791         local pref="osd-zfs.$FSNAME-MDT0000."
24792
24793         # limit available space on MDS dataset to meet nospace issue
24794         # quickly. then ZFS 0.7.2 can use reserved space if asked
24795         # properly (using netfree flag in osd_declare_destroy()
24796         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24797         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24798                 gawk '{print $3}')
24799         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24800         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24801         let "usedkb=usedkb-freekb"
24802         let "freekb=freekb/2"
24803         if let "freekb > 5000"; then
24804                 let "freekb=5000"
24805         fi
24806         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24807         trap cleanup_805 EXIT
24808         mkdir $DIR/$tdir
24809         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24810                 error "Can't set PFL layout"
24811         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24812         rm -rf $DIR/$tdir || error "not able to remove"
24813         do_facet $SINGLEMDS zfs set quota=$old $fsset
24814         trap 0
24815 }
24816 run_test 805 "ZFS can remove from full fs"
24817
24818 # Size-on-MDS test
24819 check_lsom_data()
24820 {
24821         local file=$1
24822         local size=$($LFS getsom -s $file)
24823         local expect=$(stat -c %s $file)
24824
24825         [[ $size == $expect ]] ||
24826                 error "$file expected size: $expect, got: $size"
24827
24828         local blocks=$($LFS getsom -b $file)
24829         expect=$(stat -c %b $file)
24830         [[ $blocks == $expect ]] ||
24831                 error "$file expected blocks: $expect, got: $blocks"
24832 }
24833
24834 check_lsom_size()
24835 {
24836         local size=$($LFS getsom -s $1)
24837         local expect=$2
24838
24839         [[ $size == $expect ]] ||
24840                 error "$file expected size: $expect, got: $size"
24841 }
24842
24843 test_806() {
24844         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24845                 skip "Need MDS version at least 2.11.52"
24846
24847         local bs=1048576
24848
24849         touch $DIR/$tfile || error "touch $tfile failed"
24850
24851         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24852         save_lustre_params client "llite.*.xattr_cache" > $save
24853         lctl set_param llite.*.xattr_cache=0
24854         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24855
24856         # single-threaded write
24857         echo "Test SOM for single-threaded write"
24858         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24859                 error "write $tfile failed"
24860         check_lsom_size $DIR/$tfile $bs
24861
24862         local num=32
24863         local size=$(($num * $bs))
24864         local offset=0
24865         local i
24866
24867         echo "Test SOM for single client multi-threaded($num) write"
24868         $TRUNCATE $DIR/$tfile 0
24869         for ((i = 0; i < $num; i++)); do
24870                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24871                 local pids[$i]=$!
24872                 offset=$((offset + $bs))
24873         done
24874         for (( i=0; i < $num; i++ )); do
24875                 wait ${pids[$i]}
24876         done
24877         check_lsom_size $DIR/$tfile $size
24878
24879         $TRUNCATE $DIR/$tfile 0
24880         for ((i = 0; i < $num; i++)); do
24881                 offset=$((offset - $bs))
24882                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24883                 local pids[$i]=$!
24884         done
24885         for (( i=0; i < $num; i++ )); do
24886                 wait ${pids[$i]}
24887         done
24888         check_lsom_size $DIR/$tfile $size
24889
24890         # multi-client writes
24891         num=$(get_node_count ${CLIENTS//,/ })
24892         size=$(($num * $bs))
24893         offset=0
24894         i=0
24895
24896         echo "Test SOM for multi-client ($num) writes"
24897         $TRUNCATE $DIR/$tfile 0
24898         for client in ${CLIENTS//,/ }; do
24899                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24900                 local pids[$i]=$!
24901                 i=$((i + 1))
24902                 offset=$((offset + $bs))
24903         done
24904         for (( i=0; i < $num; i++ )); do
24905                 wait ${pids[$i]}
24906         done
24907         check_lsom_size $DIR/$tfile $offset
24908
24909         i=0
24910         $TRUNCATE $DIR/$tfile 0
24911         for client in ${CLIENTS//,/ }; do
24912                 offset=$((offset - $bs))
24913                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24914                 local pids[$i]=$!
24915                 i=$((i + 1))
24916         done
24917         for (( i=0; i < $num; i++ )); do
24918                 wait ${pids[$i]}
24919         done
24920         check_lsom_size $DIR/$tfile $size
24921
24922         # verify truncate
24923         echo "Test SOM for truncate"
24924         $TRUNCATE $DIR/$tfile 1048576
24925         check_lsom_size $DIR/$tfile 1048576
24926         $TRUNCATE $DIR/$tfile 1234
24927         check_lsom_size $DIR/$tfile 1234
24928
24929         # verify SOM blocks count
24930         echo "Verify SOM block count"
24931         $TRUNCATE $DIR/$tfile 0
24932         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24933                 error "failed to write file $tfile"
24934         check_lsom_data $DIR/$tfile
24935 }
24936 run_test 806 "Verify Lazy Size on MDS"
24937
24938 test_807() {
24939         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24940         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24941                 skip "Need MDS version at least 2.11.52"
24942
24943         # Registration step
24944         changelog_register || error "changelog_register failed"
24945         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24946         changelog_users $SINGLEMDS | grep -q $cl_user ||
24947                 error "User $cl_user not found in changelog_users"
24948
24949         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24950         save_lustre_params client "llite.*.xattr_cache" > $save
24951         lctl set_param llite.*.xattr_cache=0
24952         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24953
24954         rm -rf $DIR/$tdir || error "rm $tdir failed"
24955         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24956         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24957         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24958         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24959                 error "truncate $tdir/trunc failed"
24960
24961         local bs=1048576
24962         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24963                 error "write $tfile failed"
24964
24965         # multi-client wirtes
24966         local num=$(get_node_count ${CLIENTS//,/ })
24967         local offset=0
24968         local i=0
24969
24970         echo "Test SOM for multi-client ($num) writes"
24971         touch $DIR/$tfile || error "touch $tfile failed"
24972         $TRUNCATE $DIR/$tfile 0
24973         for client in ${CLIENTS//,/ }; do
24974                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24975                 local pids[$i]=$!
24976                 i=$((i + 1))
24977                 offset=$((offset + $bs))
24978         done
24979         for (( i=0; i < $num; i++ )); do
24980                 wait ${pids[$i]}
24981         done
24982
24983         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24984         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24985         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24986         check_lsom_data $DIR/$tdir/trunc
24987         check_lsom_data $DIR/$tdir/single_dd
24988         check_lsom_data $DIR/$tfile
24989
24990         rm -rf $DIR/$tdir
24991         # Deregistration step
24992         changelog_deregister || error "changelog_deregister failed"
24993 }
24994 run_test 807 "verify LSOM syncing tool"
24995
24996 check_som_nologged()
24997 {
24998         local lines=$($LFS changelog $FSNAME-MDT0000 |
24999                 grep 'x=trusted.som' | wc -l)
25000         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25001 }
25002
25003 test_808() {
25004         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25005                 skip "Need MDS version at least 2.11.55"
25006
25007         # Registration step
25008         changelog_register || error "changelog_register failed"
25009
25010         touch $DIR/$tfile || error "touch $tfile failed"
25011         check_som_nologged
25012
25013         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25014                 error "write $tfile failed"
25015         check_som_nologged
25016
25017         $TRUNCATE $DIR/$tfile 1234
25018         check_som_nologged
25019
25020         $TRUNCATE $DIR/$tfile 1048576
25021         check_som_nologged
25022
25023         # Deregistration step
25024         changelog_deregister || error "changelog_deregister failed"
25025 }
25026 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25027
25028 check_som_nodata()
25029 {
25030         $LFS getsom $1
25031         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25032 }
25033
25034 test_809() {
25035         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25036                 skip "Need MDS version at least 2.11.56"
25037
25038         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25039                 error "failed to create DoM-only file $DIR/$tfile"
25040         touch $DIR/$tfile || error "touch $tfile failed"
25041         check_som_nodata $DIR/$tfile
25042
25043         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25044                 error "write $tfile failed"
25045         check_som_nodata $DIR/$tfile
25046
25047         $TRUNCATE $DIR/$tfile 1234
25048         check_som_nodata $DIR/$tfile
25049
25050         $TRUNCATE $DIR/$tfile 4097
25051         check_som_nodata $DIR/$file
25052 }
25053 run_test 809 "Verify no SOM xattr store for DoM-only files"
25054
25055 test_810() {
25056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25057         $GSS && skip_env "could not run with gss"
25058         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25059                 skip "OST < 2.12.58 doesn't align checksum"
25060
25061         set_checksums 1
25062         stack_trap "set_checksums $ORIG_CSUM" EXIT
25063         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25064
25065         local csum
25066         local before
25067         local after
25068         for csum in $CKSUM_TYPES; do
25069                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25070                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25071                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25072                         eval set -- $i
25073                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25074                         before=$(md5sum $DIR/$tfile)
25075                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25076                         after=$(md5sum $DIR/$tfile)
25077                         [ "$before" == "$after" ] ||
25078                                 error "$csum: $before != $after bs=$1 seek=$2"
25079                 done
25080         done
25081 }
25082 run_test 810 "partial page writes on ZFS (LU-11663)"
25083
25084 test_812a() {
25085         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25086                 skip "OST < 2.12.51 doesn't support this fail_loc"
25087
25088         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25089         # ensure ost1 is connected
25090         stat $DIR/$tfile >/dev/null || error "can't stat"
25091         wait_osc_import_state client ost1 FULL
25092         # no locks, no reqs to let the connection idle
25093         cancel_lru_locks osc
25094
25095         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25096 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25097         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25098         wait_osc_import_state client ost1 CONNECTING
25099         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25100
25101         stat $DIR/$tfile >/dev/null || error "can't stat file"
25102 }
25103 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25104
25105 test_812b() { # LU-12378
25106         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25107                 skip "OST < 2.12.51 doesn't support this fail_loc"
25108
25109         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25110         # ensure ost1 is connected
25111         stat $DIR/$tfile >/dev/null || error "can't stat"
25112         wait_osc_import_state client ost1 FULL
25113         # no locks, no reqs to let the connection idle
25114         cancel_lru_locks osc
25115
25116         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25117 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25118         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25119         wait_osc_import_state client ost1 CONNECTING
25120         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25121
25122         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25123         wait_osc_import_state client ost1 IDLE
25124 }
25125 run_test 812b "do not drop no resend request for idle connect"
25126
25127 test_813() {
25128         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25129         [ -z "$file_heat_sav" ] && skip "no file heat support"
25130
25131         local readsample
25132         local writesample
25133         local readbyte
25134         local writebyte
25135         local readsample1
25136         local writesample1
25137         local readbyte1
25138         local writebyte1
25139
25140         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25141         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25142
25143         $LCTL set_param -n llite.*.file_heat=1
25144         echo "Turn on file heat"
25145         echo "Period second: $period_second, Decay percentage: $decay_pct"
25146
25147         echo "QQQQ" > $DIR/$tfile
25148         echo "QQQQ" > $DIR/$tfile
25149         echo "QQQQ" > $DIR/$tfile
25150         cat $DIR/$tfile > /dev/null
25151         cat $DIR/$tfile > /dev/null
25152         cat $DIR/$tfile > /dev/null
25153         cat $DIR/$tfile > /dev/null
25154
25155         local out=$($LFS heat_get $DIR/$tfile)
25156
25157         $LFS heat_get $DIR/$tfile
25158         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25159         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25160         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25161         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25162
25163         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25164         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25165         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25166         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25167
25168         sleep $((period_second + 3))
25169         echo "Sleep $((period_second + 3)) seconds..."
25170         # The recursion formula to calculate the heat of the file f is as
25171         # follow:
25172         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25173         # Where Hi is the heat value in the period between time points i*I and
25174         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25175         # to the weight of Ci.
25176         out=$($LFS heat_get $DIR/$tfile)
25177         $LFS heat_get $DIR/$tfile
25178         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25179         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25180         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25181         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25182
25183         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25184                 error "read sample ($readsample) is wrong"
25185         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25186                 error "write sample ($writesample) is wrong"
25187         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25188                 error "read bytes ($readbyte) is wrong"
25189         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25190                 error "write bytes ($writebyte) is wrong"
25191
25192         echo "QQQQ" > $DIR/$tfile
25193         echo "QQQQ" > $DIR/$tfile
25194         echo "QQQQ" > $DIR/$tfile
25195         cat $DIR/$tfile > /dev/null
25196         cat $DIR/$tfile > /dev/null
25197         cat $DIR/$tfile > /dev/null
25198         cat $DIR/$tfile > /dev/null
25199
25200         sleep $((period_second + 3))
25201         echo "Sleep $((period_second + 3)) seconds..."
25202
25203         out=$($LFS heat_get $DIR/$tfile)
25204         $LFS heat_get $DIR/$tfile
25205         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25206         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25207         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25208         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25209
25210         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25211                 4 * $decay_pct) / 100") -eq 1 ] ||
25212                 error "read sample ($readsample1) is wrong"
25213         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25214                 3 * $decay_pct) / 100") -eq 1 ] ||
25215                 error "write sample ($writesample1) is wrong"
25216         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25217                 20 * $decay_pct) / 100") -eq 1 ] ||
25218                 error "read bytes ($readbyte1) is wrong"
25219         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25220                 15 * $decay_pct) / 100") -eq 1 ] ||
25221                 error "write bytes ($writebyte1) is wrong"
25222
25223         echo "Turn off file heat for the file $DIR/$tfile"
25224         $LFS heat_set -o $DIR/$tfile
25225
25226         echo "QQQQ" > $DIR/$tfile
25227         echo "QQQQ" > $DIR/$tfile
25228         echo "QQQQ" > $DIR/$tfile
25229         cat $DIR/$tfile > /dev/null
25230         cat $DIR/$tfile > /dev/null
25231         cat $DIR/$tfile > /dev/null
25232         cat $DIR/$tfile > /dev/null
25233
25234         out=$($LFS heat_get $DIR/$tfile)
25235         $LFS heat_get $DIR/$tfile
25236         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25237         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25238         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25239         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25240
25241         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25242         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25243         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25244         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25245
25246         echo "Trun on file heat for the file $DIR/$tfile"
25247         $LFS heat_set -O $DIR/$tfile
25248
25249         echo "QQQQ" > $DIR/$tfile
25250         echo "QQQQ" > $DIR/$tfile
25251         echo "QQQQ" > $DIR/$tfile
25252         cat $DIR/$tfile > /dev/null
25253         cat $DIR/$tfile > /dev/null
25254         cat $DIR/$tfile > /dev/null
25255         cat $DIR/$tfile > /dev/null
25256
25257         out=$($LFS heat_get $DIR/$tfile)
25258         $LFS heat_get $DIR/$tfile
25259         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25260         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25261         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25262         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25263
25264         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25265         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25266         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25267         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25268
25269         $LFS heat_set -c $DIR/$tfile
25270         $LCTL set_param -n llite.*.file_heat=0
25271         echo "Turn off file heat support for the Lustre filesystem"
25272
25273         echo "QQQQ" > $DIR/$tfile
25274         echo "QQQQ" > $DIR/$tfile
25275         echo "QQQQ" > $DIR/$tfile
25276         cat $DIR/$tfile > /dev/null
25277         cat $DIR/$tfile > /dev/null
25278         cat $DIR/$tfile > /dev/null
25279         cat $DIR/$tfile > /dev/null
25280
25281         out=$($LFS heat_get $DIR/$tfile)
25282         $LFS heat_get $DIR/$tfile
25283         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25284         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25285         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25286         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25287
25288         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25289         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25290         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25291         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25292
25293         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25294         rm -f $DIR/$tfile
25295 }
25296 run_test 813 "File heat verfication"
25297
25298 test_814()
25299 {
25300         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25301         echo -n y >> $DIR/$tfile
25302         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25303         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25304 }
25305 run_test 814 "sparse cp works as expected (LU-12361)"
25306
25307 test_815()
25308 {
25309         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25310         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25311 }
25312 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25313
25314 test_816() {
25315         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25316         # ensure ost1 is connected
25317         stat $DIR/$tfile >/dev/null || error "can't stat"
25318         wait_osc_import_state client ost1 FULL
25319         # no locks, no reqs to let the connection idle
25320         cancel_lru_locks osc
25321         lru_resize_disable osc
25322         local before
25323         local now
25324         before=$($LCTL get_param -n \
25325                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25326
25327         wait_osc_import_state client ost1 IDLE
25328         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25329         now=$($LCTL get_param -n \
25330               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25331         [ $before == $now ] || error "lru_size changed $before != $now"
25332 }
25333 run_test 816 "do not reset lru_resize on idle reconnect"
25334
25335 cleanup_817() {
25336         umount $tmpdir
25337         exportfs -u localhost:$DIR/nfsexp
25338         rm -rf $DIR/nfsexp
25339 }
25340
25341 test_817() {
25342         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25343
25344         mkdir -p $DIR/nfsexp
25345         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25346                 error "failed to export nfs"
25347
25348         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25349         stack_trap cleanup_817 EXIT
25350
25351         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25352                 error "failed to mount nfs to $tmpdir"
25353
25354         cp /bin/true $tmpdir
25355         $DIR/nfsexp/true || error "failed to execute 'true' command"
25356 }
25357 run_test 817 "nfsd won't cache write lock for exec file"
25358
25359 test_818() {
25360         mkdir $DIR/$tdir
25361         $LFS setstripe -c1 -i0 $DIR/$tfile
25362         $LFS setstripe -c1 -i1 $DIR/$tfile
25363         stop $SINGLEMDS
25364         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25365         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25366         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25367                 error "start $SINGLEMDS failed"
25368         rm -rf $DIR/$tdir
25369 }
25370 run_test 818 "unlink with failed llog"
25371
25372 test_819a() {
25373         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25374         cancel_lru_locks osc
25375         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25376         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25377         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25378         rm -f $TDIR/$tfile
25379 }
25380 run_test 819a "too big niobuf in read"
25381
25382 test_819b() {
25383         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25384         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25385         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25386         cancel_lru_locks osc
25387         sleep 1
25388         rm -f $TDIR/$tfile
25389 }
25390 run_test 819b "too big niobuf in write"
25391
25392
25393 function test_820_start_ost() {
25394         sleep 5
25395
25396         for num in $(seq $OSTCOUNT); do
25397                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25398         done
25399 }
25400
25401 test_820() {
25402         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25403
25404         mkdir $DIR/$tdir
25405         umount_client $MOUNT || error "umount failed"
25406         for num in $(seq $OSTCOUNT); do
25407                 stop ost$num
25408         done
25409
25410         # mount client with no active OSTs
25411         # so that the client can't initialize max LOV EA size
25412         # from OSC notifications
25413         mount_client $MOUNT || error "mount failed"
25414         # delay OST starting to keep this 0 max EA size for a while
25415         test_820_start_ost &
25416
25417         # create a directory on MDS2
25418         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25419                 error "Failed to create directory"
25420         # open intent should update default EA size
25421         # see mdc_update_max_ea_from_body()
25422         # notice this is the very first RPC to MDS2
25423         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25424         ret=$?
25425         echo $out
25426         # With SSK, this situation can lead to -EPERM being returned.
25427         # In that case, simply retry.
25428         if [ $ret -ne 0 ] && $SHARED_KEY; then
25429                 if echo "$out" | grep -q "not permitted"; then
25430                         cp /etc/services $DIR/$tdir/mds2
25431                         ret=$?
25432                 fi
25433         fi
25434         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25435 }
25436 run_test 820 "update max EA from open intent"
25437
25438 #
25439 # tests that do cleanup/setup should be run at the end
25440 #
25441
25442 test_900() {
25443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25444         local ls
25445
25446         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25447         $LCTL set_param fail_loc=0x903
25448
25449         cancel_lru_locks MGC
25450
25451         FAIL_ON_ERROR=true cleanup
25452         FAIL_ON_ERROR=true setup
25453 }
25454 run_test 900 "umount should not race with any mgc requeue thread"
25455
25456 # LUS-6253/LU-11185
25457 test_901() {
25458         local oldc
25459         local newc
25460         local olds
25461         local news
25462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25463
25464         # some get_param have a bug to handle dot in param name
25465         cancel_lru_locks MGC
25466         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25467         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25468         umount_client $MOUNT || error "umount failed"
25469         mount_client $MOUNT || error "mount failed"
25470         cancel_lru_locks MGC
25471         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25472         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25473
25474         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25475         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25476
25477         return 0
25478 }
25479 run_test 901 "don't leak a mgc lock on client umount"
25480
25481 # LU-13377
25482 test_902() {
25483         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25484                 skip "client does not have LU-13377 fix"
25485         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25486         $LCTL set_param fail_loc=0x1415
25487         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25488         cancel_lru_locks osc
25489         rm -f $DIR/$tfile
25490 }
25491 run_test 902 "test short write doesn't hang lustre"
25492
25493 complete $SECONDS
25494 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25495 check_and_cleanup_lustre
25496 if [ "$I_MOUNTED" != "yes" ]; then
25497         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25498 fi
25499 exit_status