Whamcloud - gitweb
LU-13974 tests: update log corruption
[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         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2725                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2726
2727         ! $LFS setstripe --foreign --flags foo \
2728                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2729                         error "creating $tfile with '--flags foo' should fail"
2730
2731         ! $LFS setstripe --foreign --flags 0xffffffff \
2732                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2733                         error "creating $tfile w/ 0xffffffff flags should fail"
2734
2735         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2736                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2737
2738         # verify foreign file (raw way)
2739         parse_foreign_file -f $DIR/$tdir/$tfile |
2740                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2742         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2743                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2744         parse_foreign_file -f $DIR/$tdir/$tfile |
2745                 grep "lov_foreign_size: 73" ||
2746                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2747         parse_foreign_file -f $DIR/$tdir/$tfile |
2748                 grep "lov_foreign_type: 1" ||
2749                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2750         parse_foreign_file -f $DIR/$tdir/$tfile |
2751                 grep "lov_foreign_flags: 0x0000DA08" ||
2752                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2753         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2754                 grep "lov_foreign_value: 0x" |
2755                 sed -e 's/lov_foreign_value: 0x//')
2756         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2757         [[ $lov = ${lov2// /} ]] ||
2758                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2759
2760         # create foreign file (lfs + API)
2761         $LFS setstripe --foreign=none --flags 0xda08 \
2762                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: create failed"
2764
2765         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2766                 grep "lfm_magic:.*0x0BD70BD0" ||
2767                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2768         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2769         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2770                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2771         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2772                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2773         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2774                 grep "lfm_flags:.*0x0000DA08" ||
2775                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2776         $LFS getstripe $DIR/$tdir/${tfile}2 |
2777                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2778                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2779
2780         # modify striping should fail
2781         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2782                 error "$DIR/$tdir/$tfile: setstripe should fail"
2783         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2784                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2785
2786         # R/W should fail
2787         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2788         cat $DIR/$tdir/${tfile}2 &&
2789                 error "$DIR/$tdir/${tfile}2: read should fail"
2790         cat /etc/passwd > $DIR/$tdir/$tfile &&
2791                 error "$DIR/$tdir/$tfile: write should fail"
2792         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2793                 error "$DIR/$tdir/${tfile}2: write should fail"
2794
2795         # chmod should work
2796         chmod 222 $DIR/$tdir/$tfile ||
2797                 error "$DIR/$tdir/$tfile: chmod failed"
2798         chmod 222 $DIR/$tdir/${tfile}2 ||
2799                 error "$DIR/$tdir/${tfile}2: chmod failed"
2800
2801         # chown should work
2802         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2803                 error "$DIR/$tdir/$tfile: chown failed"
2804         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2805                 error "$DIR/$tdir/${tfile}2: chown failed"
2806
2807         # rename should work
2808         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2809                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2810         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2811                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2812
2813         #remove foreign file
2814         rm $DIR/$tdir/${tfile}.new ||
2815                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2816         rm $DIR/$tdir/${tfile}2.new ||
2817                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2818 }
2819 run_test 27J "basic ops on file with foreign LOV"
2820
2821 test_27K() {
2822         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2823                 skip "Need MDS version newer than 2.12.49"
2824
2825         test_mkdir $DIR/$tdir
2826         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2827         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2828
2829         # create foreign dir (raw way)
2830         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2831                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2832
2833         ! $LFS setdirstripe --foreign --flags foo \
2834                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2835                         error "creating $tdir with '--flags foo' should fail"
2836
2837         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2838                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2839                         error "creating $tdir w/ 0xffffffff flags should fail"
2840
2841         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2842                 error "create_foreign_dir FAILED"
2843
2844         # verify foreign dir (raw way)
2845         parse_foreign_dir -d $DIR/$tdir/$tdir |
2846                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2847                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2848         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2849                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2850         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2851                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2852         parse_foreign_dir -d $DIR/$tdir/$tdir |
2853                 grep "lmv_foreign_flags: 55813$" ||
2854                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2855         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2856                 grep "lmv_foreign_value: 0x" |
2857                 sed 's/lmv_foreign_value: 0x//')
2858         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2859                 sed 's/ //g')
2860         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2861
2862         # create foreign dir (lfs + API)
2863         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2864                 $DIR/$tdir/${tdir}2 ||
2865                 error "$DIR/$tdir/${tdir}2: create failed"
2866
2867         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2868                 grep "lfm_magic:.*0x0CD50CD0" ||
2869                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2870         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2871         # - sizeof(lfm_type) - sizeof(lfm_flags)
2872         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2873                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2874         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2875                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2876         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2877                 grep "lfm_flags:.*0x0000DA05" ||
2878                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2879         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2880                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2881                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2882
2883         # file create in dir should fail
2884         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2885         touch $DIR/$tdir/${tdir}2/$tfile &&
2886                 "$DIR/${tdir}2: file create should fail"
2887
2888         # chmod should work
2889         chmod 777 $DIR/$tdir/$tdir ||
2890                 error "$DIR/$tdir: chmod failed"
2891         chmod 777 $DIR/$tdir/${tdir}2 ||
2892                 error "$DIR/${tdir}2: chmod failed"
2893
2894         # chown should work
2895         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2896                 error "$DIR/$tdir: chown failed"
2897         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2898                 error "$DIR/${tdir}2: chown failed"
2899
2900         # rename should work
2901         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2902                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2903         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2904                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2905
2906         #remove foreign dir
2907         rmdir $DIR/$tdir/${tdir}.new ||
2908                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2909         rmdir $DIR/$tdir/${tdir}2.new ||
2910                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2911 }
2912 run_test 27K "basic ops on dir with foreign LMV"
2913
2914 test_27L() {
2915         remote_mds_nodsh && skip "remote MDS with nodsh"
2916
2917         local POOL=${POOL:-$TESTNAME}
2918
2919         pool_add $POOL || error "pool_add failed"
2920
2921         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2922                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2923                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2924 }
2925 run_test 27L "lfs pool_list gives correct pool name"
2926
2927 test_27M() {
2928         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2929                 skip "Need MDS version >= than 2.12.57"
2930         remote_mds_nodsh && skip "remote MDS with nodsh"
2931         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2932
2933         test_mkdir $DIR/$tdir
2934
2935         # Set default striping on directory
2936         $LFS setstripe -C 4 $DIR/$tdir
2937
2938         echo 1 > $DIR/$tdir/${tfile}.1
2939         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2940         local setcount=4
2941         [ $count -eq $setcount ] ||
2942                 error "(1) stripe count $count, should be $setcount"
2943
2944         # Capture existing append_stripe_count setting for restore
2945         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2946         local mdts=$(comma_list $(mdts_nodes))
2947         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2948
2949         local appendcount=$orig_count
2950         echo 1 >> $DIR/$tdir/${tfile}.2_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(2)stripe count $count, should be $appendcount for append"
2954
2955         # Disable O_APPEND striping, verify it works
2956         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2957
2958         # Should now get the default striping, which is 4
2959         setcount=4
2960         echo 1 >> $DIR/$tdir/${tfile}.3_append
2961         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2962         [ $count -eq $setcount ] ||
2963                 error "(3) stripe count $count, should be $setcount"
2964
2965         # Try changing the stripe count for append files
2966         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2967
2968         # Append striping is now 2 (directory default is still 4)
2969         appendcount=2
2970         echo 1 >> $DIR/$tdir/${tfile}.4_append
2971         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2972         [ $count -eq $appendcount ] ||
2973                 error "(4) stripe count $count, should be $appendcount for append"
2974
2975         # Test append stripe count of -1
2976         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2977         appendcount=$OSTCOUNT
2978         echo 1 >> $DIR/$tdir/${tfile}.5
2979         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2980         [ $count -eq $appendcount ] ||
2981                 error "(5) stripe count $count, should be $appendcount for append"
2982
2983         # Set append striping back to default of 1
2984         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2985
2986         # Try a new default striping, PFL + DOM
2987         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2988
2989         # Create normal DOM file, DOM returns stripe count == 0
2990         setcount=0
2991         touch $DIR/$tdir/${tfile}.6
2992         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2993         [ $count -eq $setcount ] ||
2994                 error "(6) stripe count $count, should be $setcount"
2995
2996         # Show
2997         appendcount=1
2998         echo 1 >> $DIR/$tdir/${tfile}.7_append
2999         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3000         [ $count -eq $appendcount ] ||
3001                 error "(7) stripe count $count, should be $appendcount for append"
3002
3003         # Clean up DOM layout
3004         $LFS setstripe -d $DIR/$tdir
3005
3006         # Now test that append striping works when layout is from root
3007         $LFS setstripe -c 2 $MOUNT
3008         # Make a special directory for this
3009         mkdir $DIR/${tdir}/${tdir}.2
3010         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3011
3012         # Verify for normal file
3013         setcount=2
3014         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3015         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3016         [ $count -eq $setcount ] ||
3017                 error "(8) stripe count $count, should be $setcount"
3018
3019         appendcount=1
3020         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3021         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3022         [ $count -eq $appendcount ] ||
3023                 error "(9) stripe count $count, should be $appendcount for append"
3024
3025         # Now test O_APPEND striping with pools
3026         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3027         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3028
3029         # Create the pool
3030         pool_add $TESTNAME || error "pool creation failed"
3031         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3032
3033         echo 1 >> $DIR/$tdir/${tfile}.10_append
3034
3035         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3036         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3037
3038         # Check that count is still correct
3039         appendcount=1
3040         echo 1 >> $DIR/$tdir/${tfile}.11_append
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3042         [ $count -eq $appendcount ] ||
3043                 error "(11) stripe count $count, should be $appendcount for append"
3044
3045         # Disable O_APPEND stripe count, verify pool works separately
3046         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3047
3048         echo 1 >> $DIR/$tdir/${tfile}.12_append
3049
3050         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3051         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3052
3053         # Remove pool setting, verify it's not applied
3054         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3055
3056         echo 1 >> $DIR/$tdir/${tfile}.13_append
3057
3058         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3059         [ "$pool" = "" ] || error "(13) pool found: $pool"
3060 }
3061 run_test 27M "test O_APPEND striping"
3062
3063 test_27N() {
3064         combined_mgs_mds && skip "needs separate MGS/MDT"
3065
3066         pool_add $TESTNAME || error "pool_add failed"
3067         do_facet mgs "$LCTL pool_list $FSNAME" |
3068                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3069                 error "lctl pool_list on MGS failed"
3070 }
3071 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3072
3073 clean_foreign_symlink() {
3074         trap 0
3075         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3076         for i in $DIR/$tdir/* ; do
3077                 $LFS unlink_foreign $i || true
3078         done
3079 }
3080
3081 test_27O() {
3082         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3083                 skip "Need MDS version newer than 2.12.51"
3084
3085         test_mkdir $DIR/$tdir
3086         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3087         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3088
3089         trap clean_foreign_symlink EXIT
3090
3091         # enable foreign_symlink behaviour
3092         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3093
3094         # foreign symlink LOV format is a partial path by default
3095
3096         # create foreign file (lfs + API)
3097         $LFS setstripe --foreign=symlink --flags 0xda05 \
3098                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3099                 error "$DIR/$tdir/${tfile}: create failed"
3100
3101         $LFS getstripe -v $DIR/$tdir/${tfile} |
3102                 grep "lfm_magic:.*0x0BD70BD0" ||
3103                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3104         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3105                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3106         $LFS getstripe -v $DIR/$tdir/${tfile} |
3107                 grep "lfm_flags:.*0x0000DA05" ||
3108                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3109         $LFS getstripe $DIR/$tdir/${tfile} |
3110                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3111                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3112
3113         # modify striping should fail
3114         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3115                 error "$DIR/$tdir/$tfile: setstripe should fail"
3116
3117         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3118         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3119         cat /etc/passwd > $DIR/$tdir/$tfile &&
3120                 error "$DIR/$tdir/$tfile: write should fail"
3121
3122         # rename should succeed
3123         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3124                 error "$DIR/$tdir/$tfile: rename has failed"
3125
3126         #remove foreign_symlink file should fail
3127         rm $DIR/$tdir/${tfile}.new &&
3128                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3129
3130         #test fake symlink
3131         mkdir /tmp/${uuid1} ||
3132                 error "/tmp/${uuid1}: mkdir has failed"
3133         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3134                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3135         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3136         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3137                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3138         #read should succeed now
3139         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3140                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3141         #write should succeed now
3142         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3143                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3144         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3145                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3146         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3147                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3148
3149         #check that getstripe still works
3150         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3151                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3152
3153         # chmod should still succeed
3154         chmod 644 $DIR/$tdir/${tfile}.new ||
3155                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3156
3157         # chown should still succeed
3158         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3159                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3160
3161         # rename should still succeed
3162         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3163                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3164
3165         #remove foreign_symlink file should still fail
3166         rm $DIR/$tdir/${tfile} &&
3167                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3168
3169         #use special ioctl() to unlink foreign_symlink file
3170         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3171                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3172
3173 }
3174 run_test 27O "basic ops on foreign file of symlink type"
3175
3176 test_27P() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3178                 skip "Need MDS version newer than 2.12.49"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LMV format is a partial path by default
3190
3191         # create foreign dir (lfs + API)
3192         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3193                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3194                 error "$DIR/$tdir/${tdir}: create failed"
3195
3196         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3197                 grep "lfm_magic:.*0x0CD50CD0" ||
3198                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3199         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3201         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3204         $LFS getdirstripe $DIR/$tdir/${tdir} |
3205                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3207
3208         # file create in dir should fail
3209         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3210         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3211
3212         # rename should succeed
3213         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3214                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3215
3216         #remove foreign_symlink dir should fail
3217         rmdir $DIR/$tdir/${tdir}.new &&
3218                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3219
3220         #test fake symlink
3221         mkdir -p /tmp/${uuid1}/${uuid2} ||
3222                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3223         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3224                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3225         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3226         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3227                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3228         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3229                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3230
3231         #check that getstripe fails now that foreign_symlink enabled
3232         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3233                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3234
3235         # file create in dir should work now
3236         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3237                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3238         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3239                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3240         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3241                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3242
3243         # chmod should still succeed
3244         chmod 755 $DIR/$tdir/${tdir}.new ||
3245                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3246
3247         # chown should still succeed
3248         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3249                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3250
3251         # rename should still succeed
3252         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3254
3255         #remove foreign_symlink dir should still fail
3256         rmdir $DIR/$tdir/${tdir} &&
3257                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3258
3259         #use special ioctl() to unlink foreign_symlink file
3260         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3261                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3262
3263         #created file should still exist
3264         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3265                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3266         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3267                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3268 }
3269 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3270
3271 # createtest also checks that device nodes are created and
3272 # then visible correctly (#2091)
3273 test_28() { # bug 2091
3274         test_mkdir $DIR/d28
3275         $CREATETEST $DIR/d28/ct || error "createtest failed"
3276 }
3277 run_test 28 "create/mknod/mkdir with bad file types ============"
3278
3279 test_29() {
3280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3281
3282         sync; sleep 1; sync # flush out any dirty pages from previous tests
3283         cancel_lru_locks
3284         test_mkdir $DIR/d29
3285         touch $DIR/d29/foo
3286         log 'first d29'
3287         ls -l $DIR/d29
3288
3289         declare -i LOCKCOUNTORIG=0
3290         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3291                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3292         done
3293         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3294
3295         declare -i LOCKUNUSEDCOUNTORIG=0
3296         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3297                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3298         done
3299
3300         log 'second d29'
3301         ls -l $DIR/d29
3302         log 'done'
3303
3304         declare -i LOCKCOUNTCURRENT=0
3305         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3306                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3307         done
3308
3309         declare -i LOCKUNUSEDCOUNTCURRENT=0
3310         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3311                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3312         done
3313
3314         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3315                 $LCTL set_param -n ldlm.dump_namespaces ""
3316                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3317                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3318                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3319                 return 2
3320         fi
3321         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3322                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3323                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3324                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3325                 return 3
3326         fi
3327 }
3328 run_test 29 "IT_GETATTR regression  ============================"
3329
3330 test_30a() { # was test_30
3331         cp $(which ls) $DIR || cp /bin/ls $DIR
3332         $DIR/ls / || error "Can't execute binary from lustre"
3333         rm $DIR/ls
3334 }
3335 run_test 30a "execute binary from Lustre (execve) =============="
3336
3337 test_30b() {
3338         cp `which ls` $DIR || cp /bin/ls $DIR
3339         chmod go+rx $DIR/ls
3340         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3341         rm $DIR/ls
3342 }
3343 run_test 30b "execute binary from Lustre as non-root ==========="
3344
3345 test_30c() { # b=22376
3346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3347
3348         cp $(which ls) $DIR || cp /bin/ls $DIR
3349         chmod a-rw $DIR/ls
3350         cancel_lru_locks mdc
3351         cancel_lru_locks osc
3352         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3353         rm -f $DIR/ls
3354 }
3355 run_test 30c "execute binary from Lustre without read perms ===="
3356
3357 test_30d() {
3358         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3359
3360         for i in {1..10}; do
3361                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3362                 local PID=$!
3363                 sleep 1
3364                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3365                 wait $PID || error "executing dd from Lustre failed"
3366                 rm -f $DIR/$tfile
3367         done
3368
3369         rm -f $DIR/dd
3370 }
3371 run_test 30d "execute binary from Lustre while clear locks"
3372
3373 test_31a() {
3374         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3375         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3376 }
3377 run_test 31a "open-unlink file =================================="
3378
3379 test_31b() {
3380         touch $DIR/f31 || error "touch $DIR/f31 failed"
3381         ln $DIR/f31 $DIR/f31b || error "ln failed"
3382         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3383         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3384 }
3385 run_test 31b "unlink file with multiple links while open ======="
3386
3387 test_31c() {
3388         touch $DIR/f31 || error "touch $DIR/f31 failed"
3389         ln $DIR/f31 $DIR/f31c || error "ln failed"
3390         multiop_bg_pause $DIR/f31 O_uc ||
3391                 error "multiop_bg_pause for $DIR/f31 failed"
3392         MULTIPID=$!
3393         $MULTIOP $DIR/f31c Ouc
3394         kill -USR1 $MULTIPID
3395         wait $MULTIPID
3396 }
3397 run_test 31c "open-unlink file with multiple links ============="
3398
3399 test_31d() {
3400         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3401         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3402 }
3403 run_test 31d "remove of open directory ========================="
3404
3405 test_31e() { # bug 2904
3406         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3407 }
3408 run_test 31e "remove of open non-empty directory ==============="
3409
3410 test_31f() { # bug 4554
3411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3412
3413         set -vx
3414         test_mkdir $DIR/d31f
3415         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3416         cp /etc/hosts $DIR/d31f
3417         ls -l $DIR/d31f
3418         $LFS getstripe $DIR/d31f/hosts
3419         multiop_bg_pause $DIR/d31f D_c || return 1
3420         MULTIPID=$!
3421
3422         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3423         test_mkdir $DIR/d31f
3424         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3425         cp /etc/hosts $DIR/d31f
3426         ls -l $DIR/d31f
3427         $LFS getstripe $DIR/d31f/hosts
3428         multiop_bg_pause $DIR/d31f D_c || return 1
3429         MULTIPID2=$!
3430
3431         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3432         wait $MULTIPID || error "first opendir $MULTIPID failed"
3433
3434         sleep 6
3435
3436         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3437         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3438         set +vx
3439 }
3440 run_test 31f "remove of open directory with open-unlink file ==="
3441
3442 test_31g() {
3443         echo "-- cross directory link --"
3444         test_mkdir -c1 $DIR/${tdir}ga
3445         test_mkdir -c1 $DIR/${tdir}gb
3446         touch $DIR/${tdir}ga/f
3447         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3448         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3449         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3450         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3451         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3452 }
3453 run_test 31g "cross directory link==============="
3454
3455 test_31h() {
3456         echo "-- cross directory link --"
3457         test_mkdir -c1 $DIR/${tdir}
3458         test_mkdir -c1 $DIR/${tdir}/dir
3459         touch $DIR/${tdir}/f
3460         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3461         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3462         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3463         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3464         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3465 }
3466 run_test 31h "cross directory link under child==============="
3467
3468 test_31i() {
3469         echo "-- cross directory link --"
3470         test_mkdir -c1 $DIR/$tdir
3471         test_mkdir -c1 $DIR/$tdir/dir
3472         touch $DIR/$tdir/dir/f
3473         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3474         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3475         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3476         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3477         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3478 }
3479 run_test 31i "cross directory link under parent==============="
3480
3481 test_31j() {
3482         test_mkdir -c1 -p $DIR/$tdir
3483         test_mkdir -c1 -p $DIR/$tdir/dir1
3484         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3485         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3486         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3487         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3488         return 0
3489 }
3490 run_test 31j "link for directory==============="
3491
3492 test_31k() {
3493         test_mkdir -c1 -p $DIR/$tdir
3494         touch $DIR/$tdir/s
3495         touch $DIR/$tdir/exist
3496         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3497         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3498         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3499         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3500         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3501         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3502         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3503         return 0
3504 }
3505 run_test 31k "link to file: the same, non-existing, dir==============="
3506
3507 test_31m() {
3508         mkdir $DIR/d31m
3509         touch $DIR/d31m/s
3510         mkdir $DIR/d31m2
3511         touch $DIR/d31m2/exist
3512         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3513         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3514         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3515         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3516         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3517         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3518         return 0
3519 }
3520 run_test 31m "link to file: the same, non-existing, dir==============="
3521
3522 test_31n() {
3523         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3524         nlink=$(stat --format=%h $DIR/$tfile)
3525         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3526         local fd=$(free_fd)
3527         local cmd="exec $fd<$DIR/$tfile"
3528         eval $cmd
3529         cmd="exec $fd<&-"
3530         trap "eval $cmd" EXIT
3531         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3532         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3533         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3534         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3535         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3536         eval $cmd
3537 }
3538 run_test 31n "check link count of unlinked file"
3539
3540 link_one() {
3541         local tempfile=$(mktemp $1_XXXXXX)
3542         mlink $tempfile $1 2> /dev/null &&
3543                 echo "$BASHPID: link $tempfile to $1 succeeded"
3544         munlink $tempfile
3545 }
3546
3547 test_31o() { # LU-2901
3548         test_mkdir $DIR/$tdir
3549         for LOOP in $(seq 100); do
3550                 rm -f $DIR/$tdir/$tfile*
3551                 for THREAD in $(seq 8); do
3552                         link_one $DIR/$tdir/$tfile.$LOOP &
3553                 done
3554                 wait
3555                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3556                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3557                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3558                         break || true
3559         done
3560 }
3561 run_test 31o "duplicate hard links with same filename"
3562
3563 test_31p() {
3564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3565
3566         test_mkdir $DIR/$tdir
3567         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3568         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3569
3570         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3571                 error "open unlink test1 failed"
3572         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3573                 error "open unlink test2 failed"
3574
3575         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3576                 error "test1 still exists"
3577         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3578                 error "test2 still exists"
3579 }
3580 run_test 31p "remove of open striped directory"
3581
3582 test_31q() {
3583         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3584
3585         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3586         index=$($LFS getdirstripe -i $DIR/$tdir)
3587         [ $index -eq 3 ] || error "first stripe index $index != 3"
3588         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3589         [ $index -eq 1 ] || error "second stripe index $index != 1"
3590
3591         # when "-c <stripe_count>" is set, the number of MDTs specified after
3592         # "-i" should equal to the stripe count
3593         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3594 }
3595 run_test 31q "create striped directory on specific MDTs"
3596
3597 cleanup_test32_mount() {
3598         local rc=0
3599         trap 0
3600         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3601         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3602         losetup -d $loopdev || true
3603         rm -rf $DIR/$tdir
3604         return $rc
3605 }
3606
3607 test_32a() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         echo "== more mountpoints and symlinks ================="
3611         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3612         trap cleanup_test32_mount EXIT
3613         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3614         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3615                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3616         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3617                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3618         cleanup_test32_mount
3619 }
3620 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3621
3622 test_32b() {
3623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3624
3625         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3626         trap cleanup_test32_mount EXIT
3627         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3628         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3629                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3630         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3631                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3632         cleanup_test32_mount
3633 }
3634 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3635
3636 test_32c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638
3639         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3640         trap cleanup_test32_mount EXIT
3641         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3642         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3643                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3644         test_mkdir -p $DIR/$tdir/d2/test_dir
3645         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3646                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3647         cleanup_test32_mount
3648 }
3649 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3650
3651 test_32d() {
3652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3653
3654         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3655         trap cleanup_test32_mount EXIT
3656         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3657         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3658                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3659         test_mkdir -p $DIR/$tdir/d2/test_dir
3660         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3661                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3662         cleanup_test32_mount
3663 }
3664 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3665
3666 test_32e() {
3667         rm -fr $DIR/$tdir
3668         test_mkdir -p $DIR/$tdir/tmp
3669         local tmp_dir=$DIR/$tdir/tmp
3670         ln -s $DIR/$tdir $tmp_dir/symlink11
3671         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3672         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3673         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3674 }
3675 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3676
3677 test_32f() {
3678         rm -fr $DIR/$tdir
3679         test_mkdir -p $DIR/$tdir/tmp
3680         local tmp_dir=$DIR/$tdir/tmp
3681         ln -s $DIR/$tdir $tmp_dir/symlink11
3682         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3683         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3684         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3685 }
3686 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3687
3688 test_32g() {
3689         local tmp_dir=$DIR/$tdir/tmp
3690         test_mkdir -p $tmp_dir
3691         test_mkdir $DIR/${tdir}2
3692         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3693         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3694         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3695         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3696         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3697         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3698 }
3699 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3700
3701 test_32h() {
3702         rm -fr $DIR/$tdir $DIR/${tdir}2
3703         tmp_dir=$DIR/$tdir/tmp
3704         test_mkdir -p $tmp_dir
3705         test_mkdir $DIR/${tdir}2
3706         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3707         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3708         ls $tmp_dir/symlink12 || error "listing symlink12"
3709         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3710 }
3711 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3712
3713 test_32i() {
3714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3715
3716         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3717         trap cleanup_test32_mount EXIT
3718         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3719         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3720                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3721         touch $DIR/$tdir/test_file
3722         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3723                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3724         cleanup_test32_mount
3725 }
3726 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3727
3728 test_32j() {
3729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3730
3731         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3732         trap cleanup_test32_mount EXIT
3733         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3734         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3735                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3736         touch $DIR/$tdir/test_file
3737         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3738                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3739         cleanup_test32_mount
3740 }
3741 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3742
3743 test_32k() {
3744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3745
3746         rm -fr $DIR/$tdir
3747         trap cleanup_test32_mount EXIT
3748         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3749         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3750                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3751         test_mkdir -p $DIR/$tdir/d2
3752         touch $DIR/$tdir/d2/test_file || error "touch failed"
3753         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3754                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3755         cleanup_test32_mount
3756 }
3757 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3758
3759 test_32l() {
3760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3761
3762         rm -fr $DIR/$tdir
3763         trap cleanup_test32_mount EXIT
3764         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3765         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3766                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3767         test_mkdir -p $DIR/$tdir/d2
3768         touch $DIR/$tdir/d2/test_file || error "touch failed"
3769         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3770                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3771         cleanup_test32_mount
3772 }
3773 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3774
3775 test_32m() {
3776         rm -fr $DIR/d32m
3777         test_mkdir -p $DIR/d32m/tmp
3778         TMP_DIR=$DIR/d32m/tmp
3779         ln -s $DIR $TMP_DIR/symlink11
3780         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3781         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3782                 error "symlink11 not a link"
3783         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3784                 error "symlink01 not a link"
3785 }
3786 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3787
3788 test_32n() {
3789         rm -fr $DIR/d32n
3790         test_mkdir -p $DIR/d32n/tmp
3791         TMP_DIR=$DIR/d32n/tmp
3792         ln -s $DIR $TMP_DIR/symlink11
3793         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3794         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3795         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3796 }
3797 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3798
3799 test_32o() {
3800         touch $DIR/$tfile
3801         test_mkdir -p $DIR/d32o/tmp
3802         TMP_DIR=$DIR/d32o/tmp
3803         ln -s $DIR/$tfile $TMP_DIR/symlink12
3804         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3805         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3806                 error "symlink12 not a link"
3807         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3808         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3809                 error "$DIR/d32o/tmp/symlink12 not file type"
3810         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3811                 error "$DIR/d32o/symlink02 not file type"
3812 }
3813 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3814
3815 test_32p() {
3816         log 32p_1
3817         rm -fr $DIR/d32p
3818         log 32p_2
3819         rm -f $DIR/$tfile
3820         log 32p_3
3821         touch $DIR/$tfile
3822         log 32p_4
3823         test_mkdir -p $DIR/d32p/tmp
3824         log 32p_5
3825         TMP_DIR=$DIR/d32p/tmp
3826         log 32p_6
3827         ln -s $DIR/$tfile $TMP_DIR/symlink12
3828         log 32p_7
3829         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3830         log 32p_8
3831         cat $DIR/d32p/tmp/symlink12 ||
3832                 error "Can't open $DIR/d32p/tmp/symlink12"
3833         log 32p_9
3834         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3835         log 32p_10
3836 }
3837 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3838
3839 test_32q() {
3840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3841
3842         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3843         trap cleanup_test32_mount EXIT
3844         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3845         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3846         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3847                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3848         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3849         cleanup_test32_mount
3850 }
3851 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3852
3853 test_32r() {
3854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3855
3856         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3857         trap cleanup_test32_mount EXIT
3858         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3859         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3860         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3861                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3862         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3863         cleanup_test32_mount
3864 }
3865 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3866
3867 test_33aa() {
3868         rm -f $DIR/$tfile
3869         touch $DIR/$tfile
3870         chmod 444 $DIR/$tfile
3871         chown $RUNAS_ID $DIR/$tfile
3872         log 33_1
3873         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3874         log 33_2
3875 }
3876 run_test 33aa "write file with mode 444 (should return error)"
3877
3878 test_33a() {
3879         rm -fr $DIR/$tdir
3880         test_mkdir $DIR/$tdir
3881         chown $RUNAS_ID $DIR/$tdir
3882         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3883                 error "$RUNAS create $tdir/$tfile failed"
3884         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3885                 error "open RDWR" || true
3886 }
3887 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3888
3889 test_33b() {
3890         rm -fr $DIR/$tdir
3891         test_mkdir $DIR/$tdir
3892         chown $RUNAS_ID $DIR/$tdir
3893         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3894 }
3895 run_test 33b "test open file with malformed flags (No panic)"
3896
3897 test_33c() {
3898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3899         remote_ost_nodsh && skip "remote OST with nodsh"
3900
3901         local ostnum
3902         local ostname
3903         local write_bytes
3904         local all_zeros
3905
3906         all_zeros=:
3907         rm -fr $DIR/$tdir
3908         test_mkdir $DIR/$tdir
3909         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3910
3911         sync
3912         for ostnum in $(seq $OSTCOUNT); do
3913                 # test-framework's OST numbering is one-based, while Lustre's
3914                 # is zero-based
3915                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3916                 # Parsing llobdstat's output sucks; we could grep the /proc
3917                 # path, but that's likely to not be as portable as using the
3918                 # llobdstat utility.  So we parse lctl output instead.
3919                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3920                         obdfilter/$ostname/stats |
3921                         awk '/^write_bytes/ {print $7}' )
3922                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3923                 if (( ${write_bytes:-0} > 0 ))
3924                 then
3925                         all_zeros=false
3926                         break;
3927                 fi
3928         done
3929
3930         $all_zeros || return 0
3931
3932         # Write four bytes
3933         echo foo > $DIR/$tdir/bar
3934         # Really write them
3935         sync
3936
3937         # Total up write_bytes after writing.  We'd better find non-zeros.
3938         for ostnum in $(seq $OSTCOUNT); do
3939                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3940                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3941                         obdfilter/$ostname/stats |
3942                         awk '/^write_bytes/ {print $7}' )
3943                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3944                 if (( ${write_bytes:-0} > 0 ))
3945                 then
3946                         all_zeros=false
3947                         break;
3948                 fi
3949         done
3950
3951         if $all_zeros
3952         then
3953                 for ostnum in $(seq $OSTCOUNT); do
3954                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3955                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3956                         do_facet ost$ostnum lctl get_param -n \
3957                                 obdfilter/$ostname/stats
3958                 done
3959                 error "OST not keeping write_bytes stats (b22312)"
3960         fi
3961 }
3962 run_test 33c "test llobdstat and write_bytes"
3963
3964 test_33d() {
3965         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         local MDTIDX=1
3969         local remote_dir=$DIR/$tdir/remote_dir
3970
3971         test_mkdir $DIR/$tdir
3972         $LFS mkdir -i $MDTIDX $remote_dir ||
3973                 error "create remote directory failed"
3974
3975         touch $remote_dir/$tfile
3976         chmod 444 $remote_dir/$tfile
3977         chown $RUNAS_ID $remote_dir/$tfile
3978
3979         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3980
3981         chown $RUNAS_ID $remote_dir
3982         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3983                                         error "create" || true
3984         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3985                                     error "open RDWR" || true
3986         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3987 }
3988 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3989
3990 test_33e() {
3991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3992
3993         mkdir $DIR/$tdir
3994
3995         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3996         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3997         mkdir $DIR/$tdir/local_dir
3998
3999         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4000         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4001         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4002
4003         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4004                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4005
4006         rmdir $DIR/$tdir/* || error "rmdir failed"
4007
4008         umask 777
4009         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4010         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4011         mkdir $DIR/$tdir/local_dir
4012
4013         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4014         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4015         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4016
4017         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4018                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4019
4020         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4021
4022         umask 000
4023         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4024         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4025         mkdir $DIR/$tdir/local_dir
4026
4027         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4028         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4029         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4030
4031         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4032                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4033 }
4034 run_test 33e "mkdir and striped directory should have same mode"
4035
4036 cleanup_33f() {
4037         trap 0
4038         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4039 }
4040
4041 test_33f() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043         remote_mds_nodsh && skip "remote MDS with nodsh"
4044
4045         mkdir $DIR/$tdir
4046         chmod go+rwx $DIR/$tdir
4047         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4048         trap cleanup_33f EXIT
4049
4050         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4051                 error "cannot create striped directory"
4052
4053         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4054                 error "cannot create files in striped directory"
4055
4056         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4057                 error "cannot remove files in striped directory"
4058
4059         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4060                 error "cannot remove striped directory"
4061
4062         cleanup_33f
4063 }
4064 run_test 33f "nonroot user can create, access, and remove a striped directory"
4065
4066 test_33g() {
4067         mkdir -p $DIR/$tdir/dir2
4068
4069         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4070         echo $err
4071         [[ $err =~ "exists" ]] || error "Not exists error"
4072 }
4073 run_test 33g "nonroot user create already existing root created file"
4074
4075 test_33h() {
4076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4077         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4078                 skip "Need MDS version at least 2.13.50"
4079
4080         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4081                 error "mkdir $tdir failed"
4082         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4083
4084         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4085         local index2
4086
4087         for fname in $DIR/$tdir/$tfile.bak \
4088                      $DIR/$tdir/$tfile.SAV \
4089                      $DIR/$tdir/$tfile.orig \
4090                      $DIR/$tdir/$tfile~; do
4091                 touch $fname  || error "touch $fname failed"
4092                 index2=$($LFS getstripe -m $fname)
4093                 [ $index -eq $index2 ] ||
4094                         error "$fname MDT index mismatch $index != $index2"
4095         done
4096
4097         local failed=0
4098         for i in {1..250}; do
4099                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4100                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4101                         touch $fname  || error "touch $fname failed"
4102                         index2=$($LFS getstripe -m $fname)
4103                         if [[ $index != $index2 ]]; then
4104                                 failed=$((failed + 1))
4105                                 echo "$fname MDT index mismatch $index != $index2"
4106                         fi
4107                 done
4108         done
4109         echo "$failed MDT index mismatches"
4110         (( failed < 20 )) || error "MDT index mismatch $failed times"
4111
4112 }
4113 run_test 33h "temp file is located on the same MDT as target"
4114
4115 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4116 test_34a() {
4117         rm -f $DIR/f34
4118         $MCREATE $DIR/f34 || error "mcreate failed"
4119         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4120                 error "getstripe failed"
4121         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4122         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4123                 error "getstripe failed"
4124         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4125                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4126 }
4127 run_test 34a "truncate file that has not been opened ==========="
4128
4129 test_34b() {
4130         [ ! -f $DIR/f34 ] && test_34a
4131         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4132                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4133         $OPENFILE -f O_RDONLY $DIR/f34
4134         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4135                 error "getstripe failed"
4136         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4137                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4138 }
4139 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4140
4141 test_34c() {
4142         [ ! -f $DIR/f34 ] && test_34a
4143         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4144                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4145         $OPENFILE -f O_RDWR $DIR/f34
4146         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4147                 error "$LFS getstripe failed"
4148         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4149                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4150 }
4151 run_test 34c "O_RDWR opening file-with-size works =============="
4152
4153 test_34d() {
4154         [ ! -f $DIR/f34 ] && test_34a
4155         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4156                 error "dd failed"
4157         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4158                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4159         rm $DIR/f34
4160 }
4161 run_test 34d "write to sparse file ============================="
4162
4163 test_34e() {
4164         rm -f $DIR/f34e
4165         $MCREATE $DIR/f34e || error "mcreate failed"
4166         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4167         $CHECKSTAT -s 1000 $DIR/f34e ||
4168                 error "Size of $DIR/f34e not equal to 1000 bytes"
4169         $OPENFILE -f O_RDWR $DIR/f34e
4170         $CHECKSTAT -s 1000 $DIR/f34e ||
4171                 error "Size of $DIR/f34e not equal to 1000 bytes"
4172 }
4173 run_test 34e "create objects, some with size and some without =="
4174
4175 test_34f() { # bug 6242, 6243
4176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4177
4178         SIZE34F=48000
4179         rm -f $DIR/f34f
4180         $MCREATE $DIR/f34f || error "mcreate failed"
4181         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4182         dd if=$DIR/f34f of=$TMP/f34f
4183         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4184         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4185         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4186         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4187         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4188 }
4189 run_test 34f "read from a file with no objects until EOF ======="
4190
4191 test_34g() {
4192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4193
4194         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4195                 error "dd failed"
4196         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4197         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4198                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4199         cancel_lru_locks osc
4200         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4201                 error "wrong size after lock cancel"
4202
4203         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4204         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4205                 error "expanding truncate failed"
4206         cancel_lru_locks osc
4207         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4208                 error "wrong expanded size after lock cancel"
4209 }
4210 run_test 34g "truncate long file ==============================="
4211
4212 test_34h() {
4213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4214
4215         local gid=10
4216         local sz=1000
4217
4218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4219         sync # Flush the cache so that multiop below does not block on cache
4220              # flush when getting the group lock
4221         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4222         MULTIPID=$!
4223
4224         # Since just timed wait is not good enough, let's do a sync write
4225         # that way we are sure enough time for a roundtrip + processing
4226         # passed + 2 seconds of extra margin.
4227         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4228         rm $DIR/${tfile}-1
4229         sleep 2
4230
4231         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4232                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4233                 kill -9 $MULTIPID
4234         fi
4235         wait $MULTIPID
4236         local nsz=`stat -c %s $DIR/$tfile`
4237         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4238 }
4239 run_test 34h "ftruncate file under grouplock should not block"
4240
4241 test_35a() {
4242         cp /bin/sh $DIR/f35a
4243         chmod 444 $DIR/f35a
4244         chown $RUNAS_ID $DIR/f35a
4245         $RUNAS $DIR/f35a && error || true
4246         rm $DIR/f35a
4247 }
4248 run_test 35a "exec file with mode 444 (should return and not leak)"
4249
4250 test_36a() {
4251         rm -f $DIR/f36
4252         utime $DIR/f36 || error "utime failed for MDS"
4253 }
4254 run_test 36a "MDS utime check (mknod, utime)"
4255
4256 test_36b() {
4257         echo "" > $DIR/f36
4258         utime $DIR/f36 || error "utime failed for OST"
4259 }
4260 run_test 36b "OST utime check (open, utime)"
4261
4262 test_36c() {
4263         rm -f $DIR/d36/f36
4264         test_mkdir $DIR/d36
4265         chown $RUNAS_ID $DIR/d36
4266         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4267 }
4268 run_test 36c "non-root MDS utime check (mknod, utime)"
4269
4270 test_36d() {
4271         [ ! -d $DIR/d36 ] && test_36c
4272         echo "" > $DIR/d36/f36
4273         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4274 }
4275 run_test 36d "non-root OST utime check (open, utime)"
4276
4277 test_36e() {
4278         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4279
4280         test_mkdir $DIR/$tdir
4281         touch $DIR/$tdir/$tfile
4282         $RUNAS utime $DIR/$tdir/$tfile &&
4283                 error "utime worked, expected failure" || true
4284 }
4285 run_test 36e "utime on non-owned file (should return error)"
4286
4287 subr_36fh() {
4288         local fl="$1"
4289         local LANG_SAVE=$LANG
4290         local LC_LANG_SAVE=$LC_LANG
4291         export LANG=C LC_LANG=C # for date language
4292
4293         DATESTR="Dec 20  2000"
4294         test_mkdir $DIR/$tdir
4295         lctl set_param fail_loc=$fl
4296         date; date +%s
4297         cp /etc/hosts $DIR/$tdir/$tfile
4298         sync & # write RPC generated with "current" inode timestamp, but delayed
4299         sleep 1
4300         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4301         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4302         cancel_lru_locks $OSC
4303         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4304         date; date +%s
4305         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4306                 echo "BEFORE: $LS_BEFORE" && \
4307                 echo "AFTER : $LS_AFTER" && \
4308                 echo "WANT  : $DATESTR" && \
4309                 error "$DIR/$tdir/$tfile timestamps changed" || true
4310
4311         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4312 }
4313
4314 test_36f() {
4315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4316
4317         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4318         subr_36fh "0x80000214"
4319 }
4320 run_test 36f "utime on file racing with OST BRW write =========="
4321
4322 test_36g() {
4323         remote_ost_nodsh && skip "remote OST with nodsh"
4324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4325         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4326                 skip "Need MDS version at least 2.12.51"
4327
4328         local fmd_max_age
4329         local fmd
4330         local facet="ost1"
4331         local tgt="obdfilter"
4332
4333         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4334
4335         test_mkdir $DIR/$tdir
4336         fmd_max_age=$(do_facet $facet \
4337                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4338                 head -n 1")
4339
4340         echo "FMD max age: ${fmd_max_age}s"
4341         touch $DIR/$tdir/$tfile
4342         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4343                 gawk '{cnt=cnt+$1}  END{print cnt}')
4344         echo "FMD before: $fmd"
4345         [[ $fmd == 0 ]] &&
4346                 error "FMD wasn't create by touch"
4347         sleep $((fmd_max_age + 12))
4348         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4349                 gawk '{cnt=cnt+$1}  END{print cnt}')
4350         echo "FMD after: $fmd"
4351         [[ $fmd == 0 ]] ||
4352                 error "FMD wasn't expired by ping"
4353 }
4354 run_test 36g "FMD cache expiry ====================="
4355
4356 test_36h() {
4357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4358
4359         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4360         subr_36fh "0x80000227"
4361 }
4362 run_test 36h "utime on file racing with OST BRW write =========="
4363
4364 test_36i() {
4365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4366
4367         test_mkdir $DIR/$tdir
4368         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4369
4370         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4371         local new_mtime=$((mtime + 200))
4372
4373         #change Modify time of striped dir
4374         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4375                         error "change mtime failed"
4376
4377         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4378
4379         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4380 }
4381 run_test 36i "change mtime on striped directory"
4382
4383 # test_37 - duplicate with tests 32q 32r
4384
4385 test_38() {
4386         local file=$DIR/$tfile
4387         touch $file
4388         openfile -f O_DIRECTORY $file
4389         local RC=$?
4390         local ENOTDIR=20
4391         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4392         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4393 }
4394 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4395
4396 test_39a() { # was test_39
4397         touch $DIR/$tfile
4398         touch $DIR/${tfile}2
4399 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4400 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4401 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4402         sleep 2
4403         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4404         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4405                 echo "mtime"
4406                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4407                 echo "atime"
4408                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4409                 echo "ctime"
4410                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4411                 error "O_TRUNC didn't change timestamps"
4412         fi
4413 }
4414 run_test 39a "mtime changed on create"
4415
4416 test_39b() {
4417         test_mkdir -c1 $DIR/$tdir
4418         cp -p /etc/passwd $DIR/$tdir/fopen
4419         cp -p /etc/passwd $DIR/$tdir/flink
4420         cp -p /etc/passwd $DIR/$tdir/funlink
4421         cp -p /etc/passwd $DIR/$tdir/frename
4422         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4423
4424         sleep 1
4425         echo "aaaaaa" >> $DIR/$tdir/fopen
4426         echo "aaaaaa" >> $DIR/$tdir/flink
4427         echo "aaaaaa" >> $DIR/$tdir/funlink
4428         echo "aaaaaa" >> $DIR/$tdir/frename
4429
4430         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4431         local link_new=`stat -c %Y $DIR/$tdir/flink`
4432         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4433         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4434
4435         cat $DIR/$tdir/fopen > /dev/null
4436         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4437         rm -f $DIR/$tdir/funlink2
4438         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4439
4440         for (( i=0; i < 2; i++ )) ; do
4441                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4442                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4443                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4444                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4445
4446                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4447                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4448                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4449                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4450
4451                 cancel_lru_locks $OSC
4452                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4453         done
4454 }
4455 run_test 39b "mtime change on open, link, unlink, rename  ======"
4456
4457 # this should be set to past
4458 TEST_39_MTIME=`date -d "1 year ago" +%s`
4459
4460 # bug 11063
4461 test_39c() {
4462         touch $DIR1/$tfile
4463         sleep 2
4464         local mtime0=`stat -c %Y $DIR1/$tfile`
4465
4466         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4467         local mtime1=`stat -c %Y $DIR1/$tfile`
4468         [ "$mtime1" = $TEST_39_MTIME ] || \
4469                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4470
4471         local d1=`date +%s`
4472         echo hello >> $DIR1/$tfile
4473         local d2=`date +%s`
4474         local mtime2=`stat -c %Y $DIR1/$tfile`
4475         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4476                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4477
4478         mv $DIR1/$tfile $DIR1/$tfile-1
4479
4480         for (( i=0; i < 2; i++ )) ; do
4481                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4482                 [ "$mtime2" = "$mtime3" ] || \
4483                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4484
4485                 cancel_lru_locks $OSC
4486                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4487         done
4488 }
4489 run_test 39c "mtime change on rename ==========================="
4490
4491 # bug 21114
4492 test_39d() {
4493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4494
4495         touch $DIR1/$tfile
4496         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4497
4498         for (( i=0; i < 2; i++ )) ; do
4499                 local mtime=`stat -c %Y $DIR1/$tfile`
4500                 [ $mtime = $TEST_39_MTIME ] || \
4501                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4502
4503                 cancel_lru_locks $OSC
4504                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4505         done
4506 }
4507 run_test 39d "create, utime, stat =============================="
4508
4509 # bug 21114
4510 test_39e() {
4511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4512
4513         touch $DIR1/$tfile
4514         local mtime1=`stat -c %Y $DIR1/$tfile`
4515
4516         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4517
4518         for (( i=0; i < 2; i++ )) ; do
4519                 local mtime2=`stat -c %Y $DIR1/$tfile`
4520                 [ $mtime2 = $TEST_39_MTIME ] || \
4521                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4522
4523                 cancel_lru_locks $OSC
4524                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4525         done
4526 }
4527 run_test 39e "create, stat, utime, stat ========================"
4528
4529 # bug 21114
4530 test_39f() {
4531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4532
4533         touch $DIR1/$tfile
4534         mtime1=`stat -c %Y $DIR1/$tfile`
4535
4536         sleep 2
4537         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4538
4539         for (( i=0; i < 2; i++ )) ; do
4540                 local mtime2=`stat -c %Y $DIR1/$tfile`
4541                 [ $mtime2 = $TEST_39_MTIME ] || \
4542                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4543
4544                 cancel_lru_locks $OSC
4545                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4546         done
4547 }
4548 run_test 39f "create, stat, sleep, utime, stat ================="
4549
4550 # bug 11063
4551 test_39g() {
4552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4553
4554         echo hello >> $DIR1/$tfile
4555         local mtime1=`stat -c %Y $DIR1/$tfile`
4556
4557         sleep 2
4558         chmod o+r $DIR1/$tfile
4559
4560         for (( i=0; i < 2; i++ )) ; do
4561                 local mtime2=`stat -c %Y $DIR1/$tfile`
4562                 [ "$mtime1" = "$mtime2" ] || \
4563                         error "lost mtime: $mtime2, should be $mtime1"
4564
4565                 cancel_lru_locks $OSC
4566                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4567         done
4568 }
4569 run_test 39g "write, chmod, stat ==============================="
4570
4571 # bug 11063
4572 test_39h() {
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         touch $DIR1/$tfile
4576         sleep 1
4577
4578         local d1=`date`
4579         echo hello >> $DIR1/$tfile
4580         local mtime1=`stat -c %Y $DIR1/$tfile`
4581
4582         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4583         local d2=`date`
4584         if [ "$d1" != "$d2" ]; then
4585                 echo "write and touch not within one second"
4586         else
4587                 for (( i=0; i < 2; i++ )) ; do
4588                         local mtime2=`stat -c %Y $DIR1/$tfile`
4589                         [ "$mtime2" = $TEST_39_MTIME ] || \
4590                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4591
4592                         cancel_lru_locks $OSC
4593                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4594                 done
4595         fi
4596 }
4597 run_test 39h "write, utime within one second, stat ============="
4598
4599 test_39i() {
4600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4601
4602         touch $DIR1/$tfile
4603         sleep 1
4604
4605         echo hello >> $DIR1/$tfile
4606         local mtime1=`stat -c %Y $DIR1/$tfile`
4607
4608         mv $DIR1/$tfile $DIR1/$tfile-1
4609
4610         for (( i=0; i < 2; i++ )) ; do
4611                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4612
4613                 [ "$mtime1" = "$mtime2" ] || \
4614                         error "lost mtime: $mtime2, should be $mtime1"
4615
4616                 cancel_lru_locks $OSC
4617                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4618         done
4619 }
4620 run_test 39i "write, rename, stat =============================="
4621
4622 test_39j() {
4623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4624
4625         start_full_debug_logging
4626         touch $DIR1/$tfile
4627         sleep 1
4628
4629         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4630         lctl set_param fail_loc=0x80000412
4631         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4632                 error "multiop failed"
4633         local multipid=$!
4634         local mtime1=`stat -c %Y $DIR1/$tfile`
4635
4636         mv $DIR1/$tfile $DIR1/$tfile-1
4637
4638         kill -USR1 $multipid
4639         wait $multipid || error "multiop close failed"
4640
4641         for (( i=0; i < 2; i++ )) ; do
4642                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4643                 [ "$mtime1" = "$mtime2" ] ||
4644                         error "mtime is lost on close: $mtime2, " \
4645                               "should be $mtime1"
4646
4647                 cancel_lru_locks
4648                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4649         done
4650         lctl set_param fail_loc=0
4651         stop_full_debug_logging
4652 }
4653 run_test 39j "write, rename, close, stat ======================="
4654
4655 test_39k() {
4656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4657
4658         touch $DIR1/$tfile
4659         sleep 1
4660
4661         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4662         local multipid=$!
4663         local mtime1=`stat -c %Y $DIR1/$tfile`
4664
4665         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4666
4667         kill -USR1 $multipid
4668         wait $multipid || error "multiop close failed"
4669
4670         for (( i=0; i < 2; i++ )) ; do
4671                 local mtime2=`stat -c %Y $DIR1/$tfile`
4672
4673                 [ "$mtime2" = $TEST_39_MTIME ] || \
4674                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4675
4676                 cancel_lru_locks
4677                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4678         done
4679 }
4680 run_test 39k "write, utime, close, stat ========================"
4681
4682 # this should be set to future
4683 TEST_39_ATIME=`date -d "1 year" +%s`
4684
4685 test_39l() {
4686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4687         remote_mds_nodsh && skip "remote MDS with nodsh"
4688
4689         local atime_diff=$(do_facet $SINGLEMDS \
4690                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4691         rm -rf $DIR/$tdir
4692         mkdir -p $DIR/$tdir
4693
4694         # test setting directory atime to future
4695         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4696         local atime=$(stat -c %X $DIR/$tdir)
4697         [ "$atime" = $TEST_39_ATIME ] ||
4698                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4699
4700         # test setting directory atime from future to now
4701         local now=$(date +%s)
4702         touch -a -d @$now $DIR/$tdir
4703
4704         atime=$(stat -c %X $DIR/$tdir)
4705         [ "$atime" -eq "$now"  ] ||
4706                 error "atime is not updated from future: $atime, $now"
4707
4708         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4709         sleep 3
4710
4711         # test setting directory atime when now > dir atime + atime_diff
4712         local d1=$(date +%s)
4713         ls $DIR/$tdir
4714         local d2=$(date +%s)
4715         cancel_lru_locks mdc
4716         atime=$(stat -c %X $DIR/$tdir)
4717         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4718                 error "atime is not updated  : $atime, should be $d2"
4719
4720         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4721         sleep 3
4722
4723         # test not setting directory atime when now < dir atime + atime_diff
4724         ls $DIR/$tdir
4725         cancel_lru_locks mdc
4726         atime=$(stat -c %X $DIR/$tdir)
4727         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4728                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4729
4730         do_facet $SINGLEMDS \
4731                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4732 }
4733 run_test 39l "directory atime update ==========================="
4734
4735 test_39m() {
4736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4737
4738         touch $DIR1/$tfile
4739         sleep 2
4740         local far_past_mtime=$(date -d "May 29 1953" +%s)
4741         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4742
4743         touch -m -d @$far_past_mtime $DIR1/$tfile
4744         touch -a -d @$far_past_atime $DIR1/$tfile
4745
4746         for (( i=0; i < 2; i++ )) ; do
4747                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4748                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4749                         error "atime or mtime set incorrectly"
4750
4751                 cancel_lru_locks $OSC
4752                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4753         done
4754 }
4755 run_test 39m "test atime and mtime before 1970"
4756
4757 test_39n() { # LU-3832
4758         remote_mds_nodsh && skip "remote MDS with nodsh"
4759
4760         local atime_diff=$(do_facet $SINGLEMDS \
4761                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4762         local atime0
4763         local atime1
4764         local atime2
4765
4766         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4767
4768         rm -rf $DIR/$tfile
4769         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4770         atime0=$(stat -c %X $DIR/$tfile)
4771
4772         sleep 5
4773         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4774         atime1=$(stat -c %X $DIR/$tfile)
4775
4776         sleep 5
4777         cancel_lru_locks mdc
4778         cancel_lru_locks osc
4779         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4780         atime2=$(stat -c %X $DIR/$tfile)
4781
4782         do_facet $SINGLEMDS \
4783                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4784
4785         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4786         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4787 }
4788 run_test 39n "check that O_NOATIME is honored"
4789
4790 test_39o() {
4791         TESTDIR=$DIR/$tdir/$tfile
4792         [ -e $TESTDIR ] && rm -rf $TESTDIR
4793         mkdir -p $TESTDIR
4794         cd $TESTDIR
4795         links1=2
4796         ls
4797         mkdir a b
4798         ls
4799         links2=$(stat -c %h .)
4800         [ $(($links1 + 2)) != $links2 ] &&
4801                 error "wrong links count $(($links1 + 2)) != $links2"
4802         rmdir b
4803         links3=$(stat -c %h .)
4804         [ $(($links1 + 1)) != $links3 ] &&
4805                 error "wrong links count $links1 != $links3"
4806         return 0
4807 }
4808 run_test 39o "directory cached attributes updated after create"
4809
4810 test_39p() {
4811         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4812
4813         local MDTIDX=1
4814         TESTDIR=$DIR/$tdir/$tdir
4815         [ -e $TESTDIR ] && rm -rf $TESTDIR
4816         test_mkdir -p $TESTDIR
4817         cd $TESTDIR
4818         links1=2
4819         ls
4820         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4821         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4822         ls
4823         links2=$(stat -c %h .)
4824         [ $(($links1 + 2)) != $links2 ] &&
4825                 error "wrong links count $(($links1 + 2)) != $links2"
4826         rmdir remote_dir2
4827         links3=$(stat -c %h .)
4828         [ $(($links1 + 1)) != $links3 ] &&
4829                 error "wrong links count $links1 != $links3"
4830         return 0
4831 }
4832 run_test 39p "remote directory cached attributes updated after create ========"
4833
4834 test_39r() {
4835         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4836                 skip "no atime update on old OST"
4837         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4838                 skip_env "ldiskfs only test"
4839         fi
4840
4841         local saved_adiff
4842         saved_adiff=$(do_facet ost1 \
4843                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4844         stack_trap "do_facet ost1 \
4845                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4846
4847         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4848
4849         $LFS setstripe -i 0 $DIR/$tfile
4850         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4851                 error "can't write initial file"
4852         cancel_lru_locks osc
4853
4854         # exceed atime_diff and access file
4855         sleep 6
4856         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4857                 error "can't udpate atime"
4858
4859         local atime_cli=$(stat -c %X $DIR/$tfile)
4860         echo "client atime: $atime_cli"
4861         # allow atime update to be written to device
4862         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4863         sleep 5
4864
4865         local ostdev=$(ostdevname 1)
4866         local fid=($(lfs getstripe -y $DIR/$tfile |
4867                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4868         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4869         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4870
4871         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4872         local atime_ost=$(do_facet ost1 "$cmd" |&
4873                           awk -F'[: ]' '/atime:/ { print $4 }')
4874         (( atime_cli == atime_ost )) ||
4875                 error "atime on client $atime_cli != ost $atime_ost"
4876 }
4877 run_test 39r "lazy atime update on OST"
4878
4879 test_39q() { # LU-8041
4880         local testdir=$DIR/$tdir
4881         mkdir -p $testdir
4882         multiop_bg_pause $testdir D_c || error "multiop failed"
4883         local multipid=$!
4884         cancel_lru_locks mdc
4885         kill -USR1 $multipid
4886         local atime=$(stat -c %X $testdir)
4887         [ "$atime" -ne 0 ] || error "atime is zero"
4888 }
4889 run_test 39q "close won't zero out atime"
4890
4891 test_40() {
4892         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4893         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4894                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4895         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4896                 error "$tfile is not 4096 bytes in size"
4897 }
4898 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4899
4900 test_41() {
4901         # bug 1553
4902         small_write $DIR/f41 18
4903 }
4904 run_test 41 "test small file write + fstat ====================="
4905
4906 count_ost_writes() {
4907         lctl get_param -n ${OSC}.*.stats |
4908                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4909                         END { printf("%0.0f", writes) }'
4910 }
4911
4912 # decent default
4913 WRITEBACK_SAVE=500
4914 DIRTY_RATIO_SAVE=40
4915 MAX_DIRTY_RATIO=50
4916 BG_DIRTY_RATIO_SAVE=10
4917 MAX_BG_DIRTY_RATIO=25
4918
4919 start_writeback() {
4920         trap 0
4921         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4922         # dirty_ratio, dirty_background_ratio
4923         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4924                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4925                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4926                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4927         else
4928                 # if file not here, we are a 2.4 kernel
4929                 kill -CONT `pidof kupdated`
4930         fi
4931 }
4932
4933 stop_writeback() {
4934         # setup the trap first, so someone cannot exit the test at the
4935         # exact wrong time and mess up a machine
4936         trap start_writeback EXIT
4937         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4938         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4939                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4940                 sysctl -w vm.dirty_writeback_centisecs=0
4941                 sysctl -w vm.dirty_writeback_centisecs=0
4942                 # save and increase /proc/sys/vm/dirty_ratio
4943                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4944                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4945                 # save and increase /proc/sys/vm/dirty_background_ratio
4946                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4947                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4948         else
4949                 # if file not here, we are a 2.4 kernel
4950                 kill -STOP `pidof kupdated`
4951         fi
4952 }
4953
4954 # ensure that all stripes have some grant before we test client-side cache
4955 setup_test42() {
4956         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4957                 dd if=/dev/zero of=$i bs=4k count=1
4958                 rm $i
4959         done
4960 }
4961
4962 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4963 # file truncation, and file removal.
4964 test_42a() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         setup_test42
4968         cancel_lru_locks $OSC
4969         stop_writeback
4970         sync; sleep 1; sync # just to be safe
4971         BEFOREWRITES=`count_ost_writes`
4972         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4973         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4974         AFTERWRITES=`count_ost_writes`
4975         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4976                 error "$BEFOREWRITES < $AFTERWRITES"
4977         start_writeback
4978 }
4979 run_test 42a "ensure that we don't flush on close"
4980
4981 test_42b() {
4982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4983
4984         setup_test42
4985         cancel_lru_locks $OSC
4986         stop_writeback
4987         sync
4988         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4989         BEFOREWRITES=$(count_ost_writes)
4990         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4991         AFTERWRITES=$(count_ost_writes)
4992         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4993                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4994         fi
4995         BEFOREWRITES=$(count_ost_writes)
4996         sync || error "sync: $?"
4997         AFTERWRITES=$(count_ost_writes)
4998         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4999                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5000         fi
5001         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5002         start_writeback
5003         return 0
5004 }
5005 run_test 42b "test destroy of file with cached dirty data ======"
5006
5007 # if these tests just want to test the effect of truncation,
5008 # they have to be very careful.  consider:
5009 # - the first open gets a {0,EOF}PR lock
5010 # - the first write conflicts and gets a {0, count-1}PW
5011 # - the rest of the writes are under {count,EOF}PW
5012 # - the open for truncate tries to match a {0,EOF}PR
5013 #   for the filesize and cancels the PWs.
5014 # any number of fixes (don't get {0,EOF} on open, match
5015 # composite locks, do smarter file size management) fix
5016 # this, but for now we want these tests to verify that
5017 # the cancellation with truncate intent works, so we
5018 # start the file with a full-file pw lock to match against
5019 # until the truncate.
5020 trunc_test() {
5021         test=$1
5022         file=$DIR/$test
5023         offset=$2
5024         cancel_lru_locks $OSC
5025         stop_writeback
5026         # prime the file with 0,EOF PW to match
5027         touch $file
5028         $TRUNCATE $file 0
5029         sync; sync
5030         # now the real test..
5031         dd if=/dev/zero of=$file bs=1024 count=100
5032         BEFOREWRITES=`count_ost_writes`
5033         $TRUNCATE $file $offset
5034         cancel_lru_locks $OSC
5035         AFTERWRITES=`count_ost_writes`
5036         start_writeback
5037 }
5038
5039 test_42c() {
5040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5041
5042         trunc_test 42c 1024
5043         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5044                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5045         rm $file
5046 }
5047 run_test 42c "test partial truncate of file with cached dirty data"
5048
5049 test_42d() {
5050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5051
5052         trunc_test 42d 0
5053         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5054                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5055         rm $file
5056 }
5057 run_test 42d "test complete truncate of file with cached dirty data"
5058
5059 test_42e() { # bug22074
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         local TDIR=$DIR/${tdir}e
5063         local pages=16 # hardcoded 16 pages, don't change it.
5064         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5065         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5066         local max_dirty_mb
5067         local warmup_files
5068
5069         test_mkdir $DIR/${tdir}e
5070         $LFS setstripe -c 1 $TDIR
5071         createmany -o $TDIR/f $files
5072
5073         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5074
5075         # we assume that with $OSTCOUNT files, at least one of them will
5076         # be allocated on OST0.
5077         warmup_files=$((OSTCOUNT * max_dirty_mb))
5078         createmany -o $TDIR/w $warmup_files
5079
5080         # write a large amount of data into one file and sync, to get good
5081         # avail_grant number from OST.
5082         for ((i=0; i<$warmup_files; i++)); do
5083                 idx=$($LFS getstripe -i $TDIR/w$i)
5084                 [ $idx -ne 0 ] && continue
5085                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5086                 break
5087         done
5088         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5089         sync
5090         $LCTL get_param $proc_osc0/cur_dirty_bytes
5091         $LCTL get_param $proc_osc0/cur_grant_bytes
5092
5093         # create as much dirty pages as we can while not to trigger the actual
5094         # RPCs directly. but depends on the env, VFS may trigger flush during this
5095         # period, hopefully we are good.
5096         for ((i=0; i<$warmup_files; i++)); do
5097                 idx=$($LFS getstripe -i $TDIR/w$i)
5098                 [ $idx -ne 0 ] && continue
5099                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5100         done
5101         $LCTL get_param $proc_osc0/cur_dirty_bytes
5102         $LCTL get_param $proc_osc0/cur_grant_bytes
5103
5104         # perform the real test
5105         $LCTL set_param $proc_osc0/rpc_stats 0
5106         for ((;i<$files; i++)); do
5107                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5108                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5109         done
5110         sync
5111         $LCTL get_param $proc_osc0/rpc_stats
5112
5113         local percent=0
5114         local have_ppr=false
5115         $LCTL get_param $proc_osc0/rpc_stats |
5116                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5117                         # skip lines until we are at the RPC histogram data
5118                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5119                         $have_ppr || continue
5120
5121                         # we only want the percent stat for < 16 pages
5122                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5123
5124                         percent=$((percent + WPCT))
5125                         if [[ $percent -gt 15 ]]; then
5126                                 error "less than 16-pages write RPCs" \
5127                                       "$percent% > 15%"
5128                                 break
5129                         fi
5130                 done
5131         rm -rf $TDIR
5132 }
5133 run_test 42e "verify sub-RPC writes are not done synchronously"
5134
5135 test_43A() { # was test_43
5136         test_mkdir $DIR/$tdir
5137         cp -p /bin/ls $DIR/$tdir/$tfile
5138         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5139         pid=$!
5140         # give multiop a chance to open
5141         sleep 1
5142
5143         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5144         kill -USR1 $pid
5145         # Wait for multiop to exit
5146         wait $pid
5147 }
5148 run_test 43A "execution of file opened for write should return -ETXTBSY"
5149
5150 test_43a() {
5151         test_mkdir $DIR/$tdir
5152         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5153         $DIR/$tdir/sleep 60 &
5154         SLEEP_PID=$!
5155         # Make sure exec of $tdir/sleep wins race with truncate
5156         sleep 1
5157         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5158         kill $SLEEP_PID
5159 }
5160 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5161
5162 test_43b() {
5163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5164
5165         test_mkdir $DIR/$tdir
5166         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5167         $DIR/$tdir/sleep 60 &
5168         SLEEP_PID=$!
5169         # Make sure exec of $tdir/sleep wins race with truncate
5170         sleep 1
5171         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5172         kill $SLEEP_PID
5173 }
5174 run_test 43b "truncate of file being executed should return -ETXTBSY"
5175
5176 test_43c() {
5177         local testdir="$DIR/$tdir"
5178         test_mkdir $testdir
5179         cp $SHELL $testdir/
5180         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5181                 ( cd $testdir && md5sum -c )
5182 }
5183 run_test 43c "md5sum of copy into lustre"
5184
5185 test_44A() { # was test_44
5186         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5187
5188         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5189         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5190 }
5191 run_test 44A "zero length read from a sparse stripe"
5192
5193 test_44a() {
5194         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
5195                 awk '{ print $2 }')
5196         [ -z "$nstripe" ] && skip "can't get stripe info"
5197         [[ $nstripe -gt $OSTCOUNT ]] &&
5198                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5199
5200         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
5201                 awk '{ print $2 }')
5202         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5203                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
5204                         awk '{ print $2 }')
5205         fi
5206
5207         OFFSETS="0 $((stride/2)) $((stride-1))"
5208         for offset in $OFFSETS; do
5209                 for i in $(seq 0 $((nstripe-1))); do
5210                         local GLOBALOFFSETS=""
5211                         # size in Bytes
5212                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5213                         local myfn=$DIR/d44a-$size
5214                         echo "--------writing $myfn at $size"
5215                         ll_sparseness_write $myfn $size ||
5216                                 error "ll_sparseness_write"
5217                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5218                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5219                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5220
5221                         for j in $(seq 0 $((nstripe-1))); do
5222                                 # size in Bytes
5223                                 size=$((((j + $nstripe )*$stride + $offset)))
5224                                 ll_sparseness_write $myfn $size ||
5225                                         error "ll_sparseness_write"
5226                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5227                         done
5228                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5229                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5230                         rm -f $myfn
5231                 done
5232         done
5233 }
5234 run_test 44a "test sparse pwrite ==============================="
5235
5236 dirty_osc_total() {
5237         tot=0
5238         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5239                 tot=$(($tot + $d))
5240         done
5241         echo $tot
5242 }
5243 do_dirty_record() {
5244         before=`dirty_osc_total`
5245         echo executing "\"$*\""
5246         eval $*
5247         after=`dirty_osc_total`
5248         echo before $before, after $after
5249 }
5250 test_45() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252
5253         f="$DIR/f45"
5254         # Obtain grants from OST if it supports it
5255         echo blah > ${f}_grant
5256         stop_writeback
5257         sync
5258         do_dirty_record "echo blah > $f"
5259         [[ $before -eq $after ]] && error "write wasn't cached"
5260         do_dirty_record "> $f"
5261         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5262         do_dirty_record "echo blah > $f"
5263         [[ $before -eq $after ]] && error "write wasn't cached"
5264         do_dirty_record "sync"
5265         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5266         do_dirty_record "echo blah > $f"
5267         [[ $before -eq $after ]] && error "write wasn't cached"
5268         do_dirty_record "cancel_lru_locks osc"
5269         [[ $before -gt $after ]] ||
5270                 error "lock cancellation didn't lower dirty count"
5271         start_writeback
5272 }
5273 run_test 45 "osc io page accounting ============================"
5274
5275 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5276 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5277 # objects offset and an assert hit when an rpc was built with 1023's mapped
5278 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5279 test_46() {
5280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5281
5282         f="$DIR/f46"
5283         stop_writeback
5284         sync
5285         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5286         sync
5287         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5288         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5289         sync
5290         start_writeback
5291 }
5292 run_test 46 "dirtying a previously written page ================"
5293
5294 # test_47 is removed "Device nodes check" is moved to test_28
5295
5296 test_48a() { # bug 2399
5297         [ "$mds1_FSTYPE" = "zfs" ] &&
5298         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5299                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5300
5301         test_mkdir $DIR/$tdir
5302         cd $DIR/$tdir
5303         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5304         test_mkdir $DIR/$tdir
5305         touch foo || error "'touch foo' failed after recreating cwd"
5306         test_mkdir bar
5307         touch .foo || error "'touch .foo' failed after recreating cwd"
5308         test_mkdir .bar
5309         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5310         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5311         cd . || error "'cd .' failed after recreating cwd"
5312         mkdir . && error "'mkdir .' worked after recreating cwd"
5313         rmdir . && error "'rmdir .' worked after recreating cwd"
5314         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5315         cd .. || error "'cd ..' failed after recreating cwd"
5316 }
5317 run_test 48a "Access renamed working dir (should return errors)="
5318
5319 test_48b() { # bug 2399
5320         rm -rf $DIR/$tdir
5321         test_mkdir $DIR/$tdir
5322         cd $DIR/$tdir
5323         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5324         touch foo && error "'touch foo' worked after removing cwd"
5325         mkdir foo && error "'mkdir foo' worked after removing cwd"
5326         touch .foo && error "'touch .foo' worked after removing cwd"
5327         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5328         ls . > /dev/null && error "'ls .' worked after removing cwd"
5329         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5330         mkdir . && error "'mkdir .' worked after removing cwd"
5331         rmdir . && error "'rmdir .' worked after removing cwd"
5332         ln -s . foo && error "'ln -s .' worked after removing cwd"
5333         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5334 }
5335 run_test 48b "Access removed working dir (should return errors)="
5336
5337 test_48c() { # bug 2350
5338         #lctl set_param debug=-1
5339         #set -vx
5340         rm -rf $DIR/$tdir
5341         test_mkdir -p $DIR/$tdir/dir
5342         cd $DIR/$tdir/dir
5343         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5344         $TRACE touch foo && error "touch foo worked after removing cwd"
5345         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5346         touch .foo && error "touch .foo worked after removing cwd"
5347         mkdir .foo && error "mkdir .foo worked after removing cwd"
5348         $TRACE ls . && error "'ls .' worked after removing cwd"
5349         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5350         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5351         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5352         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5353         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5354 }
5355 run_test 48c "Access removed working subdir (should return errors)"
5356
5357 test_48d() { # bug 2350
5358         #lctl set_param debug=-1
5359         #set -vx
5360         rm -rf $DIR/$tdir
5361         test_mkdir -p $DIR/$tdir/dir
5362         cd $DIR/$tdir/dir
5363         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5364         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5365         $TRACE touch foo && error "'touch foo' worked after removing parent"
5366         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5367         touch .foo && error "'touch .foo' worked after removing parent"
5368         mkdir .foo && error "mkdir .foo worked after removing parent"
5369         $TRACE ls . && error "'ls .' worked after removing parent"
5370         $TRACE ls .. && error "'ls ..' worked after removing parent"
5371         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5372         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5373         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5374         true
5375 }
5376 run_test 48d "Access removed parent subdir (should return errors)"
5377
5378 test_48e() { # bug 4134
5379         #lctl set_param debug=-1
5380         #set -vx
5381         rm -rf $DIR/$tdir
5382         test_mkdir -p $DIR/$tdir/dir
5383         cd $DIR/$tdir/dir
5384         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5385         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5386         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5387         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5388         # On a buggy kernel addition of "touch foo" after cd .. will
5389         # produce kernel oops in lookup_hash_it
5390         touch ../foo && error "'cd ..' worked after recreate parent"
5391         cd $DIR
5392         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5393 }
5394 run_test 48e "Access to recreated parent subdir (should return errors)"
5395
5396 test_48f() {
5397         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5398                 skip "need MDS >= 2.13.55"
5399         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5400         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5401                 skip "needs different host for mdt1 mdt2"
5402         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5403
5404         $LFS mkdir -i0 $DIR/$tdir
5405         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5406
5407         for d in sub1 sub2 sub3; do
5408                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5409                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5410                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5411         done
5412
5413         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5414 }
5415 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5416
5417 test_49() { # LU-1030
5418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5419         remote_ost_nodsh && skip "remote OST with nodsh"
5420
5421         # get ost1 size - $FSNAME-OST0000
5422         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5423                 awk '{ print $4 }')
5424         # write 800M at maximum
5425         [[ $ost1_size -lt 2 ]] && ost1_size=2
5426         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5427
5428         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5429         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5430         local dd_pid=$!
5431
5432         # change max_pages_per_rpc while writing the file
5433         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5434         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5435         # loop until dd process exits
5436         while ps ax -opid | grep -wq $dd_pid; do
5437                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5438                 sleep $((RANDOM % 5 + 1))
5439         done
5440         # restore original max_pages_per_rpc
5441         $LCTL set_param $osc1_mppc=$orig_mppc
5442         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5443 }
5444 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5445
5446 test_50() {
5447         # bug 1485
5448         test_mkdir $DIR/$tdir
5449         cd $DIR/$tdir
5450         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5451 }
5452 run_test 50 "special situations: /proc symlinks  ==============="
5453
5454 test_51a() {    # was test_51
5455         # bug 1516 - create an empty entry right after ".." then split dir
5456         test_mkdir -c1 $DIR/$tdir
5457         touch $DIR/$tdir/foo
5458         $MCREATE $DIR/$tdir/bar
5459         rm $DIR/$tdir/foo
5460         createmany -m $DIR/$tdir/longfile 201
5461         FNUM=202
5462         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5463                 $MCREATE $DIR/$tdir/longfile$FNUM
5464                 FNUM=$(($FNUM + 1))
5465                 echo -n "+"
5466         done
5467         echo
5468         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5469 }
5470 run_test 51a "special situations: split htree with empty entry =="
5471
5472 cleanup_print_lfs_df () {
5473         trap 0
5474         $LFS df
5475         $LFS df -i
5476 }
5477
5478 test_51b() {
5479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5480
5481         local dir=$DIR/$tdir
5482         local nrdirs=$((65536 + 100))
5483
5484         # cleanup the directory
5485         rm -fr $dir
5486
5487         test_mkdir -c1 $dir
5488
5489         $LFS df
5490         $LFS df -i
5491         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5492         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5493         [[ $numfree -lt $nrdirs ]] &&
5494                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5495
5496         # need to check free space for the directories as well
5497         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5498         numfree=$(( blkfree / $(fs_inode_ksize) ))
5499         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5500
5501         trap cleanup_print_lfs_df EXIT
5502
5503         # create files
5504         createmany -d $dir/d $nrdirs || {
5505                 unlinkmany $dir/d $nrdirs
5506                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5507         }
5508
5509         # really created :
5510         nrdirs=$(ls -U $dir | wc -l)
5511
5512         # unlink all but 100 subdirectories, then check it still works
5513         local left=100
5514         local delete=$((nrdirs - left))
5515
5516         $LFS df
5517         $LFS df -i
5518
5519         # for ldiskfs the nlink count should be 1, but this is OSD specific
5520         # and so this is listed for informational purposes only
5521         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5522         unlinkmany -d $dir/d $delete ||
5523                 error "unlink of first $delete subdirs failed"
5524
5525         echo "nlink between: $(stat -c %h $dir)"
5526         local found=$(ls -U $dir | wc -l)
5527         [ $found -ne $left ] &&
5528                 error "can't find subdirs: found only $found, expected $left"
5529
5530         unlinkmany -d $dir/d $delete $left ||
5531                 error "unlink of second $left subdirs failed"
5532         # regardless of whether the backing filesystem tracks nlink accurately
5533         # or not, the nlink count shouldn't be more than "." and ".." here
5534         local after=$(stat -c %h $dir)
5535         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5536                 echo "nlink after: $after"
5537
5538         cleanup_print_lfs_df
5539 }
5540 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5541
5542 test_51d() {
5543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5544         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5545
5546         test_mkdir $DIR/$tdir
5547         createmany -o $DIR/$tdir/t- 1000
5548         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5549         for N in $(seq 0 $((OSTCOUNT - 1))); do
5550                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5551                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5552                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5553                         '($1 == '$N') { objs += 1 } \
5554                         END { printf("%0.0f", objs) }')
5555                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5556         done
5557         unlinkmany $DIR/$tdir/t- 1000
5558
5559         NLAST=0
5560         for N in $(seq 1 $((OSTCOUNT - 1))); do
5561                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5562                         error "OST $N has less objects vs OST $NLAST" \
5563                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5564                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5565                         error "OST $N has less objects vs OST $NLAST" \
5566                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5567
5568                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5569                         error "OST $N has less #0 objects vs OST $NLAST" \
5570                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5571                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5572                         error "OST $N has less #0 objects vs OST $NLAST" \
5573                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5574                 NLAST=$N
5575         done
5576         rm -f $TMP/$tfile
5577 }
5578 run_test 51d "check object distribution"
5579
5580 test_51e() {
5581         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5582                 skip_env "ldiskfs only test"
5583         fi
5584
5585         test_mkdir -c1 $DIR/$tdir
5586         test_mkdir -c1 $DIR/$tdir/d0
5587
5588         touch $DIR/$tdir/d0/foo
5589         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5590                 error "file exceed 65000 nlink limit!"
5591         unlinkmany $DIR/$tdir/d0/f- 65001
5592         return 0
5593 }
5594 run_test 51e "check file nlink limit"
5595
5596 test_51f() {
5597         test_mkdir $DIR/$tdir
5598
5599         local max=100000
5600         local ulimit_old=$(ulimit -n)
5601         local spare=20 # number of spare fd's for scripts/libraries, etc.
5602         local mdt=$($LFS getstripe -m $DIR/$tdir)
5603         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5604
5605         echo "MDT$mdt numfree=$numfree, max=$max"
5606         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5607         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5608                 while ! ulimit -n $((numfree + spare)); do
5609                         numfree=$((numfree * 3 / 4))
5610                 done
5611                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5612         else
5613                 echo "left ulimit at $ulimit_old"
5614         fi
5615
5616         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5617                 unlinkmany $DIR/$tdir/f $numfree
5618                 error "create+open $numfree files in $DIR/$tdir failed"
5619         }
5620         ulimit -n $ulimit_old
5621
5622         # if createmany exits at 120s there will be fewer than $numfree files
5623         unlinkmany $DIR/$tdir/f $numfree || true
5624 }
5625 run_test 51f "check many open files limit"
5626
5627 test_52a() {
5628         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5629         test_mkdir $DIR/$tdir
5630         touch $DIR/$tdir/foo
5631         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5632         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5633         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5634         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5635         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5636                                         error "link worked"
5637         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5638         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5639         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5640                                                      error "lsattr"
5641         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5642         cp -r $DIR/$tdir $TMP/
5643         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5644 }
5645 run_test 52a "append-only flag test (should return errors)"
5646
5647 test_52b() {
5648         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5649         test_mkdir $DIR/$tdir
5650         touch $DIR/$tdir/foo
5651         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5652         cat test > $DIR/$tdir/foo && error "cat test worked"
5653         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5654         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5655         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5656                                         error "link worked"
5657         echo foo >> $DIR/$tdir/foo && error "echo worked"
5658         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5659         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5660         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5661         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5662                                                         error "lsattr"
5663         chattr -i $DIR/$tdir/foo || error "chattr failed"
5664
5665         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5666 }
5667 run_test 52b "immutable flag test (should return errors) ======="
5668
5669 test_53() {
5670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5671         remote_mds_nodsh && skip "remote MDS with nodsh"
5672         remote_ost_nodsh && skip "remote OST with nodsh"
5673
5674         local param
5675         local param_seq
5676         local ostname
5677         local mds_last
5678         local mds_last_seq
5679         local ost_last
5680         local ost_last_seq
5681         local ost_last_id
5682         local ostnum
5683         local node
5684         local found=false
5685         local support_last_seq=true
5686
5687         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5688                 support_last_seq=false
5689
5690         # only test MDT0000
5691         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5692         local value
5693         for value in $(do_facet $SINGLEMDS \
5694                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5695                 param=$(echo ${value[0]} | cut -d "=" -f1)
5696                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5697
5698                 if $support_last_seq; then
5699                         param_seq=$(echo $param |
5700                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5701                         mds_last_seq=$(do_facet $SINGLEMDS \
5702                                        $LCTL get_param -n $param_seq)
5703                 fi
5704                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5705
5706                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5707                 node=$(facet_active_host ost$((ostnum+1)))
5708                 param="obdfilter.$ostname.last_id"
5709                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5710                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5711                         ost_last_id=$ost_last
5712
5713                         if $support_last_seq; then
5714                                 ost_last_id=$(echo $ost_last |
5715                                               awk -F':' '{print $2}' |
5716                                               sed -e "s/^0x//g")
5717                                 ost_last_seq=$(echo $ost_last |
5718                                                awk -F':' '{print $1}')
5719                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5720                         fi
5721
5722                         if [[ $ost_last_id != $mds_last ]]; then
5723                                 error "$ost_last_id != $mds_last"
5724                         else
5725                                 found=true
5726                                 break
5727                         fi
5728                 done
5729         done
5730         $found || error "can not match last_seq/last_id for $mdtosc"
5731         return 0
5732 }
5733 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5734
5735 test_54a() {
5736         perl -MSocket -e ';' || skip "no Socket perl module installed"
5737
5738         $SOCKETSERVER $DIR/socket ||
5739                 error "$SOCKETSERVER $DIR/socket failed: $?"
5740         $SOCKETCLIENT $DIR/socket ||
5741                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5742         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5743 }
5744 run_test 54a "unix domain socket test =========================="
5745
5746 test_54b() {
5747         f="$DIR/f54b"
5748         mknod $f c 1 3
5749         chmod 0666 $f
5750         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5751 }
5752 run_test 54b "char device works in lustre ======================"
5753
5754 find_loop_dev() {
5755         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5756         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5757         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5758
5759         for i in $(seq 3 7); do
5760                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5761                 LOOPDEV=$LOOPBASE$i
5762                 LOOPNUM=$i
5763                 break
5764         done
5765 }
5766
5767 cleanup_54c() {
5768         local rc=0
5769         loopdev="$DIR/loop54c"
5770
5771         trap 0
5772         $UMOUNT $DIR/$tdir || rc=$?
5773         losetup -d $loopdev || true
5774         losetup -d $LOOPDEV || true
5775         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5776         return $rc
5777 }
5778
5779 test_54c() {
5780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5781
5782         loopdev="$DIR/loop54c"
5783
5784         find_loop_dev
5785         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5786         trap cleanup_54c EXIT
5787         mknod $loopdev b 7 $LOOPNUM
5788         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5789         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5790         losetup $loopdev $DIR/$tfile ||
5791                 error "can't set up $loopdev for $DIR/$tfile"
5792         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5793         test_mkdir $DIR/$tdir
5794         mount -t ext2 $loopdev $DIR/$tdir ||
5795                 error "error mounting $loopdev on $DIR/$tdir"
5796         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5797                 error "dd write"
5798         df $DIR/$tdir
5799         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5800                 error "dd read"
5801         cleanup_54c
5802 }
5803 run_test 54c "block device works in lustre ====================="
5804
5805 test_54d() {
5806         f="$DIR/f54d"
5807         string="aaaaaa"
5808         mknod $f p
5809         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5810 }
5811 run_test 54d "fifo device works in lustre ======================"
5812
5813 test_54e() {
5814         f="$DIR/f54e"
5815         string="aaaaaa"
5816         cp -aL /dev/console $f
5817         echo $string > $f || error "echo $string to $f failed"
5818 }
5819 run_test 54e "console/tty device works in lustre ======================"
5820
5821 test_56a() {
5822         local numfiles=3
5823         local dir=$DIR/$tdir
5824
5825         rm -rf $dir
5826         test_mkdir -p $dir/dir
5827         for i in $(seq $numfiles); do
5828                 touch $dir/file$i
5829                 touch $dir/dir/file$i
5830         done
5831
5832         local numcomp=$($LFS getstripe --component-count $dir)
5833
5834         [[ $numcomp == 0 ]] && numcomp=1
5835
5836         # test lfs getstripe with --recursive
5837         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5838
5839         [[ $filenum -eq $((numfiles * 2)) ]] ||
5840                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5841         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5842         [[ $filenum -eq $numfiles ]] ||
5843                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5844         echo "$LFS getstripe showed obdidx or l_ost_idx"
5845
5846         # test lfs getstripe with file instead of dir
5847         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5848         [[ $filenum -eq 1 ]] ||
5849                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5850         echo "$LFS getstripe file1 passed"
5851
5852         #test lfs getstripe with --verbose
5853         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5854         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5855                 error "$LFS getstripe --verbose $dir: "\
5856                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5857         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5858                 error "$LFS getstripe $dir: showed lmm_magic"
5859
5860         #test lfs getstripe with -v prints lmm_fid
5861         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5862         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5863                 error "$LFS getstripe -v $dir: "\
5864                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5865         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5866                 error "$LFS getstripe $dir: showed lmm_fid by default"
5867         echo "$LFS getstripe --verbose passed"
5868
5869         #check for FID information
5870         local fid1=$($LFS getstripe --fid $dir/file1)
5871         local fid2=$($LFS getstripe --verbose $dir/file1 |
5872                      awk '/lmm_fid: / { print $2; exit; }')
5873         local fid3=$($LFS path2fid $dir/file1)
5874
5875         [ "$fid1" != "$fid2" ] &&
5876                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5877         [ "$fid1" != "$fid3" ] &&
5878                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5879         echo "$LFS getstripe --fid passed"
5880
5881         #test lfs getstripe with --obd
5882         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5883                 error "$LFS getstripe --obd wrong_uuid: should return error"
5884
5885         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5886
5887         local ostidx=1
5888         local obduuid=$(ostuuid_from_index $ostidx)
5889         local found=$($LFS getstripe -r --obd $obduuid $dir |
5890                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5891
5892         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5893         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5894                 ((filenum--))
5895         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5896                 ((filenum--))
5897
5898         [[ $found -eq $filenum ]] ||
5899                 error "$LFS getstripe --obd: found $found expect $filenum"
5900         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5901                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5902                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5903                 error "$LFS getstripe --obd: should not show file on other obd"
5904         echo "$LFS getstripe --obd passed"
5905 }
5906 run_test 56a "check $LFS getstripe"
5907
5908 test_56b() {
5909         local dir=$DIR/$tdir
5910         local numdirs=3
5911
5912         test_mkdir $dir
5913         for i in $(seq $numdirs); do
5914                 test_mkdir $dir/dir$i
5915         done
5916
5917         # test lfs getdirstripe default mode is non-recursion, which is
5918         # different from lfs getstripe
5919         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5920
5921         [[ $dircnt -eq 1 ]] ||
5922                 error "$LFS getdirstripe: found $dircnt, not 1"
5923         dircnt=$($LFS getdirstripe --recursive $dir |
5924                 grep -c lmv_stripe_count)
5925         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5926                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5927 }
5928 run_test 56b "check $LFS getdirstripe"
5929
5930 test_56c() {
5931         remote_ost_nodsh && skip "remote OST with nodsh"
5932
5933         local ost_idx=0
5934         local ost_name=$(ostname_from_index $ost_idx)
5935         local old_status=$(ost_dev_status $ost_idx)
5936         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5937
5938         [[ -z "$old_status" ]] ||
5939                 skip_env "OST $ost_name is in $old_status status"
5940
5941         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5942         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5943                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5944         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5945                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5946                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5947         fi
5948
5949         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5950                 error "$LFS df -v showing inactive devices"
5951         sleep_maxage
5952
5953         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5954
5955         [[ "$new_status" =~ "D" ]] ||
5956                 error "$ost_name status is '$new_status', missing 'D'"
5957         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5958                 [[ "$new_status" =~ "N" ]] ||
5959                         error "$ost_name status is '$new_status', missing 'N'"
5960         fi
5961         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5962                 [[ "$new_status" =~ "f" ]] ||
5963                         error "$ost_name status is '$new_status', missing 'f'"
5964         fi
5965
5966         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5967         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5968                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5969         [[ -z "$p" ]] && restore_lustre_params < $p || true
5970         sleep_maxage
5971
5972         new_status=$(ost_dev_status $ost_idx)
5973         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5974                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5975         # can't check 'f' as devices may actually be on flash
5976 }
5977 run_test 56c "check 'lfs df' showing device status"
5978
5979 test_56d() {
5980         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5981         local osts=$($LFS df -v $MOUNT | grep -c OST)
5982
5983         $LFS df $MOUNT
5984
5985         (( mdts == MDSCOUNT )) ||
5986                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5987         (( osts == OSTCOUNT )) ||
5988                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5989 }
5990 run_test 56d "'lfs df -v' prints only configured devices"
5991
5992 NUMFILES=3
5993 NUMDIRS=3
5994 setup_56() {
5995         local local_tdir="$1"
5996         local local_numfiles="$2"
5997         local local_numdirs="$3"
5998         local dir_params="$4"
5999         local dir_stripe_params="$5"
6000
6001         if [ ! -d "$local_tdir" ] ; then
6002                 test_mkdir -p $dir_stripe_params $local_tdir
6003                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6004                 for i in $(seq $local_numfiles) ; do
6005                         touch $local_tdir/file$i
6006                 done
6007                 for i in $(seq $local_numdirs) ; do
6008                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6009                         for j in $(seq $local_numfiles) ; do
6010                                 touch $local_tdir/dir$i/file$j
6011                         done
6012                 done
6013         fi
6014 }
6015
6016 setup_56_special() {
6017         local local_tdir=$1
6018         local local_numfiles=$2
6019         local local_numdirs=$3
6020
6021         setup_56 $local_tdir $local_numfiles $local_numdirs
6022
6023         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6024                 for i in $(seq $local_numfiles) ; do
6025                         mknod $local_tdir/loop${i}b b 7 $i
6026                         mknod $local_tdir/null${i}c c 1 3
6027                         ln -s $local_tdir/file1 $local_tdir/link${i}
6028                 done
6029                 for i in $(seq $local_numdirs) ; do
6030                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6031                         mknod $local_tdir/dir$i/null${i}c c 1 3
6032                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6033                 done
6034         fi
6035 }
6036
6037 test_56g() {
6038         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6039         local expected=$(($NUMDIRS + 2))
6040
6041         setup_56 $dir $NUMFILES $NUMDIRS
6042
6043         # test lfs find with -name
6044         for i in $(seq $NUMFILES) ; do
6045                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6046
6047                 [ $nums -eq $expected ] ||
6048                         error "lfs find -name '*$i' $dir wrong: "\
6049                               "found $nums, expected $expected"
6050         done
6051 }
6052 run_test 56g "check lfs find -name"
6053
6054 test_56h() {
6055         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6056         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6057
6058         setup_56 $dir $NUMFILES $NUMDIRS
6059
6060         # test lfs find with ! -name
6061         for i in $(seq $NUMFILES) ; do
6062                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6063
6064                 [ $nums -eq $expected ] ||
6065                         error "lfs find ! -name '*$i' $dir wrong: "\
6066                               "found $nums, expected $expected"
6067         done
6068 }
6069 run_test 56h "check lfs find ! -name"
6070
6071 test_56i() {
6072         local dir=$DIR/$tdir
6073
6074         test_mkdir $dir
6075
6076         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6077         local out=$($cmd)
6078
6079         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6080 }
6081 run_test 56i "check 'lfs find -ost UUID' skips directories"
6082
6083 test_56j() {
6084         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6085
6086         setup_56_special $dir $NUMFILES $NUMDIRS
6087
6088         local expected=$((NUMDIRS + 1))
6089         local cmd="$LFS find -type d $dir"
6090         local nums=$($cmd | wc -l)
6091
6092         [ $nums -eq $expected ] ||
6093                 error "'$cmd' wrong: found $nums, expected $expected"
6094 }
6095 run_test 56j "check lfs find -type d"
6096
6097 test_56k() {
6098         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6099
6100         setup_56_special $dir $NUMFILES $NUMDIRS
6101
6102         local expected=$(((NUMDIRS + 1) * NUMFILES))
6103         local cmd="$LFS find -type f $dir"
6104         local nums=$($cmd | wc -l)
6105
6106         [ $nums -eq $expected ] ||
6107                 error "'$cmd' wrong: found $nums, expected $expected"
6108 }
6109 run_test 56k "check lfs find -type f"
6110
6111 test_56l() {
6112         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6113
6114         setup_56_special $dir $NUMFILES $NUMDIRS
6115
6116         local expected=$((NUMDIRS + NUMFILES))
6117         local cmd="$LFS find -type b $dir"
6118         local nums=$($cmd | wc -l)
6119
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56l "check lfs find -type b"
6124
6125 test_56m() {
6126         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6127
6128         setup_56_special $dir $NUMFILES $NUMDIRS
6129
6130         local expected=$((NUMDIRS + NUMFILES))
6131         local cmd="$LFS find -type c $dir"
6132         local nums=$($cmd | wc -l)
6133         [ $nums -eq $expected ] ||
6134                 error "'$cmd' wrong: found $nums, expected $expected"
6135 }
6136 run_test 56m "check lfs find -type c"
6137
6138 test_56n() {
6139         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6140         setup_56_special $dir $NUMFILES $NUMDIRS
6141
6142         local expected=$((NUMDIRS + NUMFILES))
6143         local cmd="$LFS find -type l $dir"
6144         local nums=$($cmd | wc -l)
6145
6146         [ $nums -eq $expected ] ||
6147                 error "'$cmd' wrong: found $nums, expected $expected"
6148 }
6149 run_test 56n "check lfs find -type l"
6150
6151 test_56o() {
6152         local dir=$DIR/$tdir
6153
6154         setup_56 $dir $NUMFILES $NUMDIRS
6155         utime $dir/file1 > /dev/null || error "utime (1)"
6156         utime $dir/file2 > /dev/null || error "utime (2)"
6157         utime $dir/dir1 > /dev/null || error "utime (3)"
6158         utime $dir/dir2 > /dev/null || error "utime (4)"
6159         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6160         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6161
6162         local expected=4
6163         local nums=$($LFS find -mtime +0 $dir | wc -l)
6164
6165         [ $nums -eq $expected ] ||
6166                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6167
6168         expected=12
6169         cmd="$LFS find -mtime 0 $dir"
6170         nums=$($cmd | wc -l)
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173 }
6174 run_test 56o "check lfs find -mtime for old files"
6175
6176 test_56ob() {
6177         local dir=$DIR/$tdir
6178         local expected=1
6179         local count=0
6180
6181         # just to make sure there is something that won't be found
6182         test_mkdir $dir
6183         touch $dir/$tfile.now
6184
6185         for age in year week day hour min; do
6186                 count=$((count + 1))
6187
6188                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6189                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6190                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6191
6192                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6193                 local nums=$($cmd | wc -l)
6194                 [ $nums -eq $expected ] ||
6195                         error "'$cmd' wrong: found $nums, expected $expected"
6196
6197                 cmd="$LFS find $dir -atime $count${age:0:1}"
6198                 nums=$($cmd | wc -l)
6199                 [ $nums -eq $expected ] ||
6200                         error "'$cmd' wrong: found $nums, expected $expected"
6201         done
6202
6203         sleep 2
6204         cmd="$LFS find $dir -ctime +1s -type f"
6205         nums=$($cmd | wc -l)
6206         (( $nums == $count * 2 + 1)) ||
6207                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6208 }
6209 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6210
6211 test_newerXY_base() {
6212         local x=$1
6213         local y=$2
6214         local dir=$DIR/$tdir
6215         local ref
6216         local negref
6217
6218         if [ $y == "t" ]; then
6219                 if [ $x == "b" ]; then
6220                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6221                 else
6222                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6223                 fi
6224         else
6225                 ref=$DIR/$tfile.newer.$x$y
6226                 touch $ref || error "touch $ref failed"
6227         fi
6228
6229         echo "before = $ref"
6230         sleep 2
6231         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6232         sleep 2
6233         if [ $y == "t" ]; then
6234                 if [ $x == "b" ]; then
6235                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6236                 else
6237                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6238                 fi
6239         else
6240                 negref=$DIR/$tfile.negnewer.$x$y
6241                 touch $negref || error "touch $negref failed"
6242         fi
6243
6244         echo "after = $negref"
6245         local cmd="$LFS find $dir -newer$x$y $ref"
6246         local nums=$(eval $cmd | wc -l)
6247         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6248
6249         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6250                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6251
6252         cmd="$LFS find $dir ! -newer$x$y $negref"
6253         nums=$(eval $cmd | wc -l)
6254         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6255                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6256
6257         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6258         nums=$(eval $cmd | wc -l)
6259         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6260                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6261
6262         rm -rf $DIR/*
6263 }
6264
6265 test_56oc() {
6266         test_newerXY_base "a" "a"
6267         test_newerXY_base "a" "m"
6268         test_newerXY_base "a" "c"
6269         test_newerXY_base "m" "a"
6270         test_newerXY_base "m" "m"
6271         test_newerXY_base "m" "c"
6272         test_newerXY_base "c" "a"
6273         test_newerXY_base "c" "m"
6274         test_newerXY_base "c" "c"
6275
6276         [[ -n "$sles_version" ]] &&
6277                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6278
6279         test_newerXY_base "a" "t"
6280         test_newerXY_base "m" "t"
6281         test_newerXY_base "c" "t"
6282
6283         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6284            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6285                 ! btime_supported && echo "btime unsupported" && return 0
6286
6287         test_newerXY_base "b" "b"
6288         test_newerXY_base "b" "t"
6289 }
6290 run_test 56oc "check lfs find -newerXY work"
6291
6292 btime_supported() {
6293         local dir=$DIR/$tdir
6294         local rc
6295
6296         mkdir -p $dir
6297         touch $dir/$tfile
6298         $LFS find $dir -btime -1d -type f
6299         rc=$?
6300         rm -rf $dir
6301         return $rc
6302 }
6303
6304 test_56od() {
6305         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6306                 ! btime_supported && skip "btime unsupported on MDS"
6307
6308         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6309                 ! btime_supported && skip "btime unsupported on clients"
6310
6311         local dir=$DIR/$tdir
6312         local ref=$DIR/$tfile.ref
6313         local negref=$DIR/$tfile.negref
6314
6315         mkdir $dir || error "mkdir $dir failed"
6316         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6317         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6318         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6319         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6320         touch $ref || error "touch $ref failed"
6321         # sleep 3 seconds at least
6322         sleep 3
6323
6324         local before=$(do_facet mds1 date +%s)
6325         local skew=$(($(date +%s) - before + 1))
6326
6327         if (( skew < 0 && skew > -5 )); then
6328                 sleep $((0 - skew + 1))
6329                 skew=0
6330         fi
6331
6332         # Set the dir stripe params to limit files all on MDT0,
6333         # otherwise we need to calc the max clock skew between
6334         # the client and MDTs.
6335         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6336         sleep 2
6337         touch $negref || error "touch $negref failed"
6338
6339         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6340         local nums=$($cmd | wc -l)
6341         local expected=$(((NUMFILES + 1) * NUMDIRS))
6342
6343         [ $nums -eq $expected ] ||
6344                 error "'$cmd' wrong: found $nums, expected $expected"
6345
6346         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6347         nums=$($cmd | wc -l)
6348         expected=$((NUMFILES + 1))
6349         [ $nums -eq $expected ] ||
6350                 error "'$cmd' wrong: found $nums, expected $expected"
6351
6352         [ $skew -lt 0 ] && return
6353
6354         local after=$(do_facet mds1 date +%s)
6355         local age=$((after - before + 1 + skew))
6356
6357         cmd="$LFS find $dir -btime -${age}s -type f"
6358         nums=$($cmd | wc -l)
6359         expected=$(((NUMFILES + 1) * NUMDIRS))
6360
6361         echo "Clock skew between client and server: $skew, age:$age"
6362         [ $nums -eq $expected ] ||
6363                 error "'$cmd' wrong: found $nums, expected $expected"
6364
6365         expected=$(($NUMDIRS + 1))
6366         cmd="$LFS find $dir -btime -${age}s -type d"
6367         nums=$($cmd | wc -l)
6368         [ $nums -eq $expected ] ||
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370         rm -f $ref $negref || error "Failed to remove $ref $negref"
6371 }
6372 run_test 56od "check lfs find -btime with units"
6373
6374 test_56p() {
6375         [ $RUNAS_ID -eq $UID ] &&
6376                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6377
6378         local dir=$DIR/$tdir
6379
6380         setup_56 $dir $NUMFILES $NUMDIRS
6381         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6382
6383         local expected=$NUMFILES
6384         local cmd="$LFS find -uid $RUNAS_ID $dir"
6385         local nums=$($cmd | wc -l)
6386
6387         [ $nums -eq $expected ] ||
6388                 error "'$cmd' wrong: found $nums, expected $expected"
6389
6390         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6391         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6392         nums=$($cmd | wc -l)
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395 }
6396 run_test 56p "check lfs find -uid and ! -uid"
6397
6398 test_56q() {
6399         [ $RUNAS_ID -eq $UID ] &&
6400                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6401
6402         local dir=$DIR/$tdir
6403
6404         setup_56 $dir $NUMFILES $NUMDIRS
6405         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6406
6407         local expected=$NUMFILES
6408         local cmd="$LFS find -gid $RUNAS_GID $dir"
6409         local nums=$($cmd | wc -l)
6410
6411         [ $nums -eq $expected ] ||
6412                 error "'$cmd' wrong: found $nums, expected $expected"
6413
6414         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6415         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6416         nums=$($cmd | wc -l)
6417         [ $nums -eq $expected ] ||
6418                 error "'$cmd' wrong: found $nums, expected $expected"
6419 }
6420 run_test 56q "check lfs find -gid and ! -gid"
6421
6422 test_56r() {
6423         local dir=$DIR/$tdir
6424
6425         setup_56 $dir $NUMFILES $NUMDIRS
6426
6427         local expected=12
6428         local cmd="$LFS find -size 0 -type f -lazy $dir"
6429         local nums=$($cmd | wc -l)
6430
6431         [ $nums -eq $expected ] ||
6432                 error "'$cmd' wrong: found $nums, expected $expected"
6433         cmd="$LFS find -size 0 -type f $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=0
6439         cmd="$LFS find ! -size 0 -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 0 -type f $dir"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447
6448         echo "test" > $dir/$tfile
6449         echo "test2" > $dir/$tfile.2 && sync
6450         expected=1
6451         cmd="$LFS find -size 5 -type f -lazy $dir"
6452         nums=$($cmd | wc -l)
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455         cmd="$LFS find -size 5 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         expected=1
6461         cmd="$LFS find -size +5 -type f -lazy $dir"
6462         nums=$($cmd | wc -l)
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465         cmd="$LFS find -size +5 -type f $dir"
6466         nums=$($cmd | wc -l)
6467         [ $nums -eq $expected ] ||
6468                 error "'$cmd' wrong: found $nums, expected $expected"
6469
6470         expected=2
6471         cmd="$LFS find -size +0 -type f -lazy $dir"
6472         nums=$($cmd | wc -l)
6473         [ $nums -eq $expected ] ||
6474                 error "'$cmd' wrong: found $nums, expected $expected"
6475         cmd="$LFS find -size +0 -type f $dir"
6476         nums=$($cmd | wc -l)
6477         [ $nums -eq $expected ] ||
6478                 error "'$cmd' wrong: found $nums, expected $expected"
6479
6480         expected=2
6481         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485         cmd="$LFS find ! -size -5 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=12
6491         cmd="$LFS find -size -5 -type f -lazy $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495         cmd="$LFS find -size -5 -type f $dir"
6496         nums=$($cmd | wc -l)
6497         [ $nums -eq $expected ] ||
6498                 error "'$cmd' wrong: found $nums, expected $expected"
6499 }
6500 run_test 56r "check lfs find -size works"
6501
6502 test_56ra_sub() {
6503         local expected=$1
6504         local glimpses=$2
6505         local cmd="$3"
6506
6507         cancel_lru_locks $OSC
6508
6509         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6510         local nums=$($cmd | wc -l)
6511
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6516
6517         if (( rpcs_before + glimpses != rpcs_after )); then
6518                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6519                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6520
6521                 if [[ $glimpses == 0 ]]; then
6522                         error "'$cmd' should not send glimpse RPCs to OST"
6523                 else
6524                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6525                 fi
6526         fi
6527 }
6528
6529 test_56ra() {
6530         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6531                 skip "MDS < 2.12.58 doesn't return LSOM data"
6532         local dir=$DIR/$tdir
6533         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6534
6535         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6536
6537         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6538         $LCTL set_param -n llite.*.statahead_agl=0
6539         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6540
6541         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6542         # open and close all files to ensure LSOM is updated
6543         cancel_lru_locks $OSC
6544         find $dir -type f | xargs cat > /dev/null
6545
6546         #   expect_found  glimpse_rpcs  command_to_run
6547         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6548         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6549         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6550         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6551
6552         echo "test" > $dir/$tfile
6553         echo "test2" > $dir/$tfile.2 && sync
6554         cancel_lru_locks $OSC
6555         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6556
6557         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6558         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6559         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6560         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6561
6562         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6563         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6564         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6565         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6566         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6567         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6568 }
6569 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6570
6571 test_56rb() {
6572         local dir=$DIR/$tdir
6573         local tmp=$TMP/$tfile.log
6574         local mdt_idx;
6575
6576         test_mkdir -p $dir || error "failed to mkdir $dir"
6577         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6578                 error "failed to setstripe $dir/$tfile"
6579         mdt_idx=$($LFS getdirstripe -i $dir)
6580         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6581
6582         stack_trap "rm -f $tmp" EXIT
6583         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6584         ! grep -q obd_uuid $tmp ||
6585                 error "failed to find --size +100K --ost 0 $dir"
6586         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6587         ! grep -q obd_uuid $tmp ||
6588                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6589 }
6590 run_test 56rb "check lfs find --size --ost/--mdt works"
6591
6592 test_56s() { # LU-611 #LU-9369
6593         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6594
6595         local dir=$DIR/$tdir
6596         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6597
6598         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6599         for i in $(seq $NUMDIRS); do
6600                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6601         done
6602
6603         local expected=$NUMDIRS
6604         local cmd="$LFS find -c $OSTCOUNT $dir"
6605         local nums=$($cmd | wc -l)
6606
6607         [ $nums -eq $expected ] || {
6608                 $LFS getstripe -R $dir
6609                 error "'$cmd' wrong: found $nums, expected $expected"
6610         }
6611
6612         expected=$((NUMDIRS + onestripe))
6613         cmd="$LFS find -stripe-count +0 -type f $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] || {
6616                 $LFS getstripe -R $dir
6617                 error "'$cmd' wrong: found $nums, expected $expected"
6618         }
6619
6620         expected=$onestripe
6621         cmd="$LFS find -stripe-count 1 -type f $dir"
6622         nums=$($cmd | wc -l)
6623         [ $nums -eq $expected ] || {
6624                 $LFS getstripe -R $dir
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626         }
6627
6628         cmd="$LFS find -stripe-count -2 -type f $dir"
6629         nums=$($cmd | wc -l)
6630         [ $nums -eq $expected ] || {
6631                 $LFS getstripe -R $dir
6632                 error "'$cmd' wrong: found $nums, expected $expected"
6633         }
6634
6635         expected=0
6636         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6637         nums=$($cmd | wc -l)
6638         [ $nums -eq $expected ] || {
6639                 $LFS getstripe -R $dir
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641         }
6642 }
6643 run_test 56s "check lfs find -stripe-count works"
6644
6645 test_56t() { # LU-611 #LU-9369
6646         local dir=$DIR/$tdir
6647
6648         setup_56 $dir 0 $NUMDIRS
6649         for i in $(seq $NUMDIRS); do
6650                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6651         done
6652
6653         local expected=$NUMDIRS
6654         local cmd="$LFS find -S 8M $dir"
6655         local nums=$($cmd | wc -l)
6656
6657         [ $nums -eq $expected ] || {
6658                 $LFS getstripe -R $dir
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660         }
6661         rm -rf $dir
6662
6663         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6664
6665         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6666
6667         expected=$(((NUMDIRS + 1) * NUMFILES))
6668         cmd="$LFS find -stripe-size 512k -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=$(((NUMDIRS + 1) * NUMFILES + 4))
6679         cmd="$LFS find -stripe-size +200k -type f $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] ||
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683
6684         cmd="$LFS find -stripe-size -640k -type f $dir"
6685         nums=$($cmd | wc -l)
6686         [ $nums -eq $expected ] ||
6687                 error "'$cmd' wrong: found $nums, expected $expected"
6688
6689         expected=4
6690         cmd="$LFS find -stripe-size 256k -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         cmd="$LFS find -stripe-size -320k -type f $dir"
6696         nums=$($cmd | wc -l)
6697         [ $nums -eq $expected ] ||
6698                 error "'$cmd' wrong: found $nums, expected $expected"
6699
6700         expected=0
6701         cmd="$LFS find -stripe-size 1024k -type f $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] ||
6704                 error "'$cmd' wrong: found $nums, expected $expected"
6705 }
6706 run_test 56t "check lfs find -stripe-size works"
6707
6708 test_56u() { # LU-611
6709         local dir=$DIR/$tdir
6710
6711         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6712
6713         if [[ $OSTCOUNT -gt 1 ]]; then
6714                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6715                 onestripe=4
6716         else
6717                 onestripe=0
6718         fi
6719
6720         local expected=$(((NUMDIRS + 1) * NUMFILES))
6721         local cmd="$LFS find -stripe-index 0 -type f $dir"
6722         local nums=$($cmd | wc -l)
6723
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726
6727         expected=$onestripe
6728         cmd="$LFS find -stripe-index 1 -type f $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732
6733         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6734         nums=$($cmd | wc -l)
6735         [ $nums -eq $expected ] ||
6736                 error "'$cmd' wrong: found $nums, expected $expected"
6737
6738         expected=0
6739         # This should produce an error and not return any files
6740         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6741         nums=$($cmd 2>/dev/null | wc -l)
6742         [ $nums -eq $expected ] ||
6743                 error "'$cmd' wrong: found $nums, expected $expected"
6744
6745         if [[ $OSTCOUNT -gt 1 ]]; then
6746                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6747                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6748                 nums=$($cmd | wc -l)
6749                 [ $nums -eq $expected ] ||
6750                         error "'$cmd' wrong: found $nums, expected $expected"
6751         fi
6752 }
6753 run_test 56u "check lfs find -stripe-index works"
6754
6755 test_56v() {
6756         local mdt_idx=0
6757         local dir=$DIR/$tdir
6758
6759         setup_56 $dir $NUMFILES $NUMDIRS
6760
6761         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6762         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6763
6764         for file in $($LFS find -m $UUID $dir); do
6765                 file_midx=$($LFS getstripe -m $file)
6766                 [ $file_midx -eq $mdt_idx ] ||
6767                         error "lfs find -m $UUID != getstripe -m $file_midx"
6768         done
6769 }
6770 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6771
6772 test_56w() {
6773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6775
6776         local dir=$DIR/$tdir
6777
6778         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6779
6780         local stripe_size=$($LFS getstripe -S -d $dir) ||
6781                 error "$LFS getstripe -S -d $dir failed"
6782         stripe_size=${stripe_size%% *}
6783
6784         local file_size=$((stripe_size * OSTCOUNT))
6785         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6786         local required_space=$((file_num * file_size))
6787         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6788                            head -n1)
6789         [[ $free_space -le $((required_space / 1024)) ]] &&
6790                 skip_env "need $required_space, have $free_space kbytes"
6791
6792         local dd_bs=65536
6793         local dd_count=$((file_size / dd_bs))
6794
6795         # write data into the files
6796         local i
6797         local j
6798         local file
6799
6800         for i in $(seq $NUMFILES); do
6801                 file=$dir/file$i
6802                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6803                         error "write data into $file failed"
6804         done
6805         for i in $(seq $NUMDIRS); do
6806                 for j in $(seq $NUMFILES); do
6807                         file=$dir/dir$i/file$j
6808                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6809                                 error "write data into $file failed"
6810                 done
6811         done
6812
6813         # $LFS_MIGRATE will fail if hard link migration is unsupported
6814         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6815                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6816                         error "creating links to $dir/dir1/file1 failed"
6817         fi
6818
6819         local expected=-1
6820
6821         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6822
6823         # lfs_migrate file
6824         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6825
6826         echo "$cmd"
6827         eval $cmd || error "$cmd failed"
6828
6829         check_stripe_count $dir/file1 $expected
6830
6831         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6832         then
6833                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6834                 # OST 1 if it is on OST 0. This file is small enough to
6835                 # be on only one stripe.
6836                 file=$dir/migr_1_ost
6837                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6838                         error "write data into $file failed"
6839                 local obdidx=$($LFS getstripe -i $file)
6840                 local oldmd5=$(md5sum $file)
6841                 local newobdidx=0
6842
6843                 [[ $obdidx -eq 0 ]] && newobdidx=1
6844                 cmd="$LFS migrate -i $newobdidx $file"
6845                 echo $cmd
6846                 eval $cmd || error "$cmd failed"
6847
6848                 local realobdix=$($LFS getstripe -i $file)
6849                 local newmd5=$(md5sum $file)
6850
6851                 [[ $newobdidx -ne $realobdix ]] &&
6852                         error "new OST is different (was=$obdidx, "\
6853                               "wanted=$newobdidx, got=$realobdix)"
6854                 [[ "$oldmd5" != "$newmd5" ]] &&
6855                         error "md5sum differ: $oldmd5, $newmd5"
6856         fi
6857
6858         # lfs_migrate dir
6859         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6860         echo "$cmd"
6861         eval $cmd || error "$cmd failed"
6862
6863         for j in $(seq $NUMFILES); do
6864                 check_stripe_count $dir/dir1/file$j $expected
6865         done
6866
6867         # lfs_migrate works with lfs find
6868         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6869              $LFS_MIGRATE -y -c $expected"
6870         echo "$cmd"
6871         eval $cmd || error "$cmd failed"
6872
6873         for i in $(seq 2 $NUMFILES); do
6874                 check_stripe_count $dir/file$i $expected
6875         done
6876         for i in $(seq 2 $NUMDIRS); do
6877                 for j in $(seq $NUMFILES); do
6878                 check_stripe_count $dir/dir$i/file$j $expected
6879                 done
6880         done
6881 }
6882 run_test 56w "check lfs_migrate -c stripe_count works"
6883
6884 test_56wb() {
6885         local file1=$DIR/$tdir/file1
6886         local create_pool=false
6887         local initial_pool=$($LFS getstripe -p $DIR)
6888         local pool_list=()
6889         local pool=""
6890
6891         echo -n "Creating test dir..."
6892         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6893         echo "done."
6894
6895         echo -n "Creating test file..."
6896         touch $file1 || error "cannot create file"
6897         echo "done."
6898
6899         echo -n "Detecting existing pools..."
6900         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6901
6902         if [ ${#pool_list[@]} -gt 0 ]; then
6903                 echo "${pool_list[@]}"
6904                 for thispool in "${pool_list[@]}"; do
6905                         if [[ -z "$initial_pool" ||
6906                               "$initial_pool" != "$thispool" ]]; then
6907                                 pool="$thispool"
6908                                 echo "Using existing pool '$pool'"
6909                                 break
6910                         fi
6911                 done
6912         else
6913                 echo "none detected."
6914         fi
6915         if [ -z "$pool" ]; then
6916                 pool=${POOL:-testpool}
6917                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6918                 echo -n "Creating pool '$pool'..."
6919                 create_pool=true
6920                 pool_add $pool &> /dev/null ||
6921                         error "pool_add failed"
6922                 echo "done."
6923
6924                 echo -n "Adding target to pool..."
6925                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6926                         error "pool_add_targets failed"
6927                 echo "done."
6928         fi
6929
6930         echo -n "Setting pool using -p option..."
6931         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6932                 error "migrate failed rc = $?"
6933         echo "done."
6934
6935         echo -n "Verifying test file is in pool after migrating..."
6936         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6937                 error "file was not migrated to pool $pool"
6938         echo "done."
6939
6940         echo -n "Removing test file from pool '$pool'..."
6941         # "lfs migrate $file" won't remove the file from the pool
6942         # until some striping information is changed.
6943         $LFS migrate -c 1 $file1 &> /dev/null ||
6944                 error "cannot remove from pool"
6945         [ "$($LFS getstripe -p $file1)" ] &&
6946                 error "pool still set"
6947         echo "done."
6948
6949         echo -n "Setting pool using --pool option..."
6950         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6951                 error "migrate failed rc = $?"
6952         echo "done."
6953
6954         # Clean up
6955         rm -f $file1
6956         if $create_pool; then
6957                 destroy_test_pools 2> /dev/null ||
6958                         error "destroy test pools failed"
6959         fi
6960 }
6961 run_test 56wb "check lfs_migrate pool support"
6962
6963 test_56wc() {
6964         local file1="$DIR/$tdir/file1"
6965         local parent_ssize
6966         local parent_scount
6967         local cur_ssize
6968         local cur_scount
6969         local orig_ssize
6970
6971         echo -n "Creating test dir..."
6972         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6973         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6974                 error "cannot set stripe by '-S 1M -c 1'"
6975         echo "done"
6976
6977         echo -n "Setting initial stripe for test file..."
6978         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6979                 error "cannot set stripe"
6980         cur_ssize=$($LFS getstripe -S "$file1")
6981         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6982         echo "done."
6983
6984         # File currently set to -S 512K -c 1
6985
6986         # Ensure -c and -S options are rejected when -R is set
6987         echo -n "Verifying incompatible options are detected..."
6988         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6989                 error "incompatible -c and -R options not detected"
6990         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6991                 error "incompatible -S and -R options not detected"
6992         echo "done."
6993
6994         # Ensure unrecognized options are passed through to 'lfs migrate'
6995         echo -n "Verifying -S option is passed through to lfs migrate..."
6996         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6997                 error "migration failed"
6998         cur_ssize=$($LFS getstripe -S "$file1")
6999         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7000         echo "done."
7001
7002         # File currently set to -S 1M -c 1
7003
7004         # Ensure long options are supported
7005         echo -n "Verifying long options supported..."
7006         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7007                 error "long option without argument not supported"
7008         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7009                 error "long option with argument not supported"
7010         cur_ssize=$($LFS getstripe -S "$file1")
7011         [ $cur_ssize -eq 524288 ] ||
7012                 error "migrate --stripe-size $cur_ssize != 524288"
7013         echo "done."
7014
7015         # File currently set to -S 512K -c 1
7016
7017         if [ "$OSTCOUNT" -gt 1 ]; then
7018                 echo -n "Verifying explicit stripe count can be set..."
7019                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7020                         error "migrate failed"
7021                 cur_scount=$($LFS getstripe -c "$file1")
7022                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7023                 echo "done."
7024         fi
7025
7026         # File currently set to -S 512K -c 1 or -S 512K -c 2
7027
7028         # Ensure parent striping is used if -R is set, and no stripe
7029         # count or size is specified
7030         echo -n "Setting stripe for parent directory..."
7031         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7032                 error "cannot set stripe '-S 2M -c 1'"
7033         echo "done."
7034
7035         echo -n "Verifying restripe option uses parent stripe settings..."
7036         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7037         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7038         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7039                 error "migrate failed"
7040         cur_ssize=$($LFS getstripe -S "$file1")
7041         [ $cur_ssize -eq $parent_ssize ] ||
7042                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7043         cur_scount=$($LFS getstripe -c "$file1")
7044         [ $cur_scount -eq $parent_scount ] ||
7045                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7046         echo "done."
7047
7048         # File currently set to -S 1M -c 1
7049
7050         # Ensure striping is preserved if -R is not set, and no stripe
7051         # count or size is specified
7052         echo -n "Verifying striping size preserved when not specified..."
7053         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7054         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7055                 error "cannot set stripe on parent directory"
7056         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7057                 error "migrate failed"
7058         cur_ssize=$($LFS getstripe -S "$file1")
7059         [ $cur_ssize -eq $orig_ssize ] ||
7060                 error "migrate by default $cur_ssize != $orig_ssize"
7061         echo "done."
7062
7063         # Ensure file name properly detected when final option has no argument
7064         echo -n "Verifying file name properly detected..."
7065         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7066                 error "file name interpreted as option argument"
7067         echo "done."
7068
7069         # Clean up
7070         rm -f "$file1"
7071 }
7072 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7073
7074 test_56wd() {
7075         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7076
7077         local file1=$DIR/$tdir/file1
7078
7079         echo -n "Creating test dir..."
7080         test_mkdir $DIR/$tdir || error "cannot create dir"
7081         echo "done."
7082
7083         echo -n "Creating test file..."
7084         touch $file1
7085         echo "done."
7086
7087         # Ensure 'lfs migrate' will fail by using a non-existent option,
7088         # and make sure rsync is not called to recover
7089         echo -n "Make sure --no-rsync option works..."
7090         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7091                 grep -q 'refusing to fall back to rsync' ||
7092                 error "rsync was called with --no-rsync set"
7093         echo "done."
7094
7095         # Ensure rsync is called without trying 'lfs migrate' first
7096         echo -n "Make sure --rsync option works..."
7097         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7098                 grep -q 'falling back to rsync' &&
7099                 error "lfs migrate was called with --rsync set"
7100         echo "done."
7101
7102         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7103         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7104                 grep -q 'at the same time' ||
7105                 error "--rsync and --no-rsync accepted concurrently"
7106         echo "done."
7107
7108         # Clean up
7109         rm -f $file1
7110 }
7111 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7112
7113 test_56we() {
7114         local td=$DIR/$tdir
7115         local tf=$td/$tfile
7116
7117         test_mkdir $td || error "cannot create $td"
7118         touch $tf || error "cannot touch $tf"
7119
7120         echo -n "Make sure --non-direct|-D works..."
7121         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7122                 grep -q "lfs migrate --non-direct" ||
7123                 error "--non-direct option cannot work correctly"
7124         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7125                 grep -q "lfs migrate -D" ||
7126                 error "-D option cannot work correctly"
7127         echo "done."
7128 }
7129 run_test 56we "check lfs_migrate --non-direct|-D support"
7130
7131 test_56x() {
7132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7133         check_swap_layouts_support
7134
7135         local dir=$DIR/$tdir
7136         local ref1=/etc/passwd
7137         local file1=$dir/file1
7138
7139         test_mkdir $dir || error "creating dir $dir"
7140         $LFS setstripe -c 2 $file1
7141         cp $ref1 $file1
7142         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7143         stripe=$($LFS getstripe -c $file1)
7144         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7145         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7146
7147         # clean up
7148         rm -f $file1
7149 }
7150 run_test 56x "lfs migration support"
7151
7152 test_56xa() {
7153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7154         check_swap_layouts_support
7155
7156         local dir=$DIR/$tdir/$testnum
7157
7158         test_mkdir -p $dir
7159
7160         local ref1=/etc/passwd
7161         local file1=$dir/file1
7162
7163         $LFS setstripe -c 2 $file1
7164         cp $ref1 $file1
7165         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7166
7167         local stripe=$($LFS getstripe -c $file1)
7168
7169         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7170         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7171
7172         # clean up
7173         rm -f $file1
7174 }
7175 run_test 56xa "lfs migration --block support"
7176
7177 check_migrate_links() {
7178         local dir="$1"
7179         local file1="$dir/file1"
7180         local begin="$2"
7181         local count="$3"
7182         local runas="$4"
7183         local total_count=$(($begin + $count - 1))
7184         local symlink_count=10
7185         local uniq_count=10
7186
7187         if [ ! -f "$file1" ]; then
7188                 echo -n "creating initial file..."
7189                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7190                         error "cannot setstripe initial file"
7191                 echo "done"
7192
7193                 echo -n "creating symlinks..."
7194                 for s in $(seq 1 $symlink_count); do
7195                         ln -s "$file1" "$dir/slink$s" ||
7196                                 error "cannot create symlinks"
7197                 done
7198                 echo "done"
7199
7200                 echo -n "creating nonlinked files..."
7201                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7202                         error "cannot create nonlinked files"
7203                 echo "done"
7204         fi
7205
7206         # create hard links
7207         if [ ! -f "$dir/file$total_count" ]; then
7208                 echo -n "creating hard links $begin:$total_count..."
7209                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7210                         /dev/null || error "cannot create hard links"
7211                 echo "done"
7212         fi
7213
7214         echo -n "checking number of hard links listed in xattrs..."
7215         local fid=$($LFS getstripe -F "$file1")
7216         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7217
7218         echo "${#paths[*]}"
7219         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7220                         skip "hard link list has unexpected size, skipping test"
7221         fi
7222         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7223                         error "link names should exceed xattrs size"
7224         fi
7225
7226         echo -n "migrating files..."
7227         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7228         local rc=$?
7229         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7230         echo "done"
7231
7232         # make sure all links have been properly migrated
7233         echo -n "verifying files..."
7234         fid=$($LFS getstripe -F "$file1") ||
7235                 error "cannot get fid for file $file1"
7236         for i in $(seq 2 $total_count); do
7237                 local fid2=$($LFS getstripe -F $dir/file$i)
7238
7239                 [ "$fid2" == "$fid" ] ||
7240                         error "migrated hard link has mismatched FID"
7241         done
7242
7243         # make sure hard links were properly detected, and migration was
7244         # performed only once for the entire link set; nonlinked files should
7245         # also be migrated
7246         local actual=$(grep -c 'done' <<< "$migrate_out")
7247         local expected=$(($uniq_count + 1))
7248
7249         [ "$actual" -eq  "$expected" ] ||
7250                 error "hard links individually migrated ($actual != $expected)"
7251
7252         # make sure the correct number of hard links are present
7253         local hardlinks=$(stat -c '%h' "$file1")
7254
7255         [ $hardlinks -eq $total_count ] ||
7256                 error "num hard links $hardlinks != $total_count"
7257         echo "done"
7258
7259         return 0
7260 }
7261
7262 test_56xb() {
7263         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7264                 skip "Need MDS version at least 2.10.55"
7265
7266         local dir="$DIR/$tdir"
7267
7268         test_mkdir "$dir" || error "cannot create dir $dir"
7269
7270         echo "testing lfs migrate mode when all links fit within xattrs"
7271         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7272
7273         echo "testing rsync mode when all links fit within xattrs"
7274         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7275
7276         echo "testing lfs migrate mode when all links do not fit within xattrs"
7277         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7278
7279         echo "testing rsync mode when all links do not fit within xattrs"
7280         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7281
7282         chown -R $RUNAS_ID $dir
7283         echo "testing non-root lfs migrate mode when not all links are in xattr"
7284         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7285
7286         # clean up
7287         rm -rf $dir
7288 }
7289 run_test 56xb "lfs migration hard link support"
7290
7291 test_56xc() {
7292         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7293
7294         local dir="$DIR/$tdir"
7295
7296         test_mkdir "$dir" || error "cannot create dir $dir"
7297
7298         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7299         echo -n "Setting initial stripe for 20MB test file..."
7300         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7301                 error "cannot setstripe 20MB file"
7302         echo "done"
7303         echo -n "Sizing 20MB test file..."
7304         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7305         echo "done"
7306         echo -n "Verifying small file autostripe count is 1..."
7307         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7308                 error "cannot migrate 20MB file"
7309         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7310                 error "cannot get stripe for $dir/20mb"
7311         [ $stripe_count -eq 1 ] ||
7312                 error "unexpected stripe count $stripe_count for 20MB file"
7313         rm -f "$dir/20mb"
7314         echo "done"
7315
7316         # Test 2: File is small enough to fit within the available space on
7317         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7318         # have at least an additional 1KB for each desired stripe for test 3
7319         echo -n "Setting stripe for 1GB test file..."
7320         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7321         echo "done"
7322         echo -n "Sizing 1GB test file..."
7323         # File size is 1GB + 3KB
7324         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7325         echo "done"
7326
7327         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7328         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7329         if (( avail > 524288 * OSTCOUNT )); then
7330                 echo -n "Migrating 1GB file..."
7331                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7332                         error "cannot migrate 1GB file"
7333                 echo "done"
7334                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7335                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7336                         error "cannot getstripe for 1GB file"
7337                 [ $stripe_count -eq 2 ] ||
7338                         error "unexpected stripe count $stripe_count != 2"
7339                 echo "done"
7340         fi
7341
7342         # Test 3: File is too large to fit within the available space on
7343         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7344         if [ $OSTCOUNT -ge 3 ]; then
7345                 # The required available space is calculated as
7346                 # file size (1GB + 3KB) / OST count (3).
7347                 local kb_per_ost=349526
7348
7349                 echo -n "Migrating 1GB file with limit..."
7350                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7351                         error "cannot migrate 1GB file with limit"
7352                 echo "done"
7353
7354                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7355                 echo -n "Verifying 1GB autostripe count with limited space..."
7356                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7357                         error "unexpected stripe count $stripe_count (min 3)"
7358                 echo "done"
7359         fi
7360
7361         # clean up
7362         rm -rf $dir
7363 }
7364 run_test 56xc "lfs migration autostripe"
7365
7366 test_56xd() {
7367         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7368
7369         local dir=$DIR/$tdir
7370         local f_mgrt=$dir/$tfile.mgrt
7371         local f_yaml=$dir/$tfile.yaml
7372         local f_copy=$dir/$tfile.copy
7373         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7374         local layout_copy="-c 2 -S 2M -i 1"
7375         local yamlfile=$dir/yamlfile
7376         local layout_before;
7377         local layout_after;
7378
7379         test_mkdir "$dir" || error "cannot create dir $dir"
7380         $LFS setstripe $layout_yaml $f_yaml ||
7381                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7382         $LFS getstripe --yaml $f_yaml > $yamlfile
7383         $LFS setstripe $layout_copy $f_copy ||
7384                 error "cannot setstripe $f_copy with layout $layout_copy"
7385         touch $f_mgrt
7386         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7387
7388         # 1. test option --yaml
7389         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7390                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7391         layout_before=$(get_layout_param $f_yaml)
7392         layout_after=$(get_layout_param $f_mgrt)
7393         [ "$layout_after" == "$layout_before" ] ||
7394                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7395
7396         # 2. test option --copy
7397         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7398                 error "cannot migrate $f_mgrt with --copy $f_copy"
7399         layout_before=$(get_layout_param $f_copy)
7400         layout_after=$(get_layout_param $f_mgrt)
7401         [ "$layout_after" == "$layout_before" ] ||
7402                 error "lfs_migrate --copy: $layout_after != $layout_before"
7403 }
7404 run_test 56xd "check lfs_migrate --yaml and --copy support"
7405
7406 test_56xe() {
7407         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7408
7409         local dir=$DIR/$tdir
7410         local f_comp=$dir/$tfile
7411         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7412         local layout_before=""
7413         local layout_after=""
7414
7415         test_mkdir "$dir" || error "cannot create dir $dir"
7416         $LFS setstripe $layout $f_comp ||
7417                 error "cannot setstripe $f_comp with layout $layout"
7418         layout_before=$(get_layout_param $f_comp)
7419         dd if=/dev/zero of=$f_comp bs=1M count=4
7420
7421         # 1. migrate a comp layout file by lfs_migrate
7422         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7423         layout_after=$(get_layout_param $f_comp)
7424         [ "$layout_before" == "$layout_after" ] ||
7425                 error "lfs_migrate: $layout_before != $layout_after"
7426
7427         # 2. migrate a comp layout file by lfs migrate
7428         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7429         layout_after=$(get_layout_param $f_comp)
7430         [ "$layout_before" == "$layout_after" ] ||
7431                 error "lfs migrate: $layout_before != $layout_after"
7432 }
7433 run_test 56xe "migrate a composite layout file"
7434
7435 test_56xf() {
7436         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7437
7438         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7439                 skip "Need server version at least 2.13.53"
7440
7441         local dir=$DIR/$tdir
7442         local f_comp=$dir/$tfile
7443         local layout="-E 1M -c1 -E -1 -c2"
7444         local fid_before=""
7445         local fid_after=""
7446
7447         test_mkdir "$dir" || error "cannot create dir $dir"
7448         $LFS setstripe $layout $f_comp ||
7449                 error "cannot setstripe $f_comp with layout $layout"
7450         fid_before=$($LFS getstripe --fid $f_comp)
7451         dd if=/dev/zero of=$f_comp bs=1M count=4
7452
7453         # 1. migrate a comp layout file to a comp layout
7454         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7455         fid_after=$($LFS getstripe --fid $f_comp)
7456         [ "$fid_before" == "$fid_after" ] ||
7457                 error "comp-to-comp migrate: $fid_before != $fid_after"
7458
7459         # 2. migrate a comp layout file to a plain layout
7460         $LFS migrate -c2 $f_comp ||
7461                 error "cannot migrate $f_comp by lfs migrate"
7462         fid_after=$($LFS getstripe --fid $f_comp)
7463         [ "$fid_before" == "$fid_after" ] ||
7464                 error "comp-to-plain migrate: $fid_before != $fid_after"
7465
7466         # 3. migrate a plain layout file to a comp layout
7467         $LFS migrate $layout $f_comp ||
7468                 error "cannot migrate $f_comp by lfs migrate"
7469         fid_after=$($LFS getstripe --fid $f_comp)
7470         [ "$fid_before" == "$fid_after" ] ||
7471                 error "plain-to-comp migrate: $fid_before != $fid_after"
7472 }
7473 run_test 56xf "FID is not lost during migration of a composite layout file"
7474
7475 test_56y() {
7476         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7477                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7478
7479         local res=""
7480         local dir=$DIR/$tdir
7481         local f1=$dir/file1
7482         local f2=$dir/file2
7483
7484         test_mkdir -p $dir || error "creating dir $dir"
7485         touch $f1 || error "creating std file $f1"
7486         $MULTIOP $f2 H2c || error "creating released file $f2"
7487
7488         # a directory can be raid0, so ask only for files
7489         res=$($LFS find $dir -L raid0 -type f | wc -l)
7490         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7491
7492         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7493         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7494
7495         # only files can be released, so no need to force file search
7496         res=$($LFS find $dir -L released)
7497         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7498
7499         res=$($LFS find $dir -type f \! -L released)
7500         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7501 }
7502 run_test 56y "lfs find -L raid0|released"
7503
7504 test_56z() { # LU-4824
7505         # This checks to make sure 'lfs find' continues after errors
7506         # There are two classes of errors that should be caught:
7507         # - If multiple paths are provided, all should be searched even if one
7508         #   errors out
7509         # - If errors are encountered during the search, it should not terminate
7510         #   early
7511         local dir=$DIR/$tdir
7512         local i
7513
7514         test_mkdir $dir
7515         for i in d{0..9}; do
7516                 test_mkdir $dir/$i
7517                 touch $dir/$i/$tfile
7518         done
7519         $LFS find $DIR/non_existent_dir $dir &&
7520                 error "$LFS find did not return an error"
7521         # Make a directory unsearchable. This should NOT be the last entry in
7522         # directory order.  Arbitrarily pick the 6th entry
7523         chmod 700 $($LFS find $dir -type d | sed '6!d')
7524
7525         $RUNAS $LFS find $DIR/non_existent $dir
7526         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7527
7528         # The user should be able to see 10 directories and 9 files
7529         (( count == 19 )) ||
7530                 error "$LFS find found $count != 19 entries after error"
7531 }
7532 run_test 56z "lfs find should continue after an error"
7533
7534 test_56aa() { # LU-5937
7535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7536
7537         local dir=$DIR/$tdir
7538
7539         mkdir $dir
7540         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7541
7542         createmany -o $dir/striped_dir/${tfile}- 1024
7543         local dirs=$($LFS find --size +8k $dir/)
7544
7545         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7546 }
7547 run_test 56aa "lfs find --size under striped dir"
7548
7549 test_56ab() { # LU-10705
7550         test_mkdir $DIR/$tdir
7551         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7552         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7553         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7554         # Flush writes to ensure valid blocks.  Need to be more thorough for
7555         # ZFS, since blocks are not allocated/returned to client immediately.
7556         sync_all_data
7557         wait_zfs_commit ost1 2
7558         cancel_lru_locks osc
7559         ls -ls $DIR/$tdir
7560
7561         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7562
7563         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7564
7565         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7566         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7567
7568         rm -f $DIR/$tdir/$tfile.[123]
7569 }
7570 run_test 56ab "lfs find --blocks"
7571
7572 test_56ba() {
7573         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7574                 skip "Need MDS version at least 2.10.50"
7575
7576         # Create composite files with one component
7577         local dir=$DIR/$tdir
7578
7579         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7580         # Create composite files with three components
7581         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7582         # Create non-composite files
7583         createmany -o $dir/${tfile}- 10
7584
7585         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7586
7587         [[ $nfiles == 10 ]] ||
7588                 error "lfs find -E 1M found $nfiles != 10 files"
7589
7590         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7591         [[ $nfiles == 25 ]] ||
7592                 error "lfs find ! -E 1M found $nfiles != 25 files"
7593
7594         # All files have a component that starts at 0
7595         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7596         [[ $nfiles == 35 ]] ||
7597                 error "lfs find --component-start 0 - $nfiles != 35 files"
7598
7599         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7600         [[ $nfiles == 15 ]] ||
7601                 error "lfs find --component-start 2M - $nfiles != 15 files"
7602
7603         # All files created here have a componenet that does not starts at 2M
7604         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7605         [[ $nfiles == 35 ]] ||
7606                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7607
7608         # Find files with a specified number of components
7609         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7610         [[ $nfiles == 15 ]] ||
7611                 error "lfs find --component-count 3 - $nfiles != 15 files"
7612
7613         # Remember non-composite files have a component count of zero
7614         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7615         [[ $nfiles == 10 ]] ||
7616                 error "lfs find --component-count 0 - $nfiles != 10 files"
7617
7618         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7619         [[ $nfiles == 20 ]] ||
7620                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7621
7622         # All files have a flag called "init"
7623         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7624         [[ $nfiles == 35 ]] ||
7625                 error "lfs find --component-flags init - $nfiles != 35 files"
7626
7627         # Multi-component files will have a component not initialized
7628         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7629         [[ $nfiles == 15 ]] ||
7630                 error "lfs find !--component-flags init - $nfiles != 15 files"
7631
7632         rm -rf $dir
7633
7634 }
7635 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7636
7637 test_56ca() {
7638         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7639                 skip "Need MDS version at least 2.10.57"
7640
7641         local td=$DIR/$tdir
7642         local tf=$td/$tfile
7643         local dir
7644         local nfiles
7645         local cmd
7646         local i
7647         local j
7648
7649         # create mirrored directories and mirrored files
7650         mkdir $td || error "mkdir $td failed"
7651         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7652         createmany -o $tf- 10 || error "create $tf- failed"
7653
7654         for i in $(seq 2); do
7655                 dir=$td/dir$i
7656                 mkdir $dir || error "mkdir $dir failed"
7657                 $LFS mirror create -N$((3 + i)) $dir ||
7658                         error "create mirrored dir $dir failed"
7659                 createmany -o $dir/$tfile- 10 ||
7660                         error "create $dir/$tfile- failed"
7661         done
7662
7663         # change the states of some mirrored files
7664         echo foo > $tf-6
7665         for i in $(seq 2); do
7666                 dir=$td/dir$i
7667                 for j in $(seq 4 9); do
7668                         echo foo > $dir/$tfile-$j
7669                 done
7670         done
7671
7672         # find mirrored files with specific mirror count
7673         cmd="$LFS find --mirror-count 3 --type f $td"
7674         nfiles=$($cmd | wc -l)
7675         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7676
7677         cmd="$LFS find ! --mirror-count 3 --type f $td"
7678         nfiles=$($cmd | wc -l)
7679         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7680
7681         cmd="$LFS find --mirror-count +2 --type f $td"
7682         nfiles=$($cmd | wc -l)
7683         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7684
7685         cmd="$LFS find --mirror-count -6 --type f $td"
7686         nfiles=$($cmd | wc -l)
7687         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7688
7689         # find mirrored files with specific file state
7690         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7691         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7692
7693         cmd="$LFS find --mirror-state=ro --type f $td"
7694         nfiles=$($cmd | wc -l)
7695         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7696
7697         cmd="$LFS find ! --mirror-state=ro --type f $td"
7698         nfiles=$($cmd | wc -l)
7699         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7700
7701         cmd="$LFS find --mirror-state=wp --type f $td"
7702         nfiles=$($cmd | wc -l)
7703         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7704
7705         cmd="$LFS find ! --mirror-state=sp --type f $td"
7706         nfiles=$($cmd | wc -l)
7707         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7708 }
7709 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7710
7711 test_57a() {
7712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7713         # note test will not do anything if MDS is not local
7714         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7715                 skip_env "ldiskfs only test"
7716         fi
7717         remote_mds_nodsh && skip "remote MDS with nodsh"
7718
7719         local MNTDEV="osd*.*MDT*.mntdev"
7720         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7721         [ -z "$DEV" ] && error "can't access $MNTDEV"
7722         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7723                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7724                         error "can't access $DEV"
7725                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7726                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7727                 rm $TMP/t57a.dump
7728         done
7729 }
7730 run_test 57a "verify MDS filesystem created with large inodes =="
7731
7732 test_57b() {
7733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7734         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7735                 skip_env "ldiskfs only test"
7736         fi
7737         remote_mds_nodsh && skip "remote MDS with nodsh"
7738
7739         local dir=$DIR/$tdir
7740         local filecount=100
7741         local file1=$dir/f1
7742         local fileN=$dir/f$filecount
7743
7744         rm -rf $dir || error "removing $dir"
7745         test_mkdir -c1 $dir
7746         local mdtidx=$($LFS getstripe -m $dir)
7747         local mdtname=MDT$(printf %04x $mdtidx)
7748         local facet=mds$((mdtidx + 1))
7749
7750         echo "mcreating $filecount files"
7751         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7752
7753         # verify that files do not have EAs yet
7754         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7755                 error "$file1 has an EA"
7756         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7757                 error "$fileN has an EA"
7758
7759         sync
7760         sleep 1
7761         df $dir  #make sure we get new statfs data
7762         local mdsfree=$(do_facet $facet \
7763                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7764         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7765         local file
7766
7767         echo "opening files to create objects/EAs"
7768         for file in $(seq -f $dir/f%g 1 $filecount); do
7769                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7770                         error "opening $file"
7771         done
7772
7773         # verify that files have EAs now
7774         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7775         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7776
7777         sleep 1  #make sure we get new statfs data
7778         df $dir
7779         local mdsfree2=$(do_facet $facet \
7780                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7781         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7782
7783         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7784                 if [ "$mdsfree" != "$mdsfree2" ]; then
7785                         error "MDC before $mdcfree != after $mdcfree2"
7786                 else
7787                         echo "MDC before $mdcfree != after $mdcfree2"
7788                         echo "unable to confirm if MDS has large inodes"
7789                 fi
7790         fi
7791         rm -rf $dir
7792 }
7793 run_test 57b "default LOV EAs are stored inside large inodes ==="
7794
7795 test_58() {
7796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7797         [ -z "$(which wiretest 2>/dev/null)" ] &&
7798                         skip_env "could not find wiretest"
7799
7800         wiretest
7801 }
7802 run_test 58 "verify cross-platform wire constants =============="
7803
7804 test_59() {
7805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7806
7807         echo "touch 130 files"
7808         createmany -o $DIR/f59- 130
7809         echo "rm 130 files"
7810         unlinkmany $DIR/f59- 130
7811         sync
7812         # wait for commitment of removal
7813         wait_delete_completed
7814 }
7815 run_test 59 "verify cancellation of llog records async ========="
7816
7817 TEST60_HEAD="test_60 run $RANDOM"
7818 test_60a() {
7819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7820         remote_mgs_nodsh && skip "remote MGS with nodsh"
7821         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7822                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7823                         skip_env "missing subtest run-llog.sh"
7824
7825         log "$TEST60_HEAD - from kernel mode"
7826         do_facet mgs "$LCTL dk > /dev/null"
7827         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7828         do_facet mgs $LCTL dk > $TMP/$tfile
7829
7830         # LU-6388: test llog_reader
7831         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7832         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7833         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7834                         skip_env "missing llog_reader"
7835         local fstype=$(facet_fstype mgs)
7836         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7837                 skip_env "Only for ldiskfs or zfs type mgs"
7838
7839         local mntpt=$(facet_mntpt mgs)
7840         local mgsdev=$(mgsdevname 1)
7841         local fid_list
7842         local fid
7843         local rec_list
7844         local rec
7845         local rec_type
7846         local obj_file
7847         local path
7848         local seq
7849         local oid
7850         local pass=true
7851
7852         #get fid and record list
7853         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7854                 tail -n 4))
7855         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7856                 tail -n 4))
7857         #remount mgs as ldiskfs or zfs type
7858         stop mgs || error "stop mgs failed"
7859         mount_fstype mgs || error "remount mgs failed"
7860         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7861                 fid=${fid_list[i]}
7862                 rec=${rec_list[i]}
7863                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7864                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7865                 oid=$((16#$oid))
7866
7867                 case $fstype in
7868                         ldiskfs )
7869                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7870                         zfs )
7871                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7872                 esac
7873                 echo "obj_file is $obj_file"
7874                 do_facet mgs $llog_reader $obj_file
7875
7876                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7877                         awk '{ print $3 }' | sed -e "s/^type=//g")
7878                 if [ $rec_type != $rec ]; then
7879                         echo "FAILED test_60a wrong record type $rec_type," \
7880                               "should be $rec"
7881                         pass=false
7882                         break
7883                 fi
7884
7885                 #check obj path if record type is LLOG_LOGID_MAGIC
7886                 if [ "$rec" == "1064553b" ]; then
7887                         path=$(do_facet mgs $llog_reader $obj_file |
7888                                 grep "path=" | awk '{ print $NF }' |
7889                                 sed -e "s/^path=//g")
7890                         if [ $obj_file != $mntpt/$path ]; then
7891                                 echo "FAILED test_60a wrong obj path" \
7892                                       "$montpt/$path, should be $obj_file"
7893                                 pass=false
7894                                 break
7895                         fi
7896                 fi
7897         done
7898         rm -f $TMP/$tfile
7899         #restart mgs before "error", otherwise it will block the next test
7900         stop mgs || error "stop mgs failed"
7901         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7902         $pass || error "test failed, see FAILED test_60a messages for specifics"
7903 }
7904 run_test 60a "llog_test run from kernel module and test llog_reader"
7905
7906 test_60b() { # bug 6411
7907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7908
7909         dmesg > $DIR/$tfile
7910         LLOG_COUNT=$(do_facet mgs dmesg |
7911                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7912                           /llog_[a-z]*.c:[0-9]/ {
7913                                 if (marker)
7914                                         from_marker++
7915                                 from_begin++
7916                           }
7917                           END {
7918                                 if (marker)
7919                                         print from_marker
7920                                 else
7921                                         print from_begin
7922                           }")
7923
7924         [[ $LLOG_COUNT -gt 120 ]] &&
7925                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7926 }
7927 run_test 60b "limit repeated messages from CERROR/CWARN"
7928
7929 test_60c() {
7930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7931
7932         echo "create 5000 files"
7933         createmany -o $DIR/f60c- 5000
7934 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7935         lctl set_param fail_loc=0x80000137
7936         unlinkmany $DIR/f60c- 5000
7937         lctl set_param fail_loc=0
7938 }
7939 run_test 60c "unlink file when mds full"
7940
7941 test_60d() {
7942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7943
7944         SAVEPRINTK=$(lctl get_param -n printk)
7945         # verify "lctl mark" is even working"
7946         MESSAGE="test message ID $RANDOM $$"
7947         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7948         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7949
7950         lctl set_param printk=0 || error "set lnet.printk failed"
7951         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7952         MESSAGE="new test message ID $RANDOM $$"
7953         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7954         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7955         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7956
7957         lctl set_param -n printk="$SAVEPRINTK"
7958 }
7959 run_test 60d "test printk console message masking"
7960
7961 test_60e() {
7962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7963         remote_mds_nodsh && skip "remote MDS with nodsh"
7964
7965         touch $DIR/$tfile
7966 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7967         do_facet mds1 lctl set_param fail_loc=0x15b
7968         rm $DIR/$tfile
7969 }
7970 run_test 60e "no space while new llog is being created"
7971
7972 test_60g() {
7973         local pid
7974         local i
7975
7976         test_mkdir -c $MDSCOUNT $DIR/$tdir
7977
7978         (
7979                 local index=0
7980                 while true; do
7981                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7982                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7983                                 2>/dev/null
7984                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7985                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7986                         index=$((index + 1))
7987                 done
7988         ) &
7989
7990         pid=$!
7991
7992         for i in {0..100}; do
7993                 # define OBD_FAIL_OSD_TXN_START    0x19a
7994                 local index=$((i % MDSCOUNT + 1))
7995
7996                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7997                         > /dev/null
7998                 sleep 0.01
7999         done
8000
8001         kill -9 $pid
8002
8003         for i in $(seq $MDSCOUNT); do
8004                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8005         done
8006
8007         mkdir $DIR/$tdir/new || error "mkdir failed"
8008         rmdir $DIR/$tdir/new || error "rmdir failed"
8009
8010         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8011                 -t namespace
8012         for i in $(seq $MDSCOUNT); do
8013                 wait_update_facet mds$i "$LCTL get_param -n \
8014                         mdd.$(facet_svc mds$i).lfsck_namespace |
8015                         awk '/^status/ { print \\\$2 }'" "completed"
8016         done
8017
8018         ls -R $DIR/$tdir || error "ls failed"
8019         rm -rf $DIR/$tdir || error "rmdir failed"
8020 }
8021 run_test 60g "transaction abort won't cause MDT hung"
8022
8023 test_60h() {
8024         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8025                 skip "Need MDS version at least 2.12.52"
8026         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8027
8028         local f
8029
8030         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8031         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8032         for fail_loc in 0x80000188 0x80000189; do
8033                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8034                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8035                         error "mkdir $dir-$fail_loc failed"
8036                 for i in {0..10}; do
8037                         # create may fail on missing stripe
8038                         echo $i > $DIR/$tdir-$fail_loc/$i
8039                 done
8040                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8041                         error "getdirstripe $tdir-$fail_loc failed"
8042                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8043                         error "migrate $tdir-$fail_loc failed"
8044                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8045                         error "getdirstripe $tdir-$fail_loc failed"
8046                 pushd $DIR/$tdir-$fail_loc
8047                 for f in *; do
8048                         echo $f | cmp $f - || error "$f data mismatch"
8049                 done
8050                 popd
8051                 rm -rf $DIR/$tdir-$fail_loc
8052         done
8053 }
8054 run_test 60h "striped directory with missing stripes can be accessed"
8055
8056 test_61a() {
8057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8058
8059         f="$DIR/f61"
8060         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8061         cancel_lru_locks osc
8062         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8063         sync
8064 }
8065 run_test 61a "mmap() writes don't make sync hang ================"
8066
8067 test_61b() {
8068         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8069 }
8070 run_test 61b "mmap() of unstriped file is successful"
8071
8072 # bug 2330 - insufficient obd_match error checking causes LBUG
8073 test_62() {
8074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8075
8076         f="$DIR/f62"
8077         echo foo > $f
8078         cancel_lru_locks osc
8079         lctl set_param fail_loc=0x405
8080         cat $f && error "cat succeeded, expect -EIO"
8081         lctl set_param fail_loc=0
8082 }
8083 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8084 # match every page all of the time.
8085 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8086
8087 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8088 # Though this test is irrelevant anymore, it helped to reveal some
8089 # other grant bugs (LU-4482), let's keep it.
8090 test_63a() {   # was test_63
8091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8092
8093         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8094
8095         for i in `seq 10` ; do
8096                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8097                 sleep 5
8098                 kill $!
8099                 sleep 1
8100         done
8101
8102         rm -f $DIR/f63 || true
8103 }
8104 run_test 63a "Verify oig_wait interruption does not crash ======="
8105
8106 # bug 2248 - async write errors didn't return to application on sync
8107 # bug 3677 - async write errors left page locked
8108 test_63b() {
8109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8110
8111         debugsave
8112         lctl set_param debug=-1
8113
8114         # ensure we have a grant to do async writes
8115         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8116         rm $DIR/$tfile
8117
8118         sync    # sync lest earlier test intercept the fail_loc
8119
8120         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8121         lctl set_param fail_loc=0x80000406
8122         $MULTIOP $DIR/$tfile Owy && \
8123                 error "sync didn't return ENOMEM"
8124         sync; sleep 2; sync     # do a real sync this time to flush page
8125         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8126                 error "locked page left in cache after async error" || true
8127         debugrestore
8128 }
8129 run_test 63b "async write errors should be returned to fsync ==="
8130
8131 test_64a () {
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133
8134         lfs df $DIR
8135         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8136 }
8137 run_test 64a "verify filter grant calculations (in kernel) ====="
8138
8139 test_64b () {
8140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8141
8142         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8143 }
8144 run_test 64b "check out-of-space detection on client"
8145
8146 test_64c() {
8147         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8148 }
8149 run_test 64c "verify grant shrink"
8150
8151 import_param() {
8152         local tgt=$1
8153         local param=$2
8154
8155         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8156 }
8157
8158 # this does exactly what osc_request.c:osc_announce_cached() does in
8159 # order to calculate max amount of grants to ask from server
8160 want_grant() {
8161         local tgt=$1
8162
8163         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8164         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8165
8166         ((rpc_in_flight++));
8167         nrpages=$((nrpages * rpc_in_flight))
8168
8169         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8170
8171         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8172
8173         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8174         local undirty=$((nrpages * PAGE_SIZE))
8175
8176         local max_extent_pages
8177         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8178         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8179         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8180         local grant_extent_tax
8181         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8182
8183         undirty=$((undirty + nrextents * grant_extent_tax))
8184
8185         echo $undirty
8186 }
8187
8188 # this is size of unit for grant allocation. It should be equal to
8189 # what tgt_grant.c:tgt_grant_chunk() calculates
8190 grant_chunk() {
8191         local tgt=$1
8192         local max_brw_size
8193         local grant_extent_tax
8194
8195         max_brw_size=$(import_param $tgt max_brw_size)
8196
8197         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8198
8199         echo $(((max_brw_size + grant_extent_tax) * 2))
8200 }
8201
8202 test_64d() {
8203         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8204                 skip "OST < 2.10.55 doesn't limit grants enough"
8205
8206         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8207
8208         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8209                 skip "no grant_param connect flag"
8210
8211         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8212
8213         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8214         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8215
8216
8217         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8218         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8219
8220         $LFS setstripe $DIR/$tfile -i 0 -c 1
8221         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8222         ddpid=$!
8223
8224         while kill -0 $ddpid; do
8225                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8226
8227                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8228                         kill $ddpid
8229                         error "cur_grant $cur_grant > $max_cur_granted"
8230                 fi
8231
8232                 sleep 1
8233         done
8234 }
8235 run_test 64d "check grant limit exceed"
8236
8237 check_grants() {
8238         local tgt=$1
8239         local expected=$2
8240         local msg=$3
8241         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8242
8243         ((cur_grants == expected)) ||
8244                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8245 }
8246
8247 round_up_p2() {
8248         echo $((($1 + $2 - 1) & ~($2 - 1)))
8249 }
8250
8251 test_64e() {
8252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8253         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8254                 skip "Need OSS version at least 2.11.56"
8255
8256         # Remount client to reset grant
8257         remount_client $MOUNT || error "failed to remount client"
8258         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8259
8260         local init_grants=$(import_param $osc_tgt initial_grant)
8261
8262         check_grants $osc_tgt $init_grants "init grants"
8263
8264         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8265         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8266         local gbs=$(import_param $osc_tgt grant_block_size)
8267
8268         # write random number of bytes from max_brw_size / 4 to max_brw_size
8269         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8270         # align for direct io
8271         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8272         # round to grant consumption unit
8273         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8274
8275         local grants=$((wb_round_up + extent_tax))
8276
8277         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8278
8279         # define OBD_FAIL_TGT_NO_GRANT 0x725
8280         # make the server not grant more back
8281         do_facet ost1 $LCTL set_param fail_loc=0x725
8282         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8283
8284         do_facet ost1 $LCTL set_param fail_loc=0
8285
8286         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8287
8288         rm -f $DIR/$tfile || error "rm failed"
8289
8290         # Remount client to reset grant
8291         remount_client $MOUNT || error "failed to remount client"
8292         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8293
8294         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8295
8296         # define OBD_FAIL_TGT_NO_GRANT 0x725
8297         # make the server not grant more back
8298         do_facet ost1 $LCTL set_param fail_loc=0x725
8299         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8300         do_facet ost1 $LCTL set_param fail_loc=0
8301
8302         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8303 }
8304 run_test 64e "check grant consumption (no grant allocation)"
8305
8306 test_64f() {
8307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8308
8309         # Remount client to reset grant
8310         remount_client $MOUNT || error "failed to remount client"
8311         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8312
8313         local init_grants=$(import_param $osc_tgt initial_grant)
8314         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8315         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8316         local gbs=$(import_param $osc_tgt grant_block_size)
8317         local chunk=$(grant_chunk $osc_tgt)
8318
8319         # write random number of bytes from max_brw_size / 4 to max_brw_size
8320         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8321         # align for direct io
8322         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8323         # round to grant consumption unit
8324         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8325
8326         local grants=$((wb_round_up + extent_tax))
8327
8328         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8329         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8330                 error "error writing to $DIR/$tfile"
8331
8332         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8333                 "direct io with grant allocation"
8334
8335         rm -f $DIR/$tfile || error "rm failed"
8336
8337         # Remount client to reset grant
8338         remount_client $MOUNT || error "failed to remount client"
8339         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8340
8341         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8342
8343         local cmd="oO_WRONLY:w${write_bytes}_yc"
8344
8345         $MULTIOP $DIR/$tfile $cmd &
8346         MULTIPID=$!
8347         sleep 1
8348
8349         check_grants $osc_tgt $((init_grants - grants)) \
8350                 "buffered io, not write rpc"
8351
8352         kill -USR1 $MULTIPID
8353         wait
8354
8355         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8356                 "buffered io, one RPC"
8357 }
8358 run_test 64f "check grant consumption (with grant allocation)"
8359
8360 # bug 1414 - set/get directories' stripe info
8361 test_65a() {
8362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8363
8364         test_mkdir $DIR/$tdir
8365         touch $DIR/$tdir/f1
8366         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8367 }
8368 run_test 65a "directory with no stripe info"
8369
8370 test_65b() {
8371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8372
8373         test_mkdir $DIR/$tdir
8374         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8375
8376         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8377                                                 error "setstripe"
8378         touch $DIR/$tdir/f2
8379         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8380 }
8381 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8382
8383 test_65c() {
8384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8385         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8386
8387         test_mkdir $DIR/$tdir
8388         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8389
8390         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8391                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8392         touch $DIR/$tdir/f3
8393         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8394 }
8395 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8396
8397 test_65d() {
8398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8399
8400         test_mkdir $DIR/$tdir
8401         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8402         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8403
8404         if [[ $STRIPECOUNT -le 0 ]]; then
8405                 sc=1
8406         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8407                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8408                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8409         else
8410                 sc=$(($STRIPECOUNT - 1))
8411         fi
8412         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8413         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8414         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8415                 error "lverify failed"
8416 }
8417 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8418
8419 test_65e() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421
8422         test_mkdir $DIR/$tdir
8423
8424         $LFS setstripe $DIR/$tdir || error "setstripe"
8425         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8426                                         error "no stripe info failed"
8427         touch $DIR/$tdir/f6
8428         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8429 }
8430 run_test 65e "directory setstripe defaults"
8431
8432 test_65f() {
8433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8434
8435         test_mkdir $DIR/${tdir}f
8436         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8437                 error "setstripe succeeded" || true
8438 }
8439 run_test 65f "dir setstripe permission (should return error) ==="
8440
8441 test_65g() {
8442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8443
8444         test_mkdir $DIR/$tdir
8445         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8446
8447         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8448                 error "setstripe -S failed"
8449         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8450         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8451                 error "delete default stripe failed"
8452 }
8453 run_test 65g "directory setstripe -d"
8454
8455 test_65h() {
8456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8457
8458         test_mkdir $DIR/$tdir
8459         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8460
8461         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8462                 error "setstripe -S failed"
8463         test_mkdir $DIR/$tdir/dd1
8464         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8465                 error "stripe info inherit failed"
8466 }
8467 run_test 65h "directory stripe info inherit ===================="
8468
8469 test_65i() {
8470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8471
8472         save_layout_restore_at_exit $MOUNT
8473
8474         # bug6367: set non-default striping on root directory
8475         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8476
8477         # bug12836: getstripe on -1 default directory striping
8478         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8479
8480         # bug12836: getstripe -v on -1 default directory striping
8481         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8482
8483         # bug12836: new find on -1 default directory striping
8484         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8485 }
8486 run_test 65i "various tests to set root directory striping"
8487
8488 test_65j() { # bug6367
8489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8490
8491         sync; sleep 1
8492
8493         # if we aren't already remounting for each test, do so for this test
8494         if [ "$I_MOUNTED" = "yes" ]; then
8495                 cleanup || error "failed to unmount"
8496                 setup
8497         fi
8498
8499         save_layout_restore_at_exit $MOUNT
8500
8501         $LFS setstripe -d $MOUNT || error "setstripe failed"
8502 }
8503 run_test 65j "set default striping on root directory (bug 6367)="
8504
8505 cleanup_65k() {
8506         rm -rf $DIR/$tdir
8507         wait_delete_completed
8508         do_facet $SINGLEMDS "lctl set_param -n \
8509                 osp.$ost*MDT0000.max_create_count=$max_count"
8510         do_facet $SINGLEMDS "lctl set_param -n \
8511                 osp.$ost*MDT0000.create_count=$count"
8512         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8513         echo $INACTIVE_OSC "is Activate"
8514
8515         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8516 }
8517
8518 test_65k() { # bug11679
8519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8521         remote_mds_nodsh && skip "remote MDS with nodsh"
8522
8523         local disable_precreate=true
8524         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8525                 disable_precreate=false
8526
8527         echo "Check OST status: "
8528         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8529                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8530
8531         for OSC in $MDS_OSCS; do
8532                 echo $OSC "is active"
8533                 do_facet $SINGLEMDS lctl --device %$OSC activate
8534         done
8535
8536         for INACTIVE_OSC in $MDS_OSCS; do
8537                 local ost=$(osc_to_ost $INACTIVE_OSC)
8538                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8539                                lov.*md*.target_obd |
8540                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8541
8542                 mkdir -p $DIR/$tdir
8543                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8544                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8545
8546                 echo "Deactivate: " $INACTIVE_OSC
8547                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8548
8549                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8550                               osp.$ost*MDT0000.create_count")
8551                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8552                                   osp.$ost*MDT0000.max_create_count")
8553                 $disable_precreate &&
8554                         do_facet $SINGLEMDS "lctl set_param -n \
8555                                 osp.$ost*MDT0000.max_create_count=0"
8556
8557                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8558                         [ -f $DIR/$tdir/$idx ] && continue
8559                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8560                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8561                                 { cleanup_65k;
8562                                   error "setstripe $idx should succeed"; }
8563                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8564                 done
8565                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8566                 rmdir $DIR/$tdir
8567
8568                 do_facet $SINGLEMDS "lctl set_param -n \
8569                         osp.$ost*MDT0000.max_create_count=$max_count"
8570                 do_facet $SINGLEMDS "lctl set_param -n \
8571                         osp.$ost*MDT0000.create_count=$count"
8572                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8573                 echo $INACTIVE_OSC "is Activate"
8574
8575                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8576         done
8577 }
8578 run_test 65k "validate manual striping works properly with deactivated OSCs"
8579
8580 test_65l() { # bug 12836
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         test_mkdir -p $DIR/$tdir/test_dir
8584         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8585         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8586 }
8587 run_test 65l "lfs find on -1 stripe dir ========================"
8588
8589 test_65m() {
8590         local layout=$(save_layout $MOUNT)
8591         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8592                 restore_layout $MOUNT $layout
8593                 error "setstripe should fail by non-root users"
8594         }
8595         true
8596 }
8597 run_test 65m "normal user can't set filesystem default stripe"
8598
8599 test_65n() {
8600         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8601         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8602                 skip "Need MDS version at least 2.12.50"
8603         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8604
8605         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8606         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8607         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8608
8609         local root_layout=$(save_layout $MOUNT)
8610         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8611
8612         # new subdirectory under root directory should not inherit
8613         # the default layout from root
8614         local dir1=$MOUNT/$tdir-1
8615         mkdir $dir1 || error "mkdir $dir1 failed"
8616         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8617                 error "$dir1 shouldn't have LOV EA"
8618
8619         # delete the default layout on root directory
8620         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8621
8622         local dir2=$MOUNT/$tdir-2
8623         mkdir $dir2 || error "mkdir $dir2 failed"
8624         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8625                 error "$dir2 shouldn't have LOV EA"
8626
8627         # set a new striping pattern on root directory
8628         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8629         local new_def_stripe_size=$((def_stripe_size * 2))
8630         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8631                 error "set stripe size on $MOUNT failed"
8632
8633         # new file created in $dir2 should inherit the new stripe size from
8634         # the filesystem default
8635         local file2=$dir2/$tfile-2
8636         touch $file2 || error "touch $file2 failed"
8637
8638         local file2_stripe_size=$($LFS getstripe -S $file2)
8639         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8640         {
8641                 echo "file2_stripe_size: '$file2_stripe_size'"
8642                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8643                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8644         }
8645
8646         local dir3=$MOUNT/$tdir-3
8647         mkdir $dir3 || error "mkdir $dir3 failed"
8648         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8649         # the root layout, which is the actual default layout that will be used
8650         # when new files are created in $dir3.
8651         local dir3_layout=$(get_layout_param $dir3)
8652         local root_dir_layout=$(get_layout_param $MOUNT)
8653         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8654         {
8655                 echo "dir3_layout: '$dir3_layout'"
8656                 echo "root_dir_layout: '$root_dir_layout'"
8657                 error "$dir3 should show the default layout from $MOUNT"
8658         }
8659
8660         # set OST pool on root directory
8661         local pool=$TESTNAME
8662         pool_add $pool || error "add $pool failed"
8663         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8664                 error "add targets to $pool failed"
8665
8666         $LFS setstripe -p $pool $MOUNT ||
8667                 error "set OST pool on $MOUNT failed"
8668
8669         # new file created in $dir3 should inherit the pool from
8670         # the filesystem default
8671         local file3=$dir3/$tfile-3
8672         touch $file3 || error "touch $file3 failed"
8673
8674         local file3_pool=$($LFS getstripe -p $file3)
8675         [[ "$file3_pool" = "$pool" ]] ||
8676                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8677
8678         local dir4=$MOUNT/$tdir-4
8679         mkdir $dir4 || error "mkdir $dir4 failed"
8680         local dir4_layout=$(get_layout_param $dir4)
8681         root_dir_layout=$(get_layout_param $MOUNT)
8682         echo "$LFS getstripe -d $dir4"
8683         $LFS getstripe -d $dir4
8684         echo "$LFS getstripe -d $MOUNT"
8685         $LFS getstripe -d $MOUNT
8686         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8687         {
8688                 echo "dir4_layout: '$dir4_layout'"
8689                 echo "root_dir_layout: '$root_dir_layout'"
8690                 error "$dir4 should show the default layout from $MOUNT"
8691         }
8692
8693         # new file created in $dir4 should inherit the pool from
8694         # the filesystem default
8695         local file4=$dir4/$tfile-4
8696         touch $file4 || error "touch $file4 failed"
8697
8698         local file4_pool=$($LFS getstripe -p $file4)
8699         [[ "$file4_pool" = "$pool" ]] ||
8700                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8701
8702         # new subdirectory under non-root directory should inherit
8703         # the default layout from its parent directory
8704         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8705                 error "set directory layout on $dir4 failed"
8706
8707         local dir5=$dir4/$tdir-5
8708         mkdir $dir5 || error "mkdir $dir5 failed"
8709
8710         dir4_layout=$(get_layout_param $dir4)
8711         local dir5_layout=$(get_layout_param $dir5)
8712         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8713         {
8714                 echo "dir4_layout: '$dir4_layout'"
8715                 echo "dir5_layout: '$dir5_layout'"
8716                 error "$dir5 should inherit the default layout from $dir4"
8717         }
8718
8719         # though subdir under ROOT doesn't inherit default layout, but
8720         # its sub dir/file should be created with default layout.
8721         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8722         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8723                 skip "Need MDS version at least 2.12.59"
8724
8725         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8726         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8727         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8728
8729         if [ $default_lmv_hash == "none" ]; then
8730                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8731         else
8732                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8733                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8734         fi
8735
8736         $LFS setdirstripe -D -c 2 $MOUNT ||
8737                 error "setdirstripe -D -c 2 failed"
8738         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8739         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8740         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8741 }
8742 run_test 65n "don't inherit default layout from root for new subdirectories"
8743
8744 # bug 2543 - update blocks count on client
8745 test_66() {
8746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8747
8748         COUNT=${COUNT:-8}
8749         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8750         sync; sync_all_data; sync; sync_all_data
8751         cancel_lru_locks osc
8752         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8753         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8754 }
8755 run_test 66 "update inode blocks count on client ==============="
8756
8757 meminfo() {
8758         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8759 }
8760
8761 swap_used() {
8762         swapon -s | awk '($1 == "'$1'") { print $4 }'
8763 }
8764
8765 # bug5265, obdfilter oa2dentry return -ENOENT
8766 # #define OBD_FAIL_SRV_ENOENT 0x217
8767 test_69() {
8768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8769         remote_ost_nodsh && skip "remote OST with nodsh"
8770
8771         f="$DIR/$tfile"
8772         $LFS setstripe -c 1 -i 0 $f
8773
8774         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8775
8776         do_facet ost1 lctl set_param fail_loc=0x217
8777         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8778         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8779
8780         do_facet ost1 lctl set_param fail_loc=0
8781         $DIRECTIO write $f 0 2 || error "write error"
8782
8783         cancel_lru_locks osc
8784         $DIRECTIO read $f 0 1 || error "read error"
8785
8786         do_facet ost1 lctl set_param fail_loc=0x217
8787         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8788
8789         do_facet ost1 lctl set_param fail_loc=0
8790         rm -f $f
8791 }
8792 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8793
8794 test_71() {
8795         test_mkdir $DIR/$tdir
8796         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8797         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8798 }
8799 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8800
8801 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8803         [ "$RUNAS_ID" = "$UID" ] &&
8804                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8805         # Check that testing environment is properly set up. Skip if not
8806         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8807                 skip_env "User $RUNAS_ID does not exist - skipping"
8808
8809         touch $DIR/$tfile
8810         chmod 777 $DIR/$tfile
8811         chmod ug+s $DIR/$tfile
8812         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8813                 error "$RUNAS dd $DIR/$tfile failed"
8814         # See if we are still setuid/sgid
8815         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8816                 error "S/gid is not dropped on write"
8817         # Now test that MDS is updated too
8818         cancel_lru_locks mdc
8819         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8820                 error "S/gid is not dropped on MDS"
8821         rm -f $DIR/$tfile
8822 }
8823 run_test 72a "Test that remove suid works properly (bug5695) ===="
8824
8825 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8826         local perm
8827
8828         [ "$RUNAS_ID" = "$UID" ] &&
8829                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8830         [ "$RUNAS_ID" -eq 0 ] &&
8831                 skip_env "RUNAS_ID = 0 -- skipping"
8832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8833         # Check that testing environment is properly set up. Skip if not
8834         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8835                 skip_env "User $RUNAS_ID does not exist - skipping"
8836
8837         touch $DIR/${tfile}-f{g,u}
8838         test_mkdir $DIR/${tfile}-dg
8839         test_mkdir $DIR/${tfile}-du
8840         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8841         chmod g+s $DIR/${tfile}-{f,d}g
8842         chmod u+s $DIR/${tfile}-{f,d}u
8843         for perm in 777 2777 4777; do
8844                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8845                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8846                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8847                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8848         done
8849         true
8850 }
8851 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8852
8853 # bug 3462 - multiple simultaneous MDC requests
8854 test_73() {
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856
8857         test_mkdir $DIR/d73-1
8858         test_mkdir $DIR/d73-2
8859         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8860         pid1=$!
8861
8862         lctl set_param fail_loc=0x80000129
8863         $MULTIOP $DIR/d73-1/f73-2 Oc &
8864         sleep 1
8865         lctl set_param fail_loc=0
8866
8867         $MULTIOP $DIR/d73-2/f73-3 Oc &
8868         pid3=$!
8869
8870         kill -USR1 $pid1
8871         wait $pid1 || return 1
8872
8873         sleep 25
8874
8875         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8876         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8877         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8878
8879         rm -rf $DIR/d73-*
8880 }
8881 run_test 73 "multiple MDC requests (should not deadlock)"
8882
8883 test_74a() { # bug 6149, 6184
8884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8885
8886         touch $DIR/f74a
8887         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8888         #
8889         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8890         # will spin in a tight reconnection loop
8891         $LCTL set_param fail_loc=0x8000030e
8892         # get any lock that won't be difficult - lookup works.
8893         ls $DIR/f74a
8894         $LCTL set_param fail_loc=0
8895         rm -f $DIR/f74a
8896         true
8897 }
8898 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8899
8900 test_74b() { # bug 13310
8901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8902
8903         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8904         #
8905         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8906         # will spin in a tight reconnection loop
8907         $LCTL set_param fail_loc=0x8000030e
8908         # get a "difficult" lock
8909         touch $DIR/f74b
8910         $LCTL set_param fail_loc=0
8911         rm -f $DIR/f74b
8912         true
8913 }
8914 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8915
8916 test_74c() {
8917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8918
8919         #define OBD_FAIL_LDLM_NEW_LOCK
8920         $LCTL set_param fail_loc=0x319
8921         touch $DIR/$tfile && error "touch successful"
8922         $LCTL set_param fail_loc=0
8923         true
8924 }
8925 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8926
8927 slab_lic=/sys/kernel/slab/lustre_inode_cache
8928 num_objects() {
8929         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8930         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8931                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8932 }
8933
8934 test_76a() { # Now for b=20433, added originally in b=1443
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         cancel_lru_locks osc
8938         # there may be some slab objects cached per core
8939         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8940         local before=$(num_objects)
8941         local count=$((512 * cpus))
8942         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8943         local margin=$((count / 10))
8944         if [[ -f $slab_lic/aliases ]]; then
8945                 local aliases=$(cat $slab_lic/aliases)
8946                 (( aliases > 0 )) && margin=$((margin * aliases))
8947         fi
8948
8949         echo "before slab objects: $before"
8950         for i in $(seq $count); do
8951                 touch $DIR/$tfile
8952                 rm -f $DIR/$tfile
8953         done
8954         cancel_lru_locks osc
8955         local after=$(num_objects)
8956         echo "created: $count, after slab objects: $after"
8957         # shared slab counts are not very accurate, allow significant margin
8958         # the main goal is that the cache growth is not permanently > $count
8959         while (( after > before + margin )); do
8960                 sleep 1
8961                 after=$(num_objects)
8962                 wait=$((wait + 1))
8963                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8964                 if (( wait > 60 )); then
8965                         error "inode slab grew from $before+$margin to $after"
8966                 fi
8967         done
8968 }
8969 run_test 76a "confirm clients recycle inodes properly ===="
8970
8971 test_76b() {
8972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8973         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8974
8975         local count=512
8976         local before=$(num_objects)
8977
8978         for i in $(seq $count); do
8979                 mkdir $DIR/$tdir
8980                 rmdir $DIR/$tdir
8981         done
8982
8983         local after=$(num_objects)
8984         local wait=0
8985
8986         while (( after > before )); do
8987                 sleep 1
8988                 after=$(num_objects)
8989                 wait=$((wait + 1))
8990                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8991                 if (( wait > 60 )); then
8992                         error "inode slab grew from $before to $after"
8993                 fi
8994         done
8995
8996         echo "slab objects before: $before, after: $after"
8997 }
8998 run_test 76b "confirm clients recycle directory inodes properly ===="
8999
9000 export ORIG_CSUM=""
9001 set_checksums()
9002 {
9003         # Note: in sptlrpc modes which enable its own bulk checksum, the
9004         # original crc32_le bulk checksum will be automatically disabled,
9005         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9006         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9007         # In this case set_checksums() will not be no-op, because sptlrpc
9008         # bulk checksum will be enabled all through the test.
9009
9010         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9011         lctl set_param -n osc.*.checksums $1
9012         return 0
9013 }
9014
9015 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9016                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9017 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9018                              tr -d [] | head -n1)}
9019 set_checksum_type()
9020 {
9021         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9022         rc=$?
9023         log "set checksum type to $1, rc = $rc"
9024         return $rc
9025 }
9026
9027 get_osc_checksum_type()
9028 {
9029         # arugment 1: OST name, like OST0000
9030         ost=$1
9031         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9032                         sed 's/.*\[\(.*\)\].*/\1/g')
9033         rc=$?
9034         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9035         echo $checksum_type
9036 }
9037
9038 F77_TMP=$TMP/f77-temp
9039 F77SZ=8
9040 setup_f77() {
9041         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9042                 error "error writing to $F77_TMP"
9043 }
9044
9045 test_77a() { # bug 10889
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047         $GSS && skip_env "could not run with gss"
9048
9049         [ ! -f $F77_TMP ] && setup_f77
9050         set_checksums 1
9051         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9052         set_checksums 0
9053         rm -f $DIR/$tfile
9054 }
9055 run_test 77a "normal checksum read/write operation"
9056
9057 test_77b() { # bug 10889
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059         $GSS && skip_env "could not run with gss"
9060
9061         [ ! -f $F77_TMP ] && setup_f77
9062         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9063         $LCTL set_param fail_loc=0x80000409
9064         set_checksums 1
9065
9066         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9067                 error "dd error: $?"
9068         $LCTL set_param fail_loc=0
9069
9070         for algo in $CKSUM_TYPES; do
9071                 cancel_lru_locks osc
9072                 set_checksum_type $algo
9073                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9074                 $LCTL set_param fail_loc=0x80000408
9075                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9076                 $LCTL set_param fail_loc=0
9077         done
9078         set_checksums 0
9079         set_checksum_type $ORIG_CSUM_TYPE
9080         rm -f $DIR/$tfile
9081 }
9082 run_test 77b "checksum error on client write, read"
9083
9084 cleanup_77c() {
9085         trap 0
9086         set_checksums 0
9087         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9088         $check_ost &&
9089                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9090         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9091         $check_ost && [ -n "$ost_file_prefix" ] &&
9092                 do_facet ost1 rm -f ${ost_file_prefix}\*
9093 }
9094
9095 test_77c() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097         $GSS && skip_env "could not run with gss"
9098         remote_ost_nodsh && skip "remote OST with nodsh"
9099
9100         local bad1
9101         local osc_file_prefix
9102         local osc_file
9103         local check_ost=false
9104         local ost_file_prefix
9105         local ost_file
9106         local orig_cksum
9107         local dump_cksum
9108         local fid
9109
9110         # ensure corruption will occur on first OSS/OST
9111         $LFS setstripe -i 0 $DIR/$tfile
9112
9113         [ ! -f $F77_TMP ] && setup_f77
9114         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9115                 error "dd write error: $?"
9116         fid=$($LFS path2fid $DIR/$tfile)
9117
9118         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9119         then
9120                 check_ost=true
9121                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9122                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9123         else
9124                 echo "OSS do not support bulk pages dump upon error"
9125         fi
9126
9127         osc_file_prefix=$($LCTL get_param -n debug_path)
9128         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9129
9130         trap cleanup_77c EXIT
9131
9132         set_checksums 1
9133         # enable bulk pages dump upon error on Client
9134         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9135         # enable bulk pages dump upon error on OSS
9136         $check_ost &&
9137                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9138
9139         # flush Client cache to allow next read to reach OSS
9140         cancel_lru_locks osc
9141
9142         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9143         $LCTL set_param fail_loc=0x80000408
9144         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9145         $LCTL set_param fail_loc=0
9146
9147         rm -f $DIR/$tfile
9148
9149         # check cksum dump on Client
9150         osc_file=$(ls ${osc_file_prefix}*)
9151         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9152         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9153         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9154         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9155         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9156                      cksum)
9157         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9158         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9159                 error "dump content does not match on Client"
9160
9161         $check_ost || skip "No need to check cksum dump on OSS"
9162
9163         # check cksum dump on OSS
9164         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9165         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9166         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9167         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9168         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9169                 error "dump content does not match on OSS"
9170
9171         cleanup_77c
9172 }
9173 run_test 77c "checksum error on client read with debug"
9174
9175 test_77d() { # bug 10889
9176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9177         $GSS && skip_env "could not run with gss"
9178
9179         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9180         $LCTL set_param fail_loc=0x80000409
9181         set_checksums 1
9182         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9183                 error "direct write: rc=$?"
9184         $LCTL set_param fail_loc=0
9185         set_checksums 0
9186
9187         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9188         $LCTL set_param fail_loc=0x80000408
9189         set_checksums 1
9190         cancel_lru_locks osc
9191         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9192                 error "direct read: rc=$?"
9193         $LCTL set_param fail_loc=0
9194         set_checksums 0
9195 }
9196 run_test 77d "checksum error on OST direct write, read"
9197
9198 test_77f() { # bug 10889
9199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9200         $GSS && skip_env "could not run with gss"
9201
9202         set_checksums 1
9203         for algo in $CKSUM_TYPES; do
9204                 cancel_lru_locks osc
9205                 set_checksum_type $algo
9206                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9207                 $LCTL set_param fail_loc=0x409
9208                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9209                         error "direct write succeeded"
9210                 $LCTL set_param fail_loc=0
9211         done
9212         set_checksum_type $ORIG_CSUM_TYPE
9213         set_checksums 0
9214 }
9215 run_test 77f "repeat checksum error on write (expect error)"
9216
9217 test_77g() { # bug 10889
9218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9219         $GSS && skip_env "could not run with gss"
9220         remote_ost_nodsh && skip "remote OST with nodsh"
9221
9222         [ ! -f $F77_TMP ] && setup_f77
9223
9224         local file=$DIR/$tfile
9225         stack_trap "rm -f $file" EXIT
9226
9227         $LFS setstripe -c 1 -i 0 $file
9228         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9229         do_facet ost1 lctl set_param fail_loc=0x8000021a
9230         set_checksums 1
9231         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9232                 error "write error: rc=$?"
9233         do_facet ost1 lctl set_param fail_loc=0
9234         set_checksums 0
9235
9236         cancel_lru_locks osc
9237         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9238         do_facet ost1 lctl set_param fail_loc=0x8000021b
9239         set_checksums 1
9240         cmp $F77_TMP $file || error "file compare failed"
9241         do_facet ost1 lctl set_param fail_loc=0
9242         set_checksums 0
9243 }
9244 run_test 77g "checksum error on OST write, read"
9245
9246 test_77k() { # LU-10906
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248         $GSS && skip_env "could not run with gss"
9249
9250         local cksum_param="osc.$FSNAME*.checksums"
9251         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9252         local checksum
9253         local i
9254
9255         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9256         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9257         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9258
9259         for i in 0 1; do
9260                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9261                         error "failed to set checksum=$i on MGS"
9262                 wait_update $HOSTNAME "$get_checksum" $i
9263                 #remount
9264                 echo "remount client, checksum should be $i"
9265                 remount_client $MOUNT || error "failed to remount client"
9266                 checksum=$(eval $get_checksum)
9267                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9268         done
9269         # remove persistent param to avoid races with checksum mountopt below
9270         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9271                 error "failed to delete checksum on MGS"
9272
9273         for opt in "checksum" "nochecksum"; do
9274                 #remount with mount option
9275                 echo "remount client with option $opt, checksum should be $i"
9276                 umount_client $MOUNT || error "failed to umount client"
9277                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9278                         error "failed to mount client with option '$opt'"
9279                 checksum=$(eval $get_checksum)
9280                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9281                 i=$((i - 1))
9282         done
9283
9284         remount_client $MOUNT || error "failed to remount client"
9285 }
9286 run_test 77k "enable/disable checksum correctly"
9287
9288 test_77l() {
9289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9290         $GSS && skip_env "could not run with gss"
9291
9292         set_checksums 1
9293         stack_trap "set_checksums $ORIG_CSUM" EXIT
9294         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9295
9296         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9297
9298         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9299         for algo in $CKSUM_TYPES; do
9300                 set_checksum_type $algo || error "fail to set checksum type $algo"
9301                 osc_algo=$(get_osc_checksum_type OST0000)
9302                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9303
9304                 # no locks, no reqs to let the connection idle
9305                 cancel_lru_locks osc
9306                 lru_resize_disable osc
9307                 wait_osc_import_state client ost1 IDLE
9308
9309                 # ensure ost1 is connected
9310                 stat $DIR/$tfile >/dev/null || error "can't stat"
9311                 wait_osc_import_state client ost1 FULL
9312
9313                 osc_algo=$(get_osc_checksum_type OST0000)
9314                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9315         done
9316         return 0
9317 }
9318 run_test 77l "preferred checksum type is remembered after reconnected"
9319
9320 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9321 rm -f $F77_TMP
9322 unset F77_TMP
9323
9324 cleanup_test_78() {
9325         trap 0
9326         rm -f $DIR/$tfile
9327 }
9328
9329 test_78() { # bug 10901
9330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9331         remote_ost || skip_env "local OST"
9332
9333         NSEQ=5
9334         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9335         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9336         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9337         echo "MemTotal: $MEMTOTAL"
9338
9339         # reserve 256MB of memory for the kernel and other running processes,
9340         # and then take 1/2 of the remaining memory for the read/write buffers.
9341         if [ $MEMTOTAL -gt 512 ] ;then
9342                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9343         else
9344                 # for those poor memory-starved high-end clusters...
9345                 MEMTOTAL=$((MEMTOTAL / 2))
9346         fi
9347         echo "Mem to use for directio: $MEMTOTAL"
9348
9349         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9350         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9351         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9352         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9353                 head -n1)
9354         echo "Smallest OST: $SMALLESTOST"
9355         [[ $SMALLESTOST -lt 10240 ]] &&
9356                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9357
9358         trap cleanup_test_78 EXIT
9359
9360         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9361                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9362
9363         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9364         echo "File size: $F78SIZE"
9365         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9366         for i in $(seq 1 $NSEQ); do
9367                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9368                 echo directIO rdwr round $i of $NSEQ
9369                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9370         done
9371
9372         cleanup_test_78
9373 }
9374 run_test 78 "handle large O_DIRECT writes correctly ============"
9375
9376 test_79() { # bug 12743
9377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9378
9379         wait_delete_completed
9380
9381         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9382         BKFREE=$(calc_osc_kbytes kbytesfree)
9383         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9384
9385         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9386         DFTOTAL=`echo $STRING | cut -d, -f1`
9387         DFUSED=`echo $STRING  | cut -d, -f2`
9388         DFAVAIL=`echo $STRING | cut -d, -f3`
9389         DFFREE=$(($DFTOTAL - $DFUSED))
9390
9391         ALLOWANCE=$((64 * $OSTCOUNT))
9392
9393         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9394            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9395                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9396         fi
9397         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9398            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9399                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9400         fi
9401         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9402            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9403                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9404         fi
9405 }
9406 run_test 79 "df report consistency check ======================="
9407
9408 test_80() { # bug 10718
9409         remote_ost_nodsh && skip "remote OST with nodsh"
9410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9411
9412         # relax strong synchronous semantics for slow backends like ZFS
9413         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9414                 local soc="obdfilter.*.sync_lock_cancel"
9415                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9416
9417                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9418                 if [ -z "$save" ]; then
9419                         soc="obdfilter.*.sync_on_lock_cancel"
9420                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9421                 fi
9422
9423                 if [ "$save" != "never" ]; then
9424                         local hosts=$(comma_list $(osts_nodes))
9425
9426                         do_nodes $hosts $LCTL set_param $soc=never
9427                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9428                 fi
9429         fi
9430
9431         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9432         sync; sleep 1; sync
9433         local before=$(date +%s)
9434         cancel_lru_locks osc
9435         local after=$(date +%s)
9436         local diff=$((after - before))
9437         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9438
9439         rm -f $DIR/$tfile
9440 }
9441 run_test 80 "Page eviction is equally fast at high offsets too"
9442
9443 test_81a() { # LU-456
9444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9445         remote_ost_nodsh && skip "remote OST with nodsh"
9446
9447         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9448         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9449         do_facet ost1 lctl set_param fail_loc=0x80000228
9450
9451         # write should trigger a retry and success
9452         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9453         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9454         RC=$?
9455         if [ $RC -ne 0 ] ; then
9456                 error "write should success, but failed for $RC"
9457         fi
9458 }
9459 run_test 81a "OST should retry write when get -ENOSPC ==============="
9460
9461 test_81b() { # LU-456
9462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9463         remote_ost_nodsh && skip "remote OST with nodsh"
9464
9465         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9466         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9467         do_facet ost1 lctl set_param fail_loc=0x228
9468
9469         # write should retry several times and return -ENOSPC finally
9470         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9471         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9472         RC=$?
9473         ENOSPC=28
9474         if [ $RC -ne $ENOSPC ] ; then
9475                 error "dd should fail for -ENOSPC, but succeed."
9476         fi
9477 }
9478 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9479
9480 test_99() {
9481         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9482
9483         test_mkdir $DIR/$tdir.cvsroot
9484         chown $RUNAS_ID $DIR/$tdir.cvsroot
9485
9486         cd $TMP
9487         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9488
9489         cd /etc/init.d
9490         # some versions of cvs import exit(1) when asked to import links or
9491         # files they can't read.  ignore those files.
9492         local toignore=$(find . -type l -printf '-I %f\n' -o \
9493                          ! -perm /4 -printf '-I %f\n')
9494         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9495                 $tdir.reposname vtag rtag
9496
9497         cd $DIR
9498         test_mkdir $DIR/$tdir.reposname
9499         chown $RUNAS_ID $DIR/$tdir.reposname
9500         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9501
9502         cd $DIR/$tdir.reposname
9503         $RUNAS touch foo99
9504         $RUNAS cvs add -m 'addmsg' foo99
9505         $RUNAS cvs update
9506         $RUNAS cvs commit -m 'nomsg' foo99
9507         rm -fr $DIR/$tdir.cvsroot
9508 }
9509 run_test 99 "cvs strange file/directory operations"
9510
9511 test_100() {
9512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9513         [[ "$NETTYPE" =~ tcp ]] ||
9514                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9515         remote_ost_nodsh && skip "remote OST with nodsh"
9516         remote_mds_nodsh && skip "remote MDS with nodsh"
9517         remote_servers ||
9518                 skip "useless for local single node setup"
9519
9520         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9521                 [ "$PROT" != "tcp" ] && continue
9522                 RPORT=$(echo $REMOTE | cut -d: -f2)
9523                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9524
9525                 rc=0
9526                 LPORT=`echo $LOCAL | cut -d: -f2`
9527                 if [ $LPORT -ge 1024 ]; then
9528                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9529                         netstat -tna
9530                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9531                 fi
9532         done
9533         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9534 }
9535 run_test 100 "check local port using privileged port ==========="
9536
9537 function get_named_value()
9538 {
9539     local tag
9540
9541     tag=$1
9542     while read ;do
9543         line=$REPLY
9544         case $line in
9545         $tag*)
9546             echo $line | sed "s/^$tag[ ]*//"
9547             break
9548             ;;
9549         esac
9550     done
9551 }
9552
9553 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9554                    awk '/^max_cached_mb/ { print $2 }')
9555
9556 cleanup_101a() {
9557         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9558         trap 0
9559 }
9560
9561 test_101a() {
9562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9563
9564         local s
9565         local discard
9566         local nreads=10000
9567         local cache_limit=32
9568
9569         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9570         trap cleanup_101a EXIT
9571         $LCTL set_param -n llite.*.read_ahead_stats 0
9572         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9573
9574         #
9575         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9576         #
9577         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9578         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9579
9580         discard=0
9581         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9582                 get_named_value 'read but discarded' | cut -d" " -f1); do
9583                         discard=$(($discard + $s))
9584         done
9585         cleanup_101a
9586
9587         $LCTL get_param osc.*-osc*.rpc_stats
9588         $LCTL get_param llite.*.read_ahead_stats
9589
9590         # Discard is generally zero, but sometimes a few random reads line up
9591         # and trigger larger readahead, which is wasted & leads to discards.
9592         if [[ $(($discard)) -gt $nreads ]]; then
9593                 error "too many ($discard) discarded pages"
9594         fi
9595         rm -f $DIR/$tfile || true
9596 }
9597 run_test 101a "check read-ahead for random reads"
9598
9599 setup_test101bc() {
9600         test_mkdir $DIR/$tdir
9601         local ssize=$1
9602         local FILE_LENGTH=$2
9603         STRIPE_OFFSET=0
9604
9605         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9606
9607         local list=$(comma_list $(osts_nodes))
9608         set_osd_param $list '' read_cache_enable 0
9609         set_osd_param $list '' writethrough_cache_enable 0
9610
9611         trap cleanup_test101bc EXIT
9612         # prepare the read-ahead file
9613         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9614
9615         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9616                                 count=$FILE_SIZE_MB 2> /dev/null
9617
9618 }
9619
9620 cleanup_test101bc() {
9621         trap 0
9622         rm -rf $DIR/$tdir
9623         rm -f $DIR/$tfile
9624
9625         local list=$(comma_list $(osts_nodes))
9626         set_osd_param $list '' read_cache_enable 1
9627         set_osd_param $list '' writethrough_cache_enable 1
9628 }
9629
9630 calc_total() {
9631         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9632 }
9633
9634 ra_check_101() {
9635         local READ_SIZE=$1
9636         local STRIPE_SIZE=$2
9637         local FILE_LENGTH=$3
9638         local RA_INC=1048576
9639         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9640         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9641                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9642         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9643                         get_named_value 'read but discarded' |
9644                         cut -d" " -f1 | calc_total)
9645         if [[ $DISCARD -gt $discard_limit ]]; then
9646                 $LCTL get_param llite.*.read_ahead_stats
9647                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9648         else
9649                 echo "Read-ahead success for size ${READ_SIZE}"
9650         fi
9651 }
9652
9653 test_101b() {
9654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9655         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9656
9657         local STRIPE_SIZE=1048576
9658         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9659
9660         if [ $SLOW == "yes" ]; then
9661                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9662         else
9663                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9664         fi
9665
9666         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9667
9668         # prepare the read-ahead file
9669         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9670         cancel_lru_locks osc
9671         for BIDX in 2 4 8 16 32 64 128 256
9672         do
9673                 local BSIZE=$((BIDX*4096))
9674                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9675                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9676                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9677                 $LCTL set_param -n llite.*.read_ahead_stats 0
9678                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9679                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9680                 cancel_lru_locks osc
9681                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9682         done
9683         cleanup_test101bc
9684         true
9685 }
9686 run_test 101b "check stride-io mode read-ahead ================="
9687
9688 test_101c() {
9689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9690
9691         local STRIPE_SIZE=1048576
9692         local FILE_LENGTH=$((STRIPE_SIZE*100))
9693         local nreads=10000
9694         local rsize=65536
9695         local osc_rpc_stats
9696
9697         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9698
9699         cancel_lru_locks osc
9700         $LCTL set_param osc.*.rpc_stats 0
9701         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9702         $LCTL get_param osc.*.rpc_stats
9703         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9704                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9705                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9706                 local size
9707
9708                 if [ $lines -le 20 ]; then
9709                         echo "continue debug"
9710                         continue
9711                 fi
9712                 for size in 1 2 4 8; do
9713                         local rpc=$(echo "$stats" |
9714                                     awk '($1 == "'$size':") {print $2; exit; }')
9715                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9716                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9717                 done
9718                 echo "$osc_rpc_stats check passed!"
9719         done
9720         cleanup_test101bc
9721         true
9722 }
9723 run_test 101c "check stripe_size aligned read-ahead ================="
9724
9725 test_101d() {
9726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9727
9728         local file=$DIR/$tfile
9729         local sz_MB=${FILESIZE_101d:-80}
9730         local ra_MB=${READAHEAD_MB:-40}
9731
9732         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9733         [ $free_MB -lt $sz_MB ] &&
9734                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9735
9736         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9737         $LFS setstripe -c -1 $file || error "setstripe failed"
9738
9739         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9740         echo Cancel LRU locks on lustre client to flush the client cache
9741         cancel_lru_locks osc
9742
9743         echo Disable read-ahead
9744         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9745         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9746         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9747         $LCTL get_param -n llite.*.max_read_ahead_mb
9748
9749         echo "Reading the test file $file with read-ahead disabled"
9750         local sz_KB=$((sz_MB * 1024 / 4))
9751         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9752         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9753         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9754                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9755
9756         echo "Cancel LRU locks on lustre client to flush the client cache"
9757         cancel_lru_locks osc
9758         echo Enable read-ahead with ${ra_MB}MB
9759         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9760
9761         echo "Reading the test file $file with read-ahead enabled"
9762         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9763                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9764
9765         echo "read-ahead disabled time read $raOFF"
9766         echo "read-ahead enabled time read $raON"
9767
9768         rm -f $file
9769         wait_delete_completed
9770
9771         # use awk for this check instead of bash because it handles decimals
9772         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9773                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9774 }
9775 run_test 101d "file read with and without read-ahead enabled"
9776
9777 test_101e() {
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779
9780         local file=$DIR/$tfile
9781         local size_KB=500  #KB
9782         local count=100
9783         local bsize=1024
9784
9785         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9786         local need_KB=$((count * size_KB))
9787         [[ $free_KB -le $need_KB ]] &&
9788                 skip_env "Need free space $need_KB, have $free_KB"
9789
9790         echo "Creating $count ${size_KB}K test files"
9791         for ((i = 0; i < $count; i++)); do
9792                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9793         done
9794
9795         echo "Cancel LRU locks on lustre client to flush the client cache"
9796         cancel_lru_locks $OSC
9797
9798         echo "Reset readahead stats"
9799         $LCTL set_param -n llite.*.read_ahead_stats 0
9800
9801         for ((i = 0; i < $count; i++)); do
9802                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9803         done
9804
9805         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9806                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9807
9808         for ((i = 0; i < $count; i++)); do
9809                 rm -rf $file.$i 2>/dev/null
9810         done
9811
9812         #10000 means 20% reads are missing in readahead
9813         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9814 }
9815 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9816
9817 test_101f() {
9818         which iozone || skip_env "no iozone installed"
9819
9820         local old_debug=$($LCTL get_param debug)
9821         old_debug=${old_debug#*=}
9822         $LCTL set_param debug="reada mmap"
9823
9824         # create a test file
9825         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9826
9827         echo Cancel LRU locks on lustre client to flush the client cache
9828         cancel_lru_locks osc
9829
9830         echo Reset readahead stats
9831         $LCTL set_param -n llite.*.read_ahead_stats 0
9832
9833         echo mmap read the file with small block size
9834         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9835                 > /dev/null 2>&1
9836
9837         echo checking missing pages
9838         $LCTL get_param llite.*.read_ahead_stats
9839         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9840                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9841
9842         $LCTL set_param debug="$old_debug"
9843         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9844         rm -f $DIR/$tfile
9845 }
9846 run_test 101f "check mmap read performance"
9847
9848 test_101g_brw_size_test() {
9849         local mb=$1
9850         local pages=$((mb * 1048576 / PAGE_SIZE))
9851         local file=$DIR/$tfile
9852
9853         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9854                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9855         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9856                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9857                         return 2
9858         done
9859
9860         stack_trap "rm -f $file" EXIT
9861         $LCTL set_param -n osc.*.rpc_stats=0
9862
9863         # 10 RPCs should be enough for the test
9864         local count=10
9865         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9866                 { error "dd write ${mb} MB blocks failed"; return 3; }
9867         cancel_lru_locks osc
9868         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9869                 { error "dd write ${mb} MB blocks failed"; return 4; }
9870
9871         # calculate number of full-sized read and write RPCs
9872         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9873                 sed -n '/pages per rpc/,/^$/p' |
9874                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9875                 END { print reads,writes }'))
9876         # allow one extra full-sized read RPC for async readahead
9877         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9878                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9879         [[ ${rpcs[1]} == $count ]] ||
9880                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9881 }
9882
9883 test_101g() {
9884         remote_ost_nodsh && skip "remote OST with nodsh"
9885
9886         local rpcs
9887         local osts=$(get_facets OST)
9888         local list=$(comma_list $(osts_nodes))
9889         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9890         local brw_size="obdfilter.*.brw_size"
9891
9892         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9893
9894         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9895
9896         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9897                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9898                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9899            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9900                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9901                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9902
9903                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9904                         suffix="M"
9905
9906                 if [[ $orig_mb -lt 16 ]]; then
9907                         save_lustre_params $osts "$brw_size" > $p
9908                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9909                                 error "set 16MB RPC size failed"
9910
9911                         echo "remount client to enable new RPC size"
9912                         remount_client $MOUNT || error "remount_client failed"
9913                 fi
9914
9915                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9916                 # should be able to set brw_size=12, but no rpc_stats for that
9917                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9918         fi
9919
9920         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9921
9922         if [[ $orig_mb -lt 16 ]]; then
9923                 restore_lustre_params < $p
9924                 remount_client $MOUNT || error "remount_client restore failed"
9925         fi
9926
9927         rm -f $p $DIR/$tfile
9928 }
9929 run_test 101g "Big bulk(4/16 MiB) readahead"
9930
9931 test_101h() {
9932         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9933
9934         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9935                 error "dd 70M file failed"
9936         echo Cancel LRU locks on lustre client to flush the client cache
9937         cancel_lru_locks osc
9938
9939         echo "Reset readahead stats"
9940         $LCTL set_param -n llite.*.read_ahead_stats 0
9941
9942         echo "Read 10M of data but cross 64M bundary"
9943         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9944         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9945                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9946         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9947         rm -f $p $DIR/$tfile
9948 }
9949 run_test 101h "Readahead should cover current read window"
9950
9951 test_101i() {
9952         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9953                 error "dd 10M file failed"
9954
9955         local max_per_file_mb=$($LCTL get_param -n \
9956                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9957         cancel_lru_locks osc
9958         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9959         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9960                 error "set max_read_ahead_per_file_mb to 1 failed"
9961
9962         echo "Reset readahead stats"
9963         $LCTL set_param llite.*.read_ahead_stats=0
9964
9965         dd if=$DIR/$tfile of=/dev/null bs=2M
9966
9967         $LCTL get_param llite.*.read_ahead_stats
9968         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9969                      awk '/misses/ { print $2 }')
9970         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9971         rm -f $DIR/$tfile
9972 }
9973 run_test 101i "allow current readahead to exceed reservation"
9974
9975 test_101j() {
9976         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9977                 error "setstripe $DIR/$tfile failed"
9978         local file_size=$((1048576 * 16))
9979         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9980         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9981
9982         echo Disable read-ahead
9983         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9984
9985         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9986         for blk in $PAGE_SIZE 1048576 $file_size; do
9987                 cancel_lru_locks osc
9988                 echo "Reset readahead stats"
9989                 $LCTL set_param -n llite.*.read_ahead_stats=0
9990                 local count=$(($file_size / $blk))
9991                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9992                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9993                              get_named_value 'failed to fast read' |
9994                              cut -d" " -f1 | calc_total)
9995                 $LCTL get_param -n llite.*.read_ahead_stats
9996                 [ $miss -eq $count ] || error "expected $count got $miss"
9997         done
9998
9999         rm -f $p $DIR/$tfile
10000 }
10001 run_test 101j "A complete read block should be submitted when no RA"
10002
10003 setup_test102() {
10004         test_mkdir $DIR/$tdir
10005         chown $RUNAS_ID $DIR/$tdir
10006         STRIPE_SIZE=65536
10007         STRIPE_OFFSET=1
10008         STRIPE_COUNT=$OSTCOUNT
10009         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10010
10011         trap cleanup_test102 EXIT
10012         cd $DIR
10013         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10014         cd $DIR/$tdir
10015         for num in 1 2 3 4; do
10016                 for count in $(seq 1 $STRIPE_COUNT); do
10017                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10018                                 local size=`expr $STRIPE_SIZE \* $num`
10019                                 local file=file"$num-$idx-$count"
10020                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10021                         done
10022                 done
10023         done
10024
10025         cd $DIR
10026         $1 tar cf $TMP/f102.tar $tdir --xattrs
10027 }
10028
10029 cleanup_test102() {
10030         trap 0
10031         rm -f $TMP/f102.tar
10032         rm -rf $DIR/d0.sanity/d102
10033 }
10034
10035 test_102a() {
10036         [ "$UID" != 0 ] && skip "must run as root"
10037         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10038                 skip_env "must have user_xattr"
10039
10040         [ -z "$(which setfattr 2>/dev/null)" ] &&
10041                 skip_env "could not find setfattr"
10042
10043         local testfile=$DIR/$tfile
10044
10045         touch $testfile
10046         echo "set/get xattr..."
10047         setfattr -n trusted.name1 -v value1 $testfile ||
10048                 error "setfattr -n trusted.name1=value1 $testfile failed"
10049         getfattr -n trusted.name1 $testfile 2> /dev/null |
10050           grep "trusted.name1=.value1" ||
10051                 error "$testfile missing trusted.name1=value1"
10052
10053         setfattr -n user.author1 -v author1 $testfile ||
10054                 error "setfattr -n user.author1=author1 $testfile failed"
10055         getfattr -n user.author1 $testfile 2> /dev/null |
10056           grep "user.author1=.author1" ||
10057                 error "$testfile missing trusted.author1=author1"
10058
10059         echo "listxattr..."
10060         setfattr -n trusted.name2 -v value2 $testfile ||
10061                 error "$testfile unable to set trusted.name2"
10062         setfattr -n trusted.name3 -v value3 $testfile ||
10063                 error "$testfile unable to set trusted.name3"
10064         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10065             grep "trusted.name" | wc -l) -eq 3 ] ||
10066                 error "$testfile missing 3 trusted.name xattrs"
10067
10068         setfattr -n user.author2 -v author2 $testfile ||
10069                 error "$testfile unable to set user.author2"
10070         setfattr -n user.author3 -v author3 $testfile ||
10071                 error "$testfile unable to set user.author3"
10072         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10073             grep "user.author" | wc -l) -eq 3 ] ||
10074                 error "$testfile missing 3 user.author xattrs"
10075
10076         echo "remove xattr..."
10077         setfattr -x trusted.name1 $testfile ||
10078                 error "$testfile error deleting trusted.name1"
10079         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10080                 error "$testfile did not delete trusted.name1 xattr"
10081
10082         setfattr -x user.author1 $testfile ||
10083                 error "$testfile error deleting user.author1"
10084         echo "set lustre special xattr ..."
10085         $LFS setstripe -c1 $testfile
10086         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10087                 awk -F "=" '/trusted.lov/ { print $2 }' )
10088         setfattr -n "trusted.lov" -v $lovea $testfile ||
10089                 error "$testfile doesn't ignore setting trusted.lov again"
10090         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10091                 error "$testfile allow setting invalid trusted.lov"
10092         rm -f $testfile
10093 }
10094 run_test 102a "user xattr test =================================="
10095
10096 check_102b_layout() {
10097         local layout="$*"
10098         local testfile=$DIR/$tfile
10099
10100         echo "test layout '$layout'"
10101         $LFS setstripe $layout $testfile || error "setstripe failed"
10102         $LFS getstripe -y $testfile
10103
10104         echo "get/set/list trusted.lov xattr ..." # b=10930
10105         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10106         [[ "$value" =~ "trusted.lov" ]] ||
10107                 error "can't get trusted.lov from $testfile"
10108         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10109                 error "getstripe failed"
10110
10111         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10112
10113         value=$(cut -d= -f2 <<<$value)
10114         # LU-13168: truncated xattr should fail if short lov_user_md header
10115         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10116                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10117         for len in $lens; do
10118                 echo "setfattr $len $testfile.2"
10119                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10120                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10121         done
10122         local stripe_size=$($LFS getstripe -S $testfile.2)
10123         local stripe_count=$($LFS getstripe -c $testfile.2)
10124         [[ $stripe_size -eq 65536 ]] ||
10125                 error "stripe size $stripe_size != 65536"
10126         [[ $stripe_count -eq $stripe_count_orig ]] ||
10127                 error "stripe count $stripe_count != $stripe_count_orig"
10128         rm $testfile $testfile.2
10129 }
10130
10131 test_102b() {
10132         [ -z "$(which setfattr 2>/dev/null)" ] &&
10133                 skip_env "could not find setfattr"
10134         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10135
10136         # check plain layout
10137         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10138
10139         # and also check composite layout
10140         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10141
10142 }
10143 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10144
10145 test_102c() {
10146         [ -z "$(which setfattr 2>/dev/null)" ] &&
10147                 skip_env "could not find setfattr"
10148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10149
10150         # b10930: get/set/list lustre.lov xattr
10151         echo "get/set/list lustre.lov xattr ..."
10152         test_mkdir $DIR/$tdir
10153         chown $RUNAS_ID $DIR/$tdir
10154         local testfile=$DIR/$tdir/$tfile
10155         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10156                 error "setstripe failed"
10157         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10158                 error "getstripe failed"
10159         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10160         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10161
10162         local testfile2=${testfile}2
10163         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10164                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10165
10166         $RUNAS $MCREATE $testfile2
10167         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10168         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10169         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10170         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10171         [ $stripe_count -eq $STRIPECOUNT ] ||
10172                 error "stripe count $stripe_count != $STRIPECOUNT"
10173 }
10174 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10175
10176 compare_stripe_info1() {
10177         local stripe_index_all_zero=true
10178
10179         for num in 1 2 3 4; do
10180                 for count in $(seq 1 $STRIPE_COUNT); do
10181                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10182                                 local size=$((STRIPE_SIZE * num))
10183                                 local file=file"$num-$offset-$count"
10184                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10185                                 [[ $stripe_size -ne $size ]] &&
10186                                     error "$file: size $stripe_size != $size"
10187                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10188                                 # allow fewer stripes to be created, ORI-601
10189                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10190                                     error "$file: count $stripe_count != $count"
10191                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10192                                 [[ $stripe_index -ne 0 ]] &&
10193                                         stripe_index_all_zero=false
10194                         done
10195                 done
10196         done
10197         $stripe_index_all_zero &&
10198                 error "all files are being extracted starting from OST index 0"
10199         return 0
10200 }
10201
10202 have_xattrs_include() {
10203         tar --help | grep -q xattrs-include &&
10204                 echo --xattrs-include="lustre.*"
10205 }
10206
10207 test_102d() {
10208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10209         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10210
10211         XINC=$(have_xattrs_include)
10212         setup_test102
10213         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10214         cd $DIR/$tdir/$tdir
10215         compare_stripe_info1
10216 }
10217 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10218
10219 test_102f() {
10220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10221         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10222
10223         XINC=$(have_xattrs_include)
10224         setup_test102
10225         test_mkdir $DIR/$tdir.restore
10226         cd $DIR
10227         tar cf - --xattrs $tdir | tar xf - \
10228                 -C $DIR/$tdir.restore --xattrs $XINC
10229         cd $DIR/$tdir.restore/$tdir
10230         compare_stripe_info1
10231 }
10232 run_test 102f "tar copy files, not keep osts"
10233
10234 grow_xattr() {
10235         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10236                 skip "must have user_xattr"
10237         [ -z "$(which setfattr 2>/dev/null)" ] &&
10238                 skip_env "could not find setfattr"
10239         [ -z "$(which getfattr 2>/dev/null)" ] &&
10240                 skip_env "could not find getfattr"
10241
10242         local xsize=${1:-1024}  # in bytes
10243         local file=$DIR/$tfile
10244         local value="$(generate_string $xsize)"
10245         local xbig=trusted.big
10246         local toobig=$2
10247
10248         touch $file
10249         log "save $xbig on $file"
10250         if [ -z "$toobig" ]
10251         then
10252                 setfattr -n $xbig -v $value $file ||
10253                         error "saving $xbig on $file failed"
10254         else
10255                 setfattr -n $xbig -v $value $file &&
10256                         error "saving $xbig on $file succeeded"
10257                 return 0
10258         fi
10259
10260         local orig=$(get_xattr_value $xbig $file)
10261         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10262
10263         local xsml=trusted.sml
10264         log "save $xsml on $file"
10265         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10266
10267         local new=$(get_xattr_value $xbig $file)
10268         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10269
10270         log "grow $xsml on $file"
10271         setfattr -n $xsml -v "$value" $file ||
10272                 error "growing $xsml on $file failed"
10273
10274         new=$(get_xattr_value $xbig $file)
10275         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10276         log "$xbig still valid after growing $xsml"
10277
10278         rm -f $file
10279 }
10280
10281 test_102h() { # bug 15777
10282         grow_xattr 1024
10283 }
10284 run_test 102h "grow xattr from inside inode to external block"
10285
10286 test_102ha() {
10287         large_xattr_enabled || skip_env "ea_inode feature disabled"
10288
10289         echo "setting xattr of max xattr size: $(max_xattr_size)"
10290         grow_xattr $(max_xattr_size)
10291
10292         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10293         echo "This should fail:"
10294         grow_xattr $(($(max_xattr_size) + 10)) 1
10295 }
10296 run_test 102ha "grow xattr from inside inode to external inode"
10297
10298 test_102i() { # bug 17038
10299         [ -z "$(which getfattr 2>/dev/null)" ] &&
10300                 skip "could not find getfattr"
10301
10302         touch $DIR/$tfile
10303         ln -s $DIR/$tfile $DIR/${tfile}link
10304         getfattr -n trusted.lov $DIR/$tfile ||
10305                 error "lgetxattr on $DIR/$tfile failed"
10306         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10307                 grep -i "no such attr" ||
10308                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10309         rm -f $DIR/$tfile $DIR/${tfile}link
10310 }
10311 run_test 102i "lgetxattr test on symbolic link ============"
10312
10313 test_102j() {
10314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10315         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10316
10317         XINC=$(have_xattrs_include)
10318         setup_test102 "$RUNAS"
10319         chown $RUNAS_ID $DIR/$tdir
10320         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10321         cd $DIR/$tdir/$tdir
10322         compare_stripe_info1 "$RUNAS"
10323 }
10324 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10325
10326 test_102k() {
10327         [ -z "$(which setfattr 2>/dev/null)" ] &&
10328                 skip "could not find setfattr"
10329
10330         touch $DIR/$tfile
10331         # b22187 just check that does not crash for regular file.
10332         setfattr -n trusted.lov $DIR/$tfile
10333         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10334         local test_kdir=$DIR/$tdir
10335         test_mkdir $test_kdir
10336         local default_size=$($LFS getstripe -S $test_kdir)
10337         local default_count=$($LFS getstripe -c $test_kdir)
10338         local default_offset=$($LFS getstripe -i $test_kdir)
10339         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10340                 error 'dir setstripe failed'
10341         setfattr -n trusted.lov $test_kdir
10342         local stripe_size=$($LFS getstripe -S $test_kdir)
10343         local stripe_count=$($LFS getstripe -c $test_kdir)
10344         local stripe_offset=$($LFS getstripe -i $test_kdir)
10345         [ $stripe_size -eq $default_size ] ||
10346                 error "stripe size $stripe_size != $default_size"
10347         [ $stripe_count -eq $default_count ] ||
10348                 error "stripe count $stripe_count != $default_count"
10349         [ $stripe_offset -eq $default_offset ] ||
10350                 error "stripe offset $stripe_offset != $default_offset"
10351         rm -rf $DIR/$tfile $test_kdir
10352 }
10353 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10354
10355 test_102l() {
10356         [ -z "$(which getfattr 2>/dev/null)" ] &&
10357                 skip "could not find getfattr"
10358
10359         # LU-532 trusted. xattr is invisible to non-root
10360         local testfile=$DIR/$tfile
10361
10362         touch $testfile
10363
10364         echo "listxattr as user..."
10365         chown $RUNAS_ID $testfile
10366         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10367             grep -q "trusted" &&
10368                 error "$testfile trusted xattrs are user visible"
10369
10370         return 0;
10371 }
10372 run_test 102l "listxattr size test =================================="
10373
10374 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10375         local path=$DIR/$tfile
10376         touch $path
10377
10378         listxattr_size_check $path || error "listattr_size_check $path failed"
10379 }
10380 run_test 102m "Ensure listxattr fails on small bufffer ========"
10381
10382 cleanup_test102
10383
10384 getxattr() { # getxattr path name
10385         # Return the base64 encoding of the value of xattr name on path.
10386         local path=$1
10387         local name=$2
10388
10389         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10390         # file: $path
10391         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10392         #
10393         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10394
10395         getfattr --absolute-names --encoding=base64 --name=$name $path |
10396                 awk -F= -v name=$name '$1 == name {
10397                         print substr($0, index($0, "=") + 1);
10398         }'
10399 }
10400
10401 test_102n() { # LU-4101 mdt: protect internal xattrs
10402         [ -z "$(which setfattr 2>/dev/null)" ] &&
10403                 skip "could not find setfattr"
10404         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10405         then
10406                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10407         fi
10408
10409         local file0=$DIR/$tfile.0
10410         local file1=$DIR/$tfile.1
10411         local xattr0=$TMP/$tfile.0
10412         local xattr1=$TMP/$tfile.1
10413         local namelist="lov lma lmv link fid version som hsm"
10414         local name
10415         local value
10416
10417         rm -rf $file0 $file1 $xattr0 $xattr1
10418         touch $file0 $file1
10419
10420         # Get 'before' xattrs of $file1.
10421         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10422
10423         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10424                 namelist+=" lfsck_namespace"
10425         for name in $namelist; do
10426                 # Try to copy xattr from $file0 to $file1.
10427                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10428
10429                 setfattr --name=trusted.$name --value="$value" $file1 ||
10430                         error "setxattr 'trusted.$name' failed"
10431
10432                 # Try to set a garbage xattr.
10433                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10434
10435                 if [[ x$name == "xlov" ]]; then
10436                         setfattr --name=trusted.lov --value="$value" $file1 &&
10437                         error "setxattr invalid 'trusted.lov' success"
10438                 else
10439                         setfattr --name=trusted.$name --value="$value" $file1 ||
10440                                 error "setxattr invalid 'trusted.$name' failed"
10441                 fi
10442
10443                 # Try to remove the xattr from $file1. We don't care if this
10444                 # appears to succeed or fail, we just don't want there to be
10445                 # any changes or crashes.
10446                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10447         done
10448
10449         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10450         then
10451                 name="lfsck_ns"
10452                 # Try to copy xattr from $file0 to $file1.
10453                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10454
10455                 setfattr --name=trusted.$name --value="$value" $file1 ||
10456                         error "setxattr 'trusted.$name' failed"
10457
10458                 # Try to set a garbage xattr.
10459                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10460
10461                 setfattr --name=trusted.$name --value="$value" $file1 ||
10462                         error "setxattr 'trusted.$name' failed"
10463
10464                 # Try to remove the xattr from $file1. We don't care if this
10465                 # appears to succeed or fail, we just don't want there to be
10466                 # any changes or crashes.
10467                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10468         fi
10469
10470         # Get 'after' xattrs of file1.
10471         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10472
10473         if ! diff $xattr0 $xattr1; then
10474                 error "before and after xattrs of '$file1' differ"
10475         fi
10476
10477         rm -rf $file0 $file1 $xattr0 $xattr1
10478
10479         return 0
10480 }
10481 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10482
10483 test_102p() { # LU-4703 setxattr did not check ownership
10484         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10485                 skip "MDS needs to be at least 2.5.56"
10486
10487         local testfile=$DIR/$tfile
10488
10489         touch $testfile
10490
10491         echo "setfacl as user..."
10492         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10493         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10494
10495         echo "setfattr as user..."
10496         setfacl -m "u:$RUNAS_ID:---" $testfile
10497         $RUNAS setfattr -x system.posix_acl_access $testfile
10498         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10499 }
10500 run_test 102p "check setxattr(2) correctly fails without permission"
10501
10502 test_102q() {
10503         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10504                 skip "MDS needs to be at least 2.6.92"
10505
10506         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10507 }
10508 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10509
10510 test_102r() {
10511         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10512                 skip "MDS needs to be at least 2.6.93"
10513
10514         touch $DIR/$tfile || error "touch"
10515         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10516         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10517         rm $DIR/$tfile || error "rm"
10518
10519         #normal directory
10520         mkdir -p $DIR/$tdir || error "mkdir"
10521         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10522         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10523         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10524                 error "$testfile error deleting user.author1"
10525         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10526                 grep "user.$(basename $tdir)" &&
10527                 error "$tdir did not delete user.$(basename $tdir)"
10528         rmdir $DIR/$tdir || error "rmdir"
10529
10530         #striped directory
10531         test_mkdir $DIR/$tdir
10532         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10533         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10534         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10535                 error "$testfile error deleting user.author1"
10536         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10537                 grep "user.$(basename $tdir)" &&
10538                 error "$tdir did not delete user.$(basename $tdir)"
10539         rmdir $DIR/$tdir || error "rm striped dir"
10540 }
10541 run_test 102r "set EAs with empty values"
10542
10543 test_102s() {
10544         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10545                 skip "MDS needs to be at least 2.11.52"
10546
10547         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10548
10549         save_lustre_params client "llite.*.xattr_cache" > $save
10550
10551         for cache in 0 1; do
10552                 lctl set_param llite.*.xattr_cache=$cache
10553
10554                 rm -f $DIR/$tfile
10555                 touch $DIR/$tfile || error "touch"
10556                 for prefix in lustre security system trusted user; do
10557                         # Note getxattr() may fail with 'Operation not
10558                         # supported' or 'No such attribute' depending
10559                         # on prefix and cache.
10560                         getfattr -n $prefix.n102s $DIR/$tfile &&
10561                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10562                 done
10563         done
10564
10565         restore_lustre_params < $save
10566 }
10567 run_test 102s "getting nonexistent xattrs should fail"
10568
10569 test_102t() {
10570         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10571                 skip "MDS needs to be at least 2.11.52"
10572
10573         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10574
10575         save_lustre_params client "llite.*.xattr_cache" > $save
10576
10577         for cache in 0 1; do
10578                 lctl set_param llite.*.xattr_cache=$cache
10579
10580                 for buf_size in 0 256; do
10581                         rm -f $DIR/$tfile
10582                         touch $DIR/$tfile || error "touch"
10583                         setfattr -n user.multiop $DIR/$tfile
10584                         $MULTIOP $DIR/$tfile oa$buf_size ||
10585                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10586                 done
10587         done
10588
10589         restore_lustre_params < $save
10590 }
10591 run_test 102t "zero length xattr values handled correctly"
10592
10593 run_acl_subtest()
10594 {
10595     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10596     return $?
10597 }
10598
10599 test_103a() {
10600         [ "$UID" != 0 ] && skip "must run as root"
10601         $GSS && skip_env "could not run under gss"
10602         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10603                 skip_env "must have acl enabled"
10604         [ -z "$(which setfacl 2>/dev/null)" ] &&
10605                 skip_env "could not find setfacl"
10606         remote_mds_nodsh && skip "remote MDS with nodsh"
10607
10608         gpasswd -a daemon bin                           # LU-5641
10609         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10610
10611         declare -a identity_old
10612
10613         for num in $(seq $MDSCOUNT); do
10614                 switch_identity $num true || identity_old[$num]=$?
10615         done
10616
10617         SAVE_UMASK=$(umask)
10618         umask 0022
10619         mkdir -p $DIR/$tdir
10620         cd $DIR/$tdir
10621
10622         echo "performing cp ..."
10623         run_acl_subtest cp || error "run_acl_subtest cp failed"
10624         echo "performing getfacl-noacl..."
10625         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10626         echo "performing misc..."
10627         run_acl_subtest misc || error  "misc test failed"
10628         echo "performing permissions..."
10629         run_acl_subtest permissions || error "permissions failed"
10630         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10631         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10632                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10633                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10634         then
10635                 echo "performing permissions xattr..."
10636                 run_acl_subtest permissions_xattr ||
10637                         error "permissions_xattr failed"
10638         fi
10639         echo "performing setfacl..."
10640         run_acl_subtest setfacl || error  "setfacl test failed"
10641
10642         # inheritance test got from HP
10643         echo "performing inheritance..."
10644         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10645         chmod +x make-tree || error "chmod +x failed"
10646         run_acl_subtest inheritance || error "inheritance test failed"
10647         rm -f make-tree
10648
10649         echo "LU-974 ignore umask when acl is enabled..."
10650         run_acl_subtest 974 || error "LU-974 umask test failed"
10651         if [ $MDSCOUNT -ge 2 ]; then
10652                 run_acl_subtest 974_remote ||
10653                         error "LU-974 umask test failed under remote dir"
10654         fi
10655
10656         echo "LU-2561 newly created file is same size as directory..."
10657         if [ "$mds1_FSTYPE" != "zfs" ]; then
10658                 run_acl_subtest 2561 || error "LU-2561 test failed"
10659         else
10660                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10661         fi
10662
10663         run_acl_subtest 4924 || error "LU-4924 test failed"
10664
10665         cd $SAVE_PWD
10666         umask $SAVE_UMASK
10667
10668         for num in $(seq $MDSCOUNT); do
10669                 if [ "${identity_old[$num]}" = 1 ]; then
10670                         switch_identity $num false || identity_old[$num]=$?
10671                 fi
10672         done
10673 }
10674 run_test 103a "acl test"
10675
10676 test_103b() {
10677         declare -a pids
10678         local U
10679
10680         for U in {0..511}; do
10681                 {
10682                 local O=$(printf "%04o" $U)
10683
10684                 umask $(printf "%04o" $((511 ^ $O)))
10685                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10686                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10687
10688                 (( $S == ($O & 0666) )) ||
10689                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10690
10691                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10692                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10693                 (( $S == ($O & 0666) )) ||
10694                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10695
10696                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10697                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10698                 (( $S == ($O & 0666) )) ||
10699                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10700                 rm -f $DIR/$tfile.[smp]$0
10701                 } &
10702                 local pid=$!
10703
10704                 # limit the concurrently running threads to 64. LU-11878
10705                 local idx=$((U % 64))
10706                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10707                 pids[idx]=$pid
10708         done
10709         wait
10710 }
10711 run_test 103b "umask lfs setstripe"
10712
10713 test_103c() {
10714         mkdir -p $DIR/$tdir
10715         cp -rp $DIR/$tdir $DIR/$tdir.bak
10716
10717         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10718                 error "$DIR/$tdir shouldn't contain default ACL"
10719         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10720                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10721         true
10722 }
10723 run_test 103c "'cp -rp' won't set empty acl"
10724
10725 test_103e() {
10726         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10727                 skip "MDS needs to be at least 2.13.59"
10728
10729         mkdir -p $DIR/$tdir
10730         # one default ACL will be created for the file owner
10731         for U in {2..256}; do
10732                 setfacl -m default:user:$U:rwx $DIR/$tdir
10733                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10734                 touch $DIR/$tdir/$tfile.$U ||
10735                         error "failed to create $tfile.$U with $numacl ACLs"
10736         done
10737 }
10738 run_test 103e "inheritance of big amount of default ACLs"
10739
10740 test_104a() {
10741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10742
10743         touch $DIR/$tfile
10744         lfs df || error "lfs df failed"
10745         lfs df -ih || error "lfs df -ih failed"
10746         lfs df -h $DIR || error "lfs df -h $DIR failed"
10747         lfs df -i $DIR || error "lfs df -i $DIR failed"
10748         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10749         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10750
10751         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10752         lctl --device %$OSC deactivate
10753         lfs df || error "lfs df with deactivated OSC failed"
10754         lctl --device %$OSC activate
10755         # wait the osc back to normal
10756         wait_osc_import_ready client ost
10757
10758         lfs df || error "lfs df with reactivated OSC failed"
10759         rm -f $DIR/$tfile
10760 }
10761 run_test 104a "lfs df [-ih] [path] test ========================="
10762
10763 test_104b() {
10764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10765         [ $RUNAS_ID -eq $UID ] &&
10766                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10767
10768         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10769                         grep "Permission denied" | wc -l)))
10770         if [ $denied_cnt -ne 0 ]; then
10771                 error "lfs check servers test failed"
10772         fi
10773 }
10774 run_test 104b "$RUNAS lfs check servers test ===================="
10775
10776 test_105a() {
10777         # doesn't work on 2.4 kernels
10778         touch $DIR/$tfile
10779         if $(flock_is_enabled); then
10780                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10781         else
10782                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10783         fi
10784         rm -f $DIR/$tfile
10785 }
10786 run_test 105a "flock when mounted without -o flock test ========"
10787
10788 test_105b() {
10789         touch $DIR/$tfile
10790         if $(flock_is_enabled); then
10791                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10792         else
10793                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10794         fi
10795         rm -f $DIR/$tfile
10796 }
10797 run_test 105b "fcntl when mounted without -o flock test ========"
10798
10799 test_105c() {
10800         touch $DIR/$tfile
10801         if $(flock_is_enabled); then
10802                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10803         else
10804                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10805         fi
10806         rm -f $DIR/$tfile
10807 }
10808 run_test 105c "lockf when mounted without -o flock test"
10809
10810 test_105d() { # bug 15924
10811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10812
10813         test_mkdir $DIR/$tdir
10814         flock_is_enabled || skip_env "mount w/o flock enabled"
10815         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10816         $LCTL set_param fail_loc=0x80000315
10817         flocks_test 2 $DIR/$tdir
10818 }
10819 run_test 105d "flock race (should not freeze) ========"
10820
10821 test_105e() { # bug 22660 && 22040
10822         flock_is_enabled || skip_env "mount w/o flock enabled"
10823
10824         touch $DIR/$tfile
10825         flocks_test 3 $DIR/$tfile
10826 }
10827 run_test 105e "Two conflicting flocks from same process"
10828
10829 test_106() { #bug 10921
10830         test_mkdir $DIR/$tdir
10831         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10832         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10833 }
10834 run_test 106 "attempt exec of dir followed by chown of that dir"
10835
10836 test_107() {
10837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10838
10839         CDIR=`pwd`
10840         local file=core
10841
10842         cd $DIR
10843         rm -f $file
10844
10845         local save_pattern=$(sysctl -n kernel.core_pattern)
10846         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10847         sysctl -w kernel.core_pattern=$file
10848         sysctl -w kernel.core_uses_pid=0
10849
10850         ulimit -c unlimited
10851         sleep 60 &
10852         SLEEPPID=$!
10853
10854         sleep 1
10855
10856         kill -s 11 $SLEEPPID
10857         wait $SLEEPPID
10858         if [ -e $file ]; then
10859                 size=`stat -c%s $file`
10860                 [ $size -eq 0 ] && error "Fail to create core file $file"
10861         else
10862                 error "Fail to create core file $file"
10863         fi
10864         rm -f $file
10865         sysctl -w kernel.core_pattern=$save_pattern
10866         sysctl -w kernel.core_uses_pid=$save_uses_pid
10867         cd $CDIR
10868 }
10869 run_test 107 "Coredump on SIG"
10870
10871 test_110() {
10872         test_mkdir $DIR/$tdir
10873         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10874         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10875                 error "mkdir with 256 char should fail, but did not"
10876         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10877                 error "create with 255 char failed"
10878         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10879                 error "create with 256 char should fail, but did not"
10880
10881         ls -l $DIR/$tdir
10882         rm -rf $DIR/$tdir
10883 }
10884 run_test 110 "filename length checking"
10885
10886 #
10887 # Purpose: To verify dynamic thread (OSS) creation.
10888 #
10889 test_115() {
10890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10891         remote_ost_nodsh && skip "remote OST with nodsh"
10892
10893         # Lustre does not stop service threads once they are started.
10894         # Reset number of running threads to default.
10895         stopall
10896         setupall
10897
10898         local OSTIO_pre
10899         local save_params="$TMP/sanity-$TESTNAME.parameters"
10900
10901         # Get ll_ost_io count before I/O
10902         OSTIO_pre=$(do_facet ost1 \
10903                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10904         # Exit if lustre is not running (ll_ost_io not running).
10905         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10906
10907         echo "Starting with $OSTIO_pre threads"
10908         local thread_max=$((OSTIO_pre * 2))
10909         local rpc_in_flight=$((thread_max * 2))
10910         # Number of I/O Process proposed to be started.
10911         local nfiles
10912         local facets=$(get_facets OST)
10913
10914         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10915         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10916
10917         # Set in_flight to $rpc_in_flight
10918         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10919                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10920         nfiles=${rpc_in_flight}
10921         # Set ost thread_max to $thread_max
10922         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10923
10924         # 5 Minutes should be sufficient for max number of OSS
10925         # threads(thread_max) to be created.
10926         local timeout=300
10927
10928         # Start I/O.
10929         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10930         test_mkdir $DIR/$tdir
10931         for i in $(seq $nfiles); do
10932                 local file=$DIR/$tdir/${tfile}-$i
10933                 $LFS setstripe -c -1 -i 0 $file
10934                 ($WTL $file $timeout)&
10935         done
10936
10937         # I/O Started - Wait for thread_started to reach thread_max or report
10938         # error if thread_started is more than thread_max.
10939         echo "Waiting for thread_started to reach thread_max"
10940         local thread_started=0
10941         local end_time=$((SECONDS + timeout))
10942
10943         while [ $SECONDS -le $end_time ] ; do
10944                 echo -n "."
10945                 # Get ost i/o thread_started count.
10946                 thread_started=$(do_facet ost1 \
10947                         "$LCTL get_param \
10948                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10949                 # Break out if thread_started is equal/greater than thread_max
10950                 if [[ $thread_started -ge $thread_max ]]; then
10951                         echo ll_ost_io thread_started $thread_started, \
10952                                 equal/greater than thread_max $thread_max
10953                         break
10954                 fi
10955                 sleep 1
10956         done
10957
10958         # Cleanup - We have the numbers, Kill i/o jobs if running.
10959         jobcount=($(jobs -p))
10960         for i in $(seq 0 $((${#jobcount[@]}-1)))
10961         do
10962                 kill -9 ${jobcount[$i]}
10963                 if [ $? -ne 0 ] ; then
10964                         echo Warning: \
10965                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10966                 fi
10967         done
10968
10969         # Cleanup files left by WTL binary.
10970         for i in $(seq $nfiles); do
10971                 local file=$DIR/$tdir/${tfile}-$i
10972                 rm -rf $file
10973                 if [ $? -ne 0 ] ; then
10974                         echo "Warning: Failed to delete file $file"
10975                 fi
10976         done
10977
10978         restore_lustre_params <$save_params
10979         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10980
10981         # Error out if no new thread has started or Thread started is greater
10982         # than thread max.
10983         if [[ $thread_started -le $OSTIO_pre ||
10984                         $thread_started -gt $thread_max ]]; then
10985                 error "ll_ost_io: thread_started $thread_started" \
10986                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10987                       "No new thread started or thread started greater " \
10988                       "than thread_max."
10989         fi
10990 }
10991 run_test 115 "verify dynamic thread creation===================="
10992
10993 free_min_max () {
10994         wait_delete_completed
10995         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10996         echo "OST kbytes available: ${AVAIL[@]}"
10997         MAXV=${AVAIL[0]}
10998         MAXI=0
10999         MINV=${AVAIL[0]}
11000         MINI=0
11001         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11002                 #echo OST $i: ${AVAIL[i]}kb
11003                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11004                         MAXV=${AVAIL[i]}
11005                         MAXI=$i
11006                 fi
11007                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11008                         MINV=${AVAIL[i]}
11009                         MINI=$i
11010                 fi
11011         done
11012         echo "Min free space: OST $MINI: $MINV"
11013         echo "Max free space: OST $MAXI: $MAXV"
11014 }
11015
11016 test_116a() { # was previously test_116()
11017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11019         remote_mds_nodsh && skip "remote MDS with nodsh"
11020
11021         echo -n "Free space priority "
11022         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11023                 head -n1
11024         declare -a AVAIL
11025         free_min_max
11026
11027         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11028         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11029         trap simple_cleanup_common EXIT
11030
11031         # Check if we need to generate uneven OSTs
11032         test_mkdir -p $DIR/$tdir/OST${MINI}
11033         local FILL=$((MINV / 4))
11034         local DIFF=$((MAXV - MINV))
11035         local DIFF2=$((DIFF * 100 / MINV))
11036
11037         local threshold=$(do_facet $SINGLEMDS \
11038                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11039         threshold=${threshold%%%}
11040         echo -n "Check for uneven OSTs: "
11041         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11042
11043         if [[ $DIFF2 -gt $threshold ]]; then
11044                 echo "ok"
11045                 echo "Don't need to fill OST$MINI"
11046         else
11047                 # generate uneven OSTs. Write 2% over the QOS threshold value
11048                 echo "no"
11049                 DIFF=$((threshold - DIFF2 + 2))
11050                 DIFF2=$((MINV * DIFF / 100))
11051                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11052                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11053                         error "setstripe failed"
11054                 DIFF=$((DIFF2 / 2048))
11055                 i=0
11056                 while [ $i -lt $DIFF ]; do
11057                         i=$((i + 1))
11058                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11059                                 bs=2M count=1 2>/dev/null
11060                         echo -n .
11061                 done
11062                 echo .
11063                 sync
11064                 sleep_maxage
11065                 free_min_max
11066         fi
11067
11068         DIFF=$((MAXV - MINV))
11069         DIFF2=$((DIFF * 100 / MINV))
11070         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11071         if [ $DIFF2 -gt $threshold ]; then
11072                 echo "ok"
11073         else
11074                 echo "failed - QOS mode won't be used"
11075                 simple_cleanup_common
11076                 skip "QOS imbalance criteria not met"
11077         fi
11078
11079         MINI1=$MINI
11080         MINV1=$MINV
11081         MAXI1=$MAXI
11082         MAXV1=$MAXV
11083
11084         # now fill using QOS
11085         $LFS setstripe -c 1 $DIR/$tdir
11086         FILL=$((FILL / 200))
11087         if [ $FILL -gt 600 ]; then
11088                 FILL=600
11089         fi
11090         echo "writing $FILL files to QOS-assigned OSTs"
11091         i=0
11092         while [ $i -lt $FILL ]; do
11093                 i=$((i + 1))
11094                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11095                         count=1 2>/dev/null
11096                 echo -n .
11097         done
11098         echo "wrote $i 200k files"
11099         sync
11100         sleep_maxage
11101
11102         echo "Note: free space may not be updated, so measurements might be off"
11103         free_min_max
11104         DIFF2=$((MAXV - MINV))
11105         echo "free space delta: orig $DIFF final $DIFF2"
11106         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11107         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11108         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11109         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11110         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11111         if [[ $DIFF -gt 0 ]]; then
11112                 FILL=$((DIFF2 * 100 / DIFF - 100))
11113                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11114         fi
11115
11116         # Figure out which files were written where
11117         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11118                awk '/'$MINI1': / {print $2; exit}')
11119         echo $UUID
11120         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11121         echo "$MINC files created on smaller OST $MINI1"
11122         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11123                awk '/'$MAXI1': / {print $2; exit}')
11124         echo $UUID
11125         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11126         echo "$MAXC files created on larger OST $MAXI1"
11127         if [[ $MINC -gt 0 ]]; then
11128                 FILL=$((MAXC * 100 / MINC - 100))
11129                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11130         fi
11131         [[ $MAXC -gt $MINC ]] ||
11132                 error_ignore LU-9 "stripe QOS didn't balance free space"
11133         simple_cleanup_common
11134 }
11135 run_test 116a "stripe QOS: free space balance ==================="
11136
11137 test_116b() { # LU-2093
11138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11139         remote_mds_nodsh && skip "remote MDS with nodsh"
11140
11141 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11142         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11143                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11144         [ -z "$old_rr" ] && skip "no QOS"
11145         do_facet $SINGLEMDS lctl set_param \
11146                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11147         mkdir -p $DIR/$tdir
11148         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11149         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11150         do_facet $SINGLEMDS lctl set_param fail_loc=0
11151         rm -rf $DIR/$tdir
11152         do_facet $SINGLEMDS lctl set_param \
11153                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11154 }
11155 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11156
11157 test_117() # bug 10891
11158 {
11159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11160
11161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11162         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11163         lctl set_param fail_loc=0x21e
11164         > $DIR/$tfile || error "truncate failed"
11165         lctl set_param fail_loc=0
11166         echo "Truncate succeeded."
11167         rm -f $DIR/$tfile
11168 }
11169 run_test 117 "verify osd extend =========="
11170
11171 NO_SLOW_RESENDCOUNT=4
11172 export OLD_RESENDCOUNT=""
11173 set_resend_count () {
11174         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11175         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11176         lctl set_param -n $PROC_RESENDCOUNT $1
11177         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11178 }
11179
11180 # for reduce test_118* time (b=14842)
11181 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11182
11183 # Reset async IO behavior after error case
11184 reset_async() {
11185         FILE=$DIR/reset_async
11186
11187         # Ensure all OSCs are cleared
11188         $LFS setstripe -c -1 $FILE
11189         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11190         sync
11191         rm $FILE
11192 }
11193
11194 test_118a() #bug 11710
11195 {
11196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11197
11198         reset_async
11199
11200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11201         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11202         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11203
11204         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11205                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11206                 return 1;
11207         fi
11208         rm -f $DIR/$tfile
11209 }
11210 run_test 118a "verify O_SYNC works =========="
11211
11212 test_118b()
11213 {
11214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11215         remote_ost_nodsh && skip "remote OST with nodsh"
11216
11217         reset_async
11218
11219         #define OBD_FAIL_SRV_ENOENT 0x217
11220         set_nodes_failloc "$(osts_nodes)" 0x217
11221         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11222         RC=$?
11223         set_nodes_failloc "$(osts_nodes)" 0
11224         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11225         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11226                     grep -c writeback)
11227
11228         if [[ $RC -eq 0 ]]; then
11229                 error "Must return error due to dropped pages, rc=$RC"
11230                 return 1;
11231         fi
11232
11233         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11234                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11235                 return 1;
11236         fi
11237
11238         echo "Dirty pages not leaked on ENOENT"
11239
11240         # Due to the above error the OSC will issue all RPCs syncronously
11241         # until a subsequent RPC completes successfully without error.
11242         $MULTIOP $DIR/$tfile Ow4096yc
11243         rm -f $DIR/$tfile
11244
11245         return 0
11246 }
11247 run_test 118b "Reclaim dirty pages on fatal error =========="
11248
11249 test_118c()
11250 {
11251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11252
11253         # for 118c, restore the original resend count, LU-1940
11254         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11255                                 set_resend_count $OLD_RESENDCOUNT
11256         remote_ost_nodsh && skip "remote OST with nodsh"
11257
11258         reset_async
11259
11260         #define OBD_FAIL_OST_EROFS               0x216
11261         set_nodes_failloc "$(osts_nodes)" 0x216
11262
11263         # multiop should block due to fsync until pages are written
11264         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11265         MULTIPID=$!
11266         sleep 1
11267
11268         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11269                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11270         fi
11271
11272         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11273                     grep -c writeback)
11274         if [[ $WRITEBACK -eq 0 ]]; then
11275                 error "No page in writeback, writeback=$WRITEBACK"
11276         fi
11277
11278         set_nodes_failloc "$(osts_nodes)" 0
11279         wait $MULTIPID
11280         RC=$?
11281         if [[ $RC -ne 0 ]]; then
11282                 error "Multiop fsync failed, rc=$RC"
11283         fi
11284
11285         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11286         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11287                     grep -c writeback)
11288         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11289                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11290         fi
11291
11292         rm -f $DIR/$tfile
11293         echo "Dirty pages flushed via fsync on EROFS"
11294         return 0
11295 }
11296 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11297
11298 # continue to use small resend count to reduce test_118* time (b=14842)
11299 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11300
11301 test_118d()
11302 {
11303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11304         remote_ost_nodsh && skip "remote OST with nodsh"
11305
11306         reset_async
11307
11308         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11309         set_nodes_failloc "$(osts_nodes)" 0x214
11310         # multiop should block due to fsync until pages are written
11311         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11312         MULTIPID=$!
11313         sleep 1
11314
11315         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11316                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11317         fi
11318
11319         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11320                     grep -c writeback)
11321         if [[ $WRITEBACK -eq 0 ]]; then
11322                 error "No page in writeback, writeback=$WRITEBACK"
11323         fi
11324
11325         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11326         set_nodes_failloc "$(osts_nodes)" 0
11327
11328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11330                     grep -c writeback)
11331         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11332                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11333         fi
11334
11335         rm -f $DIR/$tfile
11336         echo "Dirty pages gaurenteed flushed via fsync"
11337         return 0
11338 }
11339 run_test 118d "Fsync validation inject a delay of the bulk =========="
11340
11341 test_118f() {
11342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11343
11344         reset_async
11345
11346         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11347         lctl set_param fail_loc=0x8000040a
11348
11349         # Should simulate EINVAL error which is fatal
11350         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11351         RC=$?
11352         if [[ $RC -eq 0 ]]; then
11353                 error "Must return error due to dropped pages, rc=$RC"
11354         fi
11355
11356         lctl set_param fail_loc=0x0
11357
11358         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11359         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11360         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11361                     grep -c writeback)
11362         if [[ $LOCKED -ne 0 ]]; then
11363                 error "Locked pages remain in cache, locked=$LOCKED"
11364         fi
11365
11366         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11367                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11368         fi
11369
11370         rm -f $DIR/$tfile
11371         echo "No pages locked after fsync"
11372
11373         reset_async
11374         return 0
11375 }
11376 run_test 118f "Simulate unrecoverable OSC side error =========="
11377
11378 test_118g() {
11379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11380
11381         reset_async
11382
11383         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11384         lctl set_param fail_loc=0x406
11385
11386         # simulate local -ENOMEM
11387         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11388         RC=$?
11389
11390         lctl set_param fail_loc=0
11391         if [[ $RC -eq 0 ]]; then
11392                 error "Must return error due to dropped pages, rc=$RC"
11393         fi
11394
11395         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11396         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11397         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11398                         grep -c writeback)
11399         if [[ $LOCKED -ne 0 ]]; then
11400                 error "Locked pages remain in cache, locked=$LOCKED"
11401         fi
11402
11403         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11404                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11405         fi
11406
11407         rm -f $DIR/$tfile
11408         echo "No pages locked after fsync"
11409
11410         reset_async
11411         return 0
11412 }
11413 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11414
11415 test_118h() {
11416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11417         remote_ost_nodsh && skip "remote OST with nodsh"
11418
11419         reset_async
11420
11421         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11422         set_nodes_failloc "$(osts_nodes)" 0x20e
11423         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11424         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11425         RC=$?
11426
11427         set_nodes_failloc "$(osts_nodes)" 0
11428         if [[ $RC -eq 0 ]]; then
11429                 error "Must return error due to dropped pages, rc=$RC"
11430         fi
11431
11432         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11433         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11434         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11435                     grep -c writeback)
11436         if [[ $LOCKED -ne 0 ]]; then
11437                 error "Locked pages remain in cache, locked=$LOCKED"
11438         fi
11439
11440         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11441                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11442         fi
11443
11444         rm -f $DIR/$tfile
11445         echo "No pages locked after fsync"
11446
11447         return 0
11448 }
11449 run_test 118h "Verify timeout in handling recoverables errors  =========="
11450
11451 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11452
11453 test_118i() {
11454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11455         remote_ost_nodsh && skip "remote OST with nodsh"
11456
11457         reset_async
11458
11459         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11460         set_nodes_failloc "$(osts_nodes)" 0x20e
11461
11462         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11463         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11464         PID=$!
11465         sleep 5
11466         set_nodes_failloc "$(osts_nodes)" 0
11467
11468         wait $PID
11469         RC=$?
11470         if [[ $RC -ne 0 ]]; then
11471                 error "got error, but should be not, rc=$RC"
11472         fi
11473
11474         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11475         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11476         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11477         if [[ $LOCKED -ne 0 ]]; then
11478                 error "Locked pages remain in cache, locked=$LOCKED"
11479         fi
11480
11481         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11482                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11483         fi
11484
11485         rm -f $DIR/$tfile
11486         echo "No pages locked after fsync"
11487
11488         return 0
11489 }
11490 run_test 118i "Fix error before timeout in recoverable error  =========="
11491
11492 [ "$SLOW" = "no" ] && set_resend_count 4
11493
11494 test_118j() {
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496         remote_ost_nodsh && skip "remote OST with nodsh"
11497
11498         reset_async
11499
11500         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11501         set_nodes_failloc "$(osts_nodes)" 0x220
11502
11503         # return -EIO from OST
11504         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11505         RC=$?
11506         set_nodes_failloc "$(osts_nodes)" 0x0
11507         if [[ $RC -eq 0 ]]; then
11508                 error "Must return error due to dropped pages, rc=$RC"
11509         fi
11510
11511         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11512         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11513         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11514         if [[ $LOCKED -ne 0 ]]; then
11515                 error "Locked pages remain in cache, locked=$LOCKED"
11516         fi
11517
11518         # in recoverable error on OST we want resend and stay until it finished
11519         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11520                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11521         fi
11522
11523         rm -f $DIR/$tfile
11524         echo "No pages locked after fsync"
11525
11526         return 0
11527 }
11528 run_test 118j "Simulate unrecoverable OST side error =========="
11529
11530 test_118k()
11531 {
11532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11533         remote_ost_nodsh && skip "remote OSTs with nodsh"
11534
11535         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11536         set_nodes_failloc "$(osts_nodes)" 0x20e
11537         test_mkdir $DIR/$tdir
11538
11539         for ((i=0;i<10;i++)); do
11540                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11541                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11542                 SLEEPPID=$!
11543                 sleep 0.500s
11544                 kill $SLEEPPID
11545                 wait $SLEEPPID
11546         done
11547
11548         set_nodes_failloc "$(osts_nodes)" 0
11549         rm -rf $DIR/$tdir
11550 }
11551 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11552
11553 test_118l() # LU-646
11554 {
11555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11556
11557         test_mkdir $DIR/$tdir
11558         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11559         rm -rf $DIR/$tdir
11560 }
11561 run_test 118l "fsync dir"
11562
11563 test_118m() # LU-3066
11564 {
11565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11566
11567         test_mkdir $DIR/$tdir
11568         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11569         rm -rf $DIR/$tdir
11570 }
11571 run_test 118m "fdatasync dir ========="
11572
11573 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11574
11575 test_118n()
11576 {
11577         local begin
11578         local end
11579
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         remote_ost_nodsh && skip "remote OSTs with nodsh"
11582
11583         # Sleep to avoid a cached response.
11584         #define OBD_STATFS_CACHE_SECONDS 1
11585         sleep 2
11586
11587         # Inject a 10 second delay in the OST_STATFS handler.
11588         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11589         set_nodes_failloc "$(osts_nodes)" 0x242
11590
11591         begin=$SECONDS
11592         stat --file-system $MOUNT > /dev/null
11593         end=$SECONDS
11594
11595         set_nodes_failloc "$(osts_nodes)" 0
11596
11597         if ((end - begin > 20)); then
11598             error "statfs took $((end - begin)) seconds, expected 10"
11599         fi
11600 }
11601 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11602
11603 test_119a() # bug 11737
11604 {
11605         BSIZE=$((512 * 1024))
11606         directio write $DIR/$tfile 0 1 $BSIZE
11607         # We ask to read two blocks, which is more than a file size.
11608         # directio will indicate an error when requested and actual
11609         # sizes aren't equeal (a normal situation in this case) and
11610         # print actual read amount.
11611         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11612         if [ "$NOB" != "$BSIZE" ]; then
11613                 error "read $NOB bytes instead of $BSIZE"
11614         fi
11615         rm -f $DIR/$tfile
11616 }
11617 run_test 119a "Short directIO read must return actual read amount"
11618
11619 test_119b() # bug 11737
11620 {
11621         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11622
11623         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11625         sync
11626         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11627                 error "direct read failed"
11628         rm -f $DIR/$tfile
11629 }
11630 run_test 119b "Sparse directIO read must return actual read amount"
11631
11632 test_119c() # bug 13099
11633 {
11634         BSIZE=1048576
11635         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11636         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11637         rm -f $DIR/$tfile
11638 }
11639 run_test 119c "Testing for direct read hitting hole"
11640
11641 test_119d() # bug 15950
11642 {
11643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11644
11645         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11646         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11647         BSIZE=1048576
11648         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11649         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11650         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11651         lctl set_param fail_loc=0x40d
11652         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11653         pid_dio=$!
11654         sleep 1
11655         cat $DIR/$tfile > /dev/null &
11656         lctl set_param fail_loc=0
11657         pid_reads=$!
11658         wait $pid_dio
11659         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11660         sleep 2
11661         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11662         error "the read rpcs have not completed in 2s"
11663         rm -f $DIR/$tfile
11664         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11665 }
11666 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11667
11668 test_120a() {
11669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11670         remote_mds_nodsh && skip "remote MDS with nodsh"
11671         test_mkdir -i0 -c1 $DIR/$tdir
11672         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11673                 skip_env "no early lock cancel on server"
11674
11675         lru_resize_disable mdc
11676         lru_resize_disable osc
11677         cancel_lru_locks mdc
11678         # asynchronous object destroy at MDT could cause bl ast to client
11679         cancel_lru_locks osc
11680
11681         stat $DIR/$tdir > /dev/null
11682         can1=$(do_facet mds1 \
11683                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11684                awk '/ldlm_cancel/ {print $2}')
11685         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11686                awk '/ldlm_bl_callback/ {print $2}')
11687         test_mkdir -i0 -c1 $DIR/$tdir/d1
11688         can2=$(do_facet mds1 \
11689                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11690                awk '/ldlm_cancel/ {print $2}')
11691         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11692                awk '/ldlm_bl_callback/ {print $2}')
11693         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11694         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11695         lru_resize_enable mdc
11696         lru_resize_enable osc
11697 }
11698 run_test 120a "Early Lock Cancel: mkdir test"
11699
11700 test_120b() {
11701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11702         remote_mds_nodsh && skip "remote MDS with nodsh"
11703         test_mkdir $DIR/$tdir
11704         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11705                 skip_env "no early lock cancel on server"
11706
11707         lru_resize_disable mdc
11708         lru_resize_disable osc
11709         cancel_lru_locks mdc
11710         stat $DIR/$tdir > /dev/null
11711         can1=$(do_facet $SINGLEMDS \
11712                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11713                awk '/ldlm_cancel/ {print $2}')
11714         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11715                awk '/ldlm_bl_callback/ {print $2}')
11716         touch $DIR/$tdir/f1
11717         can2=$(do_facet $SINGLEMDS \
11718                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11719                awk '/ldlm_cancel/ {print $2}')
11720         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11721                awk '/ldlm_bl_callback/ {print $2}')
11722         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11723         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11724         lru_resize_enable mdc
11725         lru_resize_enable osc
11726 }
11727 run_test 120b "Early Lock Cancel: create test"
11728
11729 test_120c() {
11730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11731         remote_mds_nodsh && skip "remote MDS with nodsh"
11732         test_mkdir -i0 -c1 $DIR/$tdir
11733         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11734                 skip "no early lock cancel on server"
11735
11736         lru_resize_disable mdc
11737         lru_resize_disable osc
11738         test_mkdir -i0 -c1 $DIR/$tdir/d1
11739         test_mkdir -i0 -c1 $DIR/$tdir/d2
11740         touch $DIR/$tdir/d1/f1
11741         cancel_lru_locks mdc
11742         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11743         can1=$(do_facet mds1 \
11744                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11745                awk '/ldlm_cancel/ {print $2}')
11746         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11747                awk '/ldlm_bl_callback/ {print $2}')
11748         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11749         can2=$(do_facet mds1 \
11750                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11751                awk '/ldlm_cancel/ {print $2}')
11752         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11753                awk '/ldlm_bl_callback/ {print $2}')
11754         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11755         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11756         lru_resize_enable mdc
11757         lru_resize_enable osc
11758 }
11759 run_test 120c "Early Lock Cancel: link test"
11760
11761 test_120d() {
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763         remote_mds_nodsh && skip "remote MDS with nodsh"
11764         test_mkdir -i0 -c1 $DIR/$tdir
11765         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11766                 skip_env "no early lock cancel on server"
11767
11768         lru_resize_disable mdc
11769         lru_resize_disable osc
11770         touch $DIR/$tdir
11771         cancel_lru_locks mdc
11772         stat $DIR/$tdir > /dev/null
11773         can1=$(do_facet mds1 \
11774                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11775                awk '/ldlm_cancel/ {print $2}')
11776         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11777                awk '/ldlm_bl_callback/ {print $2}')
11778         chmod a+x $DIR/$tdir
11779         can2=$(do_facet mds1 \
11780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11781                awk '/ldlm_cancel/ {print $2}')
11782         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11783                awk '/ldlm_bl_callback/ {print $2}')
11784         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11785         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11786         lru_resize_enable mdc
11787         lru_resize_enable osc
11788 }
11789 run_test 120d "Early Lock Cancel: setattr test"
11790
11791 test_120e() {
11792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11793         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11794                 skip_env "no early lock cancel on server"
11795         remote_mds_nodsh && skip "remote MDS with nodsh"
11796
11797         local dlmtrace_set=false
11798
11799         test_mkdir -i0 -c1 $DIR/$tdir
11800         lru_resize_disable mdc
11801         lru_resize_disable osc
11802         ! $LCTL get_param debug | grep -q dlmtrace &&
11803                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11804         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11805         cancel_lru_locks mdc
11806         cancel_lru_locks osc
11807         dd if=$DIR/$tdir/f1 of=/dev/null
11808         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11809         # XXX client can not do early lock cancel of OST lock
11810         # during unlink (LU-4206), so cancel osc lock now.
11811         sleep 2
11812         cancel_lru_locks osc
11813         can1=$(do_facet mds1 \
11814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11815                awk '/ldlm_cancel/ {print $2}')
11816         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11817                awk '/ldlm_bl_callback/ {print $2}')
11818         unlink $DIR/$tdir/f1
11819         sleep 5
11820         can2=$(do_facet mds1 \
11821                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11822                awk '/ldlm_cancel/ {print $2}')
11823         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11824                awk '/ldlm_bl_callback/ {print $2}')
11825         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11826                 $LCTL dk $TMP/cancel.debug.txt
11827         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11828                 $LCTL dk $TMP/blocking.debug.txt
11829         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11830         lru_resize_enable mdc
11831         lru_resize_enable osc
11832 }
11833 run_test 120e "Early Lock Cancel: unlink test"
11834
11835 test_120f() {
11836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11837         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11838                 skip_env "no early lock cancel on server"
11839         remote_mds_nodsh && skip "remote MDS with nodsh"
11840
11841         test_mkdir -i0 -c1 $DIR/$tdir
11842         lru_resize_disable mdc
11843         lru_resize_disable osc
11844         test_mkdir -i0 -c1 $DIR/$tdir/d1
11845         test_mkdir -i0 -c1 $DIR/$tdir/d2
11846         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11847         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11848         cancel_lru_locks mdc
11849         cancel_lru_locks osc
11850         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11851         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11852         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11853         # XXX client can not do early lock cancel of OST lock
11854         # during rename (LU-4206), so cancel osc lock now.
11855         sleep 2
11856         cancel_lru_locks osc
11857         can1=$(do_facet mds1 \
11858                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11859                awk '/ldlm_cancel/ {print $2}')
11860         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11861                awk '/ldlm_bl_callback/ {print $2}')
11862         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11863         sleep 5
11864         can2=$(do_facet mds1 \
11865                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11866                awk '/ldlm_cancel/ {print $2}')
11867         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11868                awk '/ldlm_bl_callback/ {print $2}')
11869         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11870         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11871         lru_resize_enable mdc
11872         lru_resize_enable osc
11873 }
11874 run_test 120f "Early Lock Cancel: rename test"
11875
11876 test_120g() {
11877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11878         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11879                 skip_env "no early lock cancel on server"
11880         remote_mds_nodsh && skip "remote MDS with nodsh"
11881
11882         lru_resize_disable mdc
11883         lru_resize_disable osc
11884         count=10000
11885         echo create $count files
11886         test_mkdir $DIR/$tdir
11887         cancel_lru_locks mdc
11888         cancel_lru_locks osc
11889         t0=$(date +%s)
11890
11891         can0=$(do_facet $SINGLEMDS \
11892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11893                awk '/ldlm_cancel/ {print $2}')
11894         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11895                awk '/ldlm_bl_callback/ {print $2}')
11896         createmany -o $DIR/$tdir/f $count
11897         sync
11898         can1=$(do_facet $SINGLEMDS \
11899                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11900                awk '/ldlm_cancel/ {print $2}')
11901         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11902                awk '/ldlm_bl_callback/ {print $2}')
11903         t1=$(date +%s)
11904         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11905         echo rm $count files
11906         rm -r $DIR/$tdir
11907         sync
11908         can2=$(do_facet $SINGLEMDS \
11909                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11910                awk '/ldlm_cancel/ {print $2}')
11911         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11912                awk '/ldlm_bl_callback/ {print $2}')
11913         t2=$(date +%s)
11914         echo total: $count removes in $((t2-t1))
11915         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11916         sleep 2
11917         # wait for commitment of removal
11918         lru_resize_enable mdc
11919         lru_resize_enable osc
11920 }
11921 run_test 120g "Early Lock Cancel: performance test"
11922
11923 test_121() { #bug #10589
11924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11925
11926         rm -rf $DIR/$tfile
11927         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11928 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11929         lctl set_param fail_loc=0x310
11930         cancel_lru_locks osc > /dev/null
11931         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11932         lctl set_param fail_loc=0
11933         [[ $reads -eq $writes ]] ||
11934                 error "read $reads blocks, must be $writes blocks"
11935 }
11936 run_test 121 "read cancel race ========="
11937
11938 test_123a_base() { # was test 123, statahead(bug 11401)
11939         local lsx="$1"
11940
11941         SLOWOK=0
11942         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11943                 log "testing UP system. Performance may be lower than expected."
11944                 SLOWOK=1
11945         fi
11946
11947         rm -rf $DIR/$tdir
11948         test_mkdir $DIR/$tdir
11949         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11950         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11951         MULT=10
11952         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11953                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11954
11955                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11956                 lctl set_param -n llite.*.statahead_max 0
11957                 lctl get_param llite.*.statahead_max
11958                 cancel_lru_locks mdc
11959                 cancel_lru_locks osc
11960                 stime=$(date +%s)
11961                 time $lsx $DIR/$tdir | wc -l
11962                 etime=$(date +%s)
11963                 delta=$((etime - stime))
11964                 log "$lsx $i files without statahead: $delta sec"
11965                 lctl set_param llite.*.statahead_max=$max
11966
11967                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11968                         grep "statahead wrong:" | awk '{print $3}')
11969                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11970                 cancel_lru_locks mdc
11971                 cancel_lru_locks osc
11972                 stime=$(date +%s)
11973                 time $lsx $DIR/$tdir | wc -l
11974                 etime=$(date +%s)
11975                 delta_sa=$((etime - stime))
11976                 log "$lsx $i files with statahead: $delta_sa sec"
11977                 lctl get_param -n llite.*.statahead_stats
11978                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11979                         grep "statahead wrong:" | awk '{print $3}')
11980
11981                 [[ $swrong -lt $ewrong ]] &&
11982                         log "statahead was stopped, maybe too many locks held!"
11983                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11984
11985                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11986                         max=$(lctl get_param -n llite.*.statahead_max |
11987                                 head -n 1)
11988                         lctl set_param -n llite.*.statahead_max 0
11989                         lctl get_param llite.*.statahead_max
11990                         cancel_lru_locks mdc
11991                         cancel_lru_locks osc
11992                         stime=$(date +%s)
11993                         time $lsx $DIR/$tdir | wc -l
11994                         etime=$(date +%s)
11995                         delta=$((etime - stime))
11996                         log "$lsx $i files again without statahead: $delta sec"
11997                         lctl set_param llite.*.statahead_max=$max
11998                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11999                                 if [  $SLOWOK -eq 0 ]; then
12000                                         error "$lsx $i files is slower with statahead!"
12001                                 else
12002                                         log "$lsx $i files is slower with statahead!"
12003                                 fi
12004                                 break
12005                         fi
12006                 fi
12007
12008                 [ $delta -gt 20 ] && break
12009                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12010                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12011         done
12012         log "$lsx done"
12013
12014         stime=$(date +%s)
12015         rm -r $DIR/$tdir
12016         sync
12017         etime=$(date +%s)
12018         delta=$((etime - stime))
12019         log "rm -r $DIR/$tdir/: $delta seconds"
12020         log "rm done"
12021         lctl get_param -n llite.*.statahead_stats
12022 }
12023
12024 test_123aa() {
12025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12026
12027         test_123a_base "ls -l"
12028 }
12029 run_test 123aa "verify statahead work"
12030
12031 test_123ab() {
12032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12033
12034         statx_supported || skip_env "Test must be statx() syscall supported"
12035
12036         test_123a_base "$STATX -l"
12037 }
12038 run_test 123ab "verify statahead work by using statx"
12039
12040 test_123ac() {
12041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12042
12043         statx_supported || skip_env "Test must be statx() syscall supported"
12044
12045         local rpcs_before
12046         local rpcs_after
12047         local agl_before
12048         local agl_after
12049
12050         cancel_lru_locks $OSC
12051         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12052         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12053                 awk '/agl.total:/ {print $3}')
12054         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12055         test_123a_base "$STATX --cached=always -D"
12056         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12057                 awk '/agl.total:/ {print $3}')
12058         [ $agl_before -eq $agl_after ] ||
12059                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12060         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12061         [ $rpcs_after -eq $rpcs_before ] ||
12062                 error "$STATX should not send glimpse RPCs to $OSC"
12063 }
12064 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12065
12066 test_123b () { # statahead(bug 15027)
12067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12068
12069         test_mkdir $DIR/$tdir
12070         createmany -o $DIR/$tdir/$tfile-%d 1000
12071
12072         cancel_lru_locks mdc
12073         cancel_lru_locks osc
12074
12075 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12076         lctl set_param fail_loc=0x80000803
12077         ls -lR $DIR/$tdir > /dev/null
12078         log "ls done"
12079         lctl set_param fail_loc=0x0
12080         lctl get_param -n llite.*.statahead_stats
12081         rm -r $DIR/$tdir
12082         sync
12083
12084 }
12085 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12086
12087 test_123c() {
12088         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12089
12090         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12091         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12092         touch $DIR/$tdir.1/{1..3}
12093         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12094
12095         remount_client $MOUNT
12096
12097         $MULTIOP $DIR/$tdir.0 Q
12098
12099         # let statahead to complete
12100         ls -l $DIR/$tdir.0 > /dev/null
12101
12102         testid=$(echo $TESTNAME | tr '_' ' ')
12103         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12104                 error "statahead warning" || true
12105 }
12106 run_test 123c "Can not initialize inode warning on DNE statahead"
12107
12108 test_124a() {
12109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12110         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12111                 skip_env "no lru resize on server"
12112
12113         local NR=2000
12114
12115         test_mkdir $DIR/$tdir
12116
12117         log "create $NR files at $DIR/$tdir"
12118         createmany -o $DIR/$tdir/f $NR ||
12119                 error "failed to create $NR files in $DIR/$tdir"
12120
12121         cancel_lru_locks mdc
12122         ls -l $DIR/$tdir > /dev/null
12123
12124         local NSDIR=""
12125         local LRU_SIZE=0
12126         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12127                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12128                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12129                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12130                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12131                         log "NSDIR=$NSDIR"
12132                         log "NS=$(basename $NSDIR)"
12133                         break
12134                 fi
12135         done
12136
12137         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12138                 skip "Not enough cached locks created!"
12139         fi
12140         log "LRU=$LRU_SIZE"
12141
12142         local SLEEP=30
12143
12144         # We know that lru resize allows one client to hold $LIMIT locks
12145         # for 10h. After that locks begin to be killed by client.
12146         local MAX_HRS=10
12147         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12148         log "LIMIT=$LIMIT"
12149         if [ $LIMIT -lt $LRU_SIZE ]; then
12150                 skip "Limit is too small $LIMIT"
12151         fi
12152
12153         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12154         # killing locks. Some time was spent for creating locks. This means
12155         # that up to the moment of sleep finish we must have killed some of
12156         # them (10-100 locks). This depends on how fast ther were created.
12157         # Many of them were touched in almost the same moment and thus will
12158         # be killed in groups.
12159         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12160
12161         # Use $LRU_SIZE_B here to take into account real number of locks
12162         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12163         local LRU_SIZE_B=$LRU_SIZE
12164         log "LVF=$LVF"
12165         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12166         log "OLD_LVF=$OLD_LVF"
12167         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12168
12169         # Let's make sure that we really have some margin. Client checks
12170         # cached locks every 10 sec.
12171         SLEEP=$((SLEEP+20))
12172         log "Sleep ${SLEEP} sec"
12173         local SEC=0
12174         while ((SEC<$SLEEP)); do
12175                 echo -n "..."
12176                 sleep 5
12177                 SEC=$((SEC+5))
12178                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12179                 echo -n "$LRU_SIZE"
12180         done
12181         echo ""
12182         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12183         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12184
12185         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12186                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12187                 unlinkmany $DIR/$tdir/f $NR
12188                 return
12189         }
12190
12191         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12192         log "unlink $NR files at $DIR/$tdir"
12193         unlinkmany $DIR/$tdir/f $NR
12194 }
12195 run_test 124a "lru resize ======================================="
12196
12197 get_max_pool_limit()
12198 {
12199         local limit=$($LCTL get_param \
12200                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12201         local max=0
12202         for l in $limit; do
12203                 if [[ $l -gt $max ]]; then
12204                         max=$l
12205                 fi
12206         done
12207         echo $max
12208 }
12209
12210 test_124b() {
12211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12212         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12213                 skip_env "no lru resize on server"
12214
12215         LIMIT=$(get_max_pool_limit)
12216
12217         NR=$(($(default_lru_size)*20))
12218         if [[ $NR -gt $LIMIT ]]; then
12219                 log "Limit lock number by $LIMIT locks"
12220                 NR=$LIMIT
12221         fi
12222
12223         IFree=$(mdsrate_inodes_available)
12224         if [ $IFree -lt $NR ]; then
12225                 log "Limit lock number by $IFree inodes"
12226                 NR=$IFree
12227         fi
12228
12229         lru_resize_disable mdc
12230         test_mkdir -p $DIR/$tdir/disable_lru_resize
12231
12232         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12233         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12234         cancel_lru_locks mdc
12235         stime=`date +%s`
12236         PID=""
12237         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12238         PID="$PID $!"
12239         sleep 2
12240         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12241         PID="$PID $!"
12242         sleep 2
12243         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12244         PID="$PID $!"
12245         wait $PID
12246         etime=`date +%s`
12247         nolruresize_delta=$((etime-stime))
12248         log "ls -la time: $nolruresize_delta seconds"
12249         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12250         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12251
12252         lru_resize_enable mdc
12253         test_mkdir -p $DIR/$tdir/enable_lru_resize
12254
12255         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12256         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12257         cancel_lru_locks mdc
12258         stime=`date +%s`
12259         PID=""
12260         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12261         PID="$PID $!"
12262         sleep 2
12263         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12264         PID="$PID $!"
12265         sleep 2
12266         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12267         PID="$PID $!"
12268         wait $PID
12269         etime=`date +%s`
12270         lruresize_delta=$((etime-stime))
12271         log "ls -la time: $lruresize_delta seconds"
12272         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12273
12274         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12275                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12276         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12277                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12278         else
12279                 log "lru resize performs the same with no lru resize"
12280         fi
12281         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12282 }
12283 run_test 124b "lru resize (performance test) ======================="
12284
12285 test_124c() {
12286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12287         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12288                 skip_env "no lru resize on server"
12289
12290         # cache ununsed locks on client
12291         local nr=100
12292         cancel_lru_locks mdc
12293         test_mkdir $DIR/$tdir
12294         createmany -o $DIR/$tdir/f $nr ||
12295                 error "failed to create $nr files in $DIR/$tdir"
12296         ls -l $DIR/$tdir > /dev/null
12297
12298         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12299         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12300         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12301         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12302         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12303
12304         # set lru_max_age to 1 sec
12305         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12306         echo "sleep $((recalc_p * 2)) seconds..."
12307         sleep $((recalc_p * 2))
12308
12309         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12310         # restore lru_max_age
12311         $LCTL set_param -n $nsdir.lru_max_age $max_age
12312         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12313         unlinkmany $DIR/$tdir/f $nr
12314 }
12315 run_test 124c "LRUR cancel very aged locks"
12316
12317 test_124d() {
12318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12319         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12320                 skip_env "no lru resize on server"
12321
12322         # cache ununsed locks on client
12323         local nr=100
12324
12325         lru_resize_disable mdc
12326         stack_trap "lru_resize_enable mdc" EXIT
12327
12328         cancel_lru_locks mdc
12329
12330         # asynchronous object destroy at MDT could cause bl ast to client
12331         test_mkdir $DIR/$tdir
12332         createmany -o $DIR/$tdir/f $nr ||
12333                 error "failed to create $nr files in $DIR/$tdir"
12334         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12335
12336         ls -l $DIR/$tdir > /dev/null
12337
12338         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12339         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12340         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12341         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12342
12343         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12344
12345         # set lru_max_age to 1 sec
12346         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12347         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12348
12349         echo "sleep $((recalc_p * 2)) seconds..."
12350         sleep $((recalc_p * 2))
12351
12352         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12353
12354         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12355 }
12356 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12357
12358 test_125() { # 13358
12359         $LCTL get_param -n llite.*.client_type | grep -q local ||
12360                 skip "must run as local client"
12361         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12362                 skip_env "must have acl enabled"
12363         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12364
12365         test_mkdir $DIR/$tdir
12366         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12367         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12368         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12369 }
12370 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12371
12372 test_126() { # bug 12829/13455
12373         $GSS && skip_env "must run as gss disabled"
12374         $LCTL get_param -n llite.*.client_type | grep -q local ||
12375                 skip "must run as local client"
12376         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12377
12378         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12379         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12380         rm -f $DIR/$tfile
12381         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12382 }
12383 run_test 126 "check that the fsgid provided by the client is taken into account"
12384
12385 test_127a() { # bug 15521
12386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12387         local name count samp unit min max sum sumsq
12388
12389         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12390         echo "stats before reset"
12391         $LCTL get_param osc.*.stats
12392         $LCTL set_param osc.*.stats=0
12393         local fsize=$((2048 * 1024))
12394
12395         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12396         cancel_lru_locks osc
12397         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12398
12399         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12400         stack_trap "rm -f $TMP/$tfile.tmp"
12401         while read name count samp unit min max sum sumsq; do
12402                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12403                 [ ! $min ] && error "Missing min value for $name proc entry"
12404                 eval $name=$count || error "Wrong proc format"
12405
12406                 case $name in
12407                 read_bytes|write_bytes)
12408                         [[ "$unit" =~ "bytes" ]] ||
12409                                 error "unit is not 'bytes': $unit"
12410                         (( $min >= 4096 )) || error "min is too small: $min"
12411                         (( $min <= $fsize )) || error "min is too big: $min"
12412                         (( $max >= 4096 )) || error "max is too small: $max"
12413                         (( $max <= $fsize )) || error "max is too big: $max"
12414                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12415                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12416                                 error "sumsquare is too small: $sumsq"
12417                         (( $sumsq <= $fsize * $fsize )) ||
12418                                 error "sumsquare is too big: $sumsq"
12419                         ;;
12420                 ost_read|ost_write)
12421                         [[ "$unit" =~ "usec" ]] ||
12422                                 error "unit is not 'usec': $unit"
12423                         ;;
12424                 *)      ;;
12425                 esac
12426         done < $DIR/$tfile.tmp
12427
12428         #check that we actually got some stats
12429         [ "$read_bytes" ] || error "Missing read_bytes stats"
12430         [ "$write_bytes" ] || error "Missing write_bytes stats"
12431         [ "$read_bytes" != 0 ] || error "no read done"
12432         [ "$write_bytes" != 0 ] || error "no write done"
12433 }
12434 run_test 127a "verify the client stats are sane"
12435
12436 test_127b() { # bug LU-333
12437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12438         local name count samp unit min max sum sumsq
12439
12440         echo "stats before reset"
12441         $LCTL get_param llite.*.stats
12442         $LCTL set_param llite.*.stats=0
12443
12444         # perform 2 reads and writes so MAX is different from SUM.
12445         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12446         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12447         cancel_lru_locks osc
12448         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12449         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12450
12451         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12452         stack_trap "rm -f $TMP/$tfile.tmp"
12453         while read name count samp unit min max sum sumsq; do
12454                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12455                 eval $name=$count || error "Wrong proc format"
12456
12457                 case $name in
12458                 read_bytes|write_bytes)
12459                         [[ "$unit" =~ "bytes" ]] ||
12460                                 error "unit is not 'bytes': $unit"
12461                         (( $count == 2 )) || error "count is not 2: $count"
12462                         (( $min == $PAGE_SIZE )) ||
12463                                 error "min is not $PAGE_SIZE: $min"
12464                         (( $max == $PAGE_SIZE )) ||
12465                                 error "max is not $PAGE_SIZE: $max"
12466                         (( $sum == $PAGE_SIZE * 2 )) ||
12467                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12468                         ;;
12469                 read|write)
12470                         [[ "$unit" =~ "usec" ]] ||
12471                                 error "unit is not 'usec': $unit"
12472                         ;;
12473                 *)      ;;
12474                 esac
12475         done < $TMP/$tfile.tmp
12476
12477         #check that we actually got some stats
12478         [ "$read_bytes" ] || error "Missing read_bytes stats"
12479         [ "$write_bytes" ] || error "Missing write_bytes stats"
12480         [ "$read_bytes" != 0 ] || error "no read done"
12481         [ "$write_bytes" != 0 ] || error "no write done"
12482 }
12483 run_test 127b "verify the llite client stats are sane"
12484
12485 test_127c() { # LU-12394
12486         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12487         local size
12488         local bsize
12489         local reads
12490         local writes
12491         local count
12492
12493         $LCTL set_param llite.*.extents_stats=1
12494         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12495
12496         # Use two stripes so there is enough space in default config
12497         $LFS setstripe -c 2 $DIR/$tfile
12498
12499         # Extent stats start at 0-4K and go in power of two buckets
12500         # LL_HIST_START = 12 --> 2^12 = 4K
12501         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12502         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12503         # small configs
12504         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12505                 do
12506                 # Write and read, 2x each, second time at a non-zero offset
12507                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12508                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12509                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12510                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12511                 rm -f $DIR/$tfile
12512         done
12513
12514         $LCTL get_param llite.*.extents_stats
12515
12516         count=2
12517         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12518                 do
12519                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12520                                 grep -m 1 $bsize)
12521                 reads=$(echo $bucket | awk '{print $5}')
12522                 writes=$(echo $bucket | awk '{print $9}')
12523                 [ "$reads" -eq $count ] ||
12524                         error "$reads reads in < $bsize bucket, expect $count"
12525                 [ "$writes" -eq $count ] ||
12526                         error "$writes writes in < $bsize bucket, expect $count"
12527         done
12528
12529         # Test mmap write and read
12530         $LCTL set_param llite.*.extents_stats=c
12531         size=512
12532         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12533         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12534         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12535
12536         $LCTL get_param llite.*.extents_stats
12537
12538         count=$(((size*1024) / PAGE_SIZE))
12539
12540         bsize=$((2 * PAGE_SIZE / 1024))K
12541
12542         bucket=$($LCTL get_param -n llite.*.extents_stats |
12543                         grep -m 1 $bsize)
12544         reads=$(echo $bucket | awk '{print $5}')
12545         writes=$(echo $bucket | awk '{print $9}')
12546         # mmap writes fault in the page first, creating an additonal read
12547         [ "$reads" -eq $((2 * count)) ] ||
12548                 error "$reads reads in < $bsize bucket, expect $count"
12549         [ "$writes" -eq $count ] ||
12550                 error "$writes writes in < $bsize bucket, expect $count"
12551 }
12552 run_test 127c "test llite extent stats with regular & mmap i/o"
12553
12554 test_128() { # bug 15212
12555         touch $DIR/$tfile
12556         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12557                 find $DIR/$tfile
12558                 find $DIR/$tfile
12559         EOF
12560
12561         result=$(grep error $TMP/$tfile.log)
12562         rm -f $DIR/$tfile $TMP/$tfile.log
12563         [ -z "$result" ] ||
12564                 error "consecutive find's under interactive lfs failed"
12565 }
12566 run_test 128 "interactive lfs for 2 consecutive find's"
12567
12568 set_dir_limits () {
12569         local mntdev
12570         local canondev
12571         local node
12572
12573         local ldproc=/proc/fs/ldiskfs
12574         local facets=$(get_facets MDS)
12575
12576         for facet in ${facets//,/ }; do
12577                 canondev=$(ldiskfs_canon \
12578                            *.$(convert_facet2label $facet).mntdev $facet)
12579                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12580                         ldproc=/sys/fs/ldiskfs
12581                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12582                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12583         done
12584 }
12585
12586 check_mds_dmesg() {
12587         local facets=$(get_facets MDS)
12588         for facet in ${facets//,/ }; do
12589                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12590         done
12591         return 1
12592 }
12593
12594 test_129() {
12595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12596         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12597                 skip "Need MDS version with at least 2.5.56"
12598         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12599                 skip_env "ldiskfs only test"
12600         fi
12601         remote_mds_nodsh && skip "remote MDS with nodsh"
12602
12603         local ENOSPC=28
12604         local has_warning=false
12605
12606         rm -rf $DIR/$tdir
12607         mkdir -p $DIR/$tdir
12608
12609         # block size of mds1
12610         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12611         set_dir_limits $maxsize $((maxsize * 6 / 8))
12612         stack_trap "set_dir_limits 0 0"
12613         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12614         local dirsize=$(stat -c%s "$DIR/$tdir")
12615         local nfiles=0
12616         while (( $dirsize <= $maxsize )); do
12617                 $MCREATE $DIR/$tdir/file_base_$nfiles
12618                 rc=$?
12619                 # check two errors:
12620                 # ENOSPC for ext4 max_dir_size, which has been used since
12621                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12622                 if (( rc == ENOSPC )); then
12623                         set_dir_limits 0 0
12624                         echo "rc=$rc returned as expected after $nfiles files"
12625
12626                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12627                                 error "create failed w/o dir size limit"
12628
12629                         # messages may be rate limited if test is run repeatedly
12630                         check_mds_dmesg '"is approaching max"' ||
12631                                 echo "warning message should be output"
12632                         check_mds_dmesg '"has reached max"' ||
12633                                 echo "reached message should be output"
12634
12635                         dirsize=$(stat -c%s "$DIR/$tdir")
12636
12637                         [[ $dirsize -ge $maxsize ]] && return 0
12638                         error "dirsize $dirsize < $maxsize after $nfiles files"
12639                 elif (( rc != 0 )); then
12640                         break
12641                 fi
12642                 nfiles=$((nfiles + 1))
12643                 dirsize=$(stat -c%s "$DIR/$tdir")
12644         done
12645
12646         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12647 }
12648 run_test 129 "test directory size limit ========================"
12649
12650 OLDIFS="$IFS"
12651 cleanup_130() {
12652         trap 0
12653         IFS="$OLDIFS"
12654 }
12655
12656 test_130a() {
12657         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12658         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12659
12660         trap cleanup_130 EXIT RETURN
12661
12662         local fm_file=$DIR/$tfile
12663         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12664         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12665                 error "dd failed for $fm_file"
12666
12667         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12668         filefrag -ves $fm_file
12669         RC=$?
12670         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12671                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12672         [ $RC != 0 ] && error "filefrag $fm_file failed"
12673
12674         filefrag_op=$(filefrag -ve -k $fm_file |
12675                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12676         lun=$($LFS getstripe -i $fm_file)
12677
12678         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12679         IFS=$'\n'
12680         tot_len=0
12681         for line in $filefrag_op
12682         do
12683                 frag_lun=`echo $line | cut -d: -f5`
12684                 ext_len=`echo $line | cut -d: -f4`
12685                 if (( $frag_lun != $lun )); then
12686                         cleanup_130
12687                         error "FIEMAP on 1-stripe file($fm_file) failed"
12688                         return
12689                 fi
12690                 (( tot_len += ext_len ))
12691         done
12692
12693         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12694                 cleanup_130
12695                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12696                 return
12697         fi
12698
12699         cleanup_130
12700
12701         echo "FIEMAP on single striped file succeeded"
12702 }
12703 run_test 130a "FIEMAP (1-stripe file)"
12704
12705 test_130b() {
12706         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12707
12708         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12709         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12710
12711         trap cleanup_130 EXIT RETURN
12712
12713         local fm_file=$DIR/$tfile
12714         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12715                         error "setstripe on $fm_file"
12716         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12717                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12718
12719         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12720                 error "dd failed on $fm_file"
12721
12722         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12723         filefrag_op=$(filefrag -ve -k $fm_file |
12724                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12725
12726         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12727                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12728
12729         IFS=$'\n'
12730         tot_len=0
12731         num_luns=1
12732         for line in $filefrag_op
12733         do
12734                 frag_lun=$(echo $line | cut -d: -f5 |
12735                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12736                 ext_len=$(echo $line | cut -d: -f4)
12737                 if (( $frag_lun != $last_lun )); then
12738                         if (( tot_len != 1024 )); then
12739                                 cleanup_130
12740                                 error "FIEMAP on $fm_file failed; returned " \
12741                                 "len $tot_len for OST $last_lun instead of 1024"
12742                                 return
12743                         else
12744                                 (( num_luns += 1 ))
12745                                 tot_len=0
12746                         fi
12747                 fi
12748                 (( tot_len += ext_len ))
12749                 last_lun=$frag_lun
12750         done
12751         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12752                 cleanup_130
12753                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12754                         "luns or wrong len for OST $last_lun"
12755                 return
12756         fi
12757
12758         cleanup_130
12759
12760         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12761 }
12762 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12763
12764 test_130c() {
12765         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12766
12767         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12768         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12769
12770         trap cleanup_130 EXIT RETURN
12771
12772         local fm_file=$DIR/$tfile
12773         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12774         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12775                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12776
12777         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12778                         error "dd failed on $fm_file"
12779
12780         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12781         filefrag_op=$(filefrag -ve -k $fm_file |
12782                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12783
12784         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12785                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12786
12787         IFS=$'\n'
12788         tot_len=0
12789         num_luns=1
12790         for line in $filefrag_op
12791         do
12792                 frag_lun=$(echo $line | cut -d: -f5 |
12793                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12794                 ext_len=$(echo $line | cut -d: -f4)
12795                 if (( $frag_lun != $last_lun )); then
12796                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12797                         if (( logical != 512 )); then
12798                                 cleanup_130
12799                                 error "FIEMAP on $fm_file failed; returned " \
12800                                 "logical start for lun $logical instead of 512"
12801                                 return
12802                         fi
12803                         if (( tot_len != 512 )); then
12804                                 cleanup_130
12805                                 error "FIEMAP on $fm_file failed; returned " \
12806                                 "len $tot_len for OST $last_lun instead of 1024"
12807                                 return
12808                         else
12809                                 (( num_luns += 1 ))
12810                                 tot_len=0
12811                         fi
12812                 fi
12813                 (( tot_len += ext_len ))
12814                 last_lun=$frag_lun
12815         done
12816         if (( num_luns != 2 || tot_len != 512 )); then
12817                 cleanup_130
12818                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12819                         "luns or wrong len for OST $last_lun"
12820                 return
12821         fi
12822
12823         cleanup_130
12824
12825         echo "FIEMAP on 2-stripe file with hole succeeded"
12826 }
12827 run_test 130c "FIEMAP (2-stripe file with hole)"
12828
12829 test_130d() {
12830         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12831
12832         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12833         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12834
12835         trap cleanup_130 EXIT RETURN
12836
12837         local fm_file=$DIR/$tfile
12838         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12839                         error "setstripe on $fm_file"
12840         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12841                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12842
12843         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12844         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12845                 error "dd failed on $fm_file"
12846
12847         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12848         filefrag_op=$(filefrag -ve -k $fm_file |
12849                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12850
12851         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12852                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12853
12854         IFS=$'\n'
12855         tot_len=0
12856         num_luns=1
12857         for line in $filefrag_op
12858         do
12859                 frag_lun=$(echo $line | cut -d: -f5 |
12860                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12861                 ext_len=$(echo $line | cut -d: -f4)
12862                 if (( $frag_lun != $last_lun )); then
12863                         if (( tot_len != 1024 )); then
12864                                 cleanup_130
12865                                 error "FIEMAP on $fm_file failed; returned " \
12866                                 "len $tot_len for OST $last_lun instead of 1024"
12867                                 return
12868                         else
12869                                 (( num_luns += 1 ))
12870                                 tot_len=0
12871                         fi
12872                 fi
12873                 (( tot_len += ext_len ))
12874                 last_lun=$frag_lun
12875         done
12876         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12877                 cleanup_130
12878                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12879                         "luns or wrong len for OST $last_lun"
12880                 return
12881         fi
12882
12883         cleanup_130
12884
12885         echo "FIEMAP on N-stripe file succeeded"
12886 }
12887 run_test 130d "FIEMAP (N-stripe file)"
12888
12889 test_130e() {
12890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12891
12892         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12893         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12894
12895         trap cleanup_130 EXIT RETURN
12896
12897         local fm_file=$DIR/$tfile
12898         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12899
12900         NUM_BLKS=512
12901         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12902         for ((i = 0; i < $NUM_BLKS; i++)); do
12903                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12904                         conv=notrunc > /dev/null 2>&1
12905         done
12906
12907         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12908         filefrag_op=$(filefrag -ve -k $fm_file |
12909                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12910
12911         last_lun=$(echo $filefrag_op | cut -d: -f5)
12912
12913         IFS=$'\n'
12914         tot_len=0
12915         num_luns=1
12916         for line in $filefrag_op; do
12917                 frag_lun=$(echo $line | cut -d: -f5)
12918                 ext_len=$(echo $line | cut -d: -f4)
12919                 if [[ "$frag_lun" != "$last_lun" ]]; then
12920                         if (( tot_len != $EXPECTED_LEN )); then
12921                                 cleanup_130
12922                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12923                         else
12924                                 (( num_luns += 1 ))
12925                                 tot_len=0
12926                         fi
12927                 fi
12928                 (( tot_len += ext_len ))
12929                 last_lun=$frag_lun
12930         done
12931         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12932                 cleanup_130
12933                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12934         fi
12935
12936         echo "FIEMAP with continuation calls succeeded"
12937 }
12938 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12939
12940 test_130f() {
12941         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12942         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12943
12944         local fm_file=$DIR/$tfile
12945         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12946                 error "multiop create with lov_delay_create on $fm_file"
12947
12948         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12949         filefrag_extents=$(filefrag -vek $fm_file |
12950                            awk '/extents? found/ { print $2 }')
12951         if [[ "$filefrag_extents" != "0" ]]; then
12952                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
12953         fi
12954
12955         rm -f $fm_file
12956 }
12957 run_test 130f "FIEMAP (unstriped file)"
12958
12959 test_130g() {
12960         local file=$DIR/$tfile
12961         local nr=$((OSTCOUNT * 100))
12962
12963         $LFS setstripe -C $nr $file ||
12964                 error "failed to setstripe -C $nr $file"
12965
12966         dd if=/dev/zero of=$file count=$nr bs=1M
12967         sync
12968         nr=$($LFS getstripe -c $file)
12969
12970         local extents=$(filefrag -v $file |
12971                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
12972
12973         echo "filefrag list $extents extents in file with stripecount $nr"
12974         if (( extents < nr )); then
12975                 $LFS getstripe $file
12976                 filefrag -v $file
12977                 error "filefrag printed $extents < $nr extents"
12978         fi
12979
12980         rm -f $file
12981 }
12982 run_test 130g "FIEMAP (overstripe file)"
12983
12984 # Test for writev/readv
12985 test_131a() {
12986         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12987                 error "writev test failed"
12988         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12989                 error "readv failed"
12990         rm -f $DIR/$tfile
12991 }
12992 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12993
12994 test_131b() {
12995         local fsize=$((524288 + 1048576 + 1572864))
12996         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12997                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12998                         error "append writev test failed"
12999
13000         ((fsize += 1572864 + 1048576))
13001         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13002                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13003                         error "append writev test failed"
13004         rm -f $DIR/$tfile
13005 }
13006 run_test 131b "test append writev"
13007
13008 test_131c() {
13009         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13010         error "NOT PASS"
13011 }
13012 run_test 131c "test read/write on file w/o objects"
13013
13014 test_131d() {
13015         rwv -f $DIR/$tfile -w -n 1 1572864
13016         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13017         if [ "$NOB" != 1572864 ]; then
13018                 error "Short read filed: read $NOB bytes instead of 1572864"
13019         fi
13020         rm -f $DIR/$tfile
13021 }
13022 run_test 131d "test short read"
13023
13024 test_131e() {
13025         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13026         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13027         error "read hitting hole failed"
13028         rm -f $DIR/$tfile
13029 }
13030 run_test 131e "test read hitting hole"
13031
13032 check_stats() {
13033         local facet=$1
13034         local op=$2
13035         local want=${3:-0}
13036         local res
13037
13038         case $facet in
13039         mds*) res=$(do_facet $facet \
13040                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13041                  ;;
13042         ost*) res=$(do_facet $facet \
13043                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13044                  ;;
13045         *) error "Wrong facet '$facet'" ;;
13046         esac
13047         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13048         # if the argument $3 is zero, it means any stat increment is ok.
13049         if [[ $want -gt 0 ]]; then
13050                 local count=$(echo $res | awk '{ print $2 }')
13051                 [[ $count -ne $want ]] &&
13052                         error "The $op counter on $facet is $count, not $want"
13053         fi
13054 }
13055
13056 test_133a() {
13057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13058         remote_ost_nodsh && skip "remote OST with nodsh"
13059         remote_mds_nodsh && skip "remote MDS with nodsh"
13060         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13061                 skip_env "MDS doesn't support rename stats"
13062
13063         local testdir=$DIR/${tdir}/stats_testdir
13064
13065         mkdir -p $DIR/${tdir}
13066
13067         # clear stats.
13068         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13069         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13070
13071         # verify mdt stats first.
13072         mkdir ${testdir} || error "mkdir failed"
13073         check_stats $SINGLEMDS "mkdir" 1
13074         touch ${testdir}/${tfile} || error "touch failed"
13075         check_stats $SINGLEMDS "open" 1
13076         check_stats $SINGLEMDS "close" 1
13077         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13078                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13079                 check_stats $SINGLEMDS "mknod" 2
13080         }
13081         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13082         check_stats $SINGLEMDS "unlink" 1
13083         rm -f ${testdir}/${tfile} || error "file remove failed"
13084         check_stats $SINGLEMDS "unlink" 2
13085
13086         # remove working dir and check mdt stats again.
13087         rmdir ${testdir} || error "rmdir failed"
13088         check_stats $SINGLEMDS "rmdir" 1
13089
13090         local testdir1=$DIR/${tdir}/stats_testdir1
13091         mkdir -p ${testdir}
13092         mkdir -p ${testdir1}
13093         touch ${testdir1}/test1
13094         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13095         check_stats $SINGLEMDS "crossdir_rename" 1
13096
13097         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13098         check_stats $SINGLEMDS "samedir_rename" 1
13099
13100         rm -rf $DIR/${tdir}
13101 }
13102 run_test 133a "Verifying MDT stats ========================================"
13103
13104 test_133b() {
13105         local res
13106
13107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13108         remote_ost_nodsh && skip "remote OST with nodsh"
13109         remote_mds_nodsh && skip "remote MDS with nodsh"
13110
13111         local testdir=$DIR/${tdir}/stats_testdir
13112
13113         mkdir -p ${testdir} || error "mkdir failed"
13114         touch ${testdir}/${tfile} || error "touch failed"
13115         cancel_lru_locks mdc
13116
13117         # clear stats.
13118         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13119         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13120
13121         # extra mdt stats verification.
13122         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13123         check_stats $SINGLEMDS "setattr" 1
13124         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13125         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13126         then            # LU-1740
13127                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13128                 check_stats $SINGLEMDS "getattr" 1
13129         fi
13130         rm -rf $DIR/${tdir}
13131
13132         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13133         # so the check below is not reliable
13134         [ $MDSCOUNT -eq 1 ] || return 0
13135
13136         # Sleep to avoid a cached response.
13137         #define OBD_STATFS_CACHE_SECONDS 1
13138         sleep 2
13139         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13140         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13141         $LFS df || error "lfs failed"
13142         check_stats $SINGLEMDS "statfs" 1
13143
13144         # check aggregated statfs (LU-10018)
13145         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13146                 return 0
13147         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13148                 return 0
13149         sleep 2
13150         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13151         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13152         df $DIR
13153         check_stats $SINGLEMDS "statfs" 1
13154
13155         # We want to check that the client didn't send OST_STATFS to
13156         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13157         # extra care is needed here.
13158         if remote_mds; then
13159                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13160                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13161
13162                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13163                 [ "$res" ] && error "OST got STATFS"
13164         fi
13165
13166         return 0
13167 }
13168 run_test 133b "Verifying extra MDT stats =================================="
13169
13170 test_133c() {
13171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13172         remote_ost_nodsh && skip "remote OST with nodsh"
13173         remote_mds_nodsh && skip "remote MDS with nodsh"
13174
13175         local testdir=$DIR/$tdir/stats_testdir
13176
13177         test_mkdir -p $testdir
13178
13179         # verify obdfilter stats.
13180         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13181         sync
13182         cancel_lru_locks osc
13183         wait_delete_completed
13184
13185         # clear stats.
13186         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13187         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13188
13189         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13190                 error "dd failed"
13191         sync
13192         cancel_lru_locks osc
13193         check_stats ost1 "write" 1
13194
13195         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13196         check_stats ost1 "read" 1
13197
13198         > $testdir/$tfile || error "truncate failed"
13199         check_stats ost1 "punch" 1
13200
13201         rm -f $testdir/$tfile || error "file remove failed"
13202         wait_delete_completed
13203         check_stats ost1 "destroy" 1
13204
13205         rm -rf $DIR/$tdir
13206 }
13207 run_test 133c "Verifying OST stats ========================================"
13208
13209 order_2() {
13210         local value=$1
13211         local orig=$value
13212         local order=1
13213
13214         while [ $value -ge 2 ]; do
13215                 order=$((order*2))
13216                 value=$((value/2))
13217         done
13218
13219         if [ $orig -gt $order ]; then
13220                 order=$((order*2))
13221         fi
13222         echo $order
13223 }
13224
13225 size_in_KMGT() {
13226     local value=$1
13227     local size=('K' 'M' 'G' 'T');
13228     local i=0
13229     local size_string=$value
13230
13231     while [ $value -ge 1024 ]; do
13232         if [ $i -gt 3 ]; then
13233             #T is the biggest unit we get here, if that is bigger,
13234             #just return XXXT
13235             size_string=${value}T
13236             break
13237         fi
13238         value=$((value >> 10))
13239         if [ $value -lt 1024 ]; then
13240             size_string=${value}${size[$i]}
13241             break
13242         fi
13243         i=$((i + 1))
13244     done
13245
13246     echo $size_string
13247 }
13248
13249 get_rename_size() {
13250         local size=$1
13251         local context=${2:-.}
13252         local sample=$(do_facet $SINGLEMDS $LCTL \
13253                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13254                 grep -A1 $context |
13255                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13256         echo $sample
13257 }
13258
13259 test_133d() {
13260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13261         remote_ost_nodsh && skip "remote OST with nodsh"
13262         remote_mds_nodsh && skip "remote MDS with nodsh"
13263         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13264                 skip_env "MDS doesn't support rename stats"
13265
13266         local testdir1=$DIR/${tdir}/stats_testdir1
13267         local testdir2=$DIR/${tdir}/stats_testdir2
13268         mkdir -p $DIR/${tdir}
13269
13270         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13271
13272         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13273         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13274
13275         createmany -o $testdir1/test 512 || error "createmany failed"
13276
13277         # check samedir rename size
13278         mv ${testdir1}/test0 ${testdir1}/test_0
13279
13280         local testdir1_size=$(ls -l $DIR/${tdir} |
13281                 awk '/stats_testdir1/ {print $5}')
13282         local testdir2_size=$(ls -l $DIR/${tdir} |
13283                 awk '/stats_testdir2/ {print $5}')
13284
13285         testdir1_size=$(order_2 $testdir1_size)
13286         testdir2_size=$(order_2 $testdir2_size)
13287
13288         testdir1_size=$(size_in_KMGT $testdir1_size)
13289         testdir2_size=$(size_in_KMGT $testdir2_size)
13290
13291         echo "source rename dir size: ${testdir1_size}"
13292         echo "target rename dir size: ${testdir2_size}"
13293
13294         local cmd="do_facet $SINGLEMDS $LCTL "
13295         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13296
13297         eval $cmd || error "$cmd failed"
13298         local samedir=$($cmd | grep 'same_dir')
13299         local same_sample=$(get_rename_size $testdir1_size)
13300         [ -z "$samedir" ] && error "samedir_rename_size count error"
13301         [[ $same_sample -eq 1 ]] ||
13302                 error "samedir_rename_size error $same_sample"
13303         echo "Check same dir rename stats success"
13304
13305         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13306
13307         # check crossdir rename size
13308         mv ${testdir1}/test_0 ${testdir2}/test_0
13309
13310         testdir1_size=$(ls -l $DIR/${tdir} |
13311                 awk '/stats_testdir1/ {print $5}')
13312         testdir2_size=$(ls -l $DIR/${tdir} |
13313                 awk '/stats_testdir2/ {print $5}')
13314
13315         testdir1_size=$(order_2 $testdir1_size)
13316         testdir2_size=$(order_2 $testdir2_size)
13317
13318         testdir1_size=$(size_in_KMGT $testdir1_size)
13319         testdir2_size=$(size_in_KMGT $testdir2_size)
13320
13321         echo "source rename dir size: ${testdir1_size}"
13322         echo "target rename dir size: ${testdir2_size}"
13323
13324         eval $cmd || error "$cmd failed"
13325         local crossdir=$($cmd | grep 'crossdir')
13326         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13327         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13328         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13329         [[ $src_sample -eq 1 ]] ||
13330                 error "crossdir_rename_size error $src_sample"
13331         [[ $tgt_sample -eq 1 ]] ||
13332                 error "crossdir_rename_size error $tgt_sample"
13333         echo "Check cross dir rename stats success"
13334         rm -rf $DIR/${tdir}
13335 }
13336 run_test 133d "Verifying rename_stats ========================================"
13337
13338 test_133e() {
13339         remote_mds_nodsh && skip "remote MDS with nodsh"
13340         remote_ost_nodsh && skip "remote OST with nodsh"
13341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13342
13343         local testdir=$DIR/${tdir}/stats_testdir
13344         local ctr f0 f1 bs=32768 count=42 sum
13345
13346         mkdir -p ${testdir} || error "mkdir failed"
13347
13348         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13349
13350         for ctr in {write,read}_bytes; do
13351                 sync
13352                 cancel_lru_locks osc
13353
13354                 do_facet ost1 $LCTL set_param -n \
13355                         "obdfilter.*.exports.clear=clear"
13356
13357                 if [ $ctr = write_bytes ]; then
13358                         f0=/dev/zero
13359                         f1=${testdir}/${tfile}
13360                 else
13361                         f0=${testdir}/${tfile}
13362                         f1=/dev/null
13363                 fi
13364
13365                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13366                         error "dd failed"
13367                 sync
13368                 cancel_lru_locks osc
13369
13370                 sum=$(do_facet ost1 $LCTL get_param \
13371                         "obdfilter.*.exports.*.stats" |
13372                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13373                                 $1 == ctr { sum += $7 }
13374                                 END { printf("%0.0f", sum) }')
13375
13376                 if ((sum != bs * count)); then
13377                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13378                 fi
13379         done
13380
13381         rm -rf $DIR/${tdir}
13382 }
13383 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13384
13385 test_133f() {
13386         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13387                 skip "too old lustre for get_param -R ($facet_ver)"
13388
13389         # verifying readability.
13390         $LCTL get_param -R '*' &> /dev/null
13391
13392         # Verifing writability with badarea_io.
13393         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13394                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13395                 error "client badarea_io failed"
13396
13397         # remount the FS in case writes/reads /proc break the FS
13398         cleanup || error "failed to unmount"
13399         setup || error "failed to setup"
13400 }
13401 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13402
13403 test_133g() {
13404         remote_mds_nodsh && skip "remote MDS with nodsh"
13405         remote_ost_nodsh && skip "remote OST with nodsh"
13406
13407         local facet
13408         for facet in mds1 ost1; do
13409                 local facet_ver=$(lustre_version_code $facet)
13410                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13411                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13412                 else
13413                         log "$facet: too old lustre for get_param -R"
13414                 fi
13415                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13416                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13417                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13418                                 xargs badarea_io" ||
13419                                         error "$facet badarea_io failed"
13420                 else
13421                         skip_noexit "$facet: too old lustre for get_param -R"
13422                 fi
13423         done
13424
13425         # remount the FS in case writes/reads /proc break the FS
13426         cleanup || error "failed to unmount"
13427         setup || error "failed to setup"
13428 }
13429 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13430
13431 test_133h() {
13432         remote_mds_nodsh && skip "remote MDS with nodsh"
13433         remote_ost_nodsh && skip "remote OST with nodsh"
13434         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13435                 skip "Need MDS version at least 2.9.54"
13436
13437         local facet
13438         for facet in client mds1 ost1; do
13439                 # Get the list of files that are missing the terminating newline
13440                 local plist=$(do_facet $facet
13441                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13442                 local ent
13443                 for ent in $plist; do
13444                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13445                                 awk -v FS='\v' -v RS='\v\v' \
13446                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13447                                         print FILENAME}'" 2>/dev/null)
13448                         [ -z $missing ] || {
13449                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13450                                 error "file does not end with newline: $facet-$ent"
13451                         }
13452                 done
13453         done
13454 }
13455 run_test 133h "Proc files should end with newlines"
13456
13457 test_134a() {
13458         remote_mds_nodsh && skip "remote MDS with nodsh"
13459         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13460                 skip "Need MDS version at least 2.7.54"
13461
13462         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13463         cancel_lru_locks mdc
13464
13465         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13466         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13467         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13468
13469         local nr=1000
13470         createmany -o $DIR/$tdir/f $nr ||
13471                 error "failed to create $nr files in $DIR/$tdir"
13472         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13473
13474         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13475         do_facet mds1 $LCTL set_param fail_loc=0x327
13476         do_facet mds1 $LCTL set_param fail_val=500
13477         touch $DIR/$tdir/m
13478
13479         echo "sleep 10 seconds ..."
13480         sleep 10
13481         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13482
13483         do_facet mds1 $LCTL set_param fail_loc=0
13484         do_facet mds1 $LCTL set_param fail_val=0
13485         [ $lck_cnt -lt $unused ] ||
13486                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13487
13488         rm $DIR/$tdir/m
13489         unlinkmany $DIR/$tdir/f $nr
13490 }
13491 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13492
13493 test_134b() {
13494         remote_mds_nodsh && skip "remote MDS with nodsh"
13495         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13496                 skip "Need MDS version at least 2.7.54"
13497
13498         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13499         cancel_lru_locks mdc
13500
13501         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13502                         ldlm.lock_reclaim_threshold_mb)
13503         # disable reclaim temporarily
13504         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13505
13506         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13507         do_facet mds1 $LCTL set_param fail_loc=0x328
13508         do_facet mds1 $LCTL set_param fail_val=500
13509
13510         $LCTL set_param debug=+trace
13511
13512         local nr=600
13513         createmany -o $DIR/$tdir/f $nr &
13514         local create_pid=$!
13515
13516         echo "Sleep $TIMEOUT seconds ..."
13517         sleep $TIMEOUT
13518         if ! ps -p $create_pid  > /dev/null 2>&1; then
13519                 do_facet mds1 $LCTL set_param fail_loc=0
13520                 do_facet mds1 $LCTL set_param fail_val=0
13521                 do_facet mds1 $LCTL set_param \
13522                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13523                 error "createmany finished incorrectly!"
13524         fi
13525         do_facet mds1 $LCTL set_param fail_loc=0
13526         do_facet mds1 $LCTL set_param fail_val=0
13527         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13528         wait $create_pid || return 1
13529
13530         unlinkmany $DIR/$tdir/f $nr
13531 }
13532 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13533
13534 test_135() {
13535         remote_mds_nodsh && skip "remote MDS with nodsh"
13536         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13537                 skip "Need MDS version at least 2.13.50"
13538         local fname
13539
13540         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13541
13542 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13543         #set only one record at plain llog
13544         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13545
13546         #fill already existed plain llog each 64767
13547         #wrapping whole catalog
13548         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13549
13550         createmany -o $DIR/$tdir/$tfile_ 64700
13551         for (( i = 0; i < 64700; i = i + 2 ))
13552         do
13553                 rm $DIR/$tdir/$tfile_$i &
13554                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13555                 local pid=$!
13556                 wait $pid
13557         done
13558
13559         #waiting osp synchronization
13560         wait_delete_completed
13561 }
13562 run_test 135 "Race catalog processing"
13563
13564 test_136() {
13565         remote_mds_nodsh && skip "remote MDS with nodsh"
13566         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13567                 skip "Need MDS version at least 2.13.50"
13568         local fname
13569
13570         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13571         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13572         #set only one record at plain llog
13573 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13574         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13575
13576         #fill already existed 2 plain llogs each 64767
13577         #wrapping whole catalog
13578         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13579         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13580         wait_delete_completed
13581
13582         createmany -o $DIR/$tdir/$tfile_ 10
13583         sleep 25
13584
13585         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13586         for (( i = 0; i < 10; i = i + 3 ))
13587         do
13588                 rm $DIR/$tdir/$tfile_$i &
13589                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13590                 local pid=$!
13591                 wait $pid
13592                 sleep 7
13593                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13594         done
13595
13596         #waiting osp synchronization
13597         wait_delete_completed
13598 }
13599 run_test 136 "Race catalog processing 2"
13600
13601 test_140() { #bug-17379
13602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13603
13604         test_mkdir $DIR/$tdir
13605         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13606         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13607
13608         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13609         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13610         local i=0
13611         while i=$((i + 1)); do
13612                 test_mkdir $i
13613                 cd $i || error "Changing to $i"
13614                 ln -s ../stat stat || error "Creating stat symlink"
13615                 # Read the symlink until ELOOP present,
13616                 # not LBUGing the system is considered success,
13617                 # we didn't overrun the stack.
13618                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13619                 if [ $ret -ne 0 ]; then
13620                         if [ $ret -eq 40 ]; then
13621                                 break  # -ELOOP
13622                         else
13623                                 error "Open stat symlink"
13624                                         return
13625                         fi
13626                 fi
13627         done
13628         i=$((i - 1))
13629         echo "The symlink depth = $i"
13630         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13631                 error "Invalid symlink depth"
13632
13633         # Test recursive symlink
13634         ln -s symlink_self symlink_self
13635         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13636         echo "open symlink_self returns $ret"
13637         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13638 }
13639 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13640
13641 test_150a() {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643
13644         local TF="$TMP/$tfile"
13645
13646         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13647         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13648         cp $TF $DIR/$tfile
13649         cancel_lru_locks $OSC
13650         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13651         remount_client $MOUNT
13652         df -P $MOUNT
13653         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13654
13655         $TRUNCATE $TF 6000
13656         $TRUNCATE $DIR/$tfile 6000
13657         cancel_lru_locks $OSC
13658         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13659
13660         echo "12345" >>$TF
13661         echo "12345" >>$DIR/$tfile
13662         cancel_lru_locks $OSC
13663         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13664
13665         echo "12345" >>$TF
13666         echo "12345" >>$DIR/$tfile
13667         cancel_lru_locks $OSC
13668         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13669 }
13670 run_test 150a "truncate/append tests"
13671
13672 test_150b() {
13673         check_set_fallocate_or_skip
13674
13675         touch $DIR/$tfile
13676         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13677         check_fallocate $DIR/$tfile || error "fallocate failed"
13678 }
13679 run_test 150b "Verify fallocate (prealloc) functionality"
13680
13681 test_150bb() {
13682         check_set_fallocate_or_skip
13683
13684         touch $DIR/$tfile
13685         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13686         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13687         > $DIR/$tfile
13688         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13689         # precomputed md5sum for 20MB of zeroes
13690         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13691         local sum=($(md5sum $DIR/$tfile))
13692
13693         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13694
13695         check_set_fallocate 1
13696
13697         > $DIR/$tfile
13698         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13699         sum=($(md5sum $DIR/$tfile))
13700
13701         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13702 }
13703 run_test 150bb "Verify fallocate modes both zero space"
13704
13705 test_150c() {
13706         check_set_fallocate_or_skip
13707
13708         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13709         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13710         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13711         sync; sync_all_data
13712         cancel_lru_locks $OSC
13713         sleep 5
13714         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13715         want=$((OSTCOUNT * 1048576))
13716
13717         # Must allocate all requested space, not more than 5% extra
13718         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13719                 error "bytes $bytes is not $want"
13720
13721         rm -f $DIR/$tfile
13722         # verify fallocate on PFL file
13723         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13724                 error "Create $DIR/$tfile failed"
13725         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13726                         error "fallocate failed"
13727         sync; sync_all_data
13728         cancel_lru_locks $OSC
13729         sleep 5
13730         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13731         local want=$((1024 * 1048576))
13732
13733         # Must allocate all requested space, not more than 5% extra
13734         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13735                 error "bytes $bytes is not $want"
13736 }
13737 run_test 150c "Verify fallocate Size and Blocks"
13738
13739 test_150d() {
13740         check_set_fallocate_or_skip
13741
13742         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13743         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13744         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13745         sync; sync_all_data
13746         cancel_lru_locks $OSC
13747         sleep 5
13748         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13749         local want=$((OSTCOUNT * 1048576))
13750
13751         # Must allocate all requested space, not more than 5% extra
13752         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13753                 error "bytes $bytes is not $want"
13754 }
13755 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13756
13757 test_150e() {
13758         check_set_fallocate_or_skip
13759
13760         echo "df before:"
13761         $LFS df
13762         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13763         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13764                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13765
13766         # Find OST with Minimum Size
13767         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13768                        sort -un | head -1)
13769
13770         # Get 100MB per OST of the available space to reduce run time
13771         # else 60% of the available space if we are running SLOW tests
13772         if [ $SLOW == "no" ]; then
13773                 local space=$((1024 * 100 * OSTCOUNT))
13774         else
13775                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13776         fi
13777
13778         fallocate -l${space}k $DIR/$tfile ||
13779                 error "fallocate ${space}k $DIR/$tfile failed"
13780         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13781
13782         # get size immediately after fallocate. This should be correctly
13783         # updated
13784         local size=$(stat -c '%s' $DIR/$tfile)
13785         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13786
13787         # Sleep for a while for statfs to get updated. And not pull from cache.
13788         sleep 2
13789
13790         echo "df after fallocate:"
13791         $LFS df
13792
13793         (( size / 1024 == space )) || error "size $size != requested $space"
13794         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13795                 error "used $used < space $space"
13796
13797         rm $DIR/$tfile || error "rm failed"
13798         sync
13799         wait_delete_completed
13800
13801         echo "df after unlink:"
13802         $LFS df
13803 }
13804 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13805
13806 #LU-2902 roc_hit was not able to read all values from lproc
13807 function roc_hit_init() {
13808         local list=$(comma_list $(osts_nodes))
13809         local dir=$DIR/$tdir-check
13810         local file=$dir/$tfile
13811         local BEFORE
13812         local AFTER
13813         local idx
13814
13815         test_mkdir $dir
13816         #use setstripe to do a write to every ost
13817         for i in $(seq 0 $((OSTCOUNT-1))); do
13818                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13819                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13820                 idx=$(printf %04x $i)
13821                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13822                         awk '$1 == "cache_access" {sum += $7}
13823                                 END { printf("%0.0f", sum) }')
13824
13825                 cancel_lru_locks osc
13826                 cat $file >/dev/null
13827
13828                 AFTER=$(get_osd_param $list *OST*$idx stats |
13829                         awk '$1 == "cache_access" {sum += $7}
13830                                 END { printf("%0.0f", sum) }')
13831
13832                 echo BEFORE:$BEFORE AFTER:$AFTER
13833                 if ! let "AFTER - BEFORE == 4"; then
13834                         rm -rf $dir
13835                         error "roc_hit is not safe to use"
13836                 fi
13837                 rm $file
13838         done
13839
13840         rm -rf $dir
13841 }
13842
13843 function roc_hit() {
13844         local list=$(comma_list $(osts_nodes))
13845         echo $(get_osd_param $list '' stats |
13846                 awk '$1 == "cache_hit" {sum += $7}
13847                         END { printf("%0.0f", sum) }')
13848 }
13849
13850 function set_cache() {
13851         local on=1
13852
13853         if [ "$2" == "off" ]; then
13854                 on=0;
13855         fi
13856         local list=$(comma_list $(osts_nodes))
13857         set_osd_param $list '' $1_cache_enable $on
13858
13859         cancel_lru_locks osc
13860 }
13861
13862 test_151() {
13863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13864         remote_ost_nodsh && skip "remote OST with nodsh"
13865
13866         local CPAGES=3
13867         local list=$(comma_list $(osts_nodes))
13868
13869         # check whether obdfilter is cache capable at all
13870         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13871                 skip "not cache-capable obdfilter"
13872         fi
13873
13874         # check cache is enabled on all obdfilters
13875         if get_osd_param $list '' read_cache_enable | grep 0; then
13876                 skip "oss cache is disabled"
13877         fi
13878
13879         set_osd_param $list '' writethrough_cache_enable 1
13880
13881         # check write cache is enabled on all obdfilters
13882         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13883                 skip "oss write cache is NOT enabled"
13884         fi
13885
13886         roc_hit_init
13887
13888         #define OBD_FAIL_OBD_NO_LRU  0x609
13889         do_nodes $list $LCTL set_param fail_loc=0x609
13890
13891         # pages should be in the case right after write
13892         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13893                 error "dd failed"
13894
13895         local BEFORE=$(roc_hit)
13896         cancel_lru_locks osc
13897         cat $DIR/$tfile >/dev/null
13898         local AFTER=$(roc_hit)
13899
13900         do_nodes $list $LCTL set_param fail_loc=0
13901
13902         if ! let "AFTER - BEFORE == CPAGES"; then
13903                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13904         fi
13905
13906         cancel_lru_locks osc
13907         # invalidates OST cache
13908         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13909         set_osd_param $list '' read_cache_enable 0
13910         cat $DIR/$tfile >/dev/null
13911
13912         # now data shouldn't be found in the cache
13913         BEFORE=$(roc_hit)
13914         cancel_lru_locks osc
13915         cat $DIR/$tfile >/dev/null
13916         AFTER=$(roc_hit)
13917         if let "AFTER - BEFORE != 0"; then
13918                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13919         fi
13920
13921         set_osd_param $list '' read_cache_enable 1
13922         rm -f $DIR/$tfile
13923 }
13924 run_test 151 "test cache on oss and controls ==============================="
13925
13926 test_152() {
13927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13928
13929         local TF="$TMP/$tfile"
13930
13931         # simulate ENOMEM during write
13932 #define OBD_FAIL_OST_NOMEM      0x226
13933         lctl set_param fail_loc=0x80000226
13934         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13935         cp $TF $DIR/$tfile
13936         sync || error "sync failed"
13937         lctl set_param fail_loc=0
13938
13939         # discard client's cache
13940         cancel_lru_locks osc
13941
13942         # simulate ENOMEM during read
13943         lctl set_param fail_loc=0x80000226
13944         cmp $TF $DIR/$tfile || error "cmp failed"
13945         lctl set_param fail_loc=0
13946
13947         rm -f $TF
13948 }
13949 run_test 152 "test read/write with enomem ============================"
13950
13951 test_153() {
13952         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13953 }
13954 run_test 153 "test if fdatasync does not crash ======================="
13955
13956 dot_lustre_fid_permission_check() {
13957         local fid=$1
13958         local ffid=$MOUNT/.lustre/fid/$fid
13959         local test_dir=$2
13960
13961         echo "stat fid $fid"
13962         stat $ffid > /dev/null || error "stat $ffid failed."
13963         echo "touch fid $fid"
13964         touch $ffid || error "touch $ffid failed."
13965         echo "write to fid $fid"
13966         cat /etc/hosts > $ffid || error "write $ffid failed."
13967         echo "read fid $fid"
13968         diff /etc/hosts $ffid || error "read $ffid failed."
13969         echo "append write to fid $fid"
13970         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13971         echo "rename fid $fid"
13972         mv $ffid $test_dir/$tfile.1 &&
13973                 error "rename $ffid to $tfile.1 should fail."
13974         touch $test_dir/$tfile.1
13975         mv $test_dir/$tfile.1 $ffid &&
13976                 error "rename $tfile.1 to $ffid should fail."
13977         rm -f $test_dir/$tfile.1
13978         echo "truncate fid $fid"
13979         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13980         echo "link fid $fid"
13981         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13982         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13983                 echo "setfacl fid $fid"
13984                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13985                 echo "getfacl fid $fid"
13986                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13987         fi
13988         echo "unlink fid $fid"
13989         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13990         echo "mknod fid $fid"
13991         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13992
13993         fid=[0xf00000400:0x1:0x0]
13994         ffid=$MOUNT/.lustre/fid/$fid
13995
13996         echo "stat non-exist fid $fid"
13997         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13998         echo "write to non-exist fid $fid"
13999         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14000         echo "link new fid $fid"
14001         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14002
14003         mkdir -p $test_dir/$tdir
14004         touch $test_dir/$tdir/$tfile
14005         fid=$($LFS path2fid $test_dir/$tdir)
14006         rc=$?
14007         [ $rc -ne 0 ] &&
14008                 error "error: could not get fid for $test_dir/$dir/$tfile."
14009
14010         ffid=$MOUNT/.lustre/fid/$fid
14011
14012         echo "ls $fid"
14013         ls $ffid > /dev/null || error "ls $ffid failed."
14014         echo "touch $fid/$tfile.1"
14015         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14016
14017         echo "touch $MOUNT/.lustre/fid/$tfile"
14018         touch $MOUNT/.lustre/fid/$tfile && \
14019                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14020
14021         echo "setxattr to $MOUNT/.lustre/fid"
14022         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14023
14024         echo "listxattr for $MOUNT/.lustre/fid"
14025         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14026
14027         echo "delxattr from $MOUNT/.lustre/fid"
14028         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14029
14030         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14031         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14032                 error "touch invalid fid should fail."
14033
14034         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14035         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14036                 error "touch non-normal fid should fail."
14037
14038         echo "rename $tdir to $MOUNT/.lustre/fid"
14039         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14040                 error "rename to $MOUNT/.lustre/fid should fail."
14041
14042         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14043         then            # LU-3547
14044                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14045                 local new_obf_mode=777
14046
14047                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14048                 chmod $new_obf_mode $DIR/.lustre/fid ||
14049                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14050
14051                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14052                 [ $obf_mode -eq $new_obf_mode ] ||
14053                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14054
14055                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14056                 chmod $old_obf_mode $DIR/.lustre/fid ||
14057                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14058         fi
14059
14060         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14061         fid=$($LFS path2fid $test_dir/$tfile-2)
14062
14063         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14064         then # LU-5424
14065                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14066                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14067                         error "create lov data thru .lustre failed"
14068         fi
14069         echo "cp /etc/passwd $test_dir/$tfile-2"
14070         cp /etc/passwd $test_dir/$tfile-2 ||
14071                 error "copy to $test_dir/$tfile-2 failed."
14072         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14073         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14074                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14075
14076         rm -rf $test_dir/tfile.lnk
14077         rm -rf $test_dir/$tfile-2
14078 }
14079
14080 test_154A() {
14081         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14082                 skip "Need MDS version at least 2.4.1"
14083
14084         local tf=$DIR/$tfile
14085         touch $tf
14086
14087         local fid=$($LFS path2fid $tf)
14088         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14089
14090         # check that we get the same pathname back
14091         local rootpath
14092         local found
14093         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14094                 echo "$rootpath $fid"
14095                 found=$($LFS fid2path $rootpath "$fid")
14096                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14097                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14098         done
14099
14100         # check wrong root path format
14101         rootpath=$MOUNT"_wrong"
14102         found=$($LFS fid2path $rootpath "$fid")
14103         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14104 }
14105 run_test 154A "lfs path2fid and fid2path basic checks"
14106
14107 test_154B() {
14108         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14109                 skip "Need MDS version at least 2.4.1"
14110
14111         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14112         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14113         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14114         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14115
14116         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14117         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14118
14119         # check that we get the same pathname
14120         echo "PFID: $PFID, name: $name"
14121         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14122         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14123         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14124                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14125
14126         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14127 }
14128 run_test 154B "verify the ll_decode_linkea tool"
14129
14130 test_154a() {
14131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14132         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14133         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14134                 skip "Need MDS version at least 2.2.51"
14135         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14136
14137         cp /etc/hosts $DIR/$tfile
14138
14139         fid=$($LFS path2fid $DIR/$tfile)
14140         rc=$?
14141         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14142
14143         dot_lustre_fid_permission_check "$fid" $DIR ||
14144                 error "dot lustre permission check $fid failed"
14145
14146         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14147
14148         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14149
14150         touch $MOUNT/.lustre/file &&
14151                 error "creation is not allowed under .lustre"
14152
14153         mkdir $MOUNT/.lustre/dir &&
14154                 error "mkdir is not allowed under .lustre"
14155
14156         rm -rf $DIR/$tfile
14157 }
14158 run_test 154a "Open-by-FID"
14159
14160 test_154b() {
14161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14162         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14164         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14165                 skip "Need MDS version at least 2.2.51"
14166
14167         local remote_dir=$DIR/$tdir/remote_dir
14168         local MDTIDX=1
14169         local rc=0
14170
14171         mkdir -p $DIR/$tdir
14172         $LFS mkdir -i $MDTIDX $remote_dir ||
14173                 error "create remote directory failed"
14174
14175         cp /etc/hosts $remote_dir/$tfile
14176
14177         fid=$($LFS path2fid $remote_dir/$tfile)
14178         rc=$?
14179         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14180
14181         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14182                 error "dot lustre permission check $fid failed"
14183         rm -rf $DIR/$tdir
14184 }
14185 run_test 154b "Open-by-FID for remote directory"
14186
14187 test_154c() {
14188         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14189                 skip "Need MDS version at least 2.4.1"
14190
14191         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14192         local FID1=$($LFS path2fid $DIR/$tfile.1)
14193         local FID2=$($LFS path2fid $DIR/$tfile.2)
14194         local FID3=$($LFS path2fid $DIR/$tfile.3)
14195
14196         local N=1
14197         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14198                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14199                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14200                 local want=FID$N
14201                 [ "$FID" = "${!want}" ] ||
14202                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14203                 N=$((N + 1))
14204         done
14205
14206         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14207         do
14208                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14209                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14210                 N=$((N + 1))
14211         done
14212 }
14213 run_test 154c "lfs path2fid and fid2path multiple arguments"
14214
14215 test_154d() {
14216         remote_mds_nodsh && skip "remote MDS with nodsh"
14217         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14218                 skip "Need MDS version at least 2.5.53"
14219
14220         if remote_mds; then
14221                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14222         else
14223                 nid="0@lo"
14224         fi
14225         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14226         local fd
14227         local cmd
14228
14229         rm -f $DIR/$tfile
14230         touch $DIR/$tfile
14231
14232         local fid=$($LFS path2fid $DIR/$tfile)
14233         # Open the file
14234         fd=$(free_fd)
14235         cmd="exec $fd<$DIR/$tfile"
14236         eval $cmd
14237         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14238         echo "$fid_list" | grep "$fid"
14239         rc=$?
14240
14241         cmd="exec $fd>/dev/null"
14242         eval $cmd
14243         if [ $rc -ne 0 ]; then
14244                 error "FID $fid not found in open files list $fid_list"
14245         fi
14246 }
14247 run_test 154d "Verify open file fid"
14248
14249 test_154e()
14250 {
14251         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14252                 skip "Need MDS version at least 2.6.50"
14253
14254         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14255                 error ".lustre returned by readdir"
14256         fi
14257 }
14258 run_test 154e ".lustre is not returned by readdir"
14259
14260 test_154f() {
14261         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14262
14263         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14264         test_mkdir -p -c1 $DIR/$tdir/d
14265         # test dirs inherit from its stripe
14266         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14267         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14268         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14269         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14270         touch $DIR/f
14271
14272         # get fid of parents
14273         local FID0=$($LFS path2fid $DIR/$tdir/d)
14274         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14275         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14276         local FID3=$($LFS path2fid $DIR)
14277
14278         # check that path2fid --parents returns expected <parent_fid>/name
14279         # 1) test for a directory (single parent)
14280         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14281         [ "$parent" == "$FID0/foo1" ] ||
14282                 error "expected parent: $FID0/foo1, got: $parent"
14283
14284         # 2) test for a file with nlink > 1 (multiple parents)
14285         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14286         echo "$parent" | grep -F "$FID1/$tfile" ||
14287                 error "$FID1/$tfile not returned in parent list"
14288         echo "$parent" | grep -F "$FID2/link" ||
14289                 error "$FID2/link not returned in parent list"
14290
14291         # 3) get parent by fid
14292         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14293         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14294         echo "$parent" | grep -F "$FID1/$tfile" ||
14295                 error "$FID1/$tfile not returned in parent list (by fid)"
14296         echo "$parent" | grep -F "$FID2/link" ||
14297                 error "$FID2/link not returned in parent list (by fid)"
14298
14299         # 4) test for entry in root directory
14300         parent=$($LFS path2fid --parents $DIR/f)
14301         echo "$parent" | grep -F "$FID3/f" ||
14302                 error "$FID3/f not returned in parent list"
14303
14304         # 5) test it on root directory
14305         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14306                 error "$MOUNT should not have parents"
14307
14308         # enable xattr caching and check that linkea is correctly updated
14309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14310         save_lustre_params client "llite.*.xattr_cache" > $save
14311         lctl set_param llite.*.xattr_cache 1
14312
14313         # 6.1) linkea update on rename
14314         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14315
14316         # get parents by fid
14317         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14318         # foo1 should no longer be returned in parent list
14319         echo "$parent" | grep -F "$FID1" &&
14320                 error "$FID1 should no longer be in parent list"
14321         # the new path should appear
14322         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14323                 error "$FID2/$tfile.moved is not in parent list"
14324
14325         # 6.2) linkea update on unlink
14326         rm -f $DIR/$tdir/d/foo2/link
14327         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14328         # foo2/link should no longer be returned in parent list
14329         echo "$parent" | grep -F "$FID2/link" &&
14330                 error "$FID2/link should no longer be in parent list"
14331         true
14332
14333         rm -f $DIR/f
14334         restore_lustre_params < $save
14335         rm -f $save
14336 }
14337 run_test 154f "get parent fids by reading link ea"
14338
14339 test_154g()
14340 {
14341         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14342         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14343            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14344                 skip "Need MDS version at least 2.6.92"
14345
14346         mkdir -p $DIR/$tdir
14347         llapi_fid_test -d $DIR/$tdir
14348 }
14349 run_test 154g "various llapi FID tests"
14350
14351 test_155_small_load() {
14352     local temp=$TMP/$tfile
14353     local file=$DIR/$tfile
14354
14355     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14356         error "dd of=$temp bs=6096 count=1 failed"
14357     cp $temp $file
14358     cancel_lru_locks $OSC
14359     cmp $temp $file || error "$temp $file differ"
14360
14361     $TRUNCATE $temp 6000
14362     $TRUNCATE $file 6000
14363     cmp $temp $file || error "$temp $file differ (truncate1)"
14364
14365     echo "12345" >>$temp
14366     echo "12345" >>$file
14367     cmp $temp $file || error "$temp $file differ (append1)"
14368
14369     echo "12345" >>$temp
14370     echo "12345" >>$file
14371     cmp $temp $file || error "$temp $file differ (append2)"
14372
14373     rm -f $temp $file
14374     true
14375 }
14376
14377 test_155_big_load() {
14378         remote_ost_nodsh && skip "remote OST with nodsh"
14379
14380         local temp=$TMP/$tfile
14381         local file=$DIR/$tfile
14382
14383         free_min_max
14384         local cache_size=$(do_facet ost$((MAXI+1)) \
14385                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14386         local large_file_size=$((cache_size * 2))
14387
14388         echo "OSS cache size: $cache_size KB"
14389         echo "Large file size: $large_file_size KB"
14390
14391         [ $MAXV -le $large_file_size ] &&
14392                 skip_env "max available OST size needs > $large_file_size KB"
14393
14394         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14395
14396         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14397                 error "dd of=$temp bs=$large_file_size count=1k failed"
14398         cp $temp $file
14399         ls -lh $temp $file
14400         cancel_lru_locks osc
14401         cmp $temp $file || error "$temp $file differ"
14402
14403         rm -f $temp $file
14404         true
14405 }
14406
14407 save_writethrough() {
14408         local facets=$(get_facets OST)
14409
14410         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14411 }
14412
14413 test_155a() {
14414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14415
14416         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14417
14418         save_writethrough $p
14419
14420         set_cache read on
14421         set_cache writethrough on
14422         test_155_small_load
14423         restore_lustre_params < $p
14424         rm -f $p
14425 }
14426 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14427
14428 test_155b() {
14429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14430
14431         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14432
14433         save_writethrough $p
14434
14435         set_cache read on
14436         set_cache writethrough off
14437         test_155_small_load
14438         restore_lustre_params < $p
14439         rm -f $p
14440 }
14441 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14442
14443 test_155c() {
14444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14445
14446         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14447
14448         save_writethrough $p
14449
14450         set_cache read off
14451         set_cache writethrough on
14452         test_155_small_load
14453         restore_lustre_params < $p
14454         rm -f $p
14455 }
14456 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14457
14458 test_155d() {
14459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14460
14461         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14462
14463         save_writethrough $p
14464
14465         set_cache read off
14466         set_cache writethrough off
14467         test_155_small_load
14468         restore_lustre_params < $p
14469         rm -f $p
14470 }
14471 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14472
14473 test_155e() {
14474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14475
14476         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14477
14478         save_writethrough $p
14479
14480         set_cache read on
14481         set_cache writethrough on
14482         test_155_big_load
14483         restore_lustre_params < $p
14484         rm -f $p
14485 }
14486 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14487
14488 test_155f() {
14489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14490
14491         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14492
14493         save_writethrough $p
14494
14495         set_cache read on
14496         set_cache writethrough off
14497         test_155_big_load
14498         restore_lustre_params < $p
14499         rm -f $p
14500 }
14501 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14502
14503 test_155g() {
14504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14505
14506         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14507
14508         save_writethrough $p
14509
14510         set_cache read off
14511         set_cache writethrough on
14512         test_155_big_load
14513         restore_lustre_params < $p
14514         rm -f $p
14515 }
14516 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14517
14518 test_155h() {
14519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14520
14521         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14522
14523         save_writethrough $p
14524
14525         set_cache read off
14526         set_cache writethrough off
14527         test_155_big_load
14528         restore_lustre_params < $p
14529         rm -f $p
14530 }
14531 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14532
14533 test_156() {
14534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14535         remote_ost_nodsh && skip "remote OST with nodsh"
14536         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14537                 skip "stats not implemented on old servers"
14538         [ "$ost1_FSTYPE" = "zfs" ] &&
14539                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14540
14541         local CPAGES=3
14542         local BEFORE
14543         local AFTER
14544         local file="$DIR/$tfile"
14545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14546
14547         save_writethrough $p
14548         roc_hit_init
14549
14550         log "Turn on read and write cache"
14551         set_cache read on
14552         set_cache writethrough on
14553
14554         log "Write data and read it back."
14555         log "Read should be satisfied from the cache."
14556         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14557         BEFORE=$(roc_hit)
14558         cancel_lru_locks osc
14559         cat $file >/dev/null
14560         AFTER=$(roc_hit)
14561         if ! let "AFTER - BEFORE == CPAGES"; then
14562                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14563         else
14564                 log "cache hits: before: $BEFORE, after: $AFTER"
14565         fi
14566
14567         log "Read again; it should be satisfied from the cache."
14568         BEFORE=$AFTER
14569         cancel_lru_locks osc
14570         cat $file >/dev/null
14571         AFTER=$(roc_hit)
14572         if ! let "AFTER - BEFORE == CPAGES"; then
14573                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14574         else
14575                 log "cache hits:: before: $BEFORE, after: $AFTER"
14576         fi
14577
14578         log "Turn off the read cache and turn on the write cache"
14579         set_cache read off
14580         set_cache writethrough on
14581
14582         log "Read again; it should be satisfied from the cache."
14583         BEFORE=$(roc_hit)
14584         cancel_lru_locks osc
14585         cat $file >/dev/null
14586         AFTER=$(roc_hit)
14587         if ! let "AFTER - BEFORE == CPAGES"; then
14588                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14589         else
14590                 log "cache hits:: before: $BEFORE, after: $AFTER"
14591         fi
14592
14593         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14594                 # > 2.12.56 uses pagecache if cached
14595                 log "Read again; it should not be satisfied from the cache."
14596                 BEFORE=$AFTER
14597                 cancel_lru_locks osc
14598                 cat $file >/dev/null
14599                 AFTER=$(roc_hit)
14600                 if ! let "AFTER - BEFORE == 0"; then
14601                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14602                 else
14603                         log "cache hits:: before: $BEFORE, after: $AFTER"
14604                 fi
14605         fi
14606
14607         log "Write data and read it back."
14608         log "Read should be satisfied from the cache."
14609         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14610         BEFORE=$(roc_hit)
14611         cancel_lru_locks osc
14612         cat $file >/dev/null
14613         AFTER=$(roc_hit)
14614         if ! let "AFTER - BEFORE == CPAGES"; then
14615                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14616         else
14617                 log "cache hits:: before: $BEFORE, after: $AFTER"
14618         fi
14619
14620         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14621                 # > 2.12.56 uses pagecache if cached
14622                 log "Read again; it should not be satisfied from the cache."
14623                 BEFORE=$AFTER
14624                 cancel_lru_locks osc
14625                 cat $file >/dev/null
14626                 AFTER=$(roc_hit)
14627                 if ! let "AFTER - BEFORE == 0"; then
14628                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14629                 else
14630                         log "cache hits:: before: $BEFORE, after: $AFTER"
14631                 fi
14632         fi
14633
14634         log "Turn off read and write cache"
14635         set_cache read off
14636         set_cache writethrough off
14637
14638         log "Write data and read it back"
14639         log "It should not be satisfied from the cache."
14640         rm -f $file
14641         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14642         cancel_lru_locks osc
14643         BEFORE=$(roc_hit)
14644         cat $file >/dev/null
14645         AFTER=$(roc_hit)
14646         if ! let "AFTER - BEFORE == 0"; then
14647                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14648         else
14649                 log "cache hits:: before: $BEFORE, after: $AFTER"
14650         fi
14651
14652         log "Turn on the read cache and turn off the write cache"
14653         set_cache read on
14654         set_cache writethrough off
14655
14656         log "Write data and read it back"
14657         log "It should not be satisfied from the cache."
14658         rm -f $file
14659         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14660         BEFORE=$(roc_hit)
14661         cancel_lru_locks osc
14662         cat $file >/dev/null
14663         AFTER=$(roc_hit)
14664         if ! let "AFTER - BEFORE == 0"; then
14665                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14666         else
14667                 log "cache hits:: before: $BEFORE, after: $AFTER"
14668         fi
14669
14670         log "Read again; it should be satisfied from the cache."
14671         BEFORE=$(roc_hit)
14672         cancel_lru_locks osc
14673         cat $file >/dev/null
14674         AFTER=$(roc_hit)
14675         if ! let "AFTER - BEFORE == CPAGES"; then
14676                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14677         else
14678                 log "cache hits:: before: $BEFORE, after: $AFTER"
14679         fi
14680
14681         restore_lustre_params < $p
14682         rm -f $p $file
14683 }
14684 run_test 156 "Verification of tunables"
14685
14686 test_160a() {
14687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14688         remote_mds_nodsh && skip "remote MDS with nodsh"
14689         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14690                 skip "Need MDS version at least 2.2.0"
14691
14692         changelog_register || error "changelog_register failed"
14693         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14694         changelog_users $SINGLEMDS | grep -q $cl_user ||
14695                 error "User $cl_user not found in changelog_users"
14696
14697         # change something
14698         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14699         changelog_clear 0 || error "changelog_clear failed"
14700         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14701         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14702         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14703         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14704         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14705         rm $DIR/$tdir/pics/desktop.jpg
14706
14707         changelog_dump | tail -10
14708
14709         echo "verifying changelog mask"
14710         changelog_chmask "-MKDIR"
14711         changelog_chmask "-CLOSE"
14712
14713         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14714         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14715
14716         changelog_chmask "+MKDIR"
14717         changelog_chmask "+CLOSE"
14718
14719         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14720         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14721
14722         changelog_dump | tail -10
14723         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14724         CLOSES=$(changelog_dump | grep -c "CLOSE")
14725         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14726         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14727
14728         # verify contents
14729         echo "verifying target fid"
14730         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14731         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14732         [ "$fidc" == "$fidf" ] ||
14733                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14734         echo "verifying parent fid"
14735         # The FID returned from the Changelog may be the directory shard on
14736         # a different MDT, and not the FID returned by path2fid on the parent.
14737         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14738         # since this is what will matter when recreating this file in the tree.
14739         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14740         local pathp=$($LFS fid2path $MOUNT "$fidp")
14741         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14742                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14743
14744         echo "getting records for $cl_user"
14745         changelog_users $SINGLEMDS
14746         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14747         local nclr=3
14748         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14749                 error "changelog_clear failed"
14750         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14751         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14752         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14753                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14754
14755         local min0_rec=$(changelog_users $SINGLEMDS |
14756                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14757         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14758                           awk '{ print $1; exit; }')
14759
14760         changelog_dump | tail -n 5
14761         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14762         [ $first_rec == $((min0_rec + 1)) ] ||
14763                 error "first index should be $min0_rec + 1 not $first_rec"
14764
14765         # LU-3446 changelog index reset on MDT restart
14766         local cur_rec1=$(changelog_users $SINGLEMDS |
14767                          awk '/^current.index:/ { print $NF }')
14768         changelog_clear 0 ||
14769                 error "clear all changelog records for $cl_user failed"
14770         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14771         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14772                 error "Fail to start $SINGLEMDS"
14773         local cur_rec2=$(changelog_users $SINGLEMDS |
14774                          awk '/^current.index:/ { print $NF }')
14775         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14776         [ $cur_rec1 == $cur_rec2 ] ||
14777                 error "current index should be $cur_rec1 not $cur_rec2"
14778
14779         echo "verifying users from this test are deregistered"
14780         changelog_deregister || error "changelog_deregister failed"
14781         changelog_users $SINGLEMDS | grep -q $cl_user &&
14782                 error "User '$cl_user' still in changelog_users"
14783
14784         # lctl get_param -n mdd.*.changelog_users
14785         # current index: 144
14786         # ID    index (idle seconds)
14787         # cl3   144 (2)
14788         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14789                 # this is the normal case where all users were deregistered
14790                 # make sure no new records are added when no users are present
14791                 local last_rec1=$(changelog_users $SINGLEMDS |
14792                                   awk '/^current.index:/ { print $NF }')
14793                 touch $DIR/$tdir/chloe
14794                 local last_rec2=$(changelog_users $SINGLEMDS |
14795                                   awk '/^current.index:/ { print $NF }')
14796                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14797                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14798         else
14799                 # any changelog users must be leftovers from a previous test
14800                 changelog_users $SINGLEMDS
14801                 echo "other changelog users; can't verify off"
14802         fi
14803 }
14804 run_test 160a "changelog sanity"
14805
14806 test_160b() { # LU-3587
14807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14808         remote_mds_nodsh && skip "remote MDS with nodsh"
14809         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14810                 skip "Need MDS version at least 2.2.0"
14811
14812         changelog_register || error "changelog_register failed"
14813         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14814         changelog_users $SINGLEMDS | grep -q $cl_user ||
14815                 error "User '$cl_user' not found in changelog_users"
14816
14817         local longname1=$(str_repeat a 255)
14818         local longname2=$(str_repeat b 255)
14819
14820         cd $DIR
14821         echo "creating very long named file"
14822         touch $longname1 || error "create of '$longname1' failed"
14823         echo "renaming very long named file"
14824         mv $longname1 $longname2
14825
14826         changelog_dump | grep RENME | tail -n 5
14827         rm -f $longname2
14828 }
14829 run_test 160b "Verify that very long rename doesn't crash in changelog"
14830
14831 test_160c() {
14832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14833         remote_mds_nodsh && skip "remote MDS with nodsh"
14834
14835         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14836                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14837                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14838                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14839
14840         local rc=0
14841
14842         # Registration step
14843         changelog_register || error "changelog_register failed"
14844
14845         rm -rf $DIR/$tdir
14846         mkdir -p $DIR/$tdir
14847         $MCREATE $DIR/$tdir/foo_160c
14848         changelog_chmask "-TRUNC"
14849         $TRUNCATE $DIR/$tdir/foo_160c 200
14850         changelog_chmask "+TRUNC"
14851         $TRUNCATE $DIR/$tdir/foo_160c 199
14852         changelog_dump | tail -n 5
14853         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14854         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14855 }
14856 run_test 160c "verify that changelog log catch the truncate event"
14857
14858 test_160d() {
14859         remote_mds_nodsh && skip "remote MDS with nodsh"
14860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14862         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14863                 skip "Need MDS version at least 2.7.60"
14864
14865         # Registration step
14866         changelog_register || error "changelog_register failed"
14867
14868         mkdir -p $DIR/$tdir/migrate_dir
14869         changelog_clear 0 || error "changelog_clear failed"
14870
14871         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14872         changelog_dump | tail -n 5
14873         local migrates=$(changelog_dump | grep -c "MIGRT")
14874         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14875 }
14876 run_test 160d "verify that changelog log catch the migrate event"
14877
14878 test_160e() {
14879         remote_mds_nodsh && skip "remote MDS with nodsh"
14880
14881         # Create a user
14882         changelog_register || error "changelog_register failed"
14883
14884         # Delete a future user (expect fail)
14885         local MDT0=$(facet_svc $SINGLEMDS)
14886         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14887         local rc=$?
14888
14889         if [ $rc -eq 0 ]; then
14890                 error "Deleted non-existant user cl77"
14891         elif [ $rc -ne 2 ]; then
14892                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14893         fi
14894
14895         # Clear to a bad index (1 billion should be safe)
14896         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14897         rc=$?
14898
14899         if [ $rc -eq 0 ]; then
14900                 error "Successfully cleared to invalid CL index"
14901         elif [ $rc -ne 22 ]; then
14902                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14903         fi
14904 }
14905 run_test 160e "changelog negative testing (should return errors)"
14906
14907 test_160f() {
14908         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14909         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14910                 skip "Need MDS version at least 2.10.56"
14911
14912         local mdts=$(comma_list $(mdts_nodes))
14913
14914         # Create a user
14915         changelog_register || error "first changelog_register failed"
14916         changelog_register || error "second changelog_register failed"
14917         local cl_users
14918         declare -A cl_user1
14919         declare -A cl_user2
14920         local user_rec1
14921         local user_rec2
14922         local i
14923
14924         # generate some changelog records to accumulate on each MDT
14925         # use all_char because created files should be evenly distributed
14926         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
14927                 error "test_mkdir $tdir failed"
14928         log "$(date +%s): creating first files"
14929         for ((i = 0; i < MDSCOUNT * 2; i++)); do
14930                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
14931                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
14932         done
14933
14934         # check changelogs have been generated
14935         local start=$SECONDS
14936         local idle_time=$((MDSCOUNT * 5 + 5))
14937         local nbcl=$(changelog_dump | wc -l)
14938         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14939
14940         for param in "changelog_max_idle_time=$idle_time" \
14941                      "changelog_gc=1" \
14942                      "changelog_min_gc_interval=2" \
14943                      "changelog_min_free_cat_entries=3"; do
14944                 local MDT0=$(facet_svc $SINGLEMDS)
14945                 local var="${param%=*}"
14946                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14947
14948                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14949                 do_nodes $mdts $LCTL set_param mdd.*.$param
14950         done
14951
14952         # force cl_user2 to be idle (1st part), but also cancel the
14953         # cl_user1 records so that it is not evicted later in the test.
14954         local sleep1=$((idle_time / 2))
14955         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14956         sleep $sleep1
14957
14958         # simulate changelog catalog almost full
14959         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14960         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
14961
14962         for i in $(seq $MDSCOUNT); do
14963                 cl_users=(${CL_USERS[mds$i]})
14964                 cl_user1[mds$i]="${cl_users[0]}"
14965                 cl_user2[mds$i]="${cl_users[1]}"
14966
14967                 [ -n "${cl_user1[mds$i]}" ] ||
14968                         error "mds$i: no user registered"
14969                 [ -n "${cl_user2[mds$i]}" ] ||
14970                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14971
14972                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14973                 [ -n "$user_rec1" ] ||
14974                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14975                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14976                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14977                 [ -n "$user_rec2" ] ||
14978                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14979                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14980                      "$user_rec1 + 2 == $user_rec2"
14981                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14982                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14983                               "$user_rec1 + 2, but is $user_rec2"
14984                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14985                 [ -n "$user_rec2" ] ||
14986                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14987                 [ $user_rec1 == $user_rec2 ] ||
14988                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14989                               "$user_rec1, but is $user_rec2"
14990         done
14991
14992         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14993         local sleep2=$((idle_time - (SECONDS - start) + 1))
14994         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14995         sleep $sleep2
14996
14997         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14998         # cl_user1 should be OK because it recently processed records.
14999         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15000         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15001                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15002                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15003         done
15004
15005         # ensure gc thread is done
15006         for i in $(mdts_nodes); do
15007                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15008                         error "$i: GC-thread not done"
15009         done
15010
15011         local first_rec
15012         for (( i = 1; i <= MDSCOUNT; i++ )); do
15013                 # check cl_user1 still registered
15014                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15015                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15016                 # check cl_user2 unregistered
15017                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15018                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15019
15020                 # check changelogs are present and starting at $user_rec1 + 1
15021                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15022                 [ -n "$user_rec1" ] ||
15023                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15024                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15025                             awk '{ print $1; exit; }')
15026
15027                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15028                 [ $((user_rec1 + 1)) == $first_rec ] ||
15029                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15030         done
15031 }
15032 run_test 160f "changelog garbage collect (timestamped users)"
15033
15034 test_160g() {
15035         remote_mds_nodsh && skip "remote MDS with nodsh"
15036         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15037                 skip "Need MDS version at least 2.10.56"
15038
15039         local mdts=$(comma_list $(mdts_nodes))
15040
15041         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15042         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15043
15044         # Create a user
15045         changelog_register || error "first changelog_register failed"
15046         changelog_register || error "second changelog_register failed"
15047         local cl_users
15048         declare -A cl_user1
15049         declare -A cl_user2
15050         local user_rec1
15051         local user_rec2
15052         local i
15053
15054         # generate some changelog records to accumulate on each MDT
15055         # use all_char because created files should be evenly distributed
15056         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15057                 error "test_mkdir $tdir failed"
15058         for ((i = 0; i < MDSCOUNT; i++)); do
15059                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15060                         error "create $DIR/$tdir/d$i.1 failed"
15061         done
15062
15063         # check changelogs have been generated
15064         local nbcl=$(changelog_dump | wc -l)
15065         (( $nbcl > 0 )) || error "no changelogs found"
15066
15067         # reduce the max_idle_indexes value to make sure we exceed it
15068         for param in "changelog_max_idle_indexes=1" \
15069                      "changelog_gc=1" \
15070                      "changelog_min_gc_interval=2" \
15071                      "changelog_min_free_cat_entries=3"; do
15072                 local MDT0=$(facet_svc $SINGLEMDS)
15073                 local var="${param%=*}"
15074                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15075
15076                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15077                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15078                         error "unable to set mdd.*.$param"
15079         done
15080
15081         # simulate changelog catalog almost full
15082         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15083         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15084
15085         local start=$SECONDS
15086         for i in $(seq $MDSCOUNT); do
15087                 cl_users=(${CL_USERS[mds$i]})
15088                 cl_user1[mds$i]="${cl_users[0]}"
15089                 cl_user2[mds$i]="${cl_users[1]}"
15090
15091                 [ -n "${cl_user1[mds$i]}" ] ||
15092                         error "mds$i: no user registered"
15093                 [ -n "${cl_user2[mds$i]}" ] ||
15094                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15095
15096                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15097                 [ -n "$user_rec1" ] ||
15098                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15099                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15100                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15101                 [ -n "$user_rec2" ] ||
15102                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15103                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15104                      "$user_rec1 + 2 == $user_rec2"
15105                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15106                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15107                               "$user_rec1 + 2, but is $user_rec2"
15108                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15109                 [ -n "$user_rec2" ] ||
15110                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15111                 [ $user_rec1 == $user_rec2 ] ||
15112                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15113                               "$user_rec1, but is $user_rec2"
15114         done
15115
15116         # ensure we are past the previous changelog_min_gc_interval set above
15117         local sleep2=$((start + 2 - SECONDS))
15118         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15119
15120         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15121         # cl_user1 should be OK because it recently processed records.
15122         for ((i = 0; i < MDSCOUNT; i++)); do
15123                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15124                         error "create $DIR/$tdir/d$i.3 failed"
15125         done
15126
15127         # ensure gc thread is done
15128         for i in $(mdts_nodes); do
15129                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15130                         error "$i: GC-thread not done"
15131         done
15132
15133         local first_rec
15134         for (( i = 1; i <= MDSCOUNT; i++ )); do
15135                 # check cl_user1 still registered
15136                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15137                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15138                 # check cl_user2 unregistered
15139                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15140                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15141
15142                 # check changelogs are present and starting at $user_rec1 + 1
15143                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15144                 [ -n "$user_rec1" ] ||
15145                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15146                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15147                             awk '{ print $1; exit; }')
15148
15149                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15150                 [ $((user_rec1 + 1)) == $first_rec ] ||
15151                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15152         done
15153 }
15154 run_test 160g "changelog garbage collect (old users)"
15155
15156 test_160h() {
15157         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15158         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15159                 skip "Need MDS version at least 2.10.56"
15160
15161         local mdts=$(comma_list $(mdts_nodes))
15162
15163         # Create a user
15164         changelog_register || error "first changelog_register failed"
15165         changelog_register || error "second changelog_register failed"
15166         local cl_users
15167         declare -A cl_user1
15168         declare -A cl_user2
15169         local user_rec1
15170         local user_rec2
15171         local i
15172
15173         # generate some changelog records to accumulate on each MDT
15174         # use all_char because created files should be evenly distributed
15175         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15176                 error "test_mkdir $tdir failed"
15177         for ((i = 0; i < MDSCOUNT; i++)); do
15178                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15179                         error "create $DIR/$tdir/d$i.1 failed"
15180         done
15181
15182         # check changelogs have been generated
15183         local nbcl=$(changelog_dump | wc -l)
15184         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15185
15186         for param in "changelog_max_idle_time=10" \
15187                      "changelog_gc=1" \
15188                      "changelog_min_gc_interval=2"; do
15189                 local MDT0=$(facet_svc $SINGLEMDS)
15190                 local var="${param%=*}"
15191                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15192
15193                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15194                 do_nodes $mdts $LCTL set_param mdd.*.$param
15195         done
15196
15197         # force cl_user2 to be idle (1st part)
15198         sleep 9
15199
15200         for i in $(seq $MDSCOUNT); do
15201                 cl_users=(${CL_USERS[mds$i]})
15202                 cl_user1[mds$i]="${cl_users[0]}"
15203                 cl_user2[mds$i]="${cl_users[1]}"
15204
15205                 [ -n "${cl_user1[mds$i]}" ] ||
15206                         error "mds$i: no user registered"
15207                 [ -n "${cl_user2[mds$i]}" ] ||
15208                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15209
15210                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15211                 [ -n "$user_rec1" ] ||
15212                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15213                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15214                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15215                 [ -n "$user_rec2" ] ||
15216                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15217                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15218                      "$user_rec1 + 2 == $user_rec2"
15219                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15220                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15221                               "$user_rec1 + 2, but is $user_rec2"
15222                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15223                 [ -n "$user_rec2" ] ||
15224                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15225                 [ $user_rec1 == $user_rec2 ] ||
15226                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15227                               "$user_rec1, but is $user_rec2"
15228         done
15229
15230         # force cl_user2 to be idle (2nd part) and to reach
15231         # changelog_max_idle_time
15232         sleep 2
15233
15234         # force each GC-thread start and block then
15235         # one per MDT/MDD, set fail_val accordingly
15236         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15237         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15238
15239         # generate more changelogs to trigger fail_loc
15240         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15241                 error "create $DIR/$tdir/${tfile}bis failed"
15242
15243         # stop MDT to stop GC-thread, should be done in back-ground as it will
15244         # block waiting for the thread to be released and exit
15245         declare -A stop_pids
15246         for i in $(seq $MDSCOUNT); do
15247                 stop mds$i &
15248                 stop_pids[mds$i]=$!
15249         done
15250
15251         for i in $(mdts_nodes); do
15252                 local facet
15253                 local nb=0
15254                 local facets=$(facets_up_on_host $i)
15255
15256                 for facet in ${facets//,/ }; do
15257                         if [[ $facet == mds* ]]; then
15258                                 nb=$((nb + 1))
15259                         fi
15260                 done
15261                 # ensure each MDS's gc threads are still present and all in "R"
15262                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15263                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15264                         error "$i: expected $nb GC-thread"
15265                 wait_update $i \
15266                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15267                         "R" 20 ||
15268                         error "$i: GC-thread not found in R-state"
15269                 # check umounts of each MDT on MDS have reached kthread_stop()
15270                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15271                         error "$i: expected $nb umount"
15272                 wait_update $i \
15273                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15274                         error "$i: umount not found in D-state"
15275         done
15276
15277         # release all GC-threads
15278         do_nodes $mdts $LCTL set_param fail_loc=0
15279
15280         # wait for MDT stop to complete
15281         for i in $(seq $MDSCOUNT); do
15282                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15283         done
15284
15285         # XXX
15286         # may try to check if any orphan changelog records are present
15287         # via ldiskfs/zfs and llog_reader...
15288
15289         # re-start/mount MDTs
15290         for i in $(seq $MDSCOUNT); do
15291                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15292                         error "Fail to start mds$i"
15293         done
15294
15295         local first_rec
15296         for i in $(seq $MDSCOUNT); do
15297                 # check cl_user1 still registered
15298                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15299                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15300                 # check cl_user2 unregistered
15301                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15302                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15303
15304                 # check changelogs are present and starting at $user_rec1 + 1
15305                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15306                 [ -n "$user_rec1" ] ||
15307                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15308                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15309                             awk '{ print $1; exit; }')
15310
15311                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15312                 [ $((user_rec1 + 1)) == $first_rec ] ||
15313                         error "mds$i: first index should be $user_rec1 + 1, " \
15314                               "but is $first_rec"
15315         done
15316 }
15317 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15318               "during mount"
15319
15320 test_160i() {
15321
15322         local mdts=$(comma_list $(mdts_nodes))
15323
15324         changelog_register || error "first changelog_register failed"
15325
15326         # generate some changelog records to accumulate on each MDT
15327         # use all_char because created files should be evenly distributed
15328         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15329                 error "test_mkdir $tdir failed"
15330         for ((i = 0; i < MDSCOUNT; i++)); do
15331                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15332                         error "create $DIR/$tdir/d$i.1 failed"
15333         done
15334
15335         # check changelogs have been generated
15336         local nbcl=$(changelog_dump | wc -l)
15337         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15338
15339         # simulate race between register and unregister
15340         # XXX as fail_loc is set per-MDS, with DNE configs the race
15341         # simulation will only occur for one MDT per MDS and for the
15342         # others the normal race scenario will take place
15343         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15344         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15345         do_nodes $mdts $LCTL set_param fail_val=1
15346
15347         # unregister 1st user
15348         changelog_deregister &
15349         local pid1=$!
15350         # wait some time for deregister work to reach race rdv
15351         sleep 2
15352         # register 2nd user
15353         changelog_register || error "2nd user register failed"
15354
15355         wait $pid1 || error "1st user deregister failed"
15356
15357         local i
15358         local last_rec
15359         declare -A LAST_REC
15360         for i in $(seq $MDSCOUNT); do
15361                 if changelog_users mds$i | grep "^cl"; then
15362                         # make sure new records are added with one user present
15363                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15364                                           awk '/^current.index:/ { print $NF }')
15365                 else
15366                         error "mds$i has no user registered"
15367                 fi
15368         done
15369
15370         # generate more changelog records to accumulate on each MDT
15371         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15372                 error "create $DIR/$tdir/${tfile}bis failed"
15373
15374         for i in $(seq $MDSCOUNT); do
15375                 last_rec=$(changelog_users $SINGLEMDS |
15376                            awk '/^current.index:/ { print $NF }')
15377                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15378                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15379                         error "changelogs are off on mds$i"
15380         done
15381 }
15382 run_test 160i "changelog user register/unregister race"
15383
15384 test_160j() {
15385         remote_mds_nodsh && skip "remote MDS with nodsh"
15386         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15387                 skip "Need MDS version at least 2.12.56"
15388
15389         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15390         stack_trap "umount $MOUNT2" EXIT
15391
15392         changelog_register || error "first changelog_register failed"
15393         stack_trap "changelog_deregister" EXIT
15394
15395         # generate some changelog
15396         # use all_char because created files should be evenly distributed
15397         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15398                 error "mkdir $tdir failed"
15399         for ((i = 0; i < MDSCOUNT; i++)); do
15400                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15401                         error "create $DIR/$tdir/d$i.1 failed"
15402         done
15403
15404         # open the changelog device
15405         exec 3>/dev/changelog-$FSNAME-MDT0000
15406         stack_trap "exec 3>&-" EXIT
15407         exec 4</dev/changelog-$FSNAME-MDT0000
15408         stack_trap "exec 4<&-" EXIT
15409
15410         # umount the first lustre mount
15411         umount $MOUNT
15412         stack_trap "mount_client $MOUNT" EXIT
15413
15414         # read changelog, which may or may not fail, but should not crash
15415         cat <&4 >/dev/null
15416
15417         # clear changelog
15418         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15419         changelog_users $SINGLEMDS | grep -q $cl_user ||
15420                 error "User $cl_user not found in changelog_users"
15421
15422         printf 'clear:'$cl_user':0' >&3
15423 }
15424 run_test 160j "client can be umounted while its chanangelog is being used"
15425
15426 test_160k() {
15427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15428         remote_mds_nodsh && skip "remote MDS with nodsh"
15429
15430         mkdir -p $DIR/$tdir/1/1
15431
15432         changelog_register || error "changelog_register failed"
15433         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15434
15435         changelog_users $SINGLEMDS | grep -q $cl_user ||
15436                 error "User '$cl_user' not found in changelog_users"
15437 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15438         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15439         rmdir $DIR/$tdir/1/1 & sleep 1
15440         mkdir $DIR/$tdir/2
15441         touch $DIR/$tdir/2/2
15442         rm -rf $DIR/$tdir/2
15443
15444         wait
15445         sleep 4
15446
15447         changelog_dump | grep rmdir || error "rmdir not recorded"
15448 }
15449 run_test 160k "Verify that changelog records are not lost"
15450
15451 # Verifies that a file passed as a parameter has recently had an operation
15452 # performed on it that has generated an MTIME changelog which contains the
15453 # correct parent FID. As files might reside on a different MDT from the
15454 # parent directory in DNE configurations, the FIDs are translated to paths
15455 # before being compared, which should be identical
15456 compare_mtime_changelog() {
15457         local file="${1}"
15458         local mdtidx
15459         local mtime
15460         local cl_fid
15461         local pdir
15462         local dir
15463
15464         mdtidx=$($LFS getstripe --mdt-index $file)
15465         mdtidx=$(printf "%04x" $mdtidx)
15466
15467         # Obtain the parent FID from the MTIME changelog
15468         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15469         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15470
15471         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15472         [ -z "$cl_fid" ] && error "parent FID not present"
15473
15474         # Verify that the path for the parent FID is the same as the path for
15475         # the test directory
15476         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15477
15478         dir=$(dirname $1)
15479
15480         [[ "${pdir%/}" == "$dir" ]] ||
15481                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15482 }
15483
15484 test_160l() {
15485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15486
15487         remote_mds_nodsh && skip "remote MDS with nodsh"
15488         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15489                 skip "Need MDS version at least 2.13.55"
15490
15491         local cl_user
15492
15493         changelog_register || error "changelog_register failed"
15494         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15495
15496         changelog_users $SINGLEMDS | grep -q $cl_user ||
15497                 error "User '$cl_user' not found in changelog_users"
15498
15499         # Clear some types so that MTIME changelogs are generated
15500         changelog_chmask "-CREAT"
15501         changelog_chmask "-CLOSE"
15502
15503         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15504
15505         # Test CL_MTIME during setattr
15506         touch $DIR/$tdir/$tfile
15507         compare_mtime_changelog $DIR/$tdir/$tfile
15508
15509         # Test CL_MTIME during close
15510         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15511         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15512 }
15513 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15514
15515 test_161a() {
15516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15517
15518         test_mkdir -c1 $DIR/$tdir
15519         cp /etc/hosts $DIR/$tdir/$tfile
15520         test_mkdir -c1 $DIR/$tdir/foo1
15521         test_mkdir -c1 $DIR/$tdir/foo2
15522         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15523         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15524         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15525         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15526         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15527         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15528                 $LFS fid2path $DIR $FID
15529                 error "bad link ea"
15530         fi
15531         # middle
15532         rm $DIR/$tdir/foo2/zachary
15533         # last
15534         rm $DIR/$tdir/foo2/thor
15535         # first
15536         rm $DIR/$tdir/$tfile
15537         # rename
15538         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15539         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15540                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15541         rm $DIR/$tdir/foo2/maggie
15542
15543         # overflow the EA
15544         local longname=$tfile.avg_len_is_thirty_two_
15545         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15546                 error_noexit 'failed to unlink many hardlinks'" EXIT
15547         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15548                 error "failed to hardlink many files"
15549         links=$($LFS fid2path $DIR $FID | wc -l)
15550         echo -n "${links}/1000 links in link EA"
15551         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15552 }
15553 run_test 161a "link ea sanity"
15554
15555 test_161b() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15558
15559         local MDTIDX=1
15560         local remote_dir=$DIR/$tdir/remote_dir
15561
15562         mkdir -p $DIR/$tdir
15563         $LFS mkdir -i $MDTIDX $remote_dir ||
15564                 error "create remote directory failed"
15565
15566         cp /etc/hosts $remote_dir/$tfile
15567         mkdir -p $remote_dir/foo1
15568         mkdir -p $remote_dir/foo2
15569         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15570         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15571         ln $remote_dir/$tfile $remote_dir/foo1/luna
15572         ln $remote_dir/$tfile $remote_dir/foo2/thor
15573
15574         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15575                      tr -d ']')
15576         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15577                 $LFS fid2path $DIR $FID
15578                 error "bad link ea"
15579         fi
15580         # middle
15581         rm $remote_dir/foo2/zachary
15582         # last
15583         rm $remote_dir/foo2/thor
15584         # first
15585         rm $remote_dir/$tfile
15586         # rename
15587         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15588         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15589         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15590                 $LFS fid2path $DIR $FID
15591                 error "bad link rename"
15592         fi
15593         rm $remote_dir/foo2/maggie
15594
15595         # overflow the EA
15596         local longname=filename_avg_len_is_thirty_two_
15597         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15598                 error "failed to hardlink many files"
15599         links=$($LFS fid2path $DIR $FID | wc -l)
15600         echo -n "${links}/1000 links in link EA"
15601         [[ ${links} -gt 60 ]] ||
15602                 error "expected at least 60 links in link EA"
15603         unlinkmany $remote_dir/foo2/$longname 1000 ||
15604         error "failed to unlink many hardlinks"
15605 }
15606 run_test 161b "link ea sanity under remote directory"
15607
15608 test_161c() {
15609         remote_mds_nodsh && skip "remote MDS with nodsh"
15610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15611         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15612                 skip "Need MDS version at least 2.1.5"
15613
15614         # define CLF_RENAME_LAST 0x0001
15615         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15616         changelog_register || error "changelog_register failed"
15617
15618         rm -rf $DIR/$tdir
15619         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15620         touch $DIR/$tdir/foo_161c
15621         touch $DIR/$tdir/bar_161c
15622         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15623         changelog_dump | grep RENME | tail -n 5
15624         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15625         changelog_clear 0 || error "changelog_clear failed"
15626         if [ x$flags != "x0x1" ]; then
15627                 error "flag $flags is not 0x1"
15628         fi
15629
15630         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15631         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15632         touch $DIR/$tdir/foo_161c
15633         touch $DIR/$tdir/bar_161c
15634         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15635         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15636         changelog_dump | grep RENME | tail -n 5
15637         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15638         changelog_clear 0 || error "changelog_clear failed"
15639         if [ x$flags != "x0x0" ]; then
15640                 error "flag $flags is not 0x0"
15641         fi
15642         echo "rename overwrite a target having nlink > 1," \
15643                 "changelog record has flags of $flags"
15644
15645         # rename doesn't overwrite a target (changelog flag 0x0)
15646         touch $DIR/$tdir/foo_161c
15647         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15648         changelog_dump | grep RENME | tail -n 5
15649         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15650         changelog_clear 0 || error "changelog_clear failed"
15651         if [ x$flags != "x0x0" ]; then
15652                 error "flag $flags is not 0x0"
15653         fi
15654         echo "rename doesn't overwrite a target," \
15655                 "changelog record has flags of $flags"
15656
15657         # define CLF_UNLINK_LAST 0x0001
15658         # unlink a file having nlink = 1 (changelog flag 0x1)
15659         rm -f $DIR/$tdir/foo2_161c
15660         changelog_dump | grep UNLNK | tail -n 5
15661         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15662         changelog_clear 0 || error "changelog_clear failed"
15663         if [ x$flags != "x0x1" ]; then
15664                 error "flag $flags is not 0x1"
15665         fi
15666         echo "unlink a file having nlink = 1," \
15667                 "changelog record has flags of $flags"
15668
15669         # unlink a file having nlink > 1 (changelog flag 0x0)
15670         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15671         rm -f $DIR/$tdir/foobar_161c
15672         changelog_dump | grep UNLNK | tail -n 5
15673         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15674         changelog_clear 0 || error "changelog_clear failed"
15675         if [ x$flags != "x0x0" ]; then
15676                 error "flag $flags is not 0x0"
15677         fi
15678         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15679 }
15680 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15681
15682 test_161d() {
15683         remote_mds_nodsh && skip "remote MDS with nodsh"
15684         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15685
15686         local pid
15687         local fid
15688
15689         changelog_register || error "changelog_register failed"
15690
15691         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15692         # interfer with $MOUNT/.lustre/fid/ access
15693         mkdir $DIR/$tdir
15694         [[ $? -eq 0 ]] || error "mkdir failed"
15695
15696         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15697         $LCTL set_param fail_loc=0x8000140c
15698         # 5s pause
15699         $LCTL set_param fail_val=5
15700
15701         # create file
15702         echo foofoo > $DIR/$tdir/$tfile &
15703         pid=$!
15704
15705         # wait for create to be delayed
15706         sleep 2
15707
15708         ps -p $pid
15709         [[ $? -eq 0 ]] || error "create should be blocked"
15710
15711         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15712         stack_trap "rm -f $tempfile"
15713         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15714         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15715         # some delay may occur during ChangeLog publishing and file read just
15716         # above, that could allow file write to happen finally
15717         [[ -s $tempfile ]] && echo "file should be empty"
15718
15719         $LCTL set_param fail_loc=0
15720
15721         wait $pid
15722         [[ $? -eq 0 ]] || error "create failed"
15723 }
15724 run_test 161d "create with concurrent .lustre/fid access"
15725
15726 check_path() {
15727         local expected="$1"
15728         shift
15729         local fid="$2"
15730
15731         local path
15732         path=$($LFS fid2path "$@")
15733         local rc=$?
15734
15735         if [ $rc -ne 0 ]; then
15736                 error "path looked up of '$expected' failed: rc=$rc"
15737         elif [ "$path" != "$expected" ]; then
15738                 error "path looked up '$path' instead of '$expected'"
15739         else
15740                 echo "FID '$fid' resolves to path '$path' as expected"
15741         fi
15742 }
15743
15744 test_162a() { # was test_162
15745         test_mkdir -p -c1 $DIR/$tdir/d2
15746         touch $DIR/$tdir/d2/$tfile
15747         touch $DIR/$tdir/d2/x1
15748         touch $DIR/$tdir/d2/x2
15749         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15750         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15751         # regular file
15752         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15753         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15754
15755         # softlink
15756         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15757         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15758         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15759
15760         # softlink to wrong file
15761         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15762         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15763         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15764
15765         # hardlink
15766         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15767         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15768         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15769         # fid2path dir/fsname should both work
15770         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15771         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15772
15773         # hardlink count: check that there are 2 links
15774         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15775         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15776
15777         # hardlink indexing: remove the first link
15778         rm $DIR/$tdir/d2/p/q/r/hlink
15779         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15780 }
15781 run_test 162a "path lookup sanity"
15782
15783 test_162b() {
15784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15785         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15786
15787         mkdir $DIR/$tdir
15788         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15789                                 error "create striped dir failed"
15790
15791         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15792                                         tail -n 1 | awk '{print $2}')
15793         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15794
15795         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15796         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15797
15798         # regular file
15799         for ((i=0;i<5;i++)); do
15800                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15801                         error "get fid for f$i failed"
15802                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15803
15804                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15805                         error "get fid for d$i failed"
15806                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15807         done
15808
15809         return 0
15810 }
15811 run_test 162b "striped directory path lookup sanity"
15812
15813 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15814 test_162c() {
15815         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15816                 skip "Need MDS version at least 2.7.51"
15817
15818         local lpath=$tdir.local
15819         local rpath=$tdir.remote
15820
15821         test_mkdir $DIR/$lpath
15822         test_mkdir $DIR/$rpath
15823
15824         for ((i = 0; i <= 101; i++)); do
15825                 lpath="$lpath/$i"
15826                 mkdir $DIR/$lpath
15827                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15828                         error "get fid for local directory $DIR/$lpath failed"
15829                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15830
15831                 rpath="$rpath/$i"
15832                 test_mkdir $DIR/$rpath
15833                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15834                         error "get fid for remote directory $DIR/$rpath failed"
15835                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15836         done
15837
15838         return 0
15839 }
15840 run_test 162c "fid2path works with paths 100 or more directories deep"
15841
15842 oalr_event_count() {
15843         local event="${1}"
15844         local trace="${2}"
15845
15846         awk -v name="${FSNAME}-OST0000" \
15847             -v event="${event}" \
15848             '$1 == "TRACE" && $2 == event && $3 == name' \
15849             "${trace}" |
15850         wc -l
15851 }
15852
15853 oalr_expect_event_count() {
15854         local event="${1}"
15855         local trace="${2}"
15856         local expect="${3}"
15857         local count
15858
15859         count=$(oalr_event_count "${event}" "${trace}")
15860         if ((count == expect)); then
15861                 return 0
15862         fi
15863
15864         error_noexit "${event} event count was '${count}', expected ${expect}"
15865         cat "${trace}" >&2
15866         exit 1
15867 }
15868
15869 cleanup_165() {
15870         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15871         stop ost1
15872         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15873 }
15874
15875 setup_165() {
15876         sync # Flush previous IOs so we can count log entries.
15877         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15878         stack_trap cleanup_165 EXIT
15879 }
15880
15881 test_165a() {
15882         local trace="/tmp/${tfile}.trace"
15883         local rc
15884         local count
15885
15886         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15887                 skip "OFD access log unsupported"
15888
15889         setup_165
15890         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15891         sleep 5
15892
15893         do_facet ost1 ofd_access_log_reader --list
15894         stop ost1
15895
15896         do_facet ost1 killall -TERM ofd_access_log_reader
15897         wait
15898         rc=$?
15899
15900         if ((rc != 0)); then
15901                 error "ofd_access_log_reader exited with rc = '${rc}'"
15902         fi
15903
15904         # Parse trace file for discovery events:
15905         oalr_expect_event_count alr_log_add "${trace}" 1
15906         oalr_expect_event_count alr_log_eof "${trace}" 1
15907         oalr_expect_event_count alr_log_free "${trace}" 1
15908 }
15909 run_test 165a "ofd access log discovery"
15910
15911 test_165b() {
15912         local trace="/tmp/${tfile}.trace"
15913         local file="${DIR}/${tfile}"
15914         local pfid1
15915         local pfid2
15916         local -a entry
15917         local rc
15918         local count
15919         local size
15920         local flags
15921
15922         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15923                 skip "OFD access log unsupported"
15924
15925         setup_165
15926         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15927         sleep 5
15928
15929         do_facet ost1 ofd_access_log_reader --list
15930
15931         lfs setstripe -c 1 -i 0 "${file}"
15932         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15933                 error "cannot create '${file}'"
15934
15935         sleep 5
15936         do_facet ost1 killall -TERM ofd_access_log_reader
15937         wait
15938         rc=$?
15939
15940         if ((rc != 0)); then
15941                 error "ofd_access_log_reader exited with rc = '${rc}'"
15942         fi
15943
15944         oalr_expect_event_count alr_log_entry "${trace}" 1
15945
15946         pfid1=$($LFS path2fid "${file}")
15947
15948         # 1     2             3   4    5     6   7    8    9     10
15949         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15950         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15951
15952         echo "entry = '${entry[*]}'" >&2
15953
15954         pfid2=${entry[4]}
15955         if [[ "${pfid1}" != "${pfid2}" ]]; then
15956                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15957         fi
15958
15959         size=${entry[8]}
15960         if ((size != 1048576)); then
15961                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15962         fi
15963
15964         flags=${entry[10]}
15965         if [[ "${flags}" != "w" ]]; then
15966                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15967         fi
15968
15969         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15970         sleep 5
15971
15972         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15973                 error "cannot read '${file}'"
15974         sleep 5
15975
15976         do_facet ost1 killall -TERM ofd_access_log_reader
15977         wait
15978         rc=$?
15979
15980         if ((rc != 0)); then
15981                 error "ofd_access_log_reader exited with rc = '${rc}'"
15982         fi
15983
15984         oalr_expect_event_count alr_log_entry "${trace}" 1
15985
15986         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15987         echo "entry = '${entry[*]}'" >&2
15988
15989         pfid2=${entry[4]}
15990         if [[ "${pfid1}" != "${pfid2}" ]]; then
15991                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15992         fi
15993
15994         size=${entry[8]}
15995         if ((size != 524288)); then
15996                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15997         fi
15998
15999         flags=${entry[10]}
16000         if [[ "${flags}" != "r" ]]; then
16001                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16002         fi
16003 }
16004 run_test 165b "ofd access log entries are produced and consumed"
16005
16006 test_165c() {
16007         local trace="/tmp/${tfile}.trace"
16008         local file="${DIR}/${tdir}/${tfile}"
16009
16010         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16011                 skip "OFD access log unsupported"
16012
16013         test_mkdir "${DIR}/${tdir}"
16014
16015         setup_165
16016         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16017         sleep 5
16018
16019         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16020
16021         # 4096 / 64 = 64. Create twice as many entries.
16022         for ((i = 0; i < 128; i++)); do
16023                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16024                         error "cannot create file"
16025         done
16026
16027         sync
16028
16029         do_facet ost1 killall -TERM ofd_access_log_reader
16030         wait
16031         rc=$?
16032         if ((rc != 0)); then
16033                 error "ofd_access_log_reader exited with rc = '${rc}'"
16034         fi
16035
16036         unlinkmany  "${file}-%d" 128
16037 }
16038 run_test 165c "full ofd access logs do not block IOs"
16039
16040 oal_get_read_count() {
16041         local stats="$1"
16042
16043         # STATS lustre-OST0001 alr_read_count 1
16044
16045         do_facet ost1 cat "${stats}" |
16046         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16047              END { print count; }'
16048 }
16049
16050 oal_expect_read_count() {
16051         local stats="$1"
16052         local count
16053         local expect="$2"
16054
16055         # Ask ofd_access_log_reader to write stats.
16056         do_facet ost1 killall -USR1 ofd_access_log_reader
16057
16058         # Allow some time for things to happen.
16059         sleep 1
16060
16061         count=$(oal_get_read_count "${stats}")
16062         if ((count == expect)); then
16063                 return 0
16064         fi
16065
16066         error_noexit "bad read count, got ${count}, expected ${expect}"
16067         do_facet ost1 cat "${stats}" >&2
16068         exit 1
16069 }
16070
16071 test_165d() {
16072         local stats="/tmp/${tfile}.stats"
16073         local file="${DIR}/${tdir}/${tfile}"
16074         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16075
16076         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16077                 skip "OFD access log unsupported"
16078
16079         test_mkdir "${DIR}/${tdir}"
16080
16081         setup_165
16082         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16083         sleep 5
16084
16085         lfs setstripe -c 1 -i 0 "${file}"
16086
16087         do_facet ost1 lctl set_param "${param}=rw"
16088         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16089                 error "cannot create '${file}'"
16090         oal_expect_read_count "${stats}" 1
16091
16092         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16093                 error "cannot read '${file}'"
16094         oal_expect_read_count "${stats}" 2
16095
16096         do_facet ost1 lctl set_param "${param}=r"
16097         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16098                 error "cannot create '${file}'"
16099         oal_expect_read_count "${stats}" 2
16100
16101         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16102                 error "cannot read '${file}'"
16103         oal_expect_read_count "${stats}" 3
16104
16105         do_facet ost1 lctl set_param "${param}=w"
16106         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16107                 error "cannot create '${file}'"
16108         oal_expect_read_count "${stats}" 4
16109
16110         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16111                 error "cannot read '${file}'"
16112         oal_expect_read_count "${stats}" 4
16113
16114         do_facet ost1 lctl set_param "${param}=0"
16115         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16116                 error "cannot create '${file}'"
16117         oal_expect_read_count "${stats}" 4
16118
16119         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16120                 error "cannot read '${file}'"
16121         oal_expect_read_count "${stats}" 4
16122
16123         do_facet ost1 killall -TERM ofd_access_log_reader
16124         wait
16125         rc=$?
16126         if ((rc != 0)); then
16127                 error "ofd_access_log_reader exited with rc = '${rc}'"
16128         fi
16129 }
16130 run_test 165d "ofd_access_log mask works"
16131
16132 test_165e() {
16133         local stats="/tmp/${tfile}.stats"
16134         local file0="${DIR}/${tdir}-0/${tfile}"
16135         local file1="${DIR}/${tdir}-1/${tfile}"
16136
16137         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16138                 skip "OFD access log unsupported"
16139
16140         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16141
16142         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16143         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16144
16145         lfs setstripe -c 1 -i 0 "${file0}"
16146         lfs setstripe -c 1 -i 0 "${file1}"
16147
16148         setup_165
16149         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16150         sleep 5
16151
16152         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16153                 error "cannot create '${file0}'"
16154         sync
16155         oal_expect_read_count "${stats}" 0
16156
16157         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16158                 error "cannot create '${file1}'"
16159         sync
16160         oal_expect_read_count "${stats}" 1
16161
16162         do_facet ost1 killall -TERM ofd_access_log_reader
16163         wait
16164         rc=$?
16165         if ((rc != 0)); then
16166                 error "ofd_access_log_reader exited with rc = '${rc}'"
16167         fi
16168 }
16169 run_test 165e "ofd_access_log MDT index filter works"
16170
16171 test_165f() {
16172         local trace="/tmp/${tfile}.trace"
16173         local rc
16174         local count
16175
16176         setup_165
16177         do_facet ost1 timeout 60 ofd_access_log_reader \
16178                 --exit-on-close --debug=- --trace=- > "${trace}" &
16179         sleep 5
16180         stop ost1
16181
16182         wait
16183         rc=$?
16184
16185         if ((rc != 0)); then
16186                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16187                 cat "${trace}"
16188                 exit 1
16189         fi
16190 }
16191 run_test 165f "ofd_access_log_reader --exit-on-close works"
16192
16193 test_169() {
16194         # do directio so as not to populate the page cache
16195         log "creating a 10 Mb file"
16196         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16197                 error "multiop failed while creating a file"
16198         log "starting reads"
16199         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16200         log "truncating the file"
16201         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16202                 error "multiop failed while truncating the file"
16203         log "killing dd"
16204         kill %+ || true # reads might have finished
16205         echo "wait until dd is finished"
16206         wait
16207         log "removing the temporary file"
16208         rm -rf $DIR/$tfile || error "tmp file removal failed"
16209 }
16210 run_test 169 "parallel read and truncate should not deadlock"
16211
16212 test_170() {
16213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16214
16215         $LCTL clear     # bug 18514
16216         $LCTL debug_daemon start $TMP/${tfile}_log_good
16217         touch $DIR/$tfile
16218         $LCTL debug_daemon stop
16219         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16220                 error "sed failed to read log_good"
16221
16222         $LCTL debug_daemon start $TMP/${tfile}_log_good
16223         rm -rf $DIR/$tfile
16224         $LCTL debug_daemon stop
16225
16226         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16227                error "lctl df log_bad failed"
16228
16229         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16230         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16231
16232         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16233         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16234
16235         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16236                 error "bad_line good_line1 good_line2 are empty"
16237
16238         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16239         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16240         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16241
16242         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16243         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16244         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16245
16246         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16247                 error "bad_line_new good_line_new are empty"
16248
16249         local expected_good=$((good_line1 + good_line2*2))
16250
16251         rm -f $TMP/${tfile}*
16252         # LU-231, short malformed line may not be counted into bad lines
16253         if [ $bad_line -ne $bad_line_new ] &&
16254                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16255                 error "expected $bad_line bad lines, but got $bad_line_new"
16256                 return 1
16257         fi
16258
16259         if [ $expected_good -ne $good_line_new ]; then
16260                 error "expected $expected_good good lines, but got $good_line_new"
16261                 return 2
16262         fi
16263         true
16264 }
16265 run_test 170 "test lctl df to handle corrupted log ====================="
16266
16267 test_171() { # bug20592
16268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16269
16270         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16271         $LCTL set_param fail_loc=0x50e
16272         $LCTL set_param fail_val=3000
16273         multiop_bg_pause $DIR/$tfile O_s || true
16274         local MULTIPID=$!
16275         kill -USR1 $MULTIPID
16276         # cause log dump
16277         sleep 3
16278         wait $MULTIPID
16279         if dmesg | grep "recursive fault"; then
16280                 error "caught a recursive fault"
16281         fi
16282         $LCTL set_param fail_loc=0
16283         true
16284 }
16285 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16286
16287 # it would be good to share it with obdfilter-survey/iokit-libecho code
16288 setup_obdecho_osc () {
16289         local rc=0
16290         local ost_nid=$1
16291         local obdfilter_name=$2
16292         echo "Creating new osc for $obdfilter_name on $ost_nid"
16293         # make sure we can find loopback nid
16294         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16295
16296         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16297                            ${obdfilter_name}_osc_UUID || rc=2; }
16298         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16299                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16300         return $rc
16301 }
16302
16303 cleanup_obdecho_osc () {
16304         local obdfilter_name=$1
16305         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16306         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16307         return 0
16308 }
16309
16310 obdecho_test() {
16311         local OBD=$1
16312         local node=$2
16313         local pages=${3:-64}
16314         local rc=0
16315         local id
16316
16317         local count=10
16318         local obd_size=$(get_obd_size $node $OBD)
16319         local page_size=$(get_page_size $node)
16320         if [[ -n "$obd_size" ]]; then
16321                 local new_count=$((obd_size / (pages * page_size / 1024)))
16322                 [[ $new_count -ge $count ]] || count=$new_count
16323         fi
16324
16325         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16326         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16327                            rc=2; }
16328         if [ $rc -eq 0 ]; then
16329             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16330             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16331         fi
16332         echo "New object id is $id"
16333         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16334                            rc=4; }
16335         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16336                            "test_brw $count w v $pages $id" || rc=4; }
16337         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16338                            rc=4; }
16339         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16340                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16341         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16342                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16343         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16344         return $rc
16345 }
16346
16347 test_180a() {
16348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16349
16350         if ! [ -d /sys/fs/lustre/echo_client ] &&
16351            ! module_loaded obdecho; then
16352                 load_module obdecho/obdecho &&
16353                         stack_trap "rmmod obdecho" EXIT ||
16354                         error "unable to load obdecho on client"
16355         fi
16356
16357         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16358         local host=$($LCTL get_param -n osc.$osc.import |
16359                      awk '/current_connection:/ { print $2 }' )
16360         local target=$($LCTL get_param -n osc.$osc.import |
16361                        awk '/target:/ { print $2 }' )
16362         target=${target%_UUID}
16363
16364         if [ -n "$target" ]; then
16365                 setup_obdecho_osc $host $target &&
16366                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16367                         { error "obdecho setup failed with $?"; return; }
16368
16369                 obdecho_test ${target}_osc client ||
16370                         error "obdecho_test failed on ${target}_osc"
16371         else
16372                 $LCTL get_param osc.$osc.import
16373                 error "there is no osc.$osc.import target"
16374         fi
16375 }
16376 run_test 180a "test obdecho on osc"
16377
16378 test_180b() {
16379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16380         remote_ost_nodsh && skip "remote OST with nodsh"
16381
16382         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16383                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16384                 error "failed to load module obdecho"
16385
16386         local target=$(do_facet ost1 $LCTL dl |
16387                        awk '/obdfilter/ { print $4; exit; }')
16388
16389         if [ -n "$target" ]; then
16390                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16391         else
16392                 do_facet ost1 $LCTL dl
16393                 error "there is no obdfilter target on ost1"
16394         fi
16395 }
16396 run_test 180b "test obdecho directly on obdfilter"
16397
16398 test_180c() { # LU-2598
16399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16400         remote_ost_nodsh && skip "remote OST with nodsh"
16401         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16402                 skip "Need MDS version at least 2.4.0"
16403
16404         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16405                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16406                 error "failed to load module obdecho"
16407
16408         local target=$(do_facet ost1 $LCTL dl |
16409                        awk '/obdfilter/ { print $4; exit; }')
16410
16411         if [ -n "$target" ]; then
16412                 local pages=16384 # 64MB bulk I/O RPC size
16413
16414                 obdecho_test "$target" ost1 "$pages" ||
16415                         error "obdecho_test with pages=$pages failed with $?"
16416         else
16417                 do_facet ost1 $LCTL dl
16418                 error "there is no obdfilter target on ost1"
16419         fi
16420 }
16421 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16422
16423 test_181() { # bug 22177
16424         test_mkdir $DIR/$tdir
16425         # create enough files to index the directory
16426         createmany -o $DIR/$tdir/foobar 4000
16427         # print attributes for debug purpose
16428         lsattr -d .
16429         # open dir
16430         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16431         MULTIPID=$!
16432         # remove the files & current working dir
16433         unlinkmany $DIR/$tdir/foobar 4000
16434         rmdir $DIR/$tdir
16435         kill -USR1 $MULTIPID
16436         wait $MULTIPID
16437         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16438         return 0
16439 }
16440 run_test 181 "Test open-unlinked dir ========================"
16441
16442 test_182() {
16443         local fcount=1000
16444         local tcount=10
16445
16446         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16447
16448         $LCTL set_param mdc.*.rpc_stats=clear
16449
16450         for (( i = 0; i < $tcount; i++ )) ; do
16451                 mkdir $DIR/$tdir/$i
16452         done
16453
16454         for (( i = 0; i < $tcount; i++ )) ; do
16455                 createmany -o $DIR/$tdir/$i/f- $fcount &
16456         done
16457         wait
16458
16459         for (( i = 0; i < $tcount; i++ )) ; do
16460                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16461         done
16462         wait
16463
16464         $LCTL get_param mdc.*.rpc_stats
16465
16466         rm -rf $DIR/$tdir
16467 }
16468 run_test 182 "Test parallel modify metadata operations ================"
16469
16470 test_183() { # LU-2275
16471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16472         remote_mds_nodsh && skip "remote MDS with nodsh"
16473         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16474                 skip "Need MDS version at least 2.3.56"
16475
16476         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16477         echo aaa > $DIR/$tdir/$tfile
16478
16479 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16480         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16481
16482         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16483         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16484
16485         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16486
16487         # Flush negative dentry cache
16488         touch $DIR/$tdir/$tfile
16489
16490         # We are not checking for any leaked references here, they'll
16491         # become evident next time we do cleanup with module unload.
16492         rm -rf $DIR/$tdir
16493 }
16494 run_test 183 "No crash or request leak in case of strange dispositions ========"
16495
16496 # test suite 184 is for LU-2016, LU-2017
16497 test_184a() {
16498         check_swap_layouts_support
16499
16500         dir0=$DIR/$tdir/$testnum
16501         test_mkdir -p -c1 $dir0
16502         ref1=/etc/passwd
16503         ref2=/etc/group
16504         file1=$dir0/f1
16505         file2=$dir0/f2
16506         $LFS setstripe -c1 $file1
16507         cp $ref1 $file1
16508         $LFS setstripe -c2 $file2
16509         cp $ref2 $file2
16510         gen1=$($LFS getstripe -g $file1)
16511         gen2=$($LFS getstripe -g $file2)
16512
16513         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16514         gen=$($LFS getstripe -g $file1)
16515         [[ $gen1 != $gen ]] ||
16516                 "Layout generation on $file1 does not change"
16517         gen=$($LFS getstripe -g $file2)
16518         [[ $gen2 != $gen ]] ||
16519                 "Layout generation on $file2 does not change"
16520
16521         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16522         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16523
16524         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16525 }
16526 run_test 184a "Basic layout swap"
16527
16528 test_184b() {
16529         check_swap_layouts_support
16530
16531         dir0=$DIR/$tdir/$testnum
16532         mkdir -p $dir0 || error "creating dir $dir0"
16533         file1=$dir0/f1
16534         file2=$dir0/f2
16535         file3=$dir0/f3
16536         dir1=$dir0/d1
16537         dir2=$dir0/d2
16538         mkdir $dir1 $dir2
16539         $LFS setstripe -c1 $file1
16540         $LFS setstripe -c2 $file2
16541         $LFS setstripe -c1 $file3
16542         chown $RUNAS_ID $file3
16543         gen1=$($LFS getstripe -g $file1)
16544         gen2=$($LFS getstripe -g $file2)
16545
16546         $LFS swap_layouts $dir1 $dir2 &&
16547                 error "swap of directories layouts should fail"
16548         $LFS swap_layouts $dir1 $file1 &&
16549                 error "swap of directory and file layouts should fail"
16550         $RUNAS $LFS swap_layouts $file1 $file2 &&
16551                 error "swap of file we cannot write should fail"
16552         $LFS swap_layouts $file1 $file3 &&
16553                 error "swap of file with different owner should fail"
16554         /bin/true # to clear error code
16555 }
16556 run_test 184b "Forbidden layout swap (will generate errors)"
16557
16558 test_184c() {
16559         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16560         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16561         check_swap_layouts_support
16562         check_swap_layout_no_dom $DIR
16563
16564         local dir0=$DIR/$tdir/$testnum
16565         mkdir -p $dir0 || error "creating dir $dir0"
16566
16567         local ref1=$dir0/ref1
16568         local ref2=$dir0/ref2
16569         local file1=$dir0/file1
16570         local file2=$dir0/file2
16571         # create a file large enough for the concurrent test
16572         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16573         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16574         echo "ref file size: ref1($(stat -c %s $ref1))," \
16575              "ref2($(stat -c %s $ref2))"
16576
16577         cp $ref2 $file2
16578         dd if=$ref1 of=$file1 bs=16k &
16579         local DD_PID=$!
16580
16581         # Make sure dd starts to copy file, but wait at most 5 seconds
16582         local loops=0
16583         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16584
16585         $LFS swap_layouts $file1 $file2
16586         local rc=$?
16587         wait $DD_PID
16588         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16589         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16590
16591         # how many bytes copied before swapping layout
16592         local copied=$(stat -c %s $file2)
16593         local remaining=$(stat -c %s $ref1)
16594         remaining=$((remaining - copied))
16595         echo "Copied $copied bytes before swapping layout..."
16596
16597         cmp -n $copied $file1 $ref2 | grep differ &&
16598                 error "Content mismatch [0, $copied) of ref2 and file1"
16599         cmp -n $copied $file2 $ref1 ||
16600                 error "Content mismatch [0, $copied) of ref1 and file2"
16601         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16602                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16603
16604         # clean up
16605         rm -f $ref1 $ref2 $file1 $file2
16606 }
16607 run_test 184c "Concurrent write and layout swap"
16608
16609 test_184d() {
16610         check_swap_layouts_support
16611         check_swap_layout_no_dom $DIR
16612         [ -z "$(which getfattr 2>/dev/null)" ] &&
16613                 skip_env "no getfattr command"
16614
16615         local file1=$DIR/$tdir/$tfile-1
16616         local file2=$DIR/$tdir/$tfile-2
16617         local file3=$DIR/$tdir/$tfile-3
16618         local lovea1
16619         local lovea2
16620
16621         mkdir -p $DIR/$tdir
16622         touch $file1 || error "create $file1 failed"
16623         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16624                 error "create $file2 failed"
16625         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16626                 error "create $file3 failed"
16627         lovea1=$(get_layout_param $file1)
16628
16629         $LFS swap_layouts $file2 $file3 ||
16630                 error "swap $file2 $file3 layouts failed"
16631         $LFS swap_layouts $file1 $file2 ||
16632                 error "swap $file1 $file2 layouts failed"
16633
16634         lovea2=$(get_layout_param $file2)
16635         echo "$lovea1"
16636         echo "$lovea2"
16637         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16638
16639         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16640         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16641 }
16642 run_test 184d "allow stripeless layouts swap"
16643
16644 test_184e() {
16645         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16646                 skip "Need MDS version at least 2.6.94"
16647         check_swap_layouts_support
16648         check_swap_layout_no_dom $DIR
16649         [ -z "$(which getfattr 2>/dev/null)" ] &&
16650                 skip_env "no getfattr command"
16651
16652         local file1=$DIR/$tdir/$tfile-1
16653         local file2=$DIR/$tdir/$tfile-2
16654         local file3=$DIR/$tdir/$tfile-3
16655         local lovea
16656
16657         mkdir -p $DIR/$tdir
16658         touch $file1 || error "create $file1 failed"
16659         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16660                 error "create $file2 failed"
16661         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16662                 error "create $file3 failed"
16663
16664         $LFS swap_layouts $file1 $file2 ||
16665                 error "swap $file1 $file2 layouts failed"
16666
16667         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16668         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16669
16670         echo 123 > $file1 || error "Should be able to write into $file1"
16671
16672         $LFS swap_layouts $file1 $file3 ||
16673                 error "swap $file1 $file3 layouts failed"
16674
16675         echo 123 > $file1 || error "Should be able to write into $file1"
16676
16677         rm -rf $file1 $file2 $file3
16678 }
16679 run_test 184e "Recreate layout after stripeless layout swaps"
16680
16681 test_184f() {
16682         # Create a file with name longer than sizeof(struct stat) ==
16683         # 144 to see if we can get chars from the file name to appear
16684         # in the returned striping. Note that 'f' == 0x66.
16685         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16686
16687         mkdir -p $DIR/$tdir
16688         mcreate $DIR/$tdir/$file
16689         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16690                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16691         fi
16692 }
16693 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16694
16695 test_185() { # LU-2441
16696         # LU-3553 - no volatile file support in old servers
16697         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16698                 skip "Need MDS version at least 2.3.60"
16699
16700         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16701         touch $DIR/$tdir/spoo
16702         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16703         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16704                 error "cannot create/write a volatile file"
16705         [ "$FILESET" == "" ] &&
16706         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16707                 error "FID is still valid after close"
16708
16709         multiop_bg_pause $DIR/$tdir vVw4096_c
16710         local multi_pid=$!
16711
16712         local OLD_IFS=$IFS
16713         IFS=":"
16714         local fidv=($fid)
16715         IFS=$OLD_IFS
16716         # assume that the next FID for this client is sequential, since stdout
16717         # is unfortunately eaten by multiop_bg_pause
16718         local n=$((${fidv[1]} + 1))
16719         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16720         if [ "$FILESET" == "" ]; then
16721                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16722                         error "FID is missing before close"
16723         fi
16724         kill -USR1 $multi_pid
16725         # 1 second delay, so if mtime change we will see it
16726         sleep 1
16727         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16728         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16729 }
16730 run_test 185 "Volatile file support"
16731
16732 function create_check_volatile() {
16733         local idx=$1
16734         local tgt
16735
16736         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16737         local PID=$!
16738         sleep 1
16739         local FID=$(cat /tmp/${tfile}.fid)
16740         [ "$FID" == "" ] && error "can't get FID for volatile"
16741         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16742         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16743         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16744         kill -USR1 $PID
16745         wait
16746         sleep 1
16747         cancel_lru_locks mdc # flush opencache
16748         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16749         return 0
16750 }
16751
16752 test_185a(){
16753         # LU-12516 - volatile creation via .lustre
16754         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16755                 skip "Need MDS version at least 2.3.55"
16756
16757         create_check_volatile 0
16758         [ $MDSCOUNT -lt 2 ] && return 0
16759
16760         # DNE case
16761         create_check_volatile 1
16762
16763         return 0
16764 }
16765 run_test 185a "Volatile file creation in .lustre/fid/"
16766
16767 test_187a() {
16768         remote_mds_nodsh && skip "remote MDS with nodsh"
16769         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16770                 skip "Need MDS version at least 2.3.0"
16771
16772         local dir0=$DIR/$tdir/$testnum
16773         mkdir -p $dir0 || error "creating dir $dir0"
16774
16775         local file=$dir0/file1
16776         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16777         local dv1=$($LFS data_version $file)
16778         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16779         local dv2=$($LFS data_version $file)
16780         [[ $dv1 != $dv2 ]] ||
16781                 error "data version did not change on write $dv1 == $dv2"
16782
16783         # clean up
16784         rm -f $file1
16785 }
16786 run_test 187a "Test data version change"
16787
16788 test_187b() {
16789         remote_mds_nodsh && skip "remote MDS with nodsh"
16790         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16791                 skip "Need MDS version at least 2.3.0"
16792
16793         local dir0=$DIR/$tdir/$testnum
16794         mkdir -p $dir0 || error "creating dir $dir0"
16795
16796         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16797         [[ ${DV[0]} != ${DV[1]} ]] ||
16798                 error "data version did not change on write"\
16799                       " ${DV[0]} == ${DV[1]}"
16800
16801         # clean up
16802         rm -f $file1
16803 }
16804 run_test 187b "Test data version change on volatile file"
16805
16806 test_200() {
16807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16808         remote_mgs_nodsh && skip "remote MGS with nodsh"
16809         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16810
16811         local POOL=${POOL:-cea1}
16812         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16813         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16814         # Pool OST targets
16815         local first_ost=0
16816         local last_ost=$(($OSTCOUNT - 1))
16817         local ost_step=2
16818         local ost_list=$(seq $first_ost $ost_step $last_ost)
16819         local ost_range="$first_ost $last_ost $ost_step"
16820         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16821         local file_dir=$POOL_ROOT/file_tst
16822         local subdir=$test_path/subdir
16823         local rc=0
16824
16825         while : ; do
16826                 # former test_200a test_200b
16827                 pool_add $POOL                          || { rc=$? ; break; }
16828                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16829                 # former test_200c test_200d
16830                 mkdir -p $test_path
16831                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16832                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16833                 mkdir -p $subdir
16834                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16835                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16836                                                         || { rc=$? ; break; }
16837                 # former test_200e test_200f
16838                 local files=$((OSTCOUNT*3))
16839                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16840                                                         || { rc=$? ; break; }
16841                 pool_create_files $POOL $file_dir $files "$ost_list" \
16842                                                         || { rc=$? ; break; }
16843                 # former test_200g test_200h
16844                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16845                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16846
16847                 # former test_201a test_201b test_201c
16848                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16849
16850                 local f=$test_path/$tfile
16851                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16852                 pool_remove $POOL $f                    || { rc=$? ; break; }
16853                 break
16854         done
16855
16856         destroy_test_pools
16857
16858         return $rc
16859 }
16860 run_test 200 "OST pools"
16861
16862 # usage: default_attr <count | size | offset>
16863 default_attr() {
16864         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16865 }
16866
16867 # usage: check_default_stripe_attr
16868 check_default_stripe_attr() {
16869         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16870         case $1 in
16871         --stripe-count|-c)
16872                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16873         --stripe-size|-S)
16874                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16875         --stripe-index|-i)
16876                 EXPECTED=-1;;
16877         *)
16878                 error "unknown getstripe attr '$1'"
16879         esac
16880
16881         [ $ACTUAL == $EXPECTED ] ||
16882                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16883 }
16884
16885 test_204a() {
16886         test_mkdir $DIR/$tdir
16887         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16888
16889         check_default_stripe_attr --stripe-count
16890         check_default_stripe_attr --stripe-size
16891         check_default_stripe_attr --stripe-index
16892 }
16893 run_test 204a "Print default stripe attributes"
16894
16895 test_204b() {
16896         test_mkdir $DIR/$tdir
16897         $LFS setstripe --stripe-count 1 $DIR/$tdir
16898
16899         check_default_stripe_attr --stripe-size
16900         check_default_stripe_attr --stripe-index
16901 }
16902 run_test 204b "Print default stripe size and offset"
16903
16904 test_204c() {
16905         test_mkdir $DIR/$tdir
16906         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16907
16908         check_default_stripe_attr --stripe-count
16909         check_default_stripe_attr --stripe-index
16910 }
16911 run_test 204c "Print default stripe count and offset"
16912
16913 test_204d() {
16914         test_mkdir $DIR/$tdir
16915         $LFS setstripe --stripe-index 0 $DIR/$tdir
16916
16917         check_default_stripe_attr --stripe-count
16918         check_default_stripe_attr --stripe-size
16919 }
16920 run_test 204d "Print default stripe count and size"
16921
16922 test_204e() {
16923         test_mkdir $DIR/$tdir
16924         $LFS setstripe -d $DIR/$tdir
16925
16926         check_default_stripe_attr --stripe-count --raw
16927         check_default_stripe_attr --stripe-size --raw
16928         check_default_stripe_attr --stripe-index --raw
16929 }
16930 run_test 204e "Print raw stripe attributes"
16931
16932 test_204f() {
16933         test_mkdir $DIR/$tdir
16934         $LFS setstripe --stripe-count 1 $DIR/$tdir
16935
16936         check_default_stripe_attr --stripe-size --raw
16937         check_default_stripe_attr --stripe-index --raw
16938 }
16939 run_test 204f "Print raw stripe size and offset"
16940
16941 test_204g() {
16942         test_mkdir $DIR/$tdir
16943         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16944
16945         check_default_stripe_attr --stripe-count --raw
16946         check_default_stripe_attr --stripe-index --raw
16947 }
16948 run_test 204g "Print raw stripe count and offset"
16949
16950 test_204h() {
16951         test_mkdir $DIR/$tdir
16952         $LFS setstripe --stripe-index 0 $DIR/$tdir
16953
16954         check_default_stripe_attr --stripe-count --raw
16955         check_default_stripe_attr --stripe-size --raw
16956 }
16957 run_test 204h "Print raw stripe count and size"
16958
16959 # Figure out which job scheduler is being used, if any,
16960 # or use a fake one
16961 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16962         JOBENV=SLURM_JOB_ID
16963 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16964         JOBENV=LSB_JOBID
16965 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16966         JOBENV=PBS_JOBID
16967 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16968         JOBENV=LOADL_STEP_ID
16969 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16970         JOBENV=JOB_ID
16971 else
16972         $LCTL list_param jobid_name > /dev/null 2>&1
16973         if [ $? -eq 0 ]; then
16974                 JOBENV=nodelocal
16975         else
16976                 JOBENV=FAKE_JOBID
16977         fi
16978 fi
16979 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16980
16981 verify_jobstats() {
16982         local cmd=($1)
16983         shift
16984         local facets="$@"
16985
16986 # we don't really need to clear the stats for this test to work, since each
16987 # command has a unique jobid, but it makes debugging easier if needed.
16988 #       for facet in $facets; do
16989 #               local dev=$(convert_facet2label $facet)
16990 #               # clear old jobstats
16991 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16992 #       done
16993
16994         # use a new JobID for each test, or we might see an old one
16995         [ "$JOBENV" = "FAKE_JOBID" ] &&
16996                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16997
16998         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16999
17000         [ "$JOBENV" = "nodelocal" ] && {
17001                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17002                 $LCTL set_param jobid_name=$FAKE_JOBID
17003                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17004         }
17005
17006         log "Test: ${cmd[*]}"
17007         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17008
17009         if [ $JOBENV = "FAKE_JOBID" ]; then
17010                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17011         else
17012                 ${cmd[*]}
17013         fi
17014
17015         # all files are created on OST0000
17016         for facet in $facets; do
17017                 local stats="*.$(convert_facet2label $facet).job_stats"
17018
17019                 # strip out libtool wrappers for in-tree executables
17020                 if [ $(do_facet $facet lctl get_param $stats |
17021                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17022                         do_facet $facet lctl get_param $stats
17023                         error "No jobstats for $JOBVAL found on $facet::$stats"
17024                 fi
17025         done
17026 }
17027
17028 jobstats_set() {
17029         local new_jobenv=$1
17030
17031         set_persistent_param_and_check client "jobid_var" \
17032                 "$FSNAME.sys.jobid_var" $new_jobenv
17033 }
17034
17035 test_205a() { # Job stats
17036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17037         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17038                 skip "Need MDS version with at least 2.7.1"
17039         remote_mgs_nodsh && skip "remote MGS with nodsh"
17040         remote_mds_nodsh && skip "remote MDS with nodsh"
17041         remote_ost_nodsh && skip "remote OST with nodsh"
17042         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17043                 skip "Server doesn't support jobstats"
17044         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17045
17046         local old_jobenv=$($LCTL get_param -n jobid_var)
17047         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17048
17049         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17050                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17051         else
17052                 stack_trap "do_facet mgs $PERM_CMD \
17053                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17054         fi
17055         changelog_register
17056
17057         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17058                                 mdt.*.job_cleanup_interval | head -n 1)
17059         local new_interval=5
17060         do_facet $SINGLEMDS \
17061                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17062         stack_trap "do_facet $SINGLEMDS \
17063                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17064         local start=$SECONDS
17065
17066         local cmd
17067         # mkdir
17068         cmd="mkdir $DIR/$tdir"
17069         verify_jobstats "$cmd" "$SINGLEMDS"
17070         # rmdir
17071         cmd="rmdir $DIR/$tdir"
17072         verify_jobstats "$cmd" "$SINGLEMDS"
17073         # mkdir on secondary MDT
17074         if [ $MDSCOUNT -gt 1 ]; then
17075                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17076                 verify_jobstats "$cmd" "mds2"
17077         fi
17078         # mknod
17079         cmd="mknod $DIR/$tfile c 1 3"
17080         verify_jobstats "$cmd" "$SINGLEMDS"
17081         # unlink
17082         cmd="rm -f $DIR/$tfile"
17083         verify_jobstats "$cmd" "$SINGLEMDS"
17084         # create all files on OST0000 so verify_jobstats can find OST stats
17085         # open & close
17086         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17087         verify_jobstats "$cmd" "$SINGLEMDS"
17088         # setattr
17089         cmd="touch $DIR/$tfile"
17090         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17091         # write
17092         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17093         verify_jobstats "$cmd" "ost1"
17094         # read
17095         cancel_lru_locks osc
17096         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17097         verify_jobstats "$cmd" "ost1"
17098         # truncate
17099         cmd="$TRUNCATE $DIR/$tfile 0"
17100         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17101         # rename
17102         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17103         verify_jobstats "$cmd" "$SINGLEMDS"
17104         # jobstats expiry - sleep until old stats should be expired
17105         local left=$((new_interval + 5 - (SECONDS - start)))
17106         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17107                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17108                         "0" $left
17109         cmd="mkdir $DIR/$tdir.expire"
17110         verify_jobstats "$cmd" "$SINGLEMDS"
17111         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17112             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17113
17114         # Ensure that jobid are present in changelog (if supported by MDS)
17115         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17116                 changelog_dump | tail -10
17117                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17118                 [ $jobids -eq 9 ] ||
17119                         error "Wrong changelog jobid count $jobids != 9"
17120
17121                 # LU-5862
17122                 JOBENV="disable"
17123                 jobstats_set $JOBENV
17124                 touch $DIR/$tfile
17125                 changelog_dump | grep $tfile
17126                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17127                 [ $jobids -eq 0 ] ||
17128                         error "Unexpected jobids when jobid_var=$JOBENV"
17129         fi
17130
17131         # test '%j' access to environment variable - if supported
17132         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17133                 JOBENV="JOBCOMPLEX"
17134                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17135
17136                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17137         fi
17138
17139         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17140                 JOBENV="JOBCOMPLEX"
17141                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17142
17143                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17144         fi
17145
17146         # test '%j' access to per-session jobid - if supported
17147         if lctl list_param jobid_this_session > /dev/null 2>&1
17148         then
17149                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17150                 lctl set_param jobid_this_session=$USER
17151
17152                 JOBENV="JOBCOMPLEX"
17153                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17154
17155                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17156         fi
17157 }
17158 run_test 205a "Verify job stats"
17159
17160 # LU-13117, LU-13597
17161 test_205b() {
17162         job_stats="mdt.*.job_stats"
17163         $LCTL set_param $job_stats=clear
17164         # Setting jobid_var to USER might not be supported
17165         $LCTL set_param jobid_var=USER || true
17166         $LCTL set_param jobid_name="%e.%u"
17167         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17168         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17169                 grep "job_id:.*foolish" &&
17170                         error "Unexpected jobid found"
17171         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17172                 grep "open:.*min.*max.*sum" ||
17173                         error "wrong job_stats format found"
17174 }
17175 run_test 205b "Verify job stats jobid and output format"
17176
17177 # LU-13733
17178 test_205c() {
17179         $LCTL set_param llite.*.stats=0
17180         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17181         $LCTL get_param llite.*.stats
17182         $LCTL get_param llite.*.stats | grep \
17183                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17184                         error "wrong client stats format found"
17185 }
17186 run_test 205c "Verify client stats format"
17187
17188 # LU-1480, LU-1773 and LU-1657
17189 test_206() {
17190         mkdir -p $DIR/$tdir
17191         $LFS setstripe -c -1 $DIR/$tdir
17192 #define OBD_FAIL_LOV_INIT 0x1403
17193         $LCTL set_param fail_loc=0xa0001403
17194         $LCTL set_param fail_val=1
17195         touch $DIR/$tdir/$tfile || true
17196 }
17197 run_test 206 "fail lov_init_raid0() doesn't lbug"
17198
17199 test_207a() {
17200         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17201         local fsz=`stat -c %s $DIR/$tfile`
17202         cancel_lru_locks mdc
17203
17204         # do not return layout in getattr intent
17205 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17206         $LCTL set_param fail_loc=0x170
17207         local sz=`stat -c %s $DIR/$tfile`
17208
17209         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17210
17211         rm -rf $DIR/$tfile
17212 }
17213 run_test 207a "can refresh layout at glimpse"
17214
17215 test_207b() {
17216         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17217         local cksum=`md5sum $DIR/$tfile`
17218         local fsz=`stat -c %s $DIR/$tfile`
17219         cancel_lru_locks mdc
17220         cancel_lru_locks osc
17221
17222         # do not return layout in getattr intent
17223 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17224         $LCTL set_param fail_loc=0x171
17225
17226         # it will refresh layout after the file is opened but before read issues
17227         echo checksum is "$cksum"
17228         echo "$cksum" |md5sum -c --quiet || error "file differs"
17229
17230         rm -rf $DIR/$tfile
17231 }
17232 run_test 207b "can refresh layout at open"
17233
17234 test_208() {
17235         # FIXME: in this test suite, only RD lease is used. This is okay
17236         # for now as only exclusive open is supported. After generic lease
17237         # is done, this test suite should be revised. - Jinshan
17238
17239         remote_mds_nodsh && skip "remote MDS with nodsh"
17240         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17241                 skip "Need MDS version at least 2.4.52"
17242
17243         echo "==== test 1: verify get lease work"
17244         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17245
17246         echo "==== test 2: verify lease can be broken by upcoming open"
17247         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17248         local PID=$!
17249         sleep 1
17250
17251         $MULTIOP $DIR/$tfile oO_RDONLY:c
17252         kill -USR1 $PID && wait $PID || error "break lease error"
17253
17254         echo "==== test 3: verify lease can't be granted if an open already exists"
17255         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17256         local PID=$!
17257         sleep 1
17258
17259         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17260         kill -USR1 $PID && wait $PID || error "open file error"
17261
17262         echo "==== test 4: lease can sustain over recovery"
17263         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17264         PID=$!
17265         sleep 1
17266
17267         fail mds1
17268
17269         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17270
17271         echo "==== test 5: lease broken can't be regained by replay"
17272         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17273         PID=$!
17274         sleep 1
17275
17276         # open file to break lease and then recovery
17277         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17278         fail mds1
17279
17280         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17281
17282         rm -f $DIR/$tfile
17283 }
17284 run_test 208 "Exclusive open"
17285
17286 test_209() {
17287         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17288                 skip_env "must have disp_stripe"
17289
17290         touch $DIR/$tfile
17291         sync; sleep 5; sync;
17292
17293         echo 3 > /proc/sys/vm/drop_caches
17294         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17295                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17296         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17297
17298         # open/close 500 times
17299         for i in $(seq 500); do
17300                 cat $DIR/$tfile
17301         done
17302
17303         echo 3 > /proc/sys/vm/drop_caches
17304         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17305                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17306         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17307
17308         echo "before: $req_before, after: $req_after"
17309         [ $((req_after - req_before)) -ge 300 ] &&
17310                 error "open/close requests are not freed"
17311         return 0
17312 }
17313 run_test 209 "read-only open/close requests should be freed promptly"
17314
17315 test_210() {
17316         local pid
17317
17318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17319         pid=$!
17320         sleep 1
17321
17322         $LFS getstripe $DIR/$tfile
17323         kill -USR1 $pid
17324         wait $pid || error "multiop failed"
17325
17326         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17327         pid=$!
17328         sleep 1
17329
17330         $LFS getstripe $DIR/$tfile
17331         kill -USR1 $pid
17332         wait $pid || error "multiop failed"
17333 }
17334 run_test 210 "lfs getstripe does not break leases"
17335
17336 test_212() {
17337         size=`date +%s`
17338         size=$((size % 8192 + 1))
17339         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17340         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17341         rm -f $DIR/f212 $DIR/f212.xyz
17342 }
17343 run_test 212 "Sendfile test ============================================"
17344
17345 test_213() {
17346         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17347         cancel_lru_locks osc
17348         lctl set_param fail_loc=0x8000040f
17349         # generate a read lock
17350         cat $DIR/$tfile > /dev/null
17351         # write to the file, it will try to cancel the above read lock.
17352         cat /etc/hosts >> $DIR/$tfile
17353 }
17354 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17355
17356 test_214() { # for bug 20133
17357         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17358         for (( i=0; i < 340; i++ )) ; do
17359                 touch $DIR/$tdir/d214c/a$i
17360         done
17361
17362         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17363         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17364         ls $DIR/d214c || error "ls $DIR/d214c failed"
17365         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17366         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17367 }
17368 run_test 214 "hash-indexed directory test - bug 20133"
17369
17370 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17371 create_lnet_proc_files() {
17372         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17373 }
17374
17375 # counterpart of create_lnet_proc_files
17376 remove_lnet_proc_files() {
17377         rm -f $TMP/lnet_$1.sys
17378 }
17379
17380 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17381 # 3rd arg as regexp for body
17382 check_lnet_proc_stats() {
17383         local l=$(cat "$TMP/lnet_$1" |wc -l)
17384         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17385
17386         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17387 }
17388
17389 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17390 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17391 # optional and can be regexp for 2nd line (lnet.routes case)
17392 check_lnet_proc_entry() {
17393         local blp=2          # blp stands for 'position of 1st line of body'
17394         [ -z "$5" ] || blp=3 # lnet.routes case
17395
17396         local l=$(cat "$TMP/lnet_$1" |wc -l)
17397         # subtracting one from $blp because the body can be empty
17398         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17399
17400         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17401                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17402
17403         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17404                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17405
17406         # bail out if any unexpected line happened
17407         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17408         [ "$?" != 0 ] || error "$2 misformatted"
17409 }
17410
17411 test_215() { # for bugs 18102, 21079, 21517
17412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17413
17414         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17415         local P='[1-9][0-9]*'           # positive numeric
17416         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17417         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17418         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17419         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17420
17421         local L1 # regexp for 1st line
17422         local L2 # regexp for 2nd line (optional)
17423         local BR # regexp for the rest (body)
17424
17425         # lnet.stats should look as 11 space-separated non-negative numerics
17426         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17427         create_lnet_proc_files "stats"
17428         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17429         remove_lnet_proc_files "stats"
17430
17431         # lnet.routes should look like this:
17432         # Routing disabled/enabled
17433         # net hops priority state router
17434         # where net is a string like tcp0, hops > 0, priority >= 0,
17435         # state is up/down,
17436         # router is a string like 192.168.1.1@tcp2
17437         L1="^Routing (disabled|enabled)$"
17438         L2="^net +hops +priority +state +router$"
17439         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17440         create_lnet_proc_files "routes"
17441         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17442         remove_lnet_proc_files "routes"
17443
17444         # lnet.routers should look like this:
17445         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17446         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17447         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17448         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17449         L1="^ref +rtr_ref +alive +router$"
17450         BR="^$P +$P +(up|down) +$NID$"
17451         create_lnet_proc_files "routers"
17452         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17453         remove_lnet_proc_files "routers"
17454
17455         # lnet.peers should look like this:
17456         # nid refs state last max rtr min tx min queue
17457         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17458         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17459         # numeric (0 or >0 or <0), queue >= 0.
17460         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17461         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17462         create_lnet_proc_files "peers"
17463         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17464         remove_lnet_proc_files "peers"
17465
17466         # lnet.buffers  should look like this:
17467         # pages count credits min
17468         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17469         L1="^pages +count +credits +min$"
17470         BR="^ +$N +$N +$I +$I$"
17471         create_lnet_proc_files "buffers"
17472         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17473         remove_lnet_proc_files "buffers"
17474
17475         # lnet.nis should look like this:
17476         # nid status alive refs peer rtr max tx min
17477         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17478         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17479         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17480         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17481         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17482         create_lnet_proc_files "nis"
17483         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17484         remove_lnet_proc_files "nis"
17485
17486         # can we successfully write to lnet.stats?
17487         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17488 }
17489 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17490
17491 test_216() { # bug 20317
17492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17493         remote_ost_nodsh && skip "remote OST with nodsh"
17494
17495         local node
17496         local facets=$(get_facets OST)
17497         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17498
17499         save_lustre_params client "osc.*.contention_seconds" > $p
17500         save_lustre_params $facets \
17501                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17502         save_lustre_params $facets \
17503                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17504         save_lustre_params $facets \
17505                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17506         clear_stats osc.*.osc_stats
17507
17508         # agressive lockless i/o settings
17509         do_nodes $(comma_list $(osts_nodes)) \
17510                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17511                         ldlm.namespaces.filter-*.contended_locks=0 \
17512                         ldlm.namespaces.filter-*.contention_seconds=60"
17513         lctl set_param -n osc.*.contention_seconds=60
17514
17515         $DIRECTIO write $DIR/$tfile 0 10 4096
17516         $CHECKSTAT -s 40960 $DIR/$tfile
17517
17518         # disable lockless i/o
17519         do_nodes $(comma_list $(osts_nodes)) \
17520                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17521                         ldlm.namespaces.filter-*.contended_locks=32 \
17522                         ldlm.namespaces.filter-*.contention_seconds=0"
17523         lctl set_param -n osc.*.contention_seconds=0
17524         clear_stats osc.*.osc_stats
17525
17526         dd if=/dev/zero of=$DIR/$tfile count=0
17527         $CHECKSTAT -s 0 $DIR/$tfile
17528
17529         restore_lustre_params <$p
17530         rm -f $p
17531         rm $DIR/$tfile
17532 }
17533 run_test 216 "check lockless direct write updates file size and kms correctly"
17534
17535 test_217() { # bug 22430
17536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17537
17538         local node
17539         local nid
17540
17541         for node in $(nodes_list); do
17542                 nid=$(host_nids_address $node $NETTYPE)
17543                 if [[ $nid = *-* ]] ; then
17544                         echo "lctl ping $(h2nettype $nid)"
17545                         lctl ping $(h2nettype $nid)
17546                 else
17547                         echo "skipping $node (no hyphen detected)"
17548                 fi
17549         done
17550 }
17551 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17552
17553 test_218() {
17554        # do directio so as not to populate the page cache
17555        log "creating a 10 Mb file"
17556        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17557        log "starting reads"
17558        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17559        log "truncating the file"
17560        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17561        log "killing dd"
17562        kill %+ || true # reads might have finished
17563        echo "wait until dd is finished"
17564        wait
17565        log "removing the temporary file"
17566        rm -rf $DIR/$tfile || error "tmp file removal failed"
17567 }
17568 run_test 218 "parallel read and truncate should not deadlock"
17569
17570 test_219() {
17571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17572
17573         # write one partial page
17574         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17575         # set no grant so vvp_io_commit_write will do sync write
17576         $LCTL set_param fail_loc=0x411
17577         # write a full page at the end of file
17578         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17579
17580         $LCTL set_param fail_loc=0
17581         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17582         $LCTL set_param fail_loc=0x411
17583         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17584
17585         # LU-4201
17586         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17587         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17588 }
17589 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17590
17591 test_220() { #LU-325
17592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17593         remote_ost_nodsh && skip "remote OST with nodsh"
17594         remote_mds_nodsh && skip "remote MDS with nodsh"
17595         remote_mgs_nodsh && skip "remote MGS with nodsh"
17596
17597         local OSTIDX=0
17598
17599         # create on MDT0000 so the last_id and next_id are correct
17600         mkdir $DIR/$tdir
17601         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17602         OST=${OST%_UUID}
17603
17604         # on the mdt's osc
17605         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17606         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17607                         osp.$mdtosc_proc1.prealloc_last_id)
17608         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17609                         osp.$mdtosc_proc1.prealloc_next_id)
17610
17611         $LFS df -i
17612
17613         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17614         #define OBD_FAIL_OST_ENOINO              0x229
17615         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17616         create_pool $FSNAME.$TESTNAME || return 1
17617         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17618
17619         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17620
17621         MDSOBJS=$((last_id - next_id))
17622         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17623
17624         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17625         echo "OST still has $count kbytes free"
17626
17627         echo "create $MDSOBJS files @next_id..."
17628         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17629
17630         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17631                         osp.$mdtosc_proc1.prealloc_last_id)
17632         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17633                         osp.$mdtosc_proc1.prealloc_next_id)
17634
17635         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17636         $LFS df -i
17637
17638         echo "cleanup..."
17639
17640         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17641         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17642
17643         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17644                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17645         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17646                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17647         echo "unlink $MDSOBJS files @$next_id..."
17648         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17649 }
17650 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17651
17652 test_221() {
17653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17654
17655         dd if=`which date` of=$MOUNT/date oflag=sync
17656         chmod +x $MOUNT/date
17657
17658         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17659         $LCTL set_param fail_loc=0x80001401
17660
17661         $MOUNT/date > /dev/null
17662         rm -f $MOUNT/date
17663 }
17664 run_test 221 "make sure fault and truncate race to not cause OOM"
17665
17666 test_222a () {
17667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17668
17669         rm -rf $DIR/$tdir
17670         test_mkdir $DIR/$tdir
17671         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17672         createmany -o $DIR/$tdir/$tfile 10
17673         cancel_lru_locks mdc
17674         cancel_lru_locks osc
17675         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17676         $LCTL set_param fail_loc=0x31a
17677         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17678         $LCTL set_param fail_loc=0
17679         rm -r $DIR/$tdir
17680 }
17681 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17682
17683 test_222b () {
17684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17685
17686         rm -rf $DIR/$tdir
17687         test_mkdir $DIR/$tdir
17688         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17689         createmany -o $DIR/$tdir/$tfile 10
17690         cancel_lru_locks mdc
17691         cancel_lru_locks osc
17692         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17693         $LCTL set_param fail_loc=0x31a
17694         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17695         $LCTL set_param fail_loc=0
17696 }
17697 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17698
17699 test_223 () {
17700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17701
17702         rm -rf $DIR/$tdir
17703         test_mkdir $DIR/$tdir
17704         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17705         createmany -o $DIR/$tdir/$tfile 10
17706         cancel_lru_locks mdc
17707         cancel_lru_locks osc
17708         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17709         $LCTL set_param fail_loc=0x31b
17710         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17711         $LCTL set_param fail_loc=0
17712         rm -r $DIR/$tdir
17713 }
17714 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17715
17716 test_224a() { # LU-1039, MRP-303
17717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17718
17719         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17720         $LCTL set_param fail_loc=0x508
17721         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17722         $LCTL set_param fail_loc=0
17723         df $DIR
17724 }
17725 run_test 224a "Don't panic on bulk IO failure"
17726
17727 test_224b() { # LU-1039, MRP-303
17728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17729
17730         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17731         cancel_lru_locks osc
17732         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17733         $LCTL set_param fail_loc=0x515
17734         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17735         $LCTL set_param fail_loc=0
17736         df $DIR
17737 }
17738 run_test 224b "Don't panic on bulk IO failure"
17739
17740 test_224c() { # LU-6441
17741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17742         remote_mds_nodsh && skip "remote MDS with nodsh"
17743
17744         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17745         save_writethrough $p
17746         set_cache writethrough on
17747
17748         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17749         local at_max=$($LCTL get_param -n at_max)
17750         local timeout=$($LCTL get_param -n timeout)
17751         local test_at="at_max"
17752         local param_at="$FSNAME.sys.at_max"
17753         local test_timeout="timeout"
17754         local param_timeout="$FSNAME.sys.timeout"
17755
17756         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17757
17758         set_persistent_param_and_check client "$test_at" "$param_at" 0
17759         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17760
17761         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17762         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17763         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17764         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17765         sync
17766         do_facet ost1 "$LCTL set_param fail_loc=0"
17767
17768         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17769         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17770                 $timeout
17771
17772         $LCTL set_param -n $pages_per_rpc
17773         restore_lustre_params < $p
17774         rm -f $p
17775 }
17776 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17777
17778 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17779 test_225a () {
17780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17781         if [ -z ${MDSSURVEY} ]; then
17782                 skip_env "mds-survey not found"
17783         fi
17784         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17785                 skip "Need MDS version at least 2.2.51"
17786
17787         local mds=$(facet_host $SINGLEMDS)
17788         local target=$(do_nodes $mds 'lctl dl' |
17789                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17790
17791         local cmd1="file_count=1000 thrhi=4"
17792         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17793         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17794         local cmd="$cmd1 $cmd2 $cmd3"
17795
17796         rm -f ${TMP}/mds_survey*
17797         echo + $cmd
17798         eval $cmd || error "mds-survey with zero-stripe failed"
17799         cat ${TMP}/mds_survey*
17800         rm -f ${TMP}/mds_survey*
17801 }
17802 run_test 225a "Metadata survey sanity with zero-stripe"
17803
17804 test_225b () {
17805         if [ -z ${MDSSURVEY} ]; then
17806                 skip_env "mds-survey not found"
17807         fi
17808         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17809                 skip "Need MDS version at least 2.2.51"
17810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17811         remote_mds_nodsh && skip "remote MDS with nodsh"
17812         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17813                 skip_env "Need to mount OST to test"
17814         fi
17815
17816         local mds=$(facet_host $SINGLEMDS)
17817         local target=$(do_nodes $mds 'lctl dl' |
17818                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17819
17820         local cmd1="file_count=1000 thrhi=4"
17821         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17822         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17823         local cmd="$cmd1 $cmd2 $cmd3"
17824
17825         rm -f ${TMP}/mds_survey*
17826         echo + $cmd
17827         eval $cmd || error "mds-survey with stripe_count failed"
17828         cat ${TMP}/mds_survey*
17829         rm -f ${TMP}/mds_survey*
17830 }
17831 run_test 225b "Metadata survey sanity with stripe_count = 1"
17832
17833 mcreate_path2fid () {
17834         local mode=$1
17835         local major=$2
17836         local minor=$3
17837         local name=$4
17838         local desc=$5
17839         local path=$DIR/$tdir/$name
17840         local fid
17841         local rc
17842         local fid_path
17843
17844         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17845                 error "cannot create $desc"
17846
17847         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17848         rc=$?
17849         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17850
17851         fid_path=$($LFS fid2path $MOUNT $fid)
17852         rc=$?
17853         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17854
17855         [ "$path" == "$fid_path" ] ||
17856                 error "fid2path returned $fid_path, expected $path"
17857
17858         echo "pass with $path and $fid"
17859 }
17860
17861 test_226a () {
17862         rm -rf $DIR/$tdir
17863         mkdir -p $DIR/$tdir
17864
17865         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17866         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17867         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17868         mcreate_path2fid 0040666 0 0 dir "directory"
17869         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17870         mcreate_path2fid 0100666 0 0 file "regular file"
17871         mcreate_path2fid 0120666 0 0 link "symbolic link"
17872         mcreate_path2fid 0140666 0 0 sock "socket"
17873 }
17874 run_test 226a "call path2fid and fid2path on files of all type"
17875
17876 test_226b () {
17877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17878
17879         local MDTIDX=1
17880
17881         rm -rf $DIR/$tdir
17882         mkdir -p $DIR/$tdir
17883         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17884                 error "create remote directory failed"
17885         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17886         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17887                                 "character special file (null)"
17888         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17889                                 "character special file (no device)"
17890         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17891         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17892                                 "block special file (loop)"
17893         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17894         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17895         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17896 }
17897 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17898
17899 test_226c () {
17900         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17901         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17902                 skip "Need MDS version at least 2.13.55"
17903
17904         local submnt=/mnt/submnt
17905         local srcfile=/etc/passwd
17906         local dstfile=$submnt/passwd
17907         local path
17908         local fid
17909
17910         rm -rf $DIR/$tdir
17911         rm -rf $submnt
17912         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17913                 error "create remote directory failed"
17914         mkdir -p $submnt || error "create $submnt failed"
17915         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17916                 error "mount $submnt failed"
17917         stack_trap "umount $submnt" EXIT
17918
17919         cp $srcfile $dstfile
17920         fid=$($LFS path2fid $dstfile)
17921         path=$($LFS fid2path $submnt "$fid")
17922         [ "$path" = "$dstfile" ] ||
17923                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17924 }
17925 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17926
17927 # LU-1299 Executing or running ldd on a truncated executable does not
17928 # cause an out-of-memory condition.
17929 test_227() {
17930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17931         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17932
17933         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17934         chmod +x $MOUNT/date
17935
17936         $MOUNT/date > /dev/null
17937         ldd $MOUNT/date > /dev/null
17938         rm -f $MOUNT/date
17939 }
17940 run_test 227 "running truncated executable does not cause OOM"
17941
17942 # LU-1512 try to reuse idle OI blocks
17943 test_228a() {
17944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17945         remote_mds_nodsh && skip "remote MDS with nodsh"
17946         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17947
17948         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17949         local myDIR=$DIR/$tdir
17950
17951         mkdir -p $myDIR
17952         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17953         $LCTL set_param fail_loc=0x80001002
17954         createmany -o $myDIR/t- 10000
17955         $LCTL set_param fail_loc=0
17956         # The guard is current the largest FID holder
17957         touch $myDIR/guard
17958         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17959                     tr -d '[')
17960         local IDX=$(($SEQ % 64))
17961
17962         do_facet $SINGLEMDS sync
17963         # Make sure journal flushed.
17964         sleep 6
17965         local blk1=$(do_facet $SINGLEMDS \
17966                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17967                      grep Blockcount | awk '{print $4}')
17968
17969         # Remove old files, some OI blocks will become idle.
17970         unlinkmany $myDIR/t- 10000
17971         # Create new files, idle OI blocks should be reused.
17972         createmany -o $myDIR/t- 2000
17973         do_facet $SINGLEMDS sync
17974         # Make sure journal flushed.
17975         sleep 6
17976         local blk2=$(do_facet $SINGLEMDS \
17977                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17978                      grep Blockcount | awk '{print $4}')
17979
17980         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17981 }
17982 run_test 228a "try to reuse idle OI blocks"
17983
17984 test_228b() {
17985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17986         remote_mds_nodsh && skip "remote MDS with nodsh"
17987         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17988
17989         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17990         local myDIR=$DIR/$tdir
17991
17992         mkdir -p $myDIR
17993         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17994         $LCTL set_param fail_loc=0x80001002
17995         createmany -o $myDIR/t- 10000
17996         $LCTL set_param fail_loc=0
17997         # The guard is current the largest FID holder
17998         touch $myDIR/guard
17999         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18000                     tr -d '[')
18001         local IDX=$(($SEQ % 64))
18002
18003         do_facet $SINGLEMDS sync
18004         # Make sure journal flushed.
18005         sleep 6
18006         local blk1=$(do_facet $SINGLEMDS \
18007                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18008                      grep Blockcount | awk '{print $4}')
18009
18010         # Remove old files, some OI blocks will become idle.
18011         unlinkmany $myDIR/t- 10000
18012
18013         # stop the MDT
18014         stop $SINGLEMDS || error "Fail to stop MDT."
18015         # remount the MDT
18016         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18017
18018         df $MOUNT || error "Fail to df."
18019         # Create new files, idle OI blocks should be reused.
18020         createmany -o $myDIR/t- 2000
18021         do_facet $SINGLEMDS sync
18022         # Make sure journal flushed.
18023         sleep 6
18024         local blk2=$(do_facet $SINGLEMDS \
18025                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18026                      grep Blockcount | awk '{print $4}')
18027
18028         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18029 }
18030 run_test 228b "idle OI blocks can be reused after MDT restart"
18031
18032 #LU-1881
18033 test_228c() {
18034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18035         remote_mds_nodsh && skip "remote MDS with nodsh"
18036         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18037
18038         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18039         local myDIR=$DIR/$tdir
18040
18041         mkdir -p $myDIR
18042         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18043         $LCTL set_param fail_loc=0x80001002
18044         # 20000 files can guarantee there are index nodes in the OI file
18045         createmany -o $myDIR/t- 20000
18046         $LCTL set_param fail_loc=0
18047         # The guard is current the largest FID holder
18048         touch $myDIR/guard
18049         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18050                     tr -d '[')
18051         local IDX=$(($SEQ % 64))
18052
18053         do_facet $SINGLEMDS sync
18054         # Make sure journal flushed.
18055         sleep 6
18056         local blk1=$(do_facet $SINGLEMDS \
18057                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18058                      grep Blockcount | awk '{print $4}')
18059
18060         # Remove old files, some OI blocks will become idle.
18061         unlinkmany $myDIR/t- 20000
18062         rm -f $myDIR/guard
18063         # The OI file should become empty now
18064
18065         # Create new files, idle OI blocks should be reused.
18066         createmany -o $myDIR/t- 2000
18067         do_facet $SINGLEMDS sync
18068         # Make sure journal flushed.
18069         sleep 6
18070         local blk2=$(do_facet $SINGLEMDS \
18071                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18072                      grep Blockcount | awk '{print $4}')
18073
18074         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18075 }
18076 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18077
18078 test_229() { # LU-2482, LU-3448
18079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18080         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18081         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18082                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18083
18084         rm -f $DIR/$tfile
18085
18086         # Create a file with a released layout and stripe count 2.
18087         $MULTIOP $DIR/$tfile H2c ||
18088                 error "failed to create file with released layout"
18089
18090         $LFS getstripe -v $DIR/$tfile
18091
18092         local pattern=$($LFS getstripe -L $DIR/$tfile)
18093         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18094
18095         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18096                 error "getstripe"
18097         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18098         stat $DIR/$tfile || error "failed to stat released file"
18099
18100         chown $RUNAS_ID $DIR/$tfile ||
18101                 error "chown $RUNAS_ID $DIR/$tfile failed"
18102
18103         chgrp $RUNAS_ID $DIR/$tfile ||
18104                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18105
18106         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18107         rm $DIR/$tfile || error "failed to remove released file"
18108 }
18109 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18110
18111 test_230a() {
18112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18113         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18114         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18115                 skip "Need MDS version at least 2.11.52"
18116
18117         local MDTIDX=1
18118
18119         test_mkdir $DIR/$tdir
18120         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18121         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18122         [ $mdt_idx -ne 0 ] &&
18123                 error "create local directory on wrong MDT $mdt_idx"
18124
18125         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18126                         error "create remote directory failed"
18127         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18128         [ $mdt_idx -ne $MDTIDX ] &&
18129                 error "create remote directory on wrong MDT $mdt_idx"
18130
18131         createmany -o $DIR/$tdir/test_230/t- 10 ||
18132                 error "create files on remote directory failed"
18133         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18134         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18135         rm -r $DIR/$tdir || error "unlink remote directory failed"
18136 }
18137 run_test 230a "Create remote directory and files under the remote directory"
18138
18139 test_230b() {
18140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18142         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18143                 skip "Need MDS version at least 2.11.52"
18144
18145         local MDTIDX=1
18146         local mdt_index
18147         local i
18148         local file
18149         local pid
18150         local stripe_count
18151         local migrate_dir=$DIR/$tdir/migrate_dir
18152         local other_dir=$DIR/$tdir/other_dir
18153
18154         test_mkdir $DIR/$tdir
18155         test_mkdir -i0 -c1 $migrate_dir
18156         test_mkdir -i0 -c1 $other_dir
18157         for ((i=0; i<10; i++)); do
18158                 mkdir -p $migrate_dir/dir_${i}
18159                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18160                         error "create files under remote dir failed $i"
18161         done
18162
18163         cp /etc/passwd $migrate_dir/$tfile
18164         cp /etc/passwd $other_dir/$tfile
18165         chattr +SAD $migrate_dir
18166         chattr +SAD $migrate_dir/$tfile
18167
18168         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18169         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18170         local old_dir_mode=$(stat -c%f $migrate_dir)
18171         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18172
18173         mkdir -p $migrate_dir/dir_default_stripe2
18174         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18175         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18176
18177         mkdir -p $other_dir
18178         ln $migrate_dir/$tfile $other_dir/luna
18179         ln $migrate_dir/$tfile $migrate_dir/sofia
18180         ln $other_dir/$tfile $migrate_dir/david
18181         ln -s $migrate_dir/$tfile $other_dir/zachary
18182         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18183         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18184
18185         local len
18186         local lnktgt
18187
18188         # inline symlink
18189         for len in 58 59 60; do
18190                 lnktgt=$(str_repeat 'l' $len)
18191                 touch $migrate_dir/$lnktgt
18192                 ln -s $lnktgt $migrate_dir/${len}char_ln
18193         done
18194
18195         # PATH_MAX
18196         for len in 4094 4095; do
18197                 lnktgt=$(str_repeat 'l' $len)
18198                 ln -s $lnktgt $migrate_dir/${len}char_ln
18199         done
18200
18201         # NAME_MAX
18202         for len in 254 255; do
18203                 touch $migrate_dir/$(str_repeat 'l' $len)
18204         done
18205
18206         $LFS migrate -m $MDTIDX $migrate_dir ||
18207                 error "fails on migrating remote dir to MDT1"
18208
18209         echo "migratate to MDT1, then checking.."
18210         for ((i = 0; i < 10; i++)); do
18211                 for file in $(find $migrate_dir/dir_${i}); do
18212                         mdt_index=$($LFS getstripe -m $file)
18213                         # broken symlink getstripe will fail
18214                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18215                                 error "$file is not on MDT${MDTIDX}"
18216                 done
18217         done
18218
18219         # the multiple link file should still in MDT0
18220         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18221         [ $mdt_index == 0 ] ||
18222                 error "$file is not on MDT${MDTIDX}"
18223
18224         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18225         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18226                 error " expect $old_dir_flag get $new_dir_flag"
18227
18228         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18229         [ "$old_file_flag" = "$new_file_flag" ] ||
18230                 error " expect $old_file_flag get $new_file_flag"
18231
18232         local new_dir_mode=$(stat -c%f $migrate_dir)
18233         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18234                 error "expect mode $old_dir_mode get $new_dir_mode"
18235
18236         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18237         [ "$old_file_mode" = "$new_file_mode" ] ||
18238                 error "expect mode $old_file_mode get $new_file_mode"
18239
18240         diff /etc/passwd $migrate_dir/$tfile ||
18241                 error "$tfile different after migration"
18242
18243         diff /etc/passwd $other_dir/luna ||
18244                 error "luna different after migration"
18245
18246         diff /etc/passwd $migrate_dir/sofia ||
18247                 error "sofia different after migration"
18248
18249         diff /etc/passwd $migrate_dir/david ||
18250                 error "david different after migration"
18251
18252         diff /etc/passwd $other_dir/zachary ||
18253                 error "zachary different after migration"
18254
18255         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18256                 error "${tfile}_ln different after migration"
18257
18258         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18259                 error "${tfile}_ln_other different after migration"
18260
18261         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18262         [ $stripe_count = 2 ] ||
18263                 error "dir strpe_count $d != 2 after migration."
18264
18265         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18266         [ $stripe_count = 2 ] ||
18267                 error "file strpe_count $d != 2 after migration."
18268
18269         #migrate back to MDT0
18270         MDTIDX=0
18271
18272         $LFS migrate -m $MDTIDX $migrate_dir ||
18273                 error "fails on migrating remote dir to MDT0"
18274
18275         echo "migrate back to MDT0, checking.."
18276         for file in $(find $migrate_dir); do
18277                 mdt_index=$($LFS getstripe -m $file)
18278                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18279                         error "$file is not on MDT${MDTIDX}"
18280         done
18281
18282         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18283         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18284                 error " expect $old_dir_flag get $new_dir_flag"
18285
18286         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18287         [ "$old_file_flag" = "$new_file_flag" ] ||
18288                 error " expect $old_file_flag get $new_file_flag"
18289
18290         local new_dir_mode=$(stat -c%f $migrate_dir)
18291         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18292                 error "expect mode $old_dir_mode get $new_dir_mode"
18293
18294         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18295         [ "$old_file_mode" = "$new_file_mode" ] ||
18296                 error "expect mode $old_file_mode get $new_file_mode"
18297
18298         diff /etc/passwd ${migrate_dir}/$tfile ||
18299                 error "$tfile different after migration"
18300
18301         diff /etc/passwd ${other_dir}/luna ||
18302                 error "luna different after migration"
18303
18304         diff /etc/passwd ${migrate_dir}/sofia ||
18305                 error "sofia different after migration"
18306
18307         diff /etc/passwd ${other_dir}/zachary ||
18308                 error "zachary different after migration"
18309
18310         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18311                 error "${tfile}_ln different after migration"
18312
18313         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18314                 error "${tfile}_ln_other different after migration"
18315
18316         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18317         [ $stripe_count = 2 ] ||
18318                 error "dir strpe_count $d != 2 after migration."
18319
18320         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18321         [ $stripe_count = 2 ] ||
18322                 error "file strpe_count $d != 2 after migration."
18323
18324         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18325 }
18326 run_test 230b "migrate directory"
18327
18328 test_230c() {
18329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18331         remote_mds_nodsh && skip "remote MDS with nodsh"
18332         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18333                 skip "Need MDS version at least 2.11.52"
18334
18335         local MDTIDX=1
18336         local total=3
18337         local mdt_index
18338         local file
18339         local migrate_dir=$DIR/$tdir/migrate_dir
18340
18341         #If migrating directory fails in the middle, all entries of
18342         #the directory is still accessiable.
18343         test_mkdir $DIR/$tdir
18344         test_mkdir -i0 -c1 $migrate_dir
18345         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18346         stat $migrate_dir
18347         createmany -o $migrate_dir/f $total ||
18348                 error "create files under ${migrate_dir} failed"
18349
18350         # fail after migrating top dir, and this will fail only once, so the
18351         # first sub file migration will fail (currently f3), others succeed.
18352         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18353         do_facet mds1 lctl set_param fail_loc=0x1801
18354         local t=$(ls $migrate_dir | wc -l)
18355         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18356                 error "migrate should fail"
18357         local u=$(ls $migrate_dir | wc -l)
18358         [ "$u" == "$t" ] || error "$u != $t during migration"
18359
18360         # add new dir/file should succeed
18361         mkdir $migrate_dir/dir ||
18362                 error "mkdir failed under migrating directory"
18363         touch $migrate_dir/file ||
18364                 error "create file failed under migrating directory"
18365
18366         # add file with existing name should fail
18367         for file in $migrate_dir/f*; do
18368                 stat $file > /dev/null || error "stat $file failed"
18369                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18370                         error "open(O_CREAT|O_EXCL) $file should fail"
18371                 $MULTIOP $file m && error "create $file should fail"
18372                 touch $DIR/$tdir/remote_dir/$tfile ||
18373                         error "touch $tfile failed"
18374                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18375                         error "link $file should fail"
18376                 mdt_index=$($LFS getstripe -m $file)
18377                 if [ $mdt_index == 0 ]; then
18378                         # file failed to migrate is not allowed to rename to
18379                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18380                                 error "rename to $file should fail"
18381                 else
18382                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18383                                 error "rename to $file failed"
18384                 fi
18385                 echo hello >> $file || error "write $file failed"
18386         done
18387
18388         # resume migration with different options should fail
18389         $LFS migrate -m 0 $migrate_dir &&
18390                 error "migrate -m 0 $migrate_dir should fail"
18391
18392         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18393                 error "migrate -c 2 $migrate_dir should fail"
18394
18395         # resume migration should succeed
18396         $LFS migrate -m $MDTIDX $migrate_dir ||
18397                 error "migrate $migrate_dir failed"
18398
18399         echo "Finish migration, then checking.."
18400         for file in $(find $migrate_dir); do
18401                 mdt_index=$($LFS getstripe -m $file)
18402                 [ $mdt_index == $MDTIDX ] ||
18403                         error "$file is not on MDT${MDTIDX}"
18404         done
18405
18406         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18407 }
18408 run_test 230c "check directory accessiblity if migration failed"
18409
18410 test_230d() {
18411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18413         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18414                 skip "Need MDS version at least 2.11.52"
18415         # LU-11235
18416         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18417
18418         local migrate_dir=$DIR/$tdir/migrate_dir
18419         local old_index
18420         local new_index
18421         local old_count
18422         local new_count
18423         local new_hash
18424         local mdt_index
18425         local i
18426         local j
18427
18428         old_index=$((RANDOM % MDSCOUNT))
18429         old_count=$((MDSCOUNT - old_index))
18430         new_index=$((RANDOM % MDSCOUNT))
18431         new_count=$((MDSCOUNT - new_index))
18432         new_hash=1 # for all_char
18433
18434         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18435         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18436
18437         test_mkdir $DIR/$tdir
18438         test_mkdir -i $old_index -c $old_count $migrate_dir
18439
18440         for ((i=0; i<100; i++)); do
18441                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18442                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18443                         error "create files under remote dir failed $i"
18444         done
18445
18446         echo -n "Migrate from MDT$old_index "
18447         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18448         echo -n "to MDT$new_index"
18449         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18450         echo
18451
18452         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18453         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18454                 error "migrate remote dir error"
18455
18456         echo "Finish migration, then checking.."
18457         for file in $(find $migrate_dir); do
18458                 mdt_index=$($LFS getstripe -m $file)
18459                 if [ $mdt_index -lt $new_index ] ||
18460                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18461                         error "$file is on MDT$mdt_index"
18462                 fi
18463         done
18464
18465         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18466 }
18467 run_test 230d "check migrate big directory"
18468
18469 test_230e() {
18470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18472         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18473                 skip "Need MDS version at least 2.11.52"
18474
18475         local i
18476         local j
18477         local a_fid
18478         local b_fid
18479
18480         mkdir -p $DIR/$tdir
18481         mkdir $DIR/$tdir/migrate_dir
18482         mkdir $DIR/$tdir/other_dir
18483         touch $DIR/$tdir/migrate_dir/a
18484         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18485         ls $DIR/$tdir/other_dir
18486
18487         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18488                 error "migrate dir fails"
18489
18490         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18491         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18492
18493         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18494         [ $mdt_index == 0 ] || error "a is not on MDT0"
18495
18496         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18497                 error "migrate dir fails"
18498
18499         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18500         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18501
18502         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18503         [ $mdt_index == 1 ] || error "a is not on MDT1"
18504
18505         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18506         [ $mdt_index == 1 ] || error "b is not on MDT1"
18507
18508         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18509         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18510
18511         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18512
18513         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18514 }
18515 run_test 230e "migrate mulitple local link files"
18516
18517 test_230f() {
18518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18521                 skip "Need MDS version at least 2.11.52"
18522
18523         local a_fid
18524         local ln_fid
18525
18526         mkdir -p $DIR/$tdir
18527         mkdir $DIR/$tdir/migrate_dir
18528         $LFS mkdir -i1 $DIR/$tdir/other_dir
18529         touch $DIR/$tdir/migrate_dir/a
18530         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18531         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18532         ls $DIR/$tdir/other_dir
18533
18534         # a should be migrated to MDT1, since no other links on MDT0
18535         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18536                 error "#1 migrate dir fails"
18537         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18538         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18539         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18540         [ $mdt_index == 1 ] || error "a is not on MDT1"
18541
18542         # a should stay on MDT1, because it is a mulitple link file
18543         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18544                 error "#2 migrate dir fails"
18545         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18546         [ $mdt_index == 1 ] || error "a is not on MDT1"
18547
18548         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18549                 error "#3 migrate dir fails"
18550
18551         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18552         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18553         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18554
18555         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18556         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18557
18558         # a should be migrated to MDT0, since no other links on MDT1
18559         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18560                 error "#4 migrate dir fails"
18561         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18562         [ $mdt_index == 0 ] || error "a is not on MDT0"
18563
18564         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18565 }
18566 run_test 230f "migrate mulitple remote link files"
18567
18568 test_230g() {
18569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18571         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18572                 skip "Need MDS version at least 2.11.52"
18573
18574         mkdir -p $DIR/$tdir/migrate_dir
18575
18576         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18577                 error "migrating dir to non-exist MDT succeeds"
18578         true
18579 }
18580 run_test 230g "migrate dir to non-exist MDT"
18581
18582 test_230h() {
18583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18585         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18586                 skip "Need MDS version at least 2.11.52"
18587
18588         local mdt_index
18589
18590         mkdir -p $DIR/$tdir/migrate_dir
18591
18592         $LFS migrate -m1 $DIR &&
18593                 error "migrating mountpoint1 should fail"
18594
18595         $LFS migrate -m1 $DIR/$tdir/.. &&
18596                 error "migrating mountpoint2 should fail"
18597
18598         # same as mv
18599         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18600                 error "migrating $tdir/migrate_dir/.. should fail"
18601
18602         true
18603 }
18604 run_test 230h "migrate .. and root"
18605
18606 test_230i() {
18607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18609         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18610                 skip "Need MDS version at least 2.11.52"
18611
18612         mkdir -p $DIR/$tdir/migrate_dir
18613
18614         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18615                 error "migration fails with a tailing slash"
18616
18617         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18618                 error "migration fails with two tailing slashes"
18619 }
18620 run_test 230i "lfs migrate -m tolerates trailing slashes"
18621
18622 test_230j() {
18623         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18624         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18625                 skip "Need MDS version at least 2.11.52"
18626
18627         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18628         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18629                 error "create $tfile failed"
18630         cat /etc/passwd > $DIR/$tdir/$tfile
18631
18632         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18633
18634         cmp /etc/passwd $DIR/$tdir/$tfile ||
18635                 error "DoM file mismatch after migration"
18636 }
18637 run_test 230j "DoM file data not changed after dir migration"
18638
18639 test_230k() {
18640         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18641         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18642                 skip "Need MDS version at least 2.11.56"
18643
18644         local total=20
18645         local files_on_starting_mdt=0
18646
18647         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18648         $LFS getdirstripe $DIR/$tdir
18649         for i in $(seq $total); do
18650                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18651                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18652                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18653         done
18654
18655         echo "$files_on_starting_mdt files on MDT0"
18656
18657         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18658         $LFS getdirstripe $DIR/$tdir
18659
18660         files_on_starting_mdt=0
18661         for i in $(seq $total); do
18662                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18663                         error "file $tfile.$i mismatch after migration"
18664                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18665                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18666         done
18667
18668         echo "$files_on_starting_mdt files on MDT1 after migration"
18669         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18670
18671         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18672         $LFS getdirstripe $DIR/$tdir
18673
18674         files_on_starting_mdt=0
18675         for i in $(seq $total); do
18676                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18677                         error "file $tfile.$i mismatch after 2nd migration"
18678                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18679                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18680         done
18681
18682         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18683         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18684
18685         true
18686 }
18687 run_test 230k "file data not changed after dir migration"
18688
18689 test_230l() {
18690         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18691         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18692                 skip "Need MDS version at least 2.11.56"
18693
18694         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18695         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18696                 error "create files under remote dir failed $i"
18697         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18698 }
18699 run_test 230l "readdir between MDTs won't crash"
18700
18701 test_230m() {
18702         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18703         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18704                 skip "Need MDS version at least 2.11.56"
18705
18706         local MDTIDX=1
18707         local mig_dir=$DIR/$tdir/migrate_dir
18708         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18709         local shortstr="b"
18710         local val
18711
18712         echo "Creating files and dirs with xattrs"
18713         test_mkdir $DIR/$tdir
18714         test_mkdir -i0 -c1 $mig_dir
18715         mkdir $mig_dir/dir
18716         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18717                 error "cannot set xattr attr1 on dir"
18718         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18719                 error "cannot set xattr attr2 on dir"
18720         touch $mig_dir/dir/f0
18721         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18722                 error "cannot set xattr attr1 on file"
18723         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18724                 error "cannot set xattr attr2 on file"
18725         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18726         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18727         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18728         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18729         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18730         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18731         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18732         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18733         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18734
18735         echo "Migrating to MDT1"
18736         $LFS migrate -m $MDTIDX $mig_dir ||
18737                 error "fails on migrating dir to MDT1"
18738
18739         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18740         echo "Checking xattrs"
18741         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18742         [ "$val" = $longstr ] ||
18743                 error "expecting xattr1 $longstr on dir, found $val"
18744         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18745         [ "$val" = $shortstr ] ||
18746                 error "expecting xattr2 $shortstr on dir, found $val"
18747         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18748         [ "$val" = $longstr ] ||
18749                 error "expecting xattr1 $longstr on file, found $val"
18750         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18751         [ "$val" = $shortstr ] ||
18752                 error "expecting xattr2 $shortstr on file, found $val"
18753 }
18754 run_test 230m "xattrs not changed after dir migration"
18755
18756 test_230n() {
18757         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18758         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18759                 skip "Need MDS version at least 2.13.53"
18760
18761         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18762         cat /etc/hosts > $DIR/$tdir/$tfile
18763         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18764         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18765
18766         cmp /etc/hosts $DIR/$tdir/$tfile ||
18767                 error "File data mismatch after migration"
18768 }
18769 run_test 230n "Dir migration with mirrored file"
18770
18771 test_230o() {
18772         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18773         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18774                 skip "Need MDS version at least 2.13.52"
18775
18776         local mdts=$(comma_list $(mdts_nodes))
18777         local timeout=100
18778         local restripe_status
18779         local delta
18780         local i
18781
18782         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18783
18784         # in case "crush" hash type is not set
18785         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18786
18787         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18788                            mdt.*MDT0000.enable_dir_restripe)
18789         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18790         stack_trap "do_nodes $mdts $LCTL set_param \
18791                     mdt.*.enable_dir_restripe=$restripe_status"
18792
18793         mkdir $DIR/$tdir
18794         createmany -m $DIR/$tdir/f 100 ||
18795                 error "create files under remote dir failed $i"
18796         createmany -d $DIR/$tdir/d 100 ||
18797                 error "create dirs under remote dir failed $i"
18798
18799         for i in $(seq 2 $MDSCOUNT); do
18800                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18801                 $LFS setdirstripe -c $i $DIR/$tdir ||
18802                         error "split -c $i $tdir failed"
18803                 wait_update $HOSTNAME \
18804                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18805                         error "dir split not finished"
18806                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18807                         awk '/migrate/ {sum += $2} END { print sum }')
18808                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
18809                 # delta is around total_files/stripe_count
18810                 (( $delta < 200 / (i - 1) + 4 )) ||
18811                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
18812         done
18813 }
18814 run_test 230o "dir split"
18815
18816 test_230p() {
18817         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18818         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18819                 skip "Need MDS version at least 2.13.52"
18820
18821         local mdts=$(comma_list $(mdts_nodes))
18822         local timeout=100
18823         local restripe_status
18824         local delta
18825         local i
18826
18827         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18828
18829         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18830
18831         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18832                            mdt.*MDT0000.enable_dir_restripe)
18833         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18834         stack_trap "do_nodes $mdts $LCTL set_param \
18835                     mdt.*.enable_dir_restripe=$restripe_status"
18836
18837         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18838         createmany -m $DIR/$tdir/f 100 ||
18839                 error "create files under remote dir failed $i"
18840         createmany -d $DIR/$tdir/d 100 ||
18841                 error "create dirs under remote dir failed $i"
18842
18843         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18844                 local mdt_hash="crush"
18845
18846                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18847                 $LFS setdirstripe -c $i $DIR/$tdir ||
18848                         error "split -c $i $tdir failed"
18849                 [ $i -eq 1 ] && mdt_hash="none"
18850                 wait_update $HOSTNAME \
18851                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18852                         error "dir merge not finished"
18853                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18854                         awk '/migrate/ {sum += $2} END { print sum }')
18855                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
18856                 # delta is around total_files/stripe_count
18857                 (( $delta < 200 / i + 4 )) ||
18858                         error "$delta files migrated >= $((200 / i + 4))"
18859         done
18860 }
18861 run_test 230p "dir merge"
18862
18863 test_230q() {
18864         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18865         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18866                 skip "Need MDS version at least 2.13.52"
18867
18868         local mdts=$(comma_list $(mdts_nodes))
18869         local saved_threshold=$(do_facet mds1 \
18870                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18871         local saved_delta=$(do_facet mds1 \
18872                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18873         local threshold=100
18874         local delta=2
18875         local total=0
18876         local stripe_count=0
18877         local stripe_index
18878         local nr_files
18879         local create
18880
18881         # test with fewer files on ZFS
18882         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18883
18884         stack_trap "do_nodes $mdts $LCTL set_param \
18885                     mdt.*.dir_split_count=$saved_threshold"
18886         stack_trap "do_nodes $mdts $LCTL set_param \
18887                     mdt.*.dir_split_delta=$saved_delta"
18888         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18889         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18890         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18891         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18892         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18893         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18894
18895         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18896         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18897
18898         create=$((threshold * 3 / 2))
18899         while [ $stripe_count -lt $MDSCOUNT ]; do
18900                 createmany -m $DIR/$tdir/f $total $create ||
18901                         error "create sub files failed"
18902                 stat $DIR/$tdir > /dev/null
18903                 total=$((total + create))
18904                 stripe_count=$((stripe_count + delta))
18905                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18906
18907                 wait_update $HOSTNAME \
18908                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18909                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18910
18911                 wait_update $HOSTNAME \
18912                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18913                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18914
18915                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
18916                 echo "$nr_files/$total files on MDT$stripe_index after split"
18917                 # allow 10% margin of imbalance with crush hash
18918                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
18919                         error "$nr_files files on MDT$stripe_index after split"
18920
18921                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
18922                 [ $nr_files -eq $total ] ||
18923                         error "total sub files $nr_files != $total"
18924         done
18925 }
18926 run_test 230q "dir auto split"
18927
18928 test_230r() {
18929         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18930         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18931         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18932                 skip "Need MDS version at least 2.13.54"
18933
18934         # maximum amount of local locks:
18935         # parent striped dir - 2 locks
18936         # new stripe in parent to migrate to - 1 lock
18937         # source and target - 2 locks
18938         # Total 5 locks for regular file
18939         mkdir -p $DIR/$tdir
18940         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18941         touch $DIR/$tdir/dir1/eee
18942
18943         # create 4 hardlink for 4 more locks
18944         # Total: 9 locks > RS_MAX_LOCKS (8)
18945         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18946         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18947         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18948         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18949         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18950         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18951         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18952         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18953
18954         cancel_lru_locks mdc
18955
18956         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18957                 error "migrate dir fails"
18958
18959         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18960 }
18961 run_test 230r "migrate with too many local locks"
18962
18963 test_231a()
18964 {
18965         # For simplicity this test assumes that max_pages_per_rpc
18966         # is the same across all OSCs
18967         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18968         local bulk_size=$((max_pages * PAGE_SIZE))
18969         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18970                                        head -n 1)
18971
18972         mkdir -p $DIR/$tdir
18973         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18974                 error "failed to set stripe with -S ${brw_size}M option"
18975
18976         # clear the OSC stats
18977         $LCTL set_param osc.*.stats=0 &>/dev/null
18978         stop_writeback
18979
18980         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18981         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18982                 oflag=direct &>/dev/null || error "dd failed"
18983
18984         sync; sleep 1; sync # just to be safe
18985         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18986         if [ x$nrpcs != "x1" ]; then
18987                 $LCTL get_param osc.*.stats
18988                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18989         fi
18990
18991         start_writeback
18992         # Drop the OSC cache, otherwise we will read from it
18993         cancel_lru_locks osc
18994
18995         # clear the OSC stats
18996         $LCTL set_param osc.*.stats=0 &>/dev/null
18997
18998         # Client reads $bulk_size.
18999         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19000                 iflag=direct &>/dev/null || error "dd failed"
19001
19002         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19003         if [ x$nrpcs != "x1" ]; then
19004                 $LCTL get_param osc.*.stats
19005                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19006         fi
19007 }
19008 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19009
19010 test_231b() {
19011         mkdir -p $DIR/$tdir
19012         local i
19013         for i in {0..1023}; do
19014                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19015                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19016                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19017         done
19018         sync
19019 }
19020 run_test 231b "must not assert on fully utilized OST request buffer"
19021
19022 test_232a() {
19023         mkdir -p $DIR/$tdir
19024         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19025
19026         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19027         do_facet ost1 $LCTL set_param fail_loc=0x31c
19028
19029         # ignore dd failure
19030         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19031
19032         do_facet ost1 $LCTL set_param fail_loc=0
19033         umount_client $MOUNT || error "umount failed"
19034         mount_client $MOUNT || error "mount failed"
19035         stop ost1 || error "cannot stop ost1"
19036         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19037 }
19038 run_test 232a "failed lock should not block umount"
19039
19040 test_232b() {
19041         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19042                 skip "Need MDS version at least 2.10.58"
19043
19044         mkdir -p $DIR/$tdir
19045         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19046         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19047         sync
19048         cancel_lru_locks osc
19049
19050         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19051         do_facet ost1 $LCTL set_param fail_loc=0x31c
19052
19053         # ignore failure
19054         $LFS data_version $DIR/$tdir/$tfile || true
19055
19056         do_facet ost1 $LCTL set_param fail_loc=0
19057         umount_client $MOUNT || error "umount failed"
19058         mount_client $MOUNT || error "mount failed"
19059         stop ost1 || error "cannot stop ost1"
19060         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19061 }
19062 run_test 232b "failed data version lock should not block umount"
19063
19064 test_233a() {
19065         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19066                 skip "Need MDS version at least 2.3.64"
19067         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19068
19069         local fid=$($LFS path2fid $MOUNT)
19070
19071         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19072                 error "cannot access $MOUNT using its FID '$fid'"
19073 }
19074 run_test 233a "checking that OBF of the FS root succeeds"
19075
19076 test_233b() {
19077         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19078                 skip "Need MDS version at least 2.5.90"
19079         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19080
19081         local fid=$($LFS path2fid $MOUNT/.lustre)
19082
19083         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19084                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19085
19086         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19087         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19088                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19089 }
19090 run_test 233b "checking that OBF of the FS .lustre succeeds"
19091
19092 test_234() {
19093         local p="$TMP/sanityN-$TESTNAME.parameters"
19094         save_lustre_params client "llite.*.xattr_cache" > $p
19095         lctl set_param llite.*.xattr_cache 1 ||
19096                 skip_env "xattr cache is not supported"
19097
19098         mkdir -p $DIR/$tdir || error "mkdir failed"
19099         touch $DIR/$tdir/$tfile || error "touch failed"
19100         # OBD_FAIL_LLITE_XATTR_ENOMEM
19101         $LCTL set_param fail_loc=0x1405
19102         getfattr -n user.attr $DIR/$tdir/$tfile &&
19103                 error "getfattr should have failed with ENOMEM"
19104         $LCTL set_param fail_loc=0x0
19105         rm -rf $DIR/$tdir
19106
19107         restore_lustre_params < $p
19108         rm -f $p
19109 }
19110 run_test 234 "xattr cache should not crash on ENOMEM"
19111
19112 test_235() {
19113         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19114                 skip "Need MDS version at least 2.4.52"
19115
19116         flock_deadlock $DIR/$tfile
19117         local RC=$?
19118         case $RC in
19119                 0)
19120                 ;;
19121                 124) error "process hangs on a deadlock"
19122                 ;;
19123                 *) error "error executing flock_deadlock $DIR/$tfile"
19124                 ;;
19125         esac
19126 }
19127 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19128
19129 #LU-2935
19130 test_236() {
19131         check_swap_layouts_support
19132
19133         local ref1=/etc/passwd
19134         local ref2=/etc/group
19135         local file1=$DIR/$tdir/f1
19136         local file2=$DIR/$tdir/f2
19137
19138         test_mkdir -c1 $DIR/$tdir
19139         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19140         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19141         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19142         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19143         local fd=$(free_fd)
19144         local cmd="exec $fd<>$file2"
19145         eval $cmd
19146         rm $file2
19147         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19148                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19149         cmd="exec $fd>&-"
19150         eval $cmd
19151         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19152
19153         #cleanup
19154         rm -rf $DIR/$tdir
19155 }
19156 run_test 236 "Layout swap on open unlinked file"
19157
19158 # LU-4659 linkea consistency
19159 test_238() {
19160         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19161                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19162                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19163                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19164
19165         touch $DIR/$tfile
19166         ln $DIR/$tfile $DIR/$tfile.lnk
19167         touch $DIR/$tfile.new
19168         mv $DIR/$tfile.new $DIR/$tfile
19169         local fid1=$($LFS path2fid $DIR/$tfile)
19170         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19171         local path1=$($LFS fid2path $FSNAME "$fid1")
19172         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19173         local path2=$($LFS fid2path $FSNAME "$fid2")
19174         [ $tfile.lnk == $path2 ] ||
19175                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19176         rm -f $DIR/$tfile*
19177 }
19178 run_test 238 "Verify linkea consistency"
19179
19180 test_239A() { # was test_239
19181         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19182                 skip "Need MDS version at least 2.5.60"
19183
19184         local list=$(comma_list $(mdts_nodes))
19185
19186         mkdir -p $DIR/$tdir
19187         createmany -o $DIR/$tdir/f- 5000
19188         unlinkmany $DIR/$tdir/f- 5000
19189         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19190                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19191         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19192                         osp.*MDT*.sync_in_flight" | calc_sum)
19193         [ "$changes" -eq 0 ] || error "$changes not synced"
19194 }
19195 run_test 239A "osp_sync test"
19196
19197 test_239a() { #LU-5297
19198         remote_mds_nodsh && skip "remote MDS with nodsh"
19199
19200         touch $DIR/$tfile
19201         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19202         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19203         chgrp $RUNAS_GID $DIR/$tfile
19204         wait_delete_completed
19205 }
19206 run_test 239a "process invalid osp sync record correctly"
19207
19208 test_239b() { #LU-5297
19209         remote_mds_nodsh && skip "remote MDS with nodsh"
19210
19211         touch $DIR/$tfile1
19212         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19213         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19214         chgrp $RUNAS_GID $DIR/$tfile1
19215         wait_delete_completed
19216         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19217         touch $DIR/$tfile2
19218         chgrp $RUNAS_GID $DIR/$tfile2
19219         wait_delete_completed
19220 }
19221 run_test 239b "process osp sync record with ENOMEM error correctly"
19222
19223 test_240() {
19224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19225         remote_mds_nodsh && skip "remote MDS with nodsh"
19226
19227         mkdir -p $DIR/$tdir
19228
19229         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19230                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19231         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19232                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19233
19234         umount_client $MOUNT || error "umount failed"
19235         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19236         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19237         mount_client $MOUNT || error "failed to mount client"
19238
19239         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19240         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19241 }
19242 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19243
19244 test_241_bio() {
19245         local count=$1
19246         local bsize=$2
19247
19248         for LOOP in $(seq $count); do
19249                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19250                 cancel_lru_locks $OSC || true
19251         done
19252 }
19253
19254 test_241_dio() {
19255         local count=$1
19256         local bsize=$2
19257
19258         for LOOP in $(seq $1); do
19259                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19260                         2>/dev/null
19261         done
19262 }
19263
19264 test_241a() { # was test_241
19265         local bsize=$PAGE_SIZE
19266
19267         (( bsize < 40960 )) && bsize=40960
19268         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19269         ls -la $DIR/$tfile
19270         cancel_lru_locks $OSC
19271         test_241_bio 1000 $bsize &
19272         PID=$!
19273         test_241_dio 1000 $bsize
19274         wait $PID
19275 }
19276 run_test 241a "bio vs dio"
19277
19278 test_241b() {
19279         local bsize=$PAGE_SIZE
19280
19281         (( bsize < 40960 )) && bsize=40960
19282         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19283         ls -la $DIR/$tfile
19284         test_241_dio 1000 $bsize &
19285         PID=$!
19286         test_241_dio 1000 $bsize
19287         wait $PID
19288 }
19289 run_test 241b "dio vs dio"
19290
19291 test_242() {
19292         remote_mds_nodsh && skip "remote MDS with nodsh"
19293
19294         mkdir -p $DIR/$tdir
19295         touch $DIR/$tdir/$tfile
19296
19297         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19298         do_facet mds1 lctl set_param fail_loc=0x105
19299         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19300
19301         do_facet mds1 lctl set_param fail_loc=0
19302         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19303 }
19304 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19305
19306 test_243()
19307 {
19308         test_mkdir $DIR/$tdir
19309         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19310 }
19311 run_test 243 "various group lock tests"
19312
19313 test_244a()
19314 {
19315         test_mkdir $DIR/$tdir
19316         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19317         sendfile_grouplock $DIR/$tdir/$tfile || \
19318                 error "sendfile+grouplock failed"
19319         rm -rf $DIR/$tdir
19320 }
19321 run_test 244a "sendfile with group lock tests"
19322
19323 test_244b()
19324 {
19325         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19326
19327         local threads=50
19328         local size=$((1024*1024))
19329
19330         test_mkdir $DIR/$tdir
19331         for i in $(seq 1 $threads); do
19332                 local file=$DIR/$tdir/file_$((i / 10))
19333                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19334                 local pids[$i]=$!
19335         done
19336         for i in $(seq 1 $threads); do
19337                 wait ${pids[$i]}
19338         done
19339 }
19340 run_test 244b "multi-threaded write with group lock"
19341
19342 test_245() {
19343         local flagname="multi_mod_rpcs"
19344         local connect_data_name="max_mod_rpcs"
19345         local out
19346
19347         # check if multiple modify RPCs flag is set
19348         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19349                 grep "connect_flags:")
19350         echo "$out"
19351
19352         echo "$out" | grep -qw $flagname
19353         if [ $? -ne 0 ]; then
19354                 echo "connect flag $flagname is not set"
19355                 return
19356         fi
19357
19358         # check if multiple modify RPCs data is set
19359         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19360         echo "$out"
19361
19362         echo "$out" | grep -qw $connect_data_name ||
19363                 error "import should have connect data $connect_data_name"
19364 }
19365 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19366
19367 cleanup_247() {
19368         local submount=$1
19369
19370         trap 0
19371         umount_client $submount
19372         rmdir $submount
19373 }
19374
19375 test_247a() {
19376         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19377                 grep -q subtree ||
19378                 skip_env "Fileset feature is not supported"
19379
19380         local submount=${MOUNT}_$tdir
19381
19382         mkdir $MOUNT/$tdir
19383         mkdir -p $submount || error "mkdir $submount failed"
19384         FILESET="$FILESET/$tdir" mount_client $submount ||
19385                 error "mount $submount failed"
19386         trap "cleanup_247 $submount" EXIT
19387         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19388         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19389                 error "read $MOUNT/$tdir/$tfile failed"
19390         cleanup_247 $submount
19391 }
19392 run_test 247a "mount subdir as fileset"
19393
19394 test_247b() {
19395         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19396                 skip_env "Fileset feature is not supported"
19397
19398         local submount=${MOUNT}_$tdir
19399
19400         rm -rf $MOUNT/$tdir
19401         mkdir -p $submount || error "mkdir $submount failed"
19402         SKIP_FILESET=1
19403         FILESET="$FILESET/$tdir" mount_client $submount &&
19404                 error "mount $submount should fail"
19405         rmdir $submount
19406 }
19407 run_test 247b "mount subdir that dose not exist"
19408
19409 test_247c() {
19410         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19411                 skip_env "Fileset feature is not supported"
19412
19413         local submount=${MOUNT}_$tdir
19414
19415         mkdir -p $MOUNT/$tdir/dir1
19416         mkdir -p $submount || error "mkdir $submount failed"
19417         trap "cleanup_247 $submount" EXIT
19418         FILESET="$FILESET/$tdir" mount_client $submount ||
19419                 error "mount $submount failed"
19420         local fid=$($LFS path2fid $MOUNT/)
19421         $LFS fid2path $submount $fid && error "fid2path should fail"
19422         cleanup_247 $submount
19423 }
19424 run_test 247c "running fid2path outside subdirectory root"
19425
19426 test_247d() {
19427         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19428                 skip "Fileset feature is not supported"
19429
19430         local submount=${MOUNT}_$tdir
19431
19432         mkdir -p $MOUNT/$tdir/dir1
19433         mkdir -p $submount || error "mkdir $submount failed"
19434         FILESET="$FILESET/$tdir" mount_client $submount ||
19435                 error "mount $submount failed"
19436         trap "cleanup_247 $submount" EXIT
19437
19438         local td=$submount/dir1
19439         local fid=$($LFS path2fid $td)
19440         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19441
19442         # check that we get the same pathname back
19443         local rootpath
19444         local found
19445         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19446                 echo "$rootpath $fid"
19447                 found=$($LFS fid2path $rootpath "$fid")
19448                 [ -n "found" ] || error "fid2path should succeed"
19449                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19450         done
19451         # check wrong root path format
19452         rootpath=$submount"_wrong"
19453         found=$($LFS fid2path $rootpath "$fid")
19454         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19455
19456         cleanup_247 $submount
19457 }
19458 run_test 247d "running fid2path inside subdirectory root"
19459
19460 # LU-8037
19461 test_247e() {
19462         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19463                 grep -q subtree ||
19464                 skip "Fileset feature is not supported"
19465
19466         local submount=${MOUNT}_$tdir
19467
19468         mkdir $MOUNT/$tdir
19469         mkdir -p $submount || error "mkdir $submount failed"
19470         FILESET="$FILESET/.." mount_client $submount &&
19471                 error "mount $submount should fail"
19472         rmdir $submount
19473 }
19474 run_test 247e "mount .. as fileset"
19475
19476 test_247f() {
19477         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19478         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19479                 skip "Need at least version 2.13.52"
19480         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19481                 grep -q subtree ||
19482                 skip "Fileset feature is not supported"
19483
19484         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19485         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19486                 error "mkdir remote failed"
19487         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19488         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19489                 error "mkdir striped failed"
19490         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19491
19492         local submount=${MOUNT}_$tdir
19493
19494         mkdir -p $submount || error "mkdir $submount failed"
19495
19496         local dir
19497         local fileset=$FILESET
19498
19499         for dir in $tdir/remote $tdir/remote/subdir \
19500                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19501                 FILESET="$fileset/$dir" mount_client $submount ||
19502                         error "mount $dir failed"
19503                 umount_client $submount
19504         done
19505 }
19506 run_test 247f "mount striped or remote directory as fileset"
19507
19508 test_248a() {
19509         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19510         [ -z "$fast_read_sav" ] && skip "no fast read support"
19511
19512         # create a large file for fast read verification
19513         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19514
19515         # make sure the file is created correctly
19516         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19517                 { rm -f $DIR/$tfile; skip "file creation error"; }
19518
19519         echo "Test 1: verify that fast read is 4 times faster on cache read"
19520
19521         # small read with fast read enabled
19522         $LCTL set_param -n llite.*.fast_read=1
19523         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19524                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19525                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19526         # small read with fast read disabled
19527         $LCTL set_param -n llite.*.fast_read=0
19528         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19529                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19530                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19531
19532         # verify that fast read is 4 times faster for cache read
19533         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19534                 error_not_in_vm "fast read was not 4 times faster: " \
19535                            "$t_fast vs $t_slow"
19536
19537         echo "Test 2: verify the performance between big and small read"
19538         $LCTL set_param -n llite.*.fast_read=1
19539
19540         # 1k non-cache read
19541         cancel_lru_locks osc
19542         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19543                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19544                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19545
19546         # 1M non-cache read
19547         cancel_lru_locks osc
19548         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19549                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19550                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19551
19552         # verify that big IO is not 4 times faster than small IO
19553         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19554                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19555
19556         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19557         rm -f $DIR/$tfile
19558 }
19559 run_test 248a "fast read verification"
19560
19561 test_248b() {
19562         # Default short_io_bytes=16384, try both smaller and larger sizes.
19563         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19564         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19565         echo "bs=53248 count=113 normal buffered write"
19566         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19567                 error "dd of initial data file failed"
19568         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19569
19570         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19571         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19572                 error "dd with sync normal writes failed"
19573         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19574
19575         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19576         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19577                 error "dd with sync small writes failed"
19578         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19579
19580         cancel_lru_locks osc
19581
19582         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19583         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19584         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19585         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19586                 iflag=direct || error "dd with O_DIRECT small read failed"
19587         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19588         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19589                 error "compare $TMP/$tfile.1 failed"
19590
19591         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19592         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19593
19594         # just to see what the maximum tunable value is, and test parsing
19595         echo "test invalid parameter 2MB"
19596         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19597                 error "too-large short_io_bytes allowed"
19598         echo "test maximum parameter 512KB"
19599         # if we can set a larger short_io_bytes, run test regardless of version
19600         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19601                 # older clients may not allow setting it this large, that's OK
19602                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19603                         skip "Need at least client version 2.13.50"
19604                 error "medium short_io_bytes failed"
19605         fi
19606         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19607         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19608
19609         echo "test large parameter 64KB"
19610         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19611         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19612
19613         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19614         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19615                 error "dd with sync large writes failed"
19616         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19617
19618         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19619         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19620         num=$((113 * 4096 / PAGE_SIZE))
19621         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19622         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19623                 error "dd with O_DIRECT large writes failed"
19624         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19625                 error "compare $DIR/$tfile.3 failed"
19626
19627         cancel_lru_locks osc
19628
19629         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19630         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19631                 error "dd with O_DIRECT large read failed"
19632         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19633                 error "compare $TMP/$tfile.2 failed"
19634
19635         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19636         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19637                 error "dd with O_DIRECT large read failed"
19638         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19639                 error "compare $TMP/$tfile.3 failed"
19640 }
19641 run_test 248b "test short_io read and write for both small and large sizes"
19642
19643 test_249() { # LU-7890
19644         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19645                 skip "Need at least version 2.8.54"
19646
19647         rm -f $DIR/$tfile
19648         $LFS setstripe -c 1 $DIR/$tfile
19649         # Offset 2T == 4k * 512M
19650         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19651                 error "dd to 2T offset failed"
19652 }
19653 run_test 249 "Write above 2T file size"
19654
19655 test_250() {
19656         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19657          && skip "no 16TB file size limit on ZFS"
19658
19659         $LFS setstripe -c 1 $DIR/$tfile
19660         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19661         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19662         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19663         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19664                 conv=notrunc,fsync && error "append succeeded"
19665         return 0
19666 }
19667 run_test 250 "Write above 16T limit"
19668
19669 test_251() {
19670         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19671
19672         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19673         #Skip once - writing the first stripe will succeed
19674         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19675         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19676                 error "short write happened"
19677
19678         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19679         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19680                 error "short read happened"
19681
19682         rm -f $DIR/$tfile
19683 }
19684 run_test 251 "Handling short read and write correctly"
19685
19686 test_252() {
19687         remote_mds_nodsh && skip "remote MDS with nodsh"
19688         remote_ost_nodsh && skip "remote OST with nodsh"
19689         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19690                 skip_env "ldiskfs only test"
19691         fi
19692
19693         local tgt
19694         local dev
19695         local out
19696         local uuid
19697         local num
19698         local gen
19699
19700         # check lr_reader on OST0000
19701         tgt=ost1
19702         dev=$(facet_device $tgt)
19703         out=$(do_facet $tgt $LR_READER $dev)
19704         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19705         echo "$out"
19706         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19707         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19708                 error "Invalid uuid returned by $LR_READER on target $tgt"
19709         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19710
19711         # check lr_reader -c on MDT0000
19712         tgt=mds1
19713         dev=$(facet_device $tgt)
19714         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19715                 skip "$LR_READER does not support additional options"
19716         fi
19717         out=$(do_facet $tgt $LR_READER -c $dev)
19718         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19719         echo "$out"
19720         num=$(echo "$out" | grep -c "mdtlov")
19721         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19722                 error "Invalid number of mdtlov clients returned by $LR_READER"
19723         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19724
19725         # check lr_reader -cr on MDT0000
19726         out=$(do_facet $tgt $LR_READER -cr $dev)
19727         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19728         echo "$out"
19729         echo "$out" | grep -q "^reply_data:$" ||
19730                 error "$LR_READER should have returned 'reply_data' section"
19731         num=$(echo "$out" | grep -c "client_generation")
19732         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19733 }
19734 run_test 252 "check lr_reader tool"
19735
19736 test_253() {
19737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19738         remote_mds_nodsh && skip "remote MDS with nodsh"
19739         remote_mgs_nodsh && skip "remote MGS with nodsh"
19740
19741         local ostidx=0
19742         local rc=0
19743         local ost_name=$(ostname_from_index $ostidx)
19744
19745         # on the mdt's osc
19746         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19747         do_facet $SINGLEMDS $LCTL get_param -n \
19748                 osp.$mdtosc_proc1.reserved_mb_high ||
19749                 skip  "remote MDS does not support reserved_mb_high"
19750
19751         rm -rf $DIR/$tdir
19752         wait_mds_ost_sync
19753         wait_delete_completed
19754         mkdir $DIR/$tdir
19755
19756         pool_add $TESTNAME || error "Pool creation failed"
19757         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19758
19759         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19760                 error "Setstripe failed"
19761
19762         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19763
19764         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19765                     grep "watermarks")
19766         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19767
19768         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19769                         osp.$mdtosc_proc1.prealloc_status)
19770         echo "prealloc_status $oa_status"
19771
19772         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19773                 error "File creation should fail"
19774
19775         #object allocation was stopped, but we still able to append files
19776         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19777                 oflag=append || error "Append failed"
19778
19779         rm -f $DIR/$tdir/$tfile.0
19780
19781         # For this test, we want to delete the files we created to go out of
19782         # space but leave the watermark, so we remain nearly out of space
19783         ost_watermarks_enospc_delete_files $tfile $ostidx
19784
19785         wait_delete_completed
19786
19787         sleep_maxage
19788
19789         for i in $(seq 10 12); do
19790                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19791                         2>/dev/null || error "File creation failed after rm"
19792         done
19793
19794         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19795                         osp.$mdtosc_proc1.prealloc_status)
19796         echo "prealloc_status $oa_status"
19797
19798         if (( oa_status != 0 )); then
19799                 error "Object allocation still disable after rm"
19800         fi
19801 }
19802 run_test 253 "Check object allocation limit"
19803
19804 test_254() {
19805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19806         remote_mds_nodsh && skip "remote MDS with nodsh"
19807         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19808                 skip "MDS does not support changelog_size"
19809
19810         local cl_user
19811         local MDT0=$(facet_svc $SINGLEMDS)
19812
19813         changelog_register || error "changelog_register failed"
19814
19815         changelog_clear 0 || error "changelog_clear failed"
19816
19817         local size1=$(do_facet $SINGLEMDS \
19818                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19819         echo "Changelog size $size1"
19820
19821         rm -rf $DIR/$tdir
19822         $LFS mkdir -i 0 $DIR/$tdir
19823         # change something
19824         mkdir -p $DIR/$tdir/pics/2008/zachy
19825         touch $DIR/$tdir/pics/2008/zachy/timestamp
19826         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19827         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19828         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19829         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19830         rm $DIR/$tdir/pics/desktop.jpg
19831
19832         local size2=$(do_facet $SINGLEMDS \
19833                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19834         echo "Changelog size after work $size2"
19835
19836         (( $size2 > $size1 )) ||
19837                 error "new Changelog size=$size2 less than old size=$size1"
19838 }
19839 run_test 254 "Check changelog size"
19840
19841 ladvise_no_type()
19842 {
19843         local type=$1
19844         local file=$2
19845
19846         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19847                 awk -F: '{print $2}' | grep $type > /dev/null
19848         if [ $? -ne 0 ]; then
19849                 return 0
19850         fi
19851         return 1
19852 }
19853
19854 ladvise_no_ioctl()
19855 {
19856         local file=$1
19857
19858         lfs ladvise -a willread $file > /dev/null 2>&1
19859         if [ $? -eq 0 ]; then
19860                 return 1
19861         fi
19862
19863         lfs ladvise -a willread $file 2>&1 |
19864                 grep "Inappropriate ioctl for device" > /dev/null
19865         if [ $? -eq 0 ]; then
19866                 return 0
19867         fi
19868         return 1
19869 }
19870
19871 percent() {
19872         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19873 }
19874
19875 # run a random read IO workload
19876 # usage: random_read_iops <filename> <filesize> <iosize>
19877 random_read_iops() {
19878         local file=$1
19879         local fsize=$2
19880         local iosize=${3:-4096}
19881
19882         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19883                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19884 }
19885
19886 drop_file_oss_cache() {
19887         local file="$1"
19888         local nodes="$2"
19889
19890         $LFS ladvise -a dontneed $file 2>/dev/null ||
19891                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19892 }
19893
19894 ladvise_willread_performance()
19895 {
19896         local repeat=10
19897         local average_origin=0
19898         local average_cache=0
19899         local average_ladvise=0
19900
19901         for ((i = 1; i <= $repeat; i++)); do
19902                 echo "Iter $i/$repeat: reading without willread hint"
19903                 cancel_lru_locks osc
19904                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19905                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19906                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19907                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19908
19909                 cancel_lru_locks osc
19910                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19911                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19912                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19913
19914                 cancel_lru_locks osc
19915                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19916                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19917                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19918                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19919                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19920         done
19921         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19922         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19923         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19924
19925         speedup_cache=$(percent $average_cache $average_origin)
19926         speedup_ladvise=$(percent $average_ladvise $average_origin)
19927
19928         echo "Average uncached read: $average_origin"
19929         echo "Average speedup with OSS cached read: " \
19930                 "$average_cache = +$speedup_cache%"
19931         echo "Average speedup with ladvise willread: " \
19932                 "$average_ladvise = +$speedup_ladvise%"
19933
19934         local lowest_speedup=20
19935         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19936                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19937                         "got $average_cache%. Skipping ladvise willread check."
19938                 return 0
19939         fi
19940
19941         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19942         # it is still good to run until then to exercise 'ladvise willread'
19943         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19944                 [ "$ost1_FSTYPE" = "zfs" ] &&
19945                 echo "osd-zfs does not support dontneed or drop_caches" &&
19946                 return 0
19947
19948         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19949         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19950                 error_not_in_vm "Speedup with willread is less than " \
19951                         "$lowest_speedup%, got $average_ladvise%"
19952 }
19953
19954 test_255a() {
19955         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19956                 skip "lustre < 2.8.54 does not support ladvise "
19957         remote_ost_nodsh && skip "remote OST with nodsh"
19958
19959         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19960
19961         ladvise_no_type willread $DIR/$tfile &&
19962                 skip "willread ladvise is not supported"
19963
19964         ladvise_no_ioctl $DIR/$tfile &&
19965                 skip "ladvise ioctl is not supported"
19966
19967         local size_mb=100
19968         local size=$((size_mb * 1048576))
19969         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19970                 error "dd to $DIR/$tfile failed"
19971
19972         lfs ladvise -a willread $DIR/$tfile ||
19973                 error "Ladvise failed with no range argument"
19974
19975         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19976                 error "Ladvise failed with no -l or -e argument"
19977
19978         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19979                 error "Ladvise failed with only -e argument"
19980
19981         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19982                 error "Ladvise failed with only -l argument"
19983
19984         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19985                 error "End offset should not be smaller than start offset"
19986
19987         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19988                 error "End offset should not be equal to start offset"
19989
19990         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19991                 error "Ladvise failed with overflowing -s argument"
19992
19993         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19994                 error "Ladvise failed with overflowing -e argument"
19995
19996         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19997                 error "Ladvise failed with overflowing -l argument"
19998
19999         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20000                 error "Ladvise succeeded with conflicting -l and -e arguments"
20001
20002         echo "Synchronous ladvise should wait"
20003         local delay=4
20004 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20005         do_nodes $(comma_list $(osts_nodes)) \
20006                 $LCTL set_param fail_val=$delay fail_loc=0x237
20007
20008         local start_ts=$SECONDS
20009         lfs ladvise -a willread $DIR/$tfile ||
20010                 error "Ladvise failed with no range argument"
20011         local end_ts=$SECONDS
20012         local inteval_ts=$((end_ts - start_ts))
20013
20014         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20015                 error "Synchronous advice didn't wait reply"
20016         fi
20017
20018         echo "Asynchronous ladvise shouldn't wait"
20019         local start_ts=$SECONDS
20020         lfs ladvise -a willread -b $DIR/$tfile ||
20021                 error "Ladvise failed with no range argument"
20022         local end_ts=$SECONDS
20023         local inteval_ts=$((end_ts - start_ts))
20024
20025         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20026                 error "Asynchronous advice blocked"
20027         fi
20028
20029         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20030         ladvise_willread_performance
20031 }
20032 run_test 255a "check 'lfs ladvise -a willread'"
20033
20034 facet_meminfo() {
20035         local facet=$1
20036         local info=$2
20037
20038         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20039 }
20040
20041 test_255b() {
20042         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20043                 skip "lustre < 2.8.54 does not support ladvise "
20044         remote_ost_nodsh && skip "remote OST with nodsh"
20045
20046         lfs setstripe -c 1 -i 0 $DIR/$tfile
20047
20048         ladvise_no_type dontneed $DIR/$tfile &&
20049                 skip "dontneed ladvise is not supported"
20050
20051         ladvise_no_ioctl $DIR/$tfile &&
20052                 skip "ladvise ioctl is not supported"
20053
20054         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20055                 [ "$ost1_FSTYPE" = "zfs" ] &&
20056                 skip "zfs-osd does not support 'ladvise dontneed'"
20057
20058         local size_mb=100
20059         local size=$((size_mb * 1048576))
20060         # In order to prevent disturbance of other processes, only check 3/4
20061         # of the memory usage
20062         local kibibytes=$((size_mb * 1024 * 3 / 4))
20063
20064         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20065                 error "dd to $DIR/$tfile failed"
20066
20067         #force write to complete before dropping OST cache & checking memory
20068         sync
20069
20070         local total=$(facet_meminfo ost1 MemTotal)
20071         echo "Total memory: $total KiB"
20072
20073         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20074         local before_read=$(facet_meminfo ost1 Cached)
20075         echo "Cache used before read: $before_read KiB"
20076
20077         lfs ladvise -a willread $DIR/$tfile ||
20078                 error "Ladvise willread failed"
20079         local after_read=$(facet_meminfo ost1 Cached)
20080         echo "Cache used after read: $after_read KiB"
20081
20082         lfs ladvise -a dontneed $DIR/$tfile ||
20083                 error "Ladvise dontneed again failed"
20084         local no_read=$(facet_meminfo ost1 Cached)
20085         echo "Cache used after dontneed ladvise: $no_read KiB"
20086
20087         if [ $total -lt $((before_read + kibibytes)) ]; then
20088                 echo "Memory is too small, abort checking"
20089                 return 0
20090         fi
20091
20092         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20093                 error "Ladvise willread should use more memory" \
20094                         "than $kibibytes KiB"
20095         fi
20096
20097         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20098                 error "Ladvise dontneed should release more memory" \
20099                         "than $kibibytes KiB"
20100         fi
20101 }
20102 run_test 255b "check 'lfs ladvise -a dontneed'"
20103
20104 test_255c() {
20105         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20106                 skip "lustre < 2.10.50 does not support lockahead"
20107
20108         local ost1_imp=$(get_osc_import_name client ost1)
20109         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20110                          cut -d'.' -f2)
20111         local count
20112         local new_count
20113         local difference
20114         local i
20115         local rc
20116
20117         test_mkdir -p $DIR/$tdir
20118         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20119
20120         #test 10 returns only success/failure
20121         i=10
20122         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20123         rc=$?
20124         if [ $rc -eq 255 ]; then
20125                 error "Ladvise test${i} failed, ${rc}"
20126         fi
20127
20128         #test 11 counts lock enqueue requests, all others count new locks
20129         i=11
20130         count=$(do_facet ost1 \
20131                 $LCTL get_param -n ost.OSS.ost.stats)
20132         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20133
20134         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20135         rc=$?
20136         if [ $rc -eq 255 ]; then
20137                 error "Ladvise test${i} failed, ${rc}"
20138         fi
20139
20140         new_count=$(do_facet ost1 \
20141                 $LCTL get_param -n ost.OSS.ost.stats)
20142         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20143                    awk '{ print $2 }')
20144
20145         difference="$((new_count - count))"
20146         if [ $difference -ne $rc ]; then
20147                 error "Ladvise test${i}, bad enqueue count, returned " \
20148                       "${rc}, actual ${difference}"
20149         fi
20150
20151         for i in $(seq 12 21); do
20152                 # If we do not do this, we run the risk of having too many
20153                 # locks and starting lock cancellation while we are checking
20154                 # lock counts.
20155                 cancel_lru_locks osc
20156
20157                 count=$($LCTL get_param -n \
20158                        ldlm.namespaces.$imp_name.lock_unused_count)
20159
20160                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20161                 rc=$?
20162                 if [ $rc -eq 255 ]; then
20163                         error "Ladvise test ${i} failed, ${rc}"
20164                 fi
20165
20166                 new_count=$($LCTL get_param -n \
20167                        ldlm.namespaces.$imp_name.lock_unused_count)
20168                 difference="$((new_count - count))"
20169
20170                 # Test 15 output is divided by 100 to map down to valid return
20171                 if [ $i -eq 15 ]; then
20172                         rc="$((rc * 100))"
20173                 fi
20174
20175                 if [ $difference -ne $rc ]; then
20176                         error "Ladvise test ${i}, bad lock count, returned " \
20177                               "${rc}, actual ${difference}"
20178                 fi
20179         done
20180
20181         #test 22 returns only success/failure
20182         i=22
20183         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20184         rc=$?
20185         if [ $rc -eq 255 ]; then
20186                 error "Ladvise test${i} failed, ${rc}"
20187         fi
20188 }
20189 run_test 255c "suite of ladvise lockahead tests"
20190
20191 test_256() {
20192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20193         remote_mds_nodsh && skip "remote MDS with nodsh"
20194         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20195         changelog_users $SINGLEMDS | grep "^cl" &&
20196                 skip "active changelog user"
20197
20198         local cl_user
20199         local cat_sl
20200         local mdt_dev
20201
20202         mdt_dev=$(mdsdevname 1)
20203         echo $mdt_dev
20204
20205         changelog_register || error "changelog_register failed"
20206
20207         rm -rf $DIR/$tdir
20208         mkdir -p $DIR/$tdir
20209
20210         changelog_clear 0 || error "changelog_clear failed"
20211
20212         # change something
20213         touch $DIR/$tdir/{1..10}
20214
20215         # stop the MDT
20216         stop $SINGLEMDS || error "Fail to stop MDT"
20217
20218         # remount the MDT
20219
20220         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20221
20222         #after mount new plainllog is used
20223         touch $DIR/$tdir/{11..19}
20224         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20225         stack_trap "rm -f $tmpfile"
20226         cat_sl=$(do_facet $SINGLEMDS "sync; \
20227                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20228                  llog_reader $tmpfile | grep -c type=1064553b")
20229         do_facet $SINGLEMDS llog_reader $tmpfile
20230
20231         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20232
20233         changelog_clear 0 || error "changelog_clear failed"
20234
20235         cat_sl=$(do_facet $SINGLEMDS "sync; \
20236                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20237                  llog_reader $tmpfile | grep -c type=1064553b")
20238
20239         if (( cat_sl == 2 )); then
20240                 error "Empty plain llog was not deleted from changelog catalog"
20241         elif (( cat_sl != 1 )); then
20242                 error "Active plain llog shouldn't be deleted from catalog"
20243         fi
20244 }
20245 run_test 256 "Check llog delete for empty and not full state"
20246
20247 test_257() {
20248         remote_mds_nodsh && skip "remote MDS with nodsh"
20249         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20250                 skip "Need MDS version at least 2.8.55"
20251
20252         test_mkdir $DIR/$tdir
20253
20254         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20255                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20256         stat $DIR/$tdir
20257
20258 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20259         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20260         local facet=mds$((mdtidx + 1))
20261         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20262         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20263
20264         stop $facet || error "stop MDS failed"
20265         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20266                 error "start MDS fail"
20267         wait_recovery_complete $facet
20268 }
20269 run_test 257 "xattr locks are not lost"
20270
20271 # Verify we take the i_mutex when security requires it
20272 test_258a() {
20273 #define OBD_FAIL_IMUTEX_SEC 0x141c
20274         $LCTL set_param fail_loc=0x141c
20275         touch $DIR/$tfile
20276         chmod u+s $DIR/$tfile
20277         chmod a+rwx $DIR/$tfile
20278         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20279         RC=$?
20280         if [ $RC -ne 0 ]; then
20281                 error "error, failed to take i_mutex, rc=$?"
20282         fi
20283         rm -f $DIR/$tfile
20284 }
20285 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20286
20287 # Verify we do NOT take the i_mutex in the normal case
20288 test_258b() {
20289 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20290         $LCTL set_param fail_loc=0x141d
20291         touch $DIR/$tfile
20292         chmod a+rwx $DIR
20293         chmod a+rw $DIR/$tfile
20294         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20295         RC=$?
20296         if [ $RC -ne 0 ]; then
20297                 error "error, took i_mutex unnecessarily, rc=$?"
20298         fi
20299         rm -f $DIR/$tfile
20300
20301 }
20302 run_test 258b "verify i_mutex security behavior"
20303
20304 test_259() {
20305         local file=$DIR/$tfile
20306         local before
20307         local after
20308
20309         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20310
20311         stack_trap "rm -f $file" EXIT
20312
20313         wait_delete_completed
20314         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20315         echo "before: $before"
20316
20317         $LFS setstripe -i 0 -c 1 $file
20318         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20319         sync_all_data
20320         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20321         echo "after write: $after"
20322
20323 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20324         do_facet ost1 $LCTL set_param fail_loc=0x2301
20325         $TRUNCATE $file 0
20326         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20327         echo "after truncate: $after"
20328
20329         stop ost1
20330         do_facet ost1 $LCTL set_param fail_loc=0
20331         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20332         sleep 2
20333         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20334         echo "after restart: $after"
20335         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20336                 error "missing truncate?"
20337
20338         return 0
20339 }
20340 run_test 259 "crash at delayed truncate"
20341
20342 test_260() {
20343 #define OBD_FAIL_MDC_CLOSE               0x806
20344         $LCTL set_param fail_loc=0x80000806
20345         touch $DIR/$tfile
20346
20347 }
20348 run_test 260 "Check mdc_close fail"
20349
20350 ### Data-on-MDT sanity tests ###
20351 test_270a() {
20352         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20353                 skip "Need MDS version at least 2.10.55 for DoM"
20354
20355         # create DoM file
20356         local dom=$DIR/$tdir/dom_file
20357         local tmp=$DIR/$tdir/tmp_file
20358
20359         mkdir -p $DIR/$tdir
20360
20361         # basic checks for DoM component creation
20362         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20363                 error "Can set MDT layout to non-first entry"
20364
20365         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20366                 error "Can define multiple entries as MDT layout"
20367
20368         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20369
20370         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20371         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20372         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20373
20374         local mdtidx=$($LFS getstripe -m $dom)
20375         local mdtname=MDT$(printf %04x $mdtidx)
20376         local facet=mds$((mdtidx + 1))
20377         local space_check=1
20378
20379         # Skip free space checks with ZFS
20380         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20381
20382         # write
20383         sync
20384         local size_tmp=$((65536 * 3))
20385         local mdtfree1=$(do_facet $facet \
20386                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20387
20388         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20389         # check also direct IO along write
20390         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20391         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20392         sync
20393         cmp $tmp $dom || error "file data is different"
20394         [ $(stat -c%s $dom) == $size_tmp ] ||
20395                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20396         if [ $space_check == 1 ]; then
20397                 local mdtfree2=$(do_facet $facet \
20398                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20399
20400                 # increase in usage from by $size_tmp
20401                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20402                         error "MDT free space wrong after write: " \
20403                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20404         fi
20405
20406         # truncate
20407         local size_dom=10000
20408
20409         $TRUNCATE $dom $size_dom
20410         [ $(stat -c%s $dom) == $size_dom ] ||
20411                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20412         if [ $space_check == 1 ]; then
20413                 mdtfree1=$(do_facet $facet \
20414                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20415                 # decrease in usage from $size_tmp to new $size_dom
20416                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20417                   $(((size_tmp - size_dom) / 1024)) ] ||
20418                         error "MDT free space is wrong after truncate: " \
20419                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20420         fi
20421
20422         # append
20423         cat $tmp >> $dom
20424         sync
20425         size_dom=$((size_dom + size_tmp))
20426         [ $(stat -c%s $dom) == $size_dom ] ||
20427                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20428         if [ $space_check == 1 ]; then
20429                 mdtfree2=$(do_facet $facet \
20430                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20431                 # increase in usage by $size_tmp from previous
20432                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20433                         error "MDT free space is wrong after append: " \
20434                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20435         fi
20436
20437         # delete
20438         rm $dom
20439         if [ $space_check == 1 ]; then
20440                 mdtfree1=$(do_facet $facet \
20441                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20442                 # decrease in usage by $size_dom from previous
20443                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20444                         error "MDT free space is wrong after removal: " \
20445                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20446         fi
20447
20448         # combined striping
20449         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20450                 error "Can't create DoM + OST striping"
20451
20452         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20453         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20454         # check also direct IO along write
20455         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20456         sync
20457         cmp $tmp $dom || error "file data is different"
20458         [ $(stat -c%s $dom) == $size_tmp ] ||
20459                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20460         rm $dom $tmp
20461
20462         return 0
20463 }
20464 run_test 270a "DoM: basic functionality tests"
20465
20466 test_270b() {
20467         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20468                 skip "Need MDS version at least 2.10.55"
20469
20470         local dom=$DIR/$tdir/dom_file
20471         local max_size=1048576
20472
20473         mkdir -p $DIR/$tdir
20474         $LFS setstripe -E $max_size -L mdt $dom
20475
20476         # truncate over the limit
20477         $TRUNCATE $dom $(($max_size + 1)) &&
20478                 error "successful truncate over the maximum size"
20479         # write over the limit
20480         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20481                 error "successful write over the maximum size"
20482         # append over the limit
20483         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20484         echo "12345" >> $dom && error "successful append over the maximum size"
20485         rm $dom
20486
20487         return 0
20488 }
20489 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20490
20491 test_270c() {
20492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20493                 skip "Need MDS version at least 2.10.55"
20494
20495         mkdir -p $DIR/$tdir
20496         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20497
20498         # check files inherit DoM EA
20499         touch $DIR/$tdir/first
20500         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20501                 error "bad pattern"
20502         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20503                 error "bad stripe count"
20504         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20505                 error "bad stripe size"
20506
20507         # check directory inherits DoM EA and uses it as default
20508         mkdir $DIR/$tdir/subdir
20509         touch $DIR/$tdir/subdir/second
20510         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20511                 error "bad pattern in sub-directory"
20512         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20513                 error "bad stripe count in sub-directory"
20514         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20515                 error "bad stripe size in sub-directory"
20516         return 0
20517 }
20518 run_test 270c "DoM: DoM EA inheritance tests"
20519
20520 test_270d() {
20521         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20522                 skip "Need MDS version at least 2.10.55"
20523
20524         mkdir -p $DIR/$tdir
20525         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20526
20527         # inherit default DoM striping
20528         mkdir $DIR/$tdir/subdir
20529         touch $DIR/$tdir/subdir/f1
20530
20531         # change default directory striping
20532         $LFS setstripe -c 1 $DIR/$tdir/subdir
20533         touch $DIR/$tdir/subdir/f2
20534         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20535                 error "wrong default striping in file 2"
20536         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20537                 error "bad pattern in file 2"
20538         return 0
20539 }
20540 run_test 270d "DoM: change striping from DoM to RAID0"
20541
20542 test_270e() {
20543         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20544                 skip "Need MDS version at least 2.10.55"
20545
20546         mkdir -p $DIR/$tdir/dom
20547         mkdir -p $DIR/$tdir/norm
20548         DOMFILES=20
20549         NORMFILES=10
20550         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20551         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20552
20553         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20554         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20555
20556         # find DoM files by layout
20557         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20558         [ $NUM -eq  $DOMFILES ] ||
20559                 error "lfs find -L: found $NUM, expected $DOMFILES"
20560         echo "Test 1: lfs find 20 DOM files by layout: OK"
20561
20562         # there should be 1 dir with default DOM striping
20563         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20564         [ $NUM -eq  1 ] ||
20565                 error "lfs find -L: found $NUM, expected 1 dir"
20566         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20567
20568         # find DoM files by stripe size
20569         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20570         [ $NUM -eq  $DOMFILES ] ||
20571                 error "lfs find -S: found $NUM, expected $DOMFILES"
20572         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20573
20574         # find files by stripe offset except DoM files
20575         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20576         [ $NUM -eq  $NORMFILES ] ||
20577                 error "lfs find -i: found $NUM, expected $NORMFILES"
20578         echo "Test 5: lfs find no DOM files by stripe index: OK"
20579         return 0
20580 }
20581 run_test 270e "DoM: lfs find with DoM files test"
20582
20583 test_270f() {
20584         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20585                 skip "Need MDS version at least 2.10.55"
20586
20587         local mdtname=${FSNAME}-MDT0000-mdtlov
20588         local dom=$DIR/$tdir/dom_file
20589         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20590                                                 lod.$mdtname.dom_stripesize)
20591         local dom_limit=131072
20592
20593         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20594         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20595                                                 lod.$mdtname.dom_stripesize)
20596         [ ${dom_limit} -eq ${dom_current} ] ||
20597                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20598
20599         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20600         $LFS setstripe -d $DIR/$tdir
20601         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20602                 error "Can't set directory default striping"
20603
20604         # exceed maximum stripe size
20605         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20606                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20607         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20608                 error "Able to create DoM component size more than LOD limit"
20609
20610         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20611         dom_current=$(do_facet mds1 $LCTL get_param -n \
20612                                                 lod.$mdtname.dom_stripesize)
20613         [ 0 -eq ${dom_current} ] ||
20614                 error "Can't set zero DoM stripe limit"
20615         rm $dom
20616
20617         # attempt to create DoM file on server with disabled DoM should
20618         # remove DoM entry from layout and be succeed
20619         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20620                 error "Can't create DoM file (DoM is disabled)"
20621         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20622                 error "File has DoM component while DoM is disabled"
20623         rm $dom
20624
20625         # attempt to create DoM file with only DoM stripe should return error
20626         $LFS setstripe -E $dom_limit -L mdt $dom &&
20627                 error "Able to create DoM-only file while DoM is disabled"
20628
20629         # too low values to be aligned with smallest stripe size 64K
20630         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20631         dom_current=$(do_facet mds1 $LCTL get_param -n \
20632                                                 lod.$mdtname.dom_stripesize)
20633         [ 30000 -eq ${dom_current} ] &&
20634                 error "Can set too small DoM stripe limit"
20635
20636         # 64K is a minimal stripe size in Lustre, expect limit of that size
20637         [ 65536 -eq ${dom_current} ] ||
20638                 error "Limit is not set to 64K but ${dom_current}"
20639
20640         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20641         dom_current=$(do_facet mds1 $LCTL get_param -n \
20642                                                 lod.$mdtname.dom_stripesize)
20643         echo $dom_current
20644         [ 2147483648 -eq ${dom_current} ] &&
20645                 error "Can set too large DoM stripe limit"
20646
20647         do_facet mds1 $LCTL set_param -n \
20648                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20649         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20650                 error "Can't create DoM component size after limit change"
20651         do_facet mds1 $LCTL set_param -n \
20652                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20653         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20654                 error "Can't create DoM file after limit decrease"
20655         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20656                 error "Can create big DoM component after limit decrease"
20657         touch ${dom}_def ||
20658                 error "Can't create file with old default layout"
20659
20660         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20661         return 0
20662 }
20663 run_test 270f "DoM: maximum DoM stripe size checks"
20664
20665 test_270g() {
20666         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20667                 skip "Need MDS version at least 2.13.52"
20668         local dom=$DIR/$tdir/$tfile
20669
20670         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20671         local lodname=${FSNAME}-MDT0000-mdtlov
20672
20673         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20674         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20675         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20676         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20677
20678         local dom_limit=1024
20679         local dom_threshold="50%"
20680
20681         $LFS setstripe -d $DIR/$tdir
20682         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20683                 error "Can't set directory default striping"
20684
20685         do_facet mds1 $LCTL set_param -n \
20686                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20687         # set 0 threshold and create DOM file to change tunable stripesize
20688         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20689         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20690                 error "Failed to create $dom file"
20691         # now tunable dom_cur_stripesize should reach maximum
20692         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20693                                         lod.${lodname}.dom_stripesize_cur_kb)
20694         [[ $dom_current == $dom_limit ]] ||
20695                 error "Current DOM stripesize is not maximum"
20696         rm $dom
20697
20698         # set threshold for further tests
20699         do_facet mds1 $LCTL set_param -n \
20700                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20701         echo "DOM threshold is $dom_threshold free space"
20702         local dom_def
20703         local dom_set
20704         # Spoof bfree to exceed threshold
20705         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20706         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20707         for spfree in 40 20 0 15 30 55; do
20708                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20709                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20710                         error "Failed to create $dom file"
20711                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20712                                         lod.${lodname}.dom_stripesize_cur_kb)
20713                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20714                 [[ $dom_def != $dom_current ]] ||
20715                         error "Default stripe size was not changed"
20716                 if [[ $spfree > 0 ]] ; then
20717                         dom_set=$($LFS getstripe -S $dom)
20718                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20719                                 error "DOM component size is still old"
20720                 else
20721                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20722                                 error "DoM component is set with no free space"
20723                 fi
20724                 rm $dom
20725                 dom_current=$dom_def
20726         done
20727 }
20728 run_test 270g "DoM: default DoM stripe size depends on free space"
20729
20730 test_270h() {
20731         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20732                 skip "Need MDS version at least 2.13.53"
20733
20734         local mdtname=${FSNAME}-MDT0000-mdtlov
20735         local dom=$DIR/$tdir/$tfile
20736         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20737
20738         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20739         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20740
20741         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20742         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20743                 error "can't create OST file"
20744         # mirrored file with DOM entry in the second mirror
20745         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20746                 error "can't create mirror with DoM component"
20747
20748         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20749
20750         # DOM component in the middle and has other enries in the same mirror,
20751         # should succeed but lost DoM component
20752         $LFS setstripe --copy=${dom}_1 $dom ||
20753                 error "Can't create file from OST|DOM mirror layout"
20754         # check new file has no DoM layout after all
20755         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20756                 error "File has DoM component while DoM is disabled"
20757 }
20758 run_test 270h "DoM: DoM stripe removal when disabled on server"
20759
20760 test_271a() {
20761         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20762                 skip "Need MDS version at least 2.10.55"
20763
20764         local dom=$DIR/$tdir/dom
20765
20766         mkdir -p $DIR/$tdir
20767
20768         $LFS setstripe -E 1024K -L mdt $dom
20769
20770         lctl set_param -n mdc.*.stats=clear
20771         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20772         cat $dom > /dev/null
20773         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20774         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20775         ls $dom
20776         rm -f $dom
20777 }
20778 run_test 271a "DoM: data is cached for read after write"
20779
20780 test_271b() {
20781         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20782                 skip "Need MDS version at least 2.10.55"
20783
20784         local dom=$DIR/$tdir/dom
20785
20786         mkdir -p $DIR/$tdir
20787
20788         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20789
20790         lctl set_param -n mdc.*.stats=clear
20791         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20792         cancel_lru_locks mdc
20793         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20794         # second stat to check size is cached on client
20795         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20796         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20797         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20798         rm -f $dom
20799 }
20800 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20801
20802 test_271ba() {
20803         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20804                 skip "Need MDS version at least 2.10.55"
20805
20806         local dom=$DIR/$tdir/dom
20807
20808         mkdir -p $DIR/$tdir
20809
20810         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20811
20812         lctl set_param -n mdc.*.stats=clear
20813         lctl set_param -n osc.*.stats=clear
20814         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20815         cancel_lru_locks mdc
20816         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20817         # second stat to check size is cached on client
20818         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20819         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20820         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20821         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20822         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20823         rm -f $dom
20824 }
20825 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20826
20827
20828 get_mdc_stats() {
20829         local mdtidx=$1
20830         local param=$2
20831         local mdt=MDT$(printf %04x $mdtidx)
20832
20833         if [ -z $param ]; then
20834                 lctl get_param -n mdc.*$mdt*.stats
20835         else
20836                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20837         fi
20838 }
20839
20840 test_271c() {
20841         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20842                 skip "Need MDS version at least 2.10.55"
20843
20844         local dom=$DIR/$tdir/dom
20845
20846         mkdir -p $DIR/$tdir
20847
20848         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20849
20850         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20851         local facet=mds$((mdtidx + 1))
20852
20853         cancel_lru_locks mdc
20854         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20855         createmany -o $dom 1000
20856         lctl set_param -n mdc.*.stats=clear
20857         smalliomany -w $dom 1000 200
20858         get_mdc_stats $mdtidx
20859         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20860         # Each file has 1 open, 1 IO enqueues, total 2000
20861         # but now we have also +1 getxattr for security.capability, total 3000
20862         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20863         unlinkmany $dom 1000
20864
20865         cancel_lru_locks mdc
20866         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20867         createmany -o $dom 1000
20868         lctl set_param -n mdc.*.stats=clear
20869         smalliomany -w $dom 1000 200
20870         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20871         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20872         # for OPEN and IO lock.
20873         [ $((enq - enq_2)) -ge 1000 ] ||
20874                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20875         unlinkmany $dom 1000
20876         return 0
20877 }
20878 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20879
20880 cleanup_271def_tests() {
20881         trap 0
20882         rm -f $1
20883 }
20884
20885 test_271d() {
20886         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20887                 skip "Need MDS version at least 2.10.57"
20888
20889         local dom=$DIR/$tdir/dom
20890         local tmp=$TMP/$tfile
20891         trap "cleanup_271def_tests $tmp" EXIT
20892
20893         mkdir -p $DIR/$tdir
20894
20895         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20896
20897         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20898
20899         cancel_lru_locks mdc
20900         dd if=/dev/urandom of=$tmp bs=1000 count=1
20901         dd if=$tmp of=$dom bs=1000 count=1
20902         cancel_lru_locks mdc
20903
20904         cat /etc/hosts >> $tmp
20905         lctl set_param -n mdc.*.stats=clear
20906
20907         # append data to the same file it should update local page
20908         echo "Append to the same page"
20909         cat /etc/hosts >> $dom
20910         local num=$(get_mdc_stats $mdtidx ost_read)
20911         local ra=$(get_mdc_stats $mdtidx req_active)
20912         local rw=$(get_mdc_stats $mdtidx req_waittime)
20913
20914         [ -z $num ] || error "$num READ RPC occured"
20915         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20916         echo "... DONE"
20917
20918         # compare content
20919         cmp $tmp $dom || error "file miscompare"
20920
20921         cancel_lru_locks mdc
20922         lctl set_param -n mdc.*.stats=clear
20923
20924         echo "Open and read file"
20925         cat $dom > /dev/null
20926         local num=$(get_mdc_stats $mdtidx ost_read)
20927         local ra=$(get_mdc_stats $mdtidx req_active)
20928         local rw=$(get_mdc_stats $mdtidx req_waittime)
20929
20930         [ -z $num ] || error "$num READ RPC occured"
20931         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20932         echo "... DONE"
20933
20934         # compare content
20935         cmp $tmp $dom || error "file miscompare"
20936
20937         return 0
20938 }
20939 run_test 271d "DoM: read on open (1K file in reply buffer)"
20940
20941 test_271f() {
20942         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20943                 skip "Need MDS version at least 2.10.57"
20944
20945         local dom=$DIR/$tdir/dom
20946         local tmp=$TMP/$tfile
20947         trap "cleanup_271def_tests $tmp" EXIT
20948
20949         mkdir -p $DIR/$tdir
20950
20951         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20952
20953         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20954
20955         cancel_lru_locks mdc
20956         dd if=/dev/urandom of=$tmp bs=265000 count=1
20957         dd if=$tmp of=$dom bs=265000 count=1
20958         cancel_lru_locks mdc
20959         cat /etc/hosts >> $tmp
20960         lctl set_param -n mdc.*.stats=clear
20961
20962         echo "Append to the same page"
20963         cat /etc/hosts >> $dom
20964         local num=$(get_mdc_stats $mdtidx ost_read)
20965         local ra=$(get_mdc_stats $mdtidx req_active)
20966         local rw=$(get_mdc_stats $mdtidx req_waittime)
20967
20968         [ -z $num ] || error "$num READ RPC occured"
20969         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20970         echo "... DONE"
20971
20972         # compare content
20973         cmp $tmp $dom || error "file miscompare"
20974
20975         cancel_lru_locks mdc
20976         lctl set_param -n mdc.*.stats=clear
20977
20978         echo "Open and read file"
20979         cat $dom > /dev/null
20980         local num=$(get_mdc_stats $mdtidx ost_read)
20981         local ra=$(get_mdc_stats $mdtidx req_active)
20982         local rw=$(get_mdc_stats $mdtidx req_waittime)
20983
20984         [ -z $num ] && num=0
20985         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20986         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20987         echo "... DONE"
20988
20989         # compare content
20990         cmp $tmp $dom || error "file miscompare"
20991
20992         return 0
20993 }
20994 run_test 271f "DoM: read on open (200K file and read tail)"
20995
20996 test_271g() {
20997         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20998                 skip "Skipping due to old client or server version"
20999
21000         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21001         # to get layout
21002         $CHECKSTAT -t file $DIR1/$tfile
21003
21004         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21005         MULTIOP_PID=$!
21006         sleep 1
21007         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21008         $LCTL set_param fail_loc=0x80000314
21009         rm $DIR1/$tfile || error "Unlink fails"
21010         RC=$?
21011         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21012         [ $RC -eq 0 ] || error "Failed write to stale object"
21013 }
21014 run_test 271g "Discard DoM data vs client flush race"
21015
21016 test_272a() {
21017         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21018                 skip "Need MDS version at least 2.11.50"
21019
21020         local dom=$DIR/$tdir/dom
21021         mkdir -p $DIR/$tdir
21022
21023         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21024         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21025                 error "failed to write data into $dom"
21026         local old_md5=$(md5sum $dom)
21027
21028         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21029                 error "failed to migrate to the same DoM component"
21030
21031         local new_md5=$(md5sum $dom)
21032
21033         [ "$old_md5" == "$new_md5" ] ||
21034                 error "md5sum differ: $old_md5, $new_md5"
21035
21036         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21037                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21038 }
21039 run_test 272a "DoM migration: new layout with the same DOM component"
21040
21041 test_272b() {
21042         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21043                 skip "Need MDS version at least 2.11.50"
21044
21045         local dom=$DIR/$tdir/dom
21046         mkdir -p $DIR/$tdir
21047         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21048
21049         local mdtidx=$($LFS getstripe -m $dom)
21050         local mdtname=MDT$(printf %04x $mdtidx)
21051         local facet=mds$((mdtidx + 1))
21052
21053         local mdtfree1=$(do_facet $facet \
21054                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21055         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21056                 error "failed to write data into $dom"
21057         local old_md5=$(md5sum $dom)
21058         cancel_lru_locks mdc
21059         local mdtfree1=$(do_facet $facet \
21060                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21061
21062         $LFS migrate -c2 $dom ||
21063                 error "failed to migrate to the new composite layout"
21064         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21065                 error "MDT stripe was not removed"
21066
21067         cancel_lru_locks mdc
21068         local new_md5=$(md5sum $dom)
21069         [ "$old_md5" == "$new_md5" ] ||
21070                 error "$old_md5 != $new_md5"
21071
21072         # Skip free space checks with ZFS
21073         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21074                 local mdtfree2=$(do_facet $facet \
21075                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21076                 [ $mdtfree2 -gt $mdtfree1 ] ||
21077                         error "MDT space is not freed after migration"
21078         fi
21079         return 0
21080 }
21081 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21082
21083 test_272c() {
21084         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21085                 skip "Need MDS version at least 2.11.50"
21086
21087         local dom=$DIR/$tdir/$tfile
21088         mkdir -p $DIR/$tdir
21089         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21090
21091         local mdtidx=$($LFS getstripe -m $dom)
21092         local mdtname=MDT$(printf %04x $mdtidx)
21093         local facet=mds$((mdtidx + 1))
21094
21095         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21096                 error "failed to write data into $dom"
21097         local old_md5=$(md5sum $dom)
21098         cancel_lru_locks mdc
21099         local mdtfree1=$(do_facet $facet \
21100                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21101
21102         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21103                 error "failed to migrate to the new composite layout"
21104         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21105                 error "MDT stripe was not removed"
21106
21107         cancel_lru_locks mdc
21108         local new_md5=$(md5sum $dom)
21109         [ "$old_md5" == "$new_md5" ] ||
21110                 error "$old_md5 != $new_md5"
21111
21112         # Skip free space checks with ZFS
21113         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21114                 local mdtfree2=$(do_facet $facet \
21115                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21116                 [ $mdtfree2 -gt $mdtfree1 ] ||
21117                         error "MDS space is not freed after migration"
21118         fi
21119         return 0
21120 }
21121 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21122
21123 test_272d() {
21124         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21125                 skip "Need MDS version at least 2.12.55"
21126
21127         local dom=$DIR/$tdir/$tfile
21128         mkdir -p $DIR/$tdir
21129         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21130
21131         local mdtidx=$($LFS getstripe -m $dom)
21132         local mdtname=MDT$(printf %04x $mdtidx)
21133         local facet=mds$((mdtidx + 1))
21134
21135         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21136                 error "failed to write data into $dom"
21137         local old_md5=$(md5sum $dom)
21138         cancel_lru_locks mdc
21139         local mdtfree1=$(do_facet $facet \
21140                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21141
21142         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21143                 error "failed mirroring to the new composite layout"
21144         $LFS mirror resync $dom ||
21145                 error "failed mirror resync"
21146         $LFS mirror split --mirror-id 1 -d $dom ||
21147                 error "failed mirror split"
21148
21149         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21150                 error "MDT stripe was not removed"
21151
21152         cancel_lru_locks mdc
21153         local new_md5=$(md5sum $dom)
21154         [ "$old_md5" == "$new_md5" ] ||
21155                 error "$old_md5 != $new_md5"
21156
21157         # Skip free space checks with ZFS
21158         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21159                 local mdtfree2=$(do_facet $facet \
21160                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21161                 [ $mdtfree2 -gt $mdtfree1 ] ||
21162                         error "MDS space is not freed after DOM mirror deletion"
21163         fi
21164         return 0
21165 }
21166 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21167
21168 test_272e() {
21169         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21170                 skip "Need MDS version at least 2.12.55"
21171
21172         local dom=$DIR/$tdir/$tfile
21173         mkdir -p $DIR/$tdir
21174         $LFS setstripe -c 2 $dom
21175
21176         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21177                 error "failed to write data into $dom"
21178         local old_md5=$(md5sum $dom)
21179         cancel_lru_locks mdc
21180
21181         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21182                 error "failed mirroring to the DOM layout"
21183         $LFS mirror resync $dom ||
21184                 error "failed mirror resync"
21185         $LFS mirror split --mirror-id 1 -d $dom ||
21186                 error "failed mirror split"
21187
21188         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21189                 error "MDT stripe was not removed"
21190
21191         cancel_lru_locks mdc
21192         local new_md5=$(md5sum $dom)
21193         [ "$old_md5" == "$new_md5" ] ||
21194                 error "$old_md5 != $new_md5"
21195
21196         return 0
21197 }
21198 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21199
21200 test_272f() {
21201         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21202                 skip "Need MDS version at least 2.12.55"
21203
21204         local dom=$DIR/$tdir/$tfile
21205         mkdir -p $DIR/$tdir
21206         $LFS setstripe -c 2 $dom
21207
21208         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21209                 error "failed to write data into $dom"
21210         local old_md5=$(md5sum $dom)
21211         cancel_lru_locks mdc
21212
21213         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21214                 error "failed migrating to the DOM file"
21215
21216         cancel_lru_locks mdc
21217         local new_md5=$(md5sum $dom)
21218         [ "$old_md5" != "$new_md5" ] &&
21219                 error "$old_md5 != $new_md5"
21220
21221         return 0
21222 }
21223 run_test 272f "DoM migration: OST-striped file to DOM file"
21224
21225 test_273a() {
21226         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21227                 skip "Need MDS version at least 2.11.50"
21228
21229         # Layout swap cannot be done if either file has DOM component,
21230         # this will never be supported, migration should be used instead
21231
21232         local dom=$DIR/$tdir/$tfile
21233         mkdir -p $DIR/$tdir
21234
21235         $LFS setstripe -c2 ${dom}_plain
21236         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21237         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21238                 error "can swap layout with DoM component"
21239         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21240                 error "can swap layout with DoM component"
21241
21242         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21243         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21244                 error "can swap layout with DoM component"
21245         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21246                 error "can swap layout with DoM component"
21247         return 0
21248 }
21249 run_test 273a "DoM: layout swapping should fail with DOM"
21250
21251 test_275() {
21252         remote_ost_nodsh && skip "remote OST with nodsh"
21253         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21254                 skip "Need OST version >= 2.10.57"
21255
21256         local file=$DIR/$tfile
21257         local oss
21258
21259         oss=$(comma_list $(osts_nodes))
21260
21261         dd if=/dev/urandom of=$file bs=1M count=2 ||
21262                 error "failed to create a file"
21263         cancel_lru_locks osc
21264
21265         #lock 1
21266         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21267                 error "failed to read a file"
21268
21269 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21270         $LCTL set_param fail_loc=0x8000031f
21271
21272         cancel_lru_locks osc &
21273         sleep 1
21274
21275 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21276         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21277         #IO takes another lock, but matches the PENDING one
21278         #and places it to the IO RPC
21279         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21280                 error "failed to read a file with PENDING lock"
21281 }
21282 run_test 275 "Read on a canceled duplicate lock"
21283
21284 test_276() {
21285         remote_ost_nodsh && skip "remote OST with nodsh"
21286         local pid
21287
21288         do_facet ost1 "(while true; do \
21289                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21290                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21291         pid=$!
21292
21293         for LOOP in $(seq 20); do
21294                 stop ost1
21295                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21296         done
21297         kill -9 $pid
21298         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21299                 rm $TMP/sanity_276_pid"
21300 }
21301 run_test 276 "Race between mount and obd_statfs"
21302
21303 test_277() {
21304         $LCTL set_param ldlm.namespaces.*.lru_size=0
21305         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21306         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21307                         grep ^used_mb | awk '{print $2}')
21308         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21309         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21310                 oflag=direct conv=notrunc
21311         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21312                         grep ^used_mb | awk '{print $2}')
21313         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21314 }
21315 run_test 277 "Direct IO shall drop page cache"
21316
21317 test_278() {
21318         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21320         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21321                 skip "needs the same host for mdt1 mdt2" && return
21322
21323         local pid1
21324         local pid2
21325
21326 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21327         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21328         stop mds2 &
21329         pid2=$!
21330
21331         stop mds1
21332
21333         echo "Starting MDTs"
21334         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21335         wait $pid2
21336 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21337 #will return NULL
21338         do_facet mds2 $LCTL set_param fail_loc=0
21339
21340         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21341         wait_recovery_complete mds2
21342 }
21343 run_test 278 "Race starting MDS between MDTs stop/start"
21344
21345 test_280() {
21346         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21347                 skip "Need MGS version at least 2.13.52"
21348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21349         combined_mgs_mds || skip "needs combined MGS/MDT"
21350
21351         umount_client $MOUNT
21352 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21353         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21354
21355         mount_client $MOUNT &
21356         sleep 1
21357         stop mgs || error "stop mgs failed"
21358         #for a race mgs would crash
21359         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21360         mount_client $MOUNT || error "mount client failed"
21361 }
21362 run_test 280 "Race between MGS umount and client llog processing"
21363
21364 cleanup_test_300() {
21365         trap 0
21366         umask $SAVE_UMASK
21367 }
21368 test_striped_dir() {
21369         local mdt_index=$1
21370         local stripe_count
21371         local stripe_index
21372
21373         mkdir -p $DIR/$tdir
21374
21375         SAVE_UMASK=$(umask)
21376         trap cleanup_test_300 RETURN EXIT
21377
21378         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21379                                                 $DIR/$tdir/striped_dir ||
21380                 error "set striped dir error"
21381
21382         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21383         [ "$mode" = "755" ] || error "expect 755 got $mode"
21384
21385         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21386                 error "getdirstripe failed"
21387         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21388         if [ "$stripe_count" != "2" ]; then
21389                 error "1:stripe_count is $stripe_count, expect 2"
21390         fi
21391         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21392         if [ "$stripe_count" != "2" ]; then
21393                 error "2:stripe_count is $stripe_count, expect 2"
21394         fi
21395
21396         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21397         if [ "$stripe_index" != "$mdt_index" ]; then
21398                 error "stripe_index is $stripe_index, expect $mdt_index"
21399         fi
21400
21401         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21402                 error "nlink error after create striped dir"
21403
21404         mkdir $DIR/$tdir/striped_dir/a
21405         mkdir $DIR/$tdir/striped_dir/b
21406
21407         stat $DIR/$tdir/striped_dir/a ||
21408                 error "create dir under striped dir failed"
21409         stat $DIR/$tdir/striped_dir/b ||
21410                 error "create dir under striped dir failed"
21411
21412         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21413                 error "nlink error after mkdir"
21414
21415         rmdir $DIR/$tdir/striped_dir/a
21416         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21417                 error "nlink error after rmdir"
21418
21419         rmdir $DIR/$tdir/striped_dir/b
21420         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21421                 error "nlink error after rmdir"
21422
21423         chattr +i $DIR/$tdir/striped_dir
21424         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21425                 error "immutable flags not working under striped dir!"
21426         chattr -i $DIR/$tdir/striped_dir
21427
21428         rmdir $DIR/$tdir/striped_dir ||
21429                 error "rmdir striped dir error"
21430
21431         cleanup_test_300
21432
21433         true
21434 }
21435
21436 test_300a() {
21437         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21438                 skip "skipped for lustre < 2.7.0"
21439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21441
21442         test_striped_dir 0 || error "failed on striped dir on MDT0"
21443         test_striped_dir 1 || error "failed on striped dir on MDT0"
21444 }
21445 run_test 300a "basic striped dir sanity test"
21446
21447 test_300b() {
21448         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21449                 skip "skipped for lustre < 2.7.0"
21450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21452
21453         local i
21454         local mtime1
21455         local mtime2
21456         local mtime3
21457
21458         test_mkdir $DIR/$tdir || error "mkdir fail"
21459         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21460                 error "set striped dir error"
21461         for i in {0..9}; do
21462                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21463                 sleep 1
21464                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21465                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21466                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21467                 sleep 1
21468                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21469                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21470                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21471         done
21472         true
21473 }
21474 run_test 300b "check ctime/mtime for striped dir"
21475
21476 test_300c() {
21477         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21478                 skip "skipped for lustre < 2.7.0"
21479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21481
21482         local file_count
21483
21484         mkdir -p $DIR/$tdir
21485         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21486                 error "set striped dir error"
21487
21488         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21489                 error "chown striped dir failed"
21490
21491         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21492                 error "create 5k files failed"
21493
21494         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21495
21496         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21497
21498         rm -rf $DIR/$tdir
21499 }
21500 run_test 300c "chown && check ls under striped directory"
21501
21502 test_300d() {
21503         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21504                 skip "skipped for lustre < 2.7.0"
21505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21507
21508         local stripe_count
21509         local file
21510
21511         mkdir -p $DIR/$tdir
21512         $LFS setstripe -c 2 $DIR/$tdir
21513
21514         #local striped directory
21515         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21516                 error "set striped dir error"
21517         #look at the directories for debug purposes
21518         ls -l $DIR/$tdir
21519         $LFS getdirstripe $DIR/$tdir
21520         ls -l $DIR/$tdir/striped_dir
21521         $LFS getdirstripe $DIR/$tdir/striped_dir
21522         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21523                 error "create 10 files failed"
21524
21525         #remote striped directory
21526         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21527                 error "set striped dir error"
21528         #look at the directories for debug purposes
21529         ls -l $DIR/$tdir
21530         $LFS getdirstripe $DIR/$tdir
21531         ls -l $DIR/$tdir/remote_striped_dir
21532         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21533         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21534                 error "create 10 files failed"
21535
21536         for file in $(find $DIR/$tdir); do
21537                 stripe_count=$($LFS getstripe -c $file)
21538                 [ $stripe_count -eq 2 ] ||
21539                         error "wrong stripe $stripe_count for $file"
21540         done
21541
21542         rm -rf $DIR/$tdir
21543 }
21544 run_test 300d "check default stripe under striped directory"
21545
21546 test_300e() {
21547         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21548                 skip "Need MDS version at least 2.7.55"
21549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21551
21552         local stripe_count
21553         local file
21554
21555         mkdir -p $DIR/$tdir
21556
21557         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21558                 error "set striped dir error"
21559
21560         touch $DIR/$tdir/striped_dir/a
21561         touch $DIR/$tdir/striped_dir/b
21562         touch $DIR/$tdir/striped_dir/c
21563
21564         mkdir $DIR/$tdir/striped_dir/dir_a
21565         mkdir $DIR/$tdir/striped_dir/dir_b
21566         mkdir $DIR/$tdir/striped_dir/dir_c
21567
21568         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21569                 error "set striped adir under striped dir error"
21570
21571         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21572                 error "set striped bdir under striped dir error"
21573
21574         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21575                 error "set striped cdir under striped dir error"
21576
21577         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21578                 error "rename dir under striped dir fails"
21579
21580         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21581                 error "rename dir under different stripes fails"
21582
21583         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21584                 error "rename file under striped dir should succeed"
21585
21586         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21587                 error "rename dir under striped dir should succeed"
21588
21589         rm -rf $DIR/$tdir
21590 }
21591 run_test 300e "check rename under striped directory"
21592
21593 test_300f() {
21594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21596         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21597                 skip "Need MDS version at least 2.7.55"
21598
21599         local stripe_count
21600         local file
21601
21602         rm -rf $DIR/$tdir
21603         mkdir -p $DIR/$tdir
21604
21605         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21606                 error "set striped dir error"
21607
21608         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21609                 error "set striped dir error"
21610
21611         touch $DIR/$tdir/striped_dir/a
21612         mkdir $DIR/$tdir/striped_dir/dir_a
21613         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21614                 error "create striped dir under striped dir fails"
21615
21616         touch $DIR/$tdir/striped_dir1/b
21617         mkdir $DIR/$tdir/striped_dir1/dir_b
21618         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21619                 error "create striped dir under striped dir fails"
21620
21621         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21622                 error "rename dir under different striped dir should fail"
21623
21624         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21625                 error "rename striped dir under diff striped dir should fail"
21626
21627         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21628                 error "rename file under diff striped dirs fails"
21629
21630         rm -rf $DIR/$tdir
21631 }
21632 run_test 300f "check rename cross striped directory"
21633
21634 test_300_check_default_striped_dir()
21635 {
21636         local dirname=$1
21637         local default_count=$2
21638         local default_index=$3
21639         local stripe_count
21640         local stripe_index
21641         local dir_stripe_index
21642         local dir
21643
21644         echo "checking $dirname $default_count $default_index"
21645         $LFS setdirstripe -D -c $default_count -i $default_index \
21646                                 -t all_char $DIR/$tdir/$dirname ||
21647                 error "set default stripe on striped dir error"
21648         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21649         [ $stripe_count -eq $default_count ] ||
21650                 error "expect $default_count get $stripe_count for $dirname"
21651
21652         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21653         [ $stripe_index -eq $default_index ] ||
21654                 error "expect $default_index get $stripe_index for $dirname"
21655
21656         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21657                                                 error "create dirs failed"
21658
21659         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21660         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21661         for dir in $(find $DIR/$tdir/$dirname/*); do
21662                 stripe_count=$($LFS getdirstripe -c $dir)
21663                 [ $stripe_count -eq $default_count ] ||
21664                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21665                 error "stripe count $default_count != $stripe_count for $dir"
21666
21667                 stripe_index=$($LFS getdirstripe -i $dir)
21668                 [ $default_index -eq -1 ] ||
21669                         [ $stripe_index -eq $default_index ] ||
21670                         error "$stripe_index != $default_index for $dir"
21671
21672                 #check default stripe
21673                 stripe_count=$($LFS getdirstripe -D -c $dir)
21674                 [ $stripe_count -eq $default_count ] ||
21675                 error "default count $default_count != $stripe_count for $dir"
21676
21677                 stripe_index=$($LFS getdirstripe -D -i $dir)
21678                 [ $stripe_index -eq $default_index ] ||
21679                 error "default index $default_index != $stripe_index for $dir"
21680         done
21681         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21682 }
21683
21684 test_300g() {
21685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21686         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21687                 skip "Need MDS version at least 2.7.55"
21688
21689         local dir
21690         local stripe_count
21691         local stripe_index
21692
21693         mkdir $DIR/$tdir
21694         mkdir $DIR/$tdir/normal_dir
21695
21696         #Checking when client cache stripe index
21697         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21698         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21699                 error "create striped_dir failed"
21700
21701         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21702                 error "create dir0 fails"
21703         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21704         [ $stripe_index -eq 0 ] ||
21705                 error "dir0 expect index 0 got $stripe_index"
21706
21707         mkdir $DIR/$tdir/striped_dir/dir1 ||
21708                 error "create dir1 fails"
21709         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21710         [ $stripe_index -eq 1 ] ||
21711                 error "dir1 expect index 1 got $stripe_index"
21712
21713         #check default stripe count/stripe index
21714         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21715         test_300_check_default_striped_dir normal_dir 1 0
21716         test_300_check_default_striped_dir normal_dir 2 1
21717         test_300_check_default_striped_dir normal_dir 2 -1
21718
21719         #delete default stripe information
21720         echo "delete default stripeEA"
21721         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21722                 error "set default stripe on striped dir error"
21723
21724         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21725         for dir in $(find $DIR/$tdir/normal_dir/*); do
21726                 stripe_count=$($LFS getdirstripe -c $dir)
21727                 [ $stripe_count -eq 0 ] ||
21728                         error "expect 1 get $stripe_count for $dir"
21729                 stripe_index=$($LFS getdirstripe -i $dir)
21730                 [ $stripe_index -eq 0 ] ||
21731                         error "expect 0 get $stripe_index for $dir"
21732         done
21733 }
21734 run_test 300g "check default striped directory for normal directory"
21735
21736 test_300h() {
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 dir
21742         local stripe_count
21743
21744         mkdir $DIR/$tdir
21745         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21746                 error "set striped dir error"
21747
21748         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21749         test_300_check_default_striped_dir striped_dir 1 0
21750         test_300_check_default_striped_dir striped_dir 2 1
21751         test_300_check_default_striped_dir striped_dir 2 -1
21752
21753         #delete default stripe information
21754         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21755                 error "set default stripe on striped dir error"
21756
21757         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21758         for dir in $(find $DIR/$tdir/striped_dir/*); do
21759                 stripe_count=$($LFS getdirstripe -c $dir)
21760                 [ $stripe_count -eq 0 ] ||
21761                         error "expect 1 get $stripe_count for $dir"
21762         done
21763 }
21764 run_test 300h "check default striped directory for striped directory"
21765
21766 test_300i() {
21767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21769         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21770                 skip "Need MDS version at least 2.7.55"
21771
21772         local stripe_count
21773         local file
21774
21775         mkdir $DIR/$tdir
21776
21777         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21778                 error "set striped dir error"
21779
21780         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21781                 error "create files under striped dir failed"
21782
21783         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21784                 error "set striped hashdir error"
21785
21786         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21787                 error "create dir0 under hash dir failed"
21788         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21789                 error "create dir1 under hash dir failed"
21790
21791         # unfortunately, we need to umount to clear dir layout cache for now
21792         # once we fully implement dir layout, we can drop this
21793         umount_client $MOUNT || error "umount failed"
21794         mount_client $MOUNT || error "mount failed"
21795
21796         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21797         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21798         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21799
21800         #set the stripe to be unknown hash type
21801         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21802         $LCTL set_param fail_loc=0x1901
21803         for ((i = 0; i < 10; i++)); do
21804                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21805                         error "stat f-$i failed"
21806                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21807         done
21808
21809         touch $DIR/$tdir/striped_dir/f0 &&
21810                 error "create under striped dir with unknown hash should fail"
21811
21812         $LCTL set_param fail_loc=0
21813
21814         umount_client $MOUNT || error "umount failed"
21815         mount_client $MOUNT || error "mount failed"
21816
21817         return 0
21818 }
21819 run_test 300i "client handle unknown hash type striped directory"
21820
21821 test_300j() {
21822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21824         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21825                 skip "Need MDS version at least 2.7.55"
21826
21827         local stripe_count
21828         local file
21829
21830         mkdir $DIR/$tdir
21831
21832         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21833         $LCTL set_param fail_loc=0x1702
21834         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21835                 error "set striped dir error"
21836
21837         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21838                 error "create files under striped dir failed"
21839
21840         $LCTL set_param fail_loc=0
21841
21842         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21843
21844         return 0
21845 }
21846 run_test 300j "test large update record"
21847
21848 test_300k() {
21849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21851         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21852                 skip "Need MDS version at least 2.7.55"
21853
21854         # this test needs a huge transaction
21855         local kb
21856         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21857              osd*.$FSNAME-MDT0000.kbytestotal")
21858         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21859
21860         local stripe_count
21861         local file
21862
21863         mkdir $DIR/$tdir
21864
21865         #define OBD_FAIL_LARGE_STRIPE   0x1703
21866         $LCTL set_param fail_loc=0x1703
21867         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21868                 error "set striped dir error"
21869         $LCTL set_param fail_loc=0
21870
21871         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21872                 error "getstripeddir fails"
21873         rm -rf $DIR/$tdir/striped_dir ||
21874                 error "unlink striped dir fails"
21875
21876         return 0
21877 }
21878 run_test 300k "test large striped directory"
21879
21880 test_300l() {
21881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21883         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21884                 skip "Need MDS version at least 2.7.55"
21885
21886         local stripe_index
21887
21888         test_mkdir -p $DIR/$tdir/striped_dir
21889         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21890                         error "chown $RUNAS_ID failed"
21891         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21892                 error "set default striped dir failed"
21893
21894         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21895         $LCTL set_param fail_loc=0x80000158
21896         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21897
21898         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21899         [ $stripe_index -eq 1 ] ||
21900                 error "expect 1 get $stripe_index for $dir"
21901 }
21902 run_test 300l "non-root user to create dir under striped dir with stale layout"
21903
21904 test_300m() {
21905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21906         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21907         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21908                 skip "Need MDS version at least 2.7.55"
21909
21910         mkdir -p $DIR/$tdir/striped_dir
21911         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21912                 error "set default stripes dir error"
21913
21914         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21915
21916         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21917         [ $stripe_count -eq 0 ] ||
21918                         error "expect 0 get $stripe_count for a"
21919
21920         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21921                 error "set default stripes dir error"
21922
21923         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21924
21925         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21926         [ $stripe_count -eq 0 ] ||
21927                         error "expect 0 get $stripe_count for b"
21928
21929         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21930                 error "set default stripes dir error"
21931
21932         mkdir $DIR/$tdir/striped_dir/c &&
21933                 error "default stripe_index is invalid, mkdir c should fails"
21934
21935         rm -rf $DIR/$tdir || error "rmdir fails"
21936 }
21937 run_test 300m "setstriped directory on single MDT FS"
21938
21939 cleanup_300n() {
21940         local list=$(comma_list $(mdts_nodes))
21941
21942         trap 0
21943         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21944 }
21945
21946 test_300n() {
21947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21949         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21950                 skip "Need MDS version at least 2.7.55"
21951         remote_mds_nodsh && skip "remote MDS with nodsh"
21952
21953         local stripe_index
21954         local list=$(comma_list $(mdts_nodes))
21955
21956         trap cleanup_300n RETURN EXIT
21957         mkdir -p $DIR/$tdir
21958         chmod 777 $DIR/$tdir
21959         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21960                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21961                 error "create striped dir succeeds with gid=0"
21962
21963         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21964         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21965                 error "create striped dir fails with gid=-1"
21966
21967         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21968         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21969                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21970                 error "set default striped dir succeeds with gid=0"
21971
21972
21973         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21974         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21975                 error "set default striped dir fails with gid=-1"
21976
21977
21978         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21979         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21980                                         error "create test_dir fails"
21981         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21982                                         error "create test_dir1 fails"
21983         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21984                                         error "create test_dir2 fails"
21985         cleanup_300n
21986 }
21987 run_test 300n "non-root user to create dir under striped dir with default EA"
21988
21989 test_300o() {
21990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21992         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21993                 skip "Need MDS version at least 2.7.55"
21994
21995         local numfree1
21996         local numfree2
21997
21998         mkdir -p $DIR/$tdir
21999
22000         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22001         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22002         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22003                 skip "not enough free inodes $numfree1 $numfree2"
22004         fi
22005
22006         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22007         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22008         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22009                 skip "not enough free space $numfree1 $numfree2"
22010         fi
22011
22012         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22013                 error "setdirstripe fails"
22014
22015         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22016                 error "create dirs fails"
22017
22018         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22019         ls $DIR/$tdir/striped_dir > /dev/null ||
22020                 error "ls striped dir fails"
22021         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22022                 error "unlink big striped dir fails"
22023 }
22024 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22025
22026 test_300p() {
22027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22028         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22029         remote_mds_nodsh && skip "remote MDS with nodsh"
22030
22031         mkdir -p $DIR/$tdir
22032
22033         #define OBD_FAIL_OUT_ENOSPC     0x1704
22034         do_facet mds2 lctl set_param fail_loc=0x80001704
22035         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22036                  && error "create striped directory should fail"
22037
22038         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22039
22040         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22041         true
22042 }
22043 run_test 300p "create striped directory without space"
22044
22045 test_300q() {
22046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22048
22049         local fd=$(free_fd)
22050         local cmd="exec $fd<$tdir"
22051         cd $DIR
22052         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22053         eval $cmd
22054         cmd="exec $fd<&-"
22055         trap "eval $cmd" EXIT
22056         cd $tdir || error "cd $tdir fails"
22057         rmdir  ../$tdir || error "rmdir $tdir fails"
22058         mkdir local_dir && error "create dir succeeds"
22059         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22060         eval $cmd
22061         return 0
22062 }
22063 run_test 300q "create remote directory under orphan directory"
22064
22065 test_300r() {
22066         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22067                 skip "Need MDS version at least 2.7.55" && return
22068         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22069
22070         mkdir $DIR/$tdir
22071
22072         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22073                 error "set striped dir error"
22074
22075         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22076                 error "getstripeddir fails"
22077
22078         local stripe_count
22079         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22080                       awk '/lmv_stripe_count:/ { print $2 }')
22081
22082         [ $MDSCOUNT -ne $stripe_count ] &&
22083                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22084
22085         rm -rf $DIR/$tdir/striped_dir ||
22086                 error "unlink striped dir fails"
22087 }
22088 run_test 300r "test -1 striped directory"
22089
22090 test_300s_helper() {
22091         local count=$1
22092
22093         local stripe_dir=$DIR/$tdir/striped_dir.$count
22094
22095         $LFS mkdir -c $count $stripe_dir ||
22096                 error "lfs mkdir -c error"
22097
22098         $LFS getdirstripe $stripe_dir ||
22099                 error "lfs getdirstripe fails"
22100
22101         local stripe_count
22102         stripe_count=$($LFS getdirstripe $stripe_dir |
22103                       awk '/lmv_stripe_count:/ { print $2 }')
22104
22105         [ $count -ne $stripe_count ] &&
22106                 error_noexit "bad stripe count $stripe_count expected $count"
22107
22108         local dupe_stripes
22109         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22110                 awk '/0x/ {count[$1] += 1}; END {
22111                         for (idx in count) {
22112                                 if (count[idx]>1) {
22113                                         print "index " idx " count " count[idx]
22114                                 }
22115                         }
22116                 }')
22117
22118         if [[ -n "$dupe_stripes" ]] ; then
22119                 lfs getdirstripe $stripe_dir
22120                 error_noexit "Dupe MDT above: $dupe_stripes "
22121         fi
22122
22123         rm -rf $stripe_dir ||
22124                 error_noexit "unlink $stripe_dir fails"
22125 }
22126
22127 test_300s() {
22128         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22129                 skip "Need MDS version at least 2.7.55" && return
22130         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22131
22132         mkdir $DIR/$tdir
22133         for count in $(seq 2 $MDSCOUNT); do
22134                 test_300s_helper $count
22135         done
22136 }
22137 run_test 300s "test lfs mkdir -c without -i"
22138
22139
22140 prepare_remote_file() {
22141         mkdir $DIR/$tdir/src_dir ||
22142                 error "create remote source failed"
22143
22144         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22145                  error "cp to remote source failed"
22146         touch $DIR/$tdir/src_dir/a
22147
22148         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22149                 error "create remote target dir failed"
22150
22151         touch $DIR/$tdir/tgt_dir/b
22152
22153         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22154                 error "rename dir cross MDT failed!"
22155
22156         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22157                 error "src_child still exists after rename"
22158
22159         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22160                 error "missing file(a) after rename"
22161
22162         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22163                 error "diff after rename"
22164 }
22165
22166 test_310a() {
22167         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22169
22170         local remote_file=$DIR/$tdir/tgt_dir/b
22171
22172         mkdir -p $DIR/$tdir
22173
22174         prepare_remote_file || error "prepare remote file failed"
22175
22176         #open-unlink file
22177         $OPENUNLINK $remote_file $remote_file ||
22178                 error "openunlink $remote_file failed"
22179         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22180 }
22181 run_test 310a "open unlink remote file"
22182
22183 test_310b() {
22184         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22186
22187         local remote_file=$DIR/$tdir/tgt_dir/b
22188
22189         mkdir -p $DIR/$tdir
22190
22191         prepare_remote_file || error "prepare remote file failed"
22192
22193         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22194         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22195         $CHECKSTAT -t file $remote_file || error "check file failed"
22196 }
22197 run_test 310b "unlink remote file with multiple links while open"
22198
22199 test_310c() {
22200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22201         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22202
22203         local remote_file=$DIR/$tdir/tgt_dir/b
22204
22205         mkdir -p $DIR/$tdir
22206
22207         prepare_remote_file || error "prepare remote file failed"
22208
22209         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22210         multiop_bg_pause $remote_file O_uc ||
22211                         error "mulitop failed for remote file"
22212         MULTIPID=$!
22213         $MULTIOP $DIR/$tfile Ouc
22214         kill -USR1 $MULTIPID
22215         wait $MULTIPID
22216 }
22217 run_test 310c "open-unlink remote file with multiple links"
22218
22219 #LU-4825
22220 test_311() {
22221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22222         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22223         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22224                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22225         remote_mds_nodsh && skip "remote MDS with nodsh"
22226
22227         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22228         local mdts=$(comma_list $(mdts_nodes))
22229
22230         mkdir -p $DIR/$tdir
22231         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22232         createmany -o $DIR/$tdir/$tfile. 1000
22233
22234         # statfs data is not real time, let's just calculate it
22235         old_iused=$((old_iused + 1000))
22236
22237         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22238                         osp.*OST0000*MDT0000.create_count")
22239         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22240                                 osp.*OST0000*MDT0000.max_create_count")
22241         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22242
22243         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22244         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22245         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22246
22247         unlinkmany $DIR/$tdir/$tfile. 1000
22248
22249         do_nodes $mdts "$LCTL set_param -n \
22250                         osp.*OST0000*.max_create_count=$max_count"
22251         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22252                 do_nodes $mdts "$LCTL set_param -n \
22253                                 osp.*OST0000*.create_count=$count"
22254         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22255                         grep "=0" && error "create_count is zero"
22256
22257         local new_iused
22258         for i in $(seq 120); do
22259                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22260                 # system may be too busy to destroy all objs in time, use
22261                 # a somewhat small value to not fail autotest
22262                 [ $((old_iused - new_iused)) -gt 400 ] && break
22263                 sleep 1
22264         done
22265
22266         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22267         [ $((old_iused - new_iused)) -gt 400 ] ||
22268                 error "objs not destroyed after unlink"
22269 }
22270 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22271
22272 zfs_oid_to_objid()
22273 {
22274         local ost=$1
22275         local objid=$2
22276
22277         local vdevdir=$(dirname $(facet_vdevice $ost))
22278         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22279         local zfs_zapid=$(do_facet $ost $cmd |
22280                           grep -w "/O/0/d$((objid%32))" -C 5 |
22281                           awk '/Object/{getline; print $1}')
22282         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22283                           awk "/$objid = /"'{printf $3}')
22284
22285         echo $zfs_objid
22286 }
22287
22288 zfs_object_blksz() {
22289         local ost=$1
22290         local objid=$2
22291
22292         local vdevdir=$(dirname $(facet_vdevice $ost))
22293         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22294         local blksz=$(do_facet $ost $cmd $objid |
22295                       awk '/dblk/{getline; printf $4}')
22296
22297         case "${blksz: -1}" in
22298                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22299                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22300                 *) ;;
22301         esac
22302
22303         echo $blksz
22304 }
22305
22306 test_312() { # LU-4856
22307         remote_ost_nodsh && skip "remote OST with nodsh"
22308         [ "$ost1_FSTYPE" = "zfs" ] ||
22309                 skip_env "the test only applies to zfs"
22310
22311         local max_blksz=$(do_facet ost1 \
22312                           $ZFS get -p recordsize $(facet_device ost1) |
22313                           awk '!/VALUE/{print $3}')
22314
22315         # to make life a little bit easier
22316         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22317         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22318
22319         local tf=$DIR/$tdir/$tfile
22320         touch $tf
22321         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22322
22323         # Get ZFS object id
22324         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22325         # block size change by sequential overwrite
22326         local bs
22327
22328         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22329                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22330
22331                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22332                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22333         done
22334         rm -f $tf
22335
22336         # block size change by sequential append write
22337         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22338         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22339         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22340         local count
22341
22342         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22343                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22344                         oflag=sync conv=notrunc
22345
22346                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22347                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22348                         error "blksz error, actual $blksz, " \
22349                                 "expected: 2 * $count * $PAGE_SIZE"
22350         done
22351         rm -f $tf
22352
22353         # random write
22354         touch $tf
22355         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22356         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22357
22358         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22359         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22360         [ $blksz -eq $PAGE_SIZE ] ||
22361                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22362
22363         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22364         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22365         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22366
22367         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22368         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22369         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22370 }
22371 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22372
22373 test_313() {
22374         remote_ost_nodsh && skip "remote OST with nodsh"
22375
22376         local file=$DIR/$tfile
22377
22378         rm -f $file
22379         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22380
22381         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22382         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22383         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22384                 error "write should failed"
22385         do_facet ost1 "$LCTL set_param fail_loc=0"
22386         rm -f $file
22387 }
22388 run_test 313 "io should fail after last_rcvd update fail"
22389
22390 test_314() {
22391         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22392
22393         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22394         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22395         rm -f $DIR/$tfile
22396         wait_delete_completed
22397         do_facet ost1 "$LCTL set_param fail_loc=0"
22398 }
22399 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22400
22401 test_315() { # LU-618
22402         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22403
22404         local file=$DIR/$tfile
22405         rm -f $file
22406
22407         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22408                 error "multiop file write failed"
22409         $MULTIOP $file oO_RDONLY:r4063232_c &
22410         PID=$!
22411
22412         sleep 2
22413
22414         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22415         kill -USR1 $PID
22416
22417         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22418         rm -f $file
22419 }
22420 run_test 315 "read should be accounted"
22421
22422 test_316() {
22423         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22424         large_xattr_enabled || skip_env "ea_inode feature disabled"
22425
22426         rm -rf $DIR/$tdir/d
22427         mkdir -p $DIR/$tdir/d
22428         chown nobody $DIR/$tdir/d
22429         touch $DIR/$tdir/d/file
22430
22431         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22432 }
22433 run_test 316 "lfs mv"
22434
22435 test_317() {
22436         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22437                 skip "Need MDS version at least 2.11.53"
22438         if [ "$ost1_FSTYPE" == "zfs" ]; then
22439                 skip "LU-10370: no implementation for ZFS"
22440         fi
22441
22442         local trunc_sz
22443         local grant_blk_size
22444
22445         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22446                         awk '/grant_block_size:/ { print $2; exit; }')
22447         #
22448         # Create File of size 5M. Truncate it to below size's and verify
22449         # blocks count.
22450         #
22451         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22452                 error "Create file $DIR/$tfile failed"
22453         stack_trap "rm -f $DIR/$tfile" EXIT
22454
22455         for trunc_sz in 2097152 4097 4000 509 0; do
22456                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22457                         error "truncate $tfile to $trunc_sz failed"
22458                 local sz=$(stat --format=%s $DIR/$tfile)
22459                 local blk=$(stat --format=%b $DIR/$tfile)
22460                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22461                                      grant_blk_size) * 8))
22462
22463                 if [[ $blk -ne $trunc_blk ]]; then
22464                         $(which stat) $DIR/$tfile
22465                         error "Expected Block $trunc_blk 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         done
22471
22472         #
22473         # sparse file test
22474         # Create file with a hole and write actual two blocks. Block count
22475         # must be 16.
22476         #
22477         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22478                 conv=fsync || error "Create file : $DIR/$tfile"
22479
22480         # Calculate the final truncate size.
22481         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22482
22483         #
22484         # truncate to size $trunc_sz bytes. Strip the last block
22485         # The block count must drop to 8
22486         #
22487         $TRUNCATE $DIR/$tfile $trunc_sz ||
22488                 error "truncate $tfile to $trunc_sz failed"
22489
22490         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22491         sz=$(stat --format=%s $DIR/$tfile)
22492         blk=$(stat --format=%b $DIR/$tfile)
22493
22494         if [[ $blk -ne $trunc_bsz ]]; then
22495                 $(which stat) $DIR/$tfile
22496                 error "Expected Block $trunc_bsz got $blk for $tfile"
22497         fi
22498
22499         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22500                 error "Expected Size $trunc_sz got $sz for $tfile"
22501 }
22502 run_test 317 "Verify blocks get correctly update after truncate"
22503
22504 test_318() {
22505         local old_max_active=$($LCTL get_param -n \
22506                             llite.*.max_read_ahead_async_active 2>/dev/null)
22507
22508         $LCTL set_param llite.*.max_read_ahead_async_active=256
22509         local max_active=$($LCTL get_param -n \
22510                            llite.*.max_read_ahead_async_active 2>/dev/null)
22511         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22512
22513         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22514                 error "set max_read_ahead_async_active should succeed"
22515
22516         $LCTL set_param llite.*.max_read_ahead_async_active=512
22517         max_active=$($LCTL get_param -n \
22518                      llite.*.max_read_ahead_async_active 2>/dev/null)
22519         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22520
22521         # restore @max_active
22522         [ $old_max_active -ne 0 ] && $LCTL set_param \
22523                 llite.*.max_read_ahead_async_active=$old_max_active
22524
22525         local old_threshold=$($LCTL get_param -n \
22526                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22527         local max_per_file_mb=$($LCTL get_param -n \
22528                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22529
22530         local invalid=$(($max_per_file_mb + 1))
22531         $LCTL set_param \
22532                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22533                         && error "set $invalid should fail"
22534
22535         local valid=$(($invalid - 1))
22536         $LCTL set_param \
22537                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22538                         error "set $valid should succeed"
22539         local threshold=$($LCTL get_param -n \
22540                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22541         [ $threshold -eq $valid ] || error \
22542                 "expect threshold $valid got $threshold"
22543         $LCTL set_param \
22544                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22545 }
22546 run_test 318 "Verify async readahead tunables"
22547
22548 test_319() {
22549         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22550
22551         local before=$(date +%s)
22552         local evict
22553         local mdir=$DIR/$tdir
22554         local file=$mdir/xxx
22555
22556         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22557         touch $file
22558
22559 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22560         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22561         $LFS mv -m1 $file &
22562
22563         sleep 1
22564         dd if=$file of=/dev/null
22565         wait
22566         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22567           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22568
22569         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22570 }
22571 run_test 319 "lost lease lock on migrate error"
22572
22573 test_398a() { # LU-4198
22574         local ost1_imp=$(get_osc_import_name client ost1)
22575         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22576                          cut -d'.' -f2)
22577
22578         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22579         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22580
22581         # request a new lock on client
22582         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22583
22584         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22585         local lock_count=$($LCTL get_param -n \
22586                            ldlm.namespaces.$imp_name.lru_size)
22587         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22588
22589         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22590
22591         # no lock cached, should use lockless IO and not enqueue new lock
22592         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22593         lock_count=$($LCTL get_param -n \
22594                      ldlm.namespaces.$imp_name.lru_size)
22595         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22596 }
22597 run_test 398a "direct IO should cancel lock otherwise lockless"
22598
22599 test_398b() { # LU-4198
22600         which fio || skip_env "no fio installed"
22601         $LFS setstripe -c -1 $DIR/$tfile
22602
22603         local size=12
22604         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22605
22606         local njobs=4
22607         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22608         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22609                 --numjobs=$njobs --fallocate=none \
22610                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22611                 --filename=$DIR/$tfile &
22612         bg_pid=$!
22613
22614         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22615         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22616                 --numjobs=$njobs --fallocate=none \
22617                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22618                 --filename=$DIR/$tfile || true
22619         wait $bg_pid
22620
22621         rm -rf $DIR/$tfile
22622 }
22623 run_test 398b "DIO and buffer IO race"
22624
22625 test_398c() { # LU-4198
22626         local ost1_imp=$(get_osc_import_name client ost1)
22627         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22628                          cut -d'.' -f2)
22629
22630         which fio || skip_env "no fio installed"
22631
22632         saved_debug=$($LCTL get_param -n debug)
22633         $LCTL set_param debug=0
22634
22635         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22636         ((size /= 1024)) # by megabytes
22637         ((size /= 2)) # write half of the OST at most
22638         [ $size -gt 40 ] && size=40 #reduce test time anyway
22639
22640         $LFS setstripe -c 1 $DIR/$tfile
22641
22642         # it seems like ldiskfs reserves more space than necessary if the
22643         # writing blocks are not mapped, so it extends the file firstly
22644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22645         cancel_lru_locks osc
22646
22647         # clear and verify rpc_stats later
22648         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22649
22650         local njobs=4
22651         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22652         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22653                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22654                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22655                 --filename=$DIR/$tfile
22656         [ $? -eq 0 ] || error "fio write error"
22657
22658         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
22659                 error "Locks were requested while doing AIO"
22660
22661         # get the percentage of 1-page I/O
22662         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22663                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22664                 awk '{print $7}')
22665         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22666
22667         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22668         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22669                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22670                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22671                 --filename=$DIR/$tfile
22672         [ $? -eq 0 ] || error "fio mixed read write error"
22673
22674         echo "AIO with large block size ${size}M"
22675         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22676                 --numjobs=1 --fallocate=none --ioengine=libaio \
22677                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22678                 --filename=$DIR/$tfile
22679         [ $? -eq 0 ] || error "fio large block size failed"
22680
22681         rm -rf $DIR/$tfile
22682         $LCTL set_param debug="$saved_debug"
22683 }
22684 run_test 398c "run fio to test AIO"
22685
22686 test_398d() { #  LU-13846
22687         test -f aiocp || skip_env "no aiocp installed"
22688         local aio_file=$DIR/aio_file
22689
22690         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22691
22692         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22693         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22694
22695         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22696
22697         # make sure we don't crash and fail properly
22698         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22699                 error "aio not aligned with PAGE SIZE should fail"
22700
22701         rm -rf $DIR/$tfile $aio_file
22702 }
22703 run_test 398d "run aiocp to verify block size > stripe size"
22704
22705 test_398e() {
22706         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22707         touch $DIR/$tfile.new
22708         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22709 }
22710 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22711
22712 test_fake_rw() {
22713         local read_write=$1
22714         if [ "$read_write" = "write" ]; then
22715                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22716         elif [ "$read_write" = "read" ]; then
22717                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22718         else
22719                 error "argument error"
22720         fi
22721
22722         # turn off debug for performance testing
22723         local saved_debug=$($LCTL get_param -n debug)
22724         $LCTL set_param debug=0
22725
22726         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22727
22728         # get ost1 size - $FSNAME-OST0000
22729         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22730         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22731         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22732
22733         if [ "$read_write" = "read" ]; then
22734                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22735         fi
22736
22737         local start_time=$(date +%s.%N)
22738         $dd_cmd bs=1M count=$blocks oflag=sync ||
22739                 error "real dd $read_write error"
22740         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22741
22742         if [ "$read_write" = "write" ]; then
22743                 rm -f $DIR/$tfile
22744         fi
22745
22746         # define OBD_FAIL_OST_FAKE_RW           0x238
22747         do_facet ost1 $LCTL set_param fail_loc=0x238
22748
22749         local start_time=$(date +%s.%N)
22750         $dd_cmd bs=1M count=$blocks oflag=sync ||
22751                 error "fake dd $read_write error"
22752         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22753
22754         if [ "$read_write" = "write" ]; then
22755                 # verify file size
22756                 cancel_lru_locks osc
22757                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22758                         error "$tfile size not $blocks MB"
22759         fi
22760         do_facet ost1 $LCTL set_param fail_loc=0
22761
22762         echo "fake $read_write $duration_fake vs. normal $read_write" \
22763                 "$duration in seconds"
22764         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22765                 error_not_in_vm "fake write is slower"
22766
22767         $LCTL set_param -n debug="$saved_debug"
22768         rm -f $DIR/$tfile
22769 }
22770 test_399a() { # LU-7655 for OST fake write
22771         remote_ost_nodsh && skip "remote OST with nodsh"
22772
22773         test_fake_rw write
22774 }
22775 run_test 399a "fake write should not be slower than normal write"
22776
22777 test_399b() { # LU-8726 for OST fake read
22778         remote_ost_nodsh && skip "remote OST with nodsh"
22779         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22780                 skip_env "ldiskfs only test"
22781         fi
22782
22783         test_fake_rw read
22784 }
22785 run_test 399b "fake read should not be slower than normal read"
22786
22787 test_400a() { # LU-1606, was conf-sanity test_74
22788         if ! which $CC > /dev/null 2>&1; then
22789                 skip_env "$CC is not installed"
22790         fi
22791
22792         local extra_flags=''
22793         local out=$TMP/$tfile
22794         local prefix=/usr/include/lustre
22795         local prog
22796
22797         # Oleg removes c files in his test rig so test if any c files exist
22798         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22799                 skip_env "Needed c test files are missing"
22800
22801         if ! [[ -d $prefix ]]; then
22802                 # Assume we're running in tree and fixup the include path.
22803                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22804                 extra_flags+=" -L$LUSTRE/utils/.lib"
22805         fi
22806
22807         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22808                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22809                         error "client api broken"
22810         done
22811         rm -f $out
22812 }
22813 run_test 400a "Lustre client api program can compile and link"
22814
22815 test_400b() { # LU-1606, LU-5011
22816         local header
22817         local out=$TMP/$tfile
22818         local prefix=/usr/include/linux/lustre
22819
22820         # We use a hard coded prefix so that this test will not fail
22821         # when run in tree. There are headers in lustre/include/lustre/
22822         # that are not packaged (like lustre_idl.h) and have more
22823         # complicated include dependencies (like config.h and lnet/types.h).
22824         # Since this test about correct packaging we just skip them when
22825         # they don't exist (see below) rather than try to fixup cppflags.
22826
22827         if ! which $CC > /dev/null 2>&1; then
22828                 skip_env "$CC is not installed"
22829         fi
22830
22831         for header in $prefix/*.h; do
22832                 if ! [[ -f "$header" ]]; then
22833                         continue
22834                 fi
22835
22836                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22837                         continue # lustre_ioctl.h is internal header
22838                 fi
22839
22840                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22841                         error "cannot compile '$header'"
22842         done
22843         rm -f $out
22844 }
22845 run_test 400b "packaged headers can be compiled"
22846
22847 test_401a() { #LU-7437
22848         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22849         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22850
22851         #count the number of parameters by "list_param -R"
22852         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22853         #count the number of parameters by listing proc files
22854         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22855         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22856         echo "proc_dirs='$proc_dirs'"
22857         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22858         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22859                       sort -u | wc -l)
22860
22861         [ $params -eq $procs ] ||
22862                 error "found $params parameters vs. $procs proc files"
22863
22864         # test the list_param -D option only returns directories
22865         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22866         #count the number of parameters by listing proc directories
22867         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22868                 sort -u | wc -l)
22869
22870         [ $params -eq $procs ] ||
22871                 error "found $params parameters vs. $procs proc files"
22872 }
22873 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22874
22875 test_401b() {
22876         # jobid_var may not allow arbitrary values, so use jobid_name
22877         # if available
22878         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22879                 local testname=jobid_name tmp='testing%p'
22880         else
22881                 local testname=jobid_var tmp=testing
22882         fi
22883
22884         local save=$($LCTL get_param -n $testname)
22885
22886         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22887                 error "no error returned when setting bad parameters"
22888
22889         local jobid_new=$($LCTL get_param -n foe $testname baz)
22890         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22891
22892         $LCTL set_param -n fog=bam $testname=$save bat=fog
22893         local jobid_old=$($LCTL get_param -n foe $testname bag)
22894         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22895 }
22896 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22897
22898 test_401c() {
22899         # jobid_var may not allow arbitrary values, so use jobid_name
22900         # if available
22901         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22902                 local testname=jobid_name
22903         else
22904                 local testname=jobid_var
22905         fi
22906
22907         local jobid_var_old=$($LCTL get_param -n $testname)
22908         local jobid_var_new
22909
22910         $LCTL set_param $testname= &&
22911                 error "no error returned for 'set_param a='"
22912
22913         jobid_var_new=$($LCTL get_param -n $testname)
22914         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22915                 error "$testname was changed by setting without value"
22916
22917         $LCTL set_param $testname &&
22918                 error "no error returned for 'set_param a'"
22919
22920         jobid_var_new=$($LCTL get_param -n $testname)
22921         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22922                 error "$testname was changed by setting without value"
22923 }
22924 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22925
22926 test_401d() {
22927         # jobid_var may not allow arbitrary values, so use jobid_name
22928         # if available
22929         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22930                 local testname=jobid_name new_value='foo=bar%p'
22931         else
22932                 local testname=jobid_var new_valuie=foo=bar
22933         fi
22934
22935         local jobid_var_old=$($LCTL get_param -n $testname)
22936         local jobid_var_new
22937
22938         $LCTL set_param $testname=$new_value ||
22939                 error "'set_param a=b' did not accept a value containing '='"
22940
22941         jobid_var_new=$($LCTL get_param -n $testname)
22942         [[ "$jobid_var_new" == "$new_value" ]] ||
22943                 error "'set_param a=b' failed on a value containing '='"
22944
22945         # Reset the $testname to test the other format
22946         $LCTL set_param $testname=$jobid_var_old
22947         jobid_var_new=$($LCTL get_param -n $testname)
22948         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22949                 error "failed to reset $testname"
22950
22951         $LCTL set_param $testname $new_value ||
22952                 error "'set_param a b' did not accept a value containing '='"
22953
22954         jobid_var_new=$($LCTL get_param -n $testname)
22955         [[ "$jobid_var_new" == "$new_value" ]] ||
22956                 error "'set_param a b' failed on a value containing '='"
22957
22958         $LCTL set_param $testname $jobid_var_old
22959         jobid_var_new=$($LCTL get_param -n $testname)
22960         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22961                 error "failed to reset $testname"
22962 }
22963 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22964
22965 test_402() {
22966         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22967         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22968                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22969         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22970                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22971                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22972         remote_mds_nodsh && skip "remote MDS with nodsh"
22973
22974         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22975 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22976         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22977         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22978                 echo "Touch failed - OK"
22979 }
22980 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22981
22982 test_403() {
22983         local file1=$DIR/$tfile.1
22984         local file2=$DIR/$tfile.2
22985         local tfile=$TMP/$tfile
22986
22987         rm -f $file1 $file2 $tfile
22988
22989         touch $file1
22990         ln $file1 $file2
22991
22992         # 30 sec OBD_TIMEOUT in ll_getattr()
22993         # right before populating st_nlink
22994         $LCTL set_param fail_loc=0x80001409
22995         stat -c %h $file1 > $tfile &
22996
22997         # create an alias, drop all locks and reclaim the dentry
22998         < $file2
22999         cancel_lru_locks mdc
23000         cancel_lru_locks osc
23001         sysctl -w vm.drop_caches=2
23002
23003         wait
23004
23005         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23006
23007         rm -f $tfile $file1 $file2
23008 }
23009 run_test 403 "i_nlink should not drop to zero due to aliasing"
23010
23011 test_404() { # LU-6601
23012         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23013                 skip "Need server version newer than 2.8.52"
23014         remote_mds_nodsh && skip "remote MDS with nodsh"
23015
23016         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23017                 awk '/osp .*-osc-MDT/ { print $4}')
23018
23019         local osp
23020         for osp in $mosps; do
23021                 echo "Deactivate: " $osp
23022                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23023                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23024                         awk -vp=$osp '$4 == p { print $2 }')
23025                 [ $stat = IN ] || {
23026                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23027                         error "deactivate error"
23028                 }
23029                 echo "Activate: " $osp
23030                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23031                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23032                         awk -vp=$osp '$4 == p { print $2 }')
23033                 [ $stat = UP ] || {
23034                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23035                         error "activate error"
23036                 }
23037         done
23038 }
23039 run_test 404 "validate manual {de}activated works properly for OSPs"
23040
23041 test_405() {
23042         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23043         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23044                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23045                         skip "Layout swap lock is not supported"
23046
23047         check_swap_layouts_support
23048         check_swap_layout_no_dom $DIR
23049
23050         test_mkdir $DIR/$tdir
23051         swap_lock_test -d $DIR/$tdir ||
23052                 error "One layout swap locked test failed"
23053 }
23054 run_test 405 "Various layout swap lock tests"
23055
23056 test_406() {
23057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23058         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23059         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23061         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23062                 skip "Need MDS version at least 2.8.50"
23063
23064         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23065         local test_pool=$TESTNAME
23066
23067         pool_add $test_pool || error "pool_add failed"
23068         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23069                 error "pool_add_targets failed"
23070
23071         save_layout_restore_at_exit $MOUNT
23072
23073         # parent set default stripe count only, child will stripe from both
23074         # parent and fs default
23075         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23076                 error "setstripe $MOUNT failed"
23077         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23078         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23079         for i in $(seq 10); do
23080                 local f=$DIR/$tdir/$tfile.$i
23081                 touch $f || error "touch failed"
23082                 local count=$($LFS getstripe -c $f)
23083                 [ $count -eq $OSTCOUNT ] ||
23084                         error "$f stripe count $count != $OSTCOUNT"
23085                 local offset=$($LFS getstripe -i $f)
23086                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23087                 local size=$($LFS getstripe -S $f)
23088                 [ $size -eq $((def_stripe_size * 2)) ] ||
23089                         error "$f stripe size $size != $((def_stripe_size * 2))"
23090                 local pool=$($LFS getstripe -p $f)
23091                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23092         done
23093
23094         # change fs default striping, delete parent default striping, now child
23095         # will stripe from new fs default striping only
23096         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23097                 error "change $MOUNT default stripe failed"
23098         $LFS setstripe -c 0 $DIR/$tdir ||
23099                 error "delete $tdir default stripe failed"
23100         for i in $(seq 11 20); do
23101                 local f=$DIR/$tdir/$tfile.$i
23102                 touch $f || error "touch $f failed"
23103                 local count=$($LFS getstripe -c $f)
23104                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23105                 local offset=$($LFS getstripe -i $f)
23106                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23107                 local size=$($LFS getstripe -S $f)
23108                 [ $size -eq $def_stripe_size ] ||
23109                         error "$f stripe size $size != $def_stripe_size"
23110                 local pool=$($LFS getstripe -p $f)
23111                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23112         done
23113
23114         unlinkmany $DIR/$tdir/$tfile. 1 20
23115
23116         local f=$DIR/$tdir/$tfile
23117         pool_remove_all_targets $test_pool $f
23118         pool_remove $test_pool $f
23119 }
23120 run_test 406 "DNE support fs default striping"
23121
23122 test_407() {
23123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23124         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23125                 skip "Need MDS version at least 2.8.55"
23126         remote_mds_nodsh && skip "remote MDS with nodsh"
23127
23128         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23129                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23130         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23131                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23132         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23133
23134         #define OBD_FAIL_DT_TXN_STOP    0x2019
23135         for idx in $(seq $MDSCOUNT); do
23136                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23137         done
23138         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23139         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23140                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23141         true
23142 }
23143 run_test 407 "transaction fail should cause operation fail"
23144
23145 test_408() {
23146         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23147
23148         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23149         lctl set_param fail_loc=0x8000040a
23150         # let ll_prepare_partial_page() fail
23151         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23152
23153         rm -f $DIR/$tfile
23154
23155         # create at least 100 unused inodes so that
23156         # shrink_icache_memory(0) should not return 0
23157         touch $DIR/$tfile-{0..100}
23158         rm -f $DIR/$tfile-{0..100}
23159         sync
23160
23161         echo 2 > /proc/sys/vm/drop_caches
23162 }
23163 run_test 408 "drop_caches should not hang due to page leaks"
23164
23165 test_409()
23166 {
23167         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23168
23169         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23170         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23171         touch $DIR/$tdir/guard || error "(2) Fail to create"
23172
23173         local PREFIX=$(str_repeat 'A' 128)
23174         echo "Create 1K hard links start at $(date)"
23175         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23176                 error "(3) Fail to hard link"
23177
23178         echo "Links count should be right although linkEA overflow"
23179         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23180         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23181         [ $linkcount -eq 1001 ] ||
23182                 error "(5) Unexpected hard links count: $linkcount"
23183
23184         echo "List all links start at $(date)"
23185         ls -l $DIR/$tdir/foo > /dev/null ||
23186                 error "(6) Fail to list $DIR/$tdir/foo"
23187
23188         echo "Unlink hard links start at $(date)"
23189         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23190                 error "(7) Fail to unlink"
23191         echo "Unlink hard links finished at $(date)"
23192 }
23193 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23194
23195 test_410()
23196 {
23197         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23198                 skip "Need client version at least 2.9.59"
23199         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23200                 skip "Need MODULES build"
23201
23202         # Create a file, and stat it from the kernel
23203         local testfile=$DIR/$tfile
23204         touch $testfile
23205
23206         local run_id=$RANDOM
23207         local my_ino=$(stat --format "%i" $testfile)
23208
23209         # Try to insert the module. This will always fail as the
23210         # module is designed to not be inserted.
23211         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23212             &> /dev/null
23213
23214         # Anything but success is a test failure
23215         dmesg | grep -q \
23216             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23217             error "no inode match"
23218 }
23219 run_test 410 "Test inode number returned from kernel thread"
23220
23221 cleanup_test411_cgroup() {
23222         trap 0
23223         rmdir "$1"
23224 }
23225
23226 test_411() {
23227         local cg_basedir=/sys/fs/cgroup/memory
23228         # LU-9966
23229         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23230                 skip "no setup for cgroup"
23231
23232         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23233                 error "test file creation failed"
23234         cancel_lru_locks osc
23235
23236         # Create a very small memory cgroup to force a slab allocation error
23237         local cgdir=$cg_basedir/osc_slab_alloc
23238         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23239         trap "cleanup_test411_cgroup $cgdir" EXIT
23240         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23241         echo 1M > $cgdir/memory.limit_in_bytes
23242
23243         # Should not LBUG, just be killed by oom-killer
23244         # dd will return 0 even allocation failure in some environment.
23245         # So don't check return value
23246         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23247         cleanup_test411_cgroup $cgdir
23248
23249         return 0
23250 }
23251 run_test 411 "Slab allocation error with cgroup does not LBUG"
23252
23253 test_412() {
23254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23255         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23256                 skip "Need server version at least 2.10.55"
23257         fi
23258
23259         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23260                 error "mkdir failed"
23261         $LFS getdirstripe $DIR/$tdir
23262         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23263         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23264                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23265         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23266         [ $stripe_count -eq 2 ] ||
23267                 error "expect 2 get $stripe_count"
23268 }
23269 run_test 412 "mkdir on specific MDTs"
23270
23271 test_qos_mkdir() {
23272         local mkdir_cmd=$1
23273         local stripe_count=$2
23274         local mdts=$(comma_list $(mdts_nodes))
23275
23276         local testdir
23277         local lmv_qos_prio_free
23278         local lmv_qos_threshold_rr
23279         local lmv_qos_maxage
23280         local lod_qos_prio_free
23281         local lod_qos_threshold_rr
23282         local lod_qos_maxage
23283         local count
23284         local i
23285
23286         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23287         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23288         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23289                 head -n1)
23290         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23291         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23292         stack_trap "$LCTL set_param \
23293                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23294         stack_trap "$LCTL set_param \
23295                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23296         stack_trap "$LCTL set_param \
23297                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23298
23299         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23300                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23301         lod_qos_prio_free=${lod_qos_prio_free%%%}
23302         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23303                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23304         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23305         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23306                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23307         stack_trap "do_nodes $mdts $LCTL set_param \
23308                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23309         stack_trap "do_nodes $mdts $LCTL set_param \
23310                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23311                 EXIT
23312         stack_trap "do_nodes $mdts $LCTL set_param \
23313                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23314
23315         echo
23316         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23317
23318         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23319         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23320
23321         testdir=$DIR/$tdir-s$stripe_count/rr
23322
23323         for i in $(seq $((100 * MDSCOUNT))); do
23324                 eval $mkdir_cmd $testdir/subdir$i ||
23325                         error "$mkdir_cmd subdir$i failed"
23326         done
23327
23328         for i in $(seq $MDSCOUNT); do
23329                 count=$($LFS getdirstripe -i $testdir/* |
23330                                 grep ^$((i - 1))$ | wc -l)
23331                 echo "$count directories created on MDT$((i - 1))"
23332                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23333
23334                 if [ $stripe_count -gt 1 ]; then
23335                         count=$($LFS getdirstripe $testdir/* |
23336                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23337                         echo "$count stripes created on MDT$((i - 1))"
23338                         # deviation should < 5% of average
23339                         [ $count -lt $((95 * stripe_count)) ] ||
23340                         [ $count -gt $((105 * stripe_count)) ] &&
23341                                 error "stripes are not evenly distributed"
23342                 fi
23343         done
23344
23345         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23346         do_nodes $mdts $LCTL set_param \
23347                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23348
23349         echo
23350         echo "Check for uneven MDTs: "
23351
23352         local ffree
23353         local bavail
23354         local max
23355         local min
23356         local max_index
23357         local min_index
23358         local tmp
23359
23360         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23361         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23362         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23363
23364         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23365         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23366         max_index=0
23367         min_index=0
23368         for ((i = 1; i < ${#ffree[@]}; i++)); do
23369                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23370                 if [ $tmp -gt $max ]; then
23371                         max=$tmp
23372                         max_index=$i
23373                 fi
23374                 if [ $tmp -lt $min ]; then
23375                         min=$tmp
23376                         min_index=$i
23377                 fi
23378         done
23379
23380         [ ${ffree[min_index]} -eq 0 ] &&
23381                 skip "no free files in MDT$min_index"
23382         [ ${ffree[min_index]} -gt 100000000 ] &&
23383                 skip "too much free files in MDT$min_index"
23384
23385         # Check if we need to generate uneven MDTs
23386         local threshold=50
23387         local diff=$(((max - min) * 100 / min))
23388         local value="$(generate_string 1024)"
23389
23390         while [ $diff -lt $threshold ]; do
23391                 # generate uneven MDTs, create till $threshold% diff
23392                 echo -n "weight diff=$diff% must be > $threshold% ..."
23393                 count=$((${ffree[min_index]} / 10))
23394                 # 50 sec per 10000 files in vm
23395                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23396                         skip "$count files to create"
23397                 echo "Fill MDT$min_index with $count files"
23398                 [ -d $DIR/$tdir-MDT$min_index ] ||
23399                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23400                         error "mkdir $tdir-MDT$min_index failed"
23401                 for i in $(seq $count); do
23402                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23403                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23404                                 error "create f$j_$i failed"
23405                         setfattr -n user.413b -v $value \
23406                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23407                                 error "setfattr f$j_$i failed"
23408                 done
23409
23410                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23411                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23412                 max=$(((${ffree[max_index]} >> 8) * \
23413                         (${bavail[max_index]} * bsize >> 16)))
23414                 min=$(((${ffree[min_index]} >> 8) * \
23415                         (${bavail[min_index]} * bsize >> 16)))
23416                 diff=$(((max - min) * 100 / min))
23417         done
23418
23419         echo "MDT filesfree available: ${ffree[@]}"
23420         echo "MDT blocks available: ${bavail[@]}"
23421         echo "weight diff=$diff%"
23422
23423         echo
23424         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23425
23426         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23427         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23428         # decrease statfs age, so that it can be updated in time
23429         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23430         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23431
23432         sleep 1
23433
23434         testdir=$DIR/$tdir-s$stripe_count/qos
23435
23436         for i in $(seq $((100 * MDSCOUNT))); do
23437                 eval $mkdir_cmd $testdir/subdir$i ||
23438                         error "$mkdir_cmd subdir$i failed"
23439         done
23440
23441         for i in $(seq $MDSCOUNT); do
23442                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23443                         wc -l)
23444                 echo "$count directories created on MDT$((i - 1))"
23445
23446                 if [ $stripe_count -gt 1 ]; then
23447                         count=$($LFS getdirstripe $testdir/* |
23448                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23449                         echo "$count stripes created on MDT$((i - 1))"
23450                 fi
23451         done
23452
23453         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23454         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23455
23456         # D-value should > 10% of averge
23457         [ $((max - min)) -lt 10 ] &&
23458                 error "subdirs shouldn't be evenly distributed"
23459
23460         # ditto
23461         if [ $stripe_count -gt 1 ]; then
23462                 max=$($LFS getdirstripe $testdir/* |
23463                         grep -P "^\s+$max_index\t" | wc -l)
23464                 min=$($LFS getdirstripe $testdir/* |
23465                         grep -P "^\s+$min_index\t" | wc -l)
23466                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23467                         error "stripes shouldn't be evenly distributed"|| true
23468         fi
23469 }
23470
23471 test_413a() {
23472         [ $MDSCOUNT -lt 2 ] &&
23473                 skip "We need at least 2 MDTs for this test"
23474
23475         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23476                 skip "Need server version at least 2.12.52"
23477
23478         local stripe_count
23479
23480         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23481                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23482                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23483                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23484                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23485         done
23486 }
23487 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23488
23489 test_413b() {
23490         [ $MDSCOUNT -lt 2 ] &&
23491                 skip "We need at least 2 MDTs for this test"
23492
23493         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23494                 skip "Need server version at least 2.12.52"
23495
23496         local stripe_count
23497
23498         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23499                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23500                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23501                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23502                 $LFS setdirstripe -D -c $stripe_count \
23503                         $DIR/$tdir-s$stripe_count/rr ||
23504                         error "setdirstripe failed"
23505                 $LFS setdirstripe -D -c $stripe_count \
23506                         $DIR/$tdir-s$stripe_count/qos ||
23507                         error "setdirstripe failed"
23508                 test_qos_mkdir "mkdir" $stripe_count
23509         done
23510 }
23511 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23512
23513 test_414() {
23514 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23515         $LCTL set_param fail_loc=0x80000521
23516         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23517         rm -f $DIR/$tfile
23518 }
23519 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23520
23521 test_415() {
23522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23523         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23524                 skip "Need server version at least 2.11.52"
23525
23526         # LU-11102
23527         local total
23528         local setattr_pid
23529         local start_time
23530         local end_time
23531         local duration
23532
23533         total=500
23534         # this test may be slow on ZFS
23535         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23536
23537         # though this test is designed for striped directory, let's test normal
23538         # directory too since lock is always saved as CoS lock.
23539         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23540         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23541
23542         (
23543                 while true; do
23544                         touch $DIR/$tdir
23545                 done
23546         ) &
23547         setattr_pid=$!
23548
23549         start_time=$(date +%s)
23550         for i in $(seq $total); do
23551                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23552                         > /dev/null
23553         done
23554         end_time=$(date +%s)
23555         duration=$((end_time - start_time))
23556
23557         kill -9 $setattr_pid
23558
23559         echo "rename $total files took $duration sec"
23560         [ $duration -lt 100 ] || error "rename took $duration sec"
23561 }
23562 run_test 415 "lock revoke is not missing"
23563
23564 test_416() {
23565         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23566                 skip "Need server version at least 2.11.55"
23567
23568         # define OBD_FAIL_OSD_TXN_START    0x19a
23569         do_facet mds1 lctl set_param fail_loc=0x19a
23570
23571         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23572
23573         true
23574 }
23575 run_test 416 "transaction start failure won't cause system hung"
23576
23577 cleanup_417() {
23578         trap 0
23579         do_nodes $(comma_list $(mdts_nodes)) \
23580                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23581         do_nodes $(comma_list $(mdts_nodes)) \
23582                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23583         do_nodes $(comma_list $(mdts_nodes)) \
23584                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23585 }
23586
23587 test_417() {
23588         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23589         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23590                 skip "Need MDS version at least 2.11.56"
23591
23592         trap cleanup_417 RETURN EXIT
23593
23594         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23595         do_nodes $(comma_list $(mdts_nodes)) \
23596                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23597         $LFS migrate -m 0 $DIR/$tdir.1 &&
23598                 error "migrate dir $tdir.1 should fail"
23599
23600         do_nodes $(comma_list $(mdts_nodes)) \
23601                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23602         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23603                 error "create remote dir $tdir.2 should fail"
23604
23605         do_nodes $(comma_list $(mdts_nodes)) \
23606                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23607         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23608                 error "create striped dir $tdir.3 should fail"
23609         true
23610 }
23611 run_test 417 "disable remote dir, striped dir and dir migration"
23612
23613 # Checks that the outputs of df [-i] and lfs df [-i] match
23614 #
23615 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23616 check_lfs_df() {
23617         local dir=$2
23618         local inodes
23619         local df_out
23620         local lfs_df_out
23621         local count
23622         local passed=false
23623
23624         # blocks or inodes
23625         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23626
23627         for count in {1..100}; do
23628                 cancel_lru_locks
23629                 sync; sleep 0.2
23630
23631                 # read the lines of interest
23632                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23633                         error "df $inodes $dir | tail -n +2 failed"
23634                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23635                         error "lfs df $inodes $dir | grep summary: failed"
23636
23637                 # skip first substrings of each output as they are different
23638                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23639                 # compare the two outputs
23640                 passed=true
23641                 for i in {1..5}; do
23642                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23643                 done
23644                 $passed && break
23645         done
23646
23647         if ! $passed; then
23648                 df -P $inodes $dir
23649                 echo
23650                 lfs df $inodes $dir
23651                 error "df and lfs df $1 output mismatch: "      \
23652                       "df ${inodes}: ${df_out[*]}, "            \
23653                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23654         fi
23655 }
23656
23657 test_418() {
23658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23659
23660         local dir=$DIR/$tdir
23661         local numfiles=$((RANDOM % 4096 + 2))
23662         local numblocks=$((RANDOM % 256 + 1))
23663
23664         wait_delete_completed
23665         test_mkdir $dir
23666
23667         # check block output
23668         check_lfs_df blocks $dir
23669         # check inode output
23670         check_lfs_df inodes $dir
23671
23672         # create a single file and retest
23673         echo "Creating a single file and testing"
23674         createmany -o $dir/$tfile- 1 &>/dev/null ||
23675                 error "creating 1 file in $dir failed"
23676         check_lfs_df blocks $dir
23677         check_lfs_df inodes $dir
23678
23679         # create a random number of files
23680         echo "Creating $((numfiles - 1)) files and testing"
23681         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23682                 error "creating $((numfiles - 1)) files in $dir failed"
23683
23684         # write a random number of blocks to the first test file
23685         echo "Writing $numblocks 4K blocks and testing"
23686         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23687                 count=$numblocks &>/dev/null ||
23688                 error "dd to $dir/${tfile}-0 failed"
23689
23690         # retest
23691         check_lfs_df blocks $dir
23692         check_lfs_df inodes $dir
23693
23694         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23695                 error "unlinking $numfiles files in $dir failed"
23696 }
23697 run_test 418 "df and lfs df outputs match"
23698
23699 test_419()
23700 {
23701         local dir=$DIR/$tdir
23702
23703         mkdir -p $dir
23704         touch $dir/file
23705
23706         cancel_lru_locks mdc
23707
23708         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23709         $LCTL set_param fail_loc=0x1410
23710         cat $dir/file
23711         $LCTL set_param fail_loc=0
23712         rm -rf $dir
23713 }
23714 run_test 419 "Verify open file by name doesn't crash kernel"
23715
23716 test_420()
23717 {
23718         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23719                 skip "Need MDS version at least 2.12.53"
23720
23721         local SAVE_UMASK=$(umask)
23722         local dir=$DIR/$tdir
23723         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23724
23725         mkdir -p $dir
23726         umask 0000
23727         mkdir -m03777 $dir/testdir
23728         ls -dn $dir/testdir
23729         # Need to remove trailing '.' when SELinux is enabled
23730         local dirperms=$(ls -dn $dir/testdir |
23731                          awk '{ sub(/\.$/, "", $1); print $1}')
23732         [ $dirperms == "drwxrwsrwt" ] ||
23733                 error "incorrect perms on $dir/testdir"
23734
23735         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23736                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23737         ls -n $dir/testdir/testfile
23738         local fileperms=$(ls -n $dir/testdir/testfile |
23739                           awk '{ sub(/\.$/, "", $1); print $1}')
23740         [ $fileperms == "-rwxr-xr-x" ] ||
23741                 error "incorrect perms on $dir/testdir/testfile"
23742
23743         umask $SAVE_UMASK
23744 }
23745 run_test 420 "clear SGID bit on non-directories for non-members"
23746
23747 test_421a() {
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         cnt=$(ls -1 $DIR/$tdir | wc -l)
23758         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23759
23760         fid1=$(lfs path2fid $DIR/$tdir/f1)
23761         fid2=$(lfs path2fid $DIR/$tdir/f2)
23762         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23763
23764         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23765         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23766
23767         cnt=$(ls -1 $DIR/$tdir | wc -l)
23768         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23769
23770         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23771         createmany -o $DIR/$tdir/f 3
23772         cnt=$(ls -1 $DIR/$tdir | wc -l)
23773         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23774
23775         fid1=$(lfs path2fid $DIR/$tdir/f1)
23776         fid2=$(lfs path2fid $DIR/$tdir/f2)
23777         echo "remove using fsname $FSNAME"
23778         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23779
23780         cnt=$(ls -1 $DIR/$tdir | wc -l)
23781         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23782 }
23783 run_test 421a "simple rm by fid"
23784
23785 test_421b() {
23786         local cnt
23787         local FID1
23788         local FID2
23789
23790         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23791                 skip "Need MDS version at least 2.12.54"
23792
23793         test_mkdir $DIR/$tdir
23794         createmany -o $DIR/$tdir/f 3
23795         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23796         MULTIPID=$!
23797
23798         FID1=$(lfs path2fid $DIR/$tdir/f1)
23799         FID2=$(lfs path2fid $DIR/$tdir/f2)
23800         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23801
23802         kill -USR1 $MULTIPID
23803         wait
23804
23805         cnt=$(ls $DIR/$tdir | wc -l)
23806         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23807 }
23808 run_test 421b "rm by fid on open file"
23809
23810 test_421c() {
23811         local cnt
23812         local FIDS
23813
23814         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23815                 skip "Need MDS version at least 2.12.54"
23816
23817         test_mkdir $DIR/$tdir
23818         createmany -o $DIR/$tdir/f 3
23819         touch $DIR/$tdir/$tfile
23820         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23821         cnt=$(ls -1 $DIR/$tdir | wc -l)
23822         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23823
23824         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23825         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23826
23827         cnt=$(ls $DIR/$tdir | wc -l)
23828         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23829 }
23830 run_test 421c "rm by fid against hardlinked files"
23831
23832 test_421d() {
23833         local cnt
23834         local FIDS
23835
23836         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23837                 skip "Need MDS version at least 2.12.54"
23838
23839         test_mkdir $DIR/$tdir
23840         createmany -o $DIR/$tdir/f 4097
23841         cnt=$(ls -1 $DIR/$tdir | wc -l)
23842         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23843
23844         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23845         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23846
23847         cnt=$(ls $DIR/$tdir | wc -l)
23848         rm -rf $DIR/$tdir
23849         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23850 }
23851 run_test 421d "rmfid en masse"
23852
23853 test_421e() {
23854         local cnt
23855         local FID
23856
23857         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23858         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23859                 skip "Need MDS version at least 2.12.54"
23860
23861         mkdir -p $DIR/$tdir
23862         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23863         createmany -o $DIR/$tdir/striped_dir/f 512
23864         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23865         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23866
23867         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23868                 sed "s/[/][^:]*://g")
23869         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23870
23871         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23872         rm -rf $DIR/$tdir
23873         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23874 }
23875 run_test 421e "rmfid in DNE"
23876
23877 test_421f() {
23878         local cnt
23879         local FID
23880
23881         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23882                 skip "Need MDS version at least 2.12.54"
23883
23884         test_mkdir $DIR/$tdir
23885         touch $DIR/$tdir/f
23886         cnt=$(ls -1 $DIR/$tdir | wc -l)
23887         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23888
23889         FID=$(lfs path2fid $DIR/$tdir/f)
23890         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23891         # rmfid should fail
23892         cnt=$(ls -1 $DIR/$tdir | wc -l)
23893         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23894
23895         chmod a+rw $DIR/$tdir
23896         ls -la $DIR/$tdir
23897         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23898         # rmfid should fail
23899         cnt=$(ls -1 $DIR/$tdir | wc -l)
23900         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23901
23902         rm -f $DIR/$tdir/f
23903         $RUNAS touch $DIR/$tdir/f
23904         FID=$(lfs path2fid $DIR/$tdir/f)
23905         echo "rmfid as root"
23906         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23907         cnt=$(ls -1 $DIR/$tdir | wc -l)
23908         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23909
23910         rm -f $DIR/$tdir/f
23911         $RUNAS touch $DIR/$tdir/f
23912         cnt=$(ls -1 $DIR/$tdir | wc -l)
23913         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23914         FID=$(lfs path2fid $DIR/$tdir/f)
23915         # rmfid w/o user_fid2path mount option should fail
23916         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23917         cnt=$(ls -1 $DIR/$tdir | wc -l)
23918         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23919
23920         umount_client $MOUNT || error "failed to umount client"
23921         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23922                 error "failed to mount client'"
23923
23924         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23925         # rmfid should succeed
23926         cnt=$(ls -1 $DIR/$tdir | wc -l)
23927         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23928
23929         # rmfid shouldn't allow to remove files due to dir's permission
23930         chmod a+rwx $DIR/$tdir
23931         touch $DIR/$tdir/f
23932         ls -la $DIR/$tdir
23933         FID=$(lfs path2fid $DIR/$tdir/f)
23934         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23935
23936         umount_client $MOUNT || error "failed to umount client"
23937         mount_client $MOUNT "$MOUNT_OPTS" ||
23938                 error "failed to mount client'"
23939
23940 }
23941 run_test 421f "rmfid checks permissions"
23942
23943 test_421g() {
23944         local cnt
23945         local FIDS
23946
23947         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23948         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23949                 skip "Need MDS version at least 2.12.54"
23950
23951         mkdir -p $DIR/$tdir
23952         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23953         createmany -o $DIR/$tdir/striped_dir/f 512
23954         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23955         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23956
23957         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23958                 sed "s/[/][^:]*://g")
23959
23960         rm -f $DIR/$tdir/striped_dir/f1*
23961         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23962         removed=$((512 - cnt))
23963
23964         # few files have been just removed, so we expect
23965         # rmfid to fail on their fids
23966         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23967         [ $removed != $errors ] && error "$errors != $removed"
23968
23969         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23970         rm -rf $DIR/$tdir
23971         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23972 }
23973 run_test 421g "rmfid to return errors properly"
23974
23975 test_422() {
23976         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23977         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23978         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23979         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23980         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23981
23982         local amc=$(at_max_get client)
23983         local amo=$(at_max_get mds1)
23984         local timeout=`lctl get_param -n timeout`
23985
23986         at_max_set 0 client
23987         at_max_set 0 mds1
23988
23989 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23990         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23991                         fail_val=$(((2*timeout + 10)*1000))
23992         touch $DIR/$tdir/d3/file &
23993         sleep 2
23994 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23995         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23996                         fail_val=$((2*timeout + 5))
23997         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23998         local pid=$!
23999         sleep 1
24000         kill -9 $pid
24001         sleep $((2 * timeout))
24002         echo kill $pid
24003         kill -9 $pid
24004         lctl mark touch
24005         touch $DIR/$tdir/d2/file3
24006         touch $DIR/$tdir/d2/file4
24007         touch $DIR/$tdir/d2/file5
24008
24009         wait
24010         at_max_set $amc client
24011         at_max_set $amo mds1
24012
24013         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24014         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24015                 error "Watchdog is always throttled"
24016 }
24017 run_test 422 "kill a process with RPC in progress"
24018
24019 stat_test() {
24020     df -h $MOUNT &
24021     df -h $MOUNT &
24022     df -h $MOUNT &
24023     df -h $MOUNT &
24024     df -h $MOUNT &
24025     df -h $MOUNT &
24026 }
24027
24028 test_423() {
24029     local _stats
24030     # ensure statfs cache is expired
24031     sleep 2;
24032
24033     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24034     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24035
24036     return 0
24037 }
24038 run_test 423 "statfs should return a right data"
24039
24040 test_424() {
24041 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24042         $LCTL set_param fail_loc=0x80000522
24043         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24044         rm -f $DIR/$tfile
24045 }
24046 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24047
24048 test_425() {
24049         test_mkdir -c -1 $DIR/$tdir
24050         $LFS setstripe -c -1 $DIR/$tdir
24051
24052         lru_resize_disable "" 100
24053         stack_trap "lru_resize_enable" EXIT
24054
24055         sleep 5
24056
24057         for i in $(seq $((MDSCOUNT * 125))); do
24058                 local t=$DIR/$tdir/$tfile_$i
24059
24060                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24061                         error_noexit "Create file $t"
24062         done
24063         stack_trap "rm -rf $DIR/$tdir" EXIT
24064
24065         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24066                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24067                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24068
24069                 [ $lock_count -le $lru_size ] ||
24070                         error "osc lock count $lock_count > lru size $lru_size"
24071         done
24072
24073         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24074                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24075                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24076
24077                 [ $lock_count -le $lru_size ] ||
24078                         error "mdc lock count $lock_count > lru size $lru_size"
24079         done
24080 }
24081 run_test 425 "lock count should not exceed lru size"
24082
24083 test_426() {
24084         splice-test -r $DIR/$tfile
24085         splice-test -rd $DIR/$tfile
24086         splice-test $DIR/$tfile
24087         splice-test -d $DIR/$tfile
24088 }
24089 run_test 426 "splice test on Lustre"
24090
24091 test_427() {
24092         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24093         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24094                 skip "Need MDS version at least 2.12.4"
24095         local log
24096
24097         mkdir $DIR/$tdir
24098         mkdir $DIR/$tdir/1
24099         mkdir $DIR/$tdir/2
24100         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24101         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24102
24103         $LFS getdirstripe $DIR/$tdir/1/dir
24104
24105         #first setfattr for creating updatelog
24106         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24107
24108 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24109         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24110         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24111         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24112
24113         sleep 2
24114         fail mds2
24115         wait_recovery_complete mds2 $((2*TIMEOUT))
24116
24117         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24118         echo $log | grep "get update log failed" &&
24119                 error "update log corruption is detected" || true
24120 }
24121 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24122
24123 lseek_test_430() {
24124         local offset
24125         local file=$1
24126
24127         # data at [200K, 400K)
24128         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24129                 error "256K->512K dd fails"
24130         # data at [2M, 3M)
24131         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24132                 error "2M->3M dd fails"
24133         # data at [4M, 5M)
24134         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24135                 error "4M->5M dd fails"
24136         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24137         # start at first component hole #1
24138         printf "Seeking hole from 1000 ... "
24139         offset=$(lseek_test -l 1000 $file)
24140         echo $offset
24141         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24142         printf "Seeking data from 1000 ... "
24143         offset=$(lseek_test -d 1000 $file)
24144         echo $offset
24145         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24146
24147         # start at first component data block
24148         printf "Seeking hole from 300000 ... "
24149         offset=$(lseek_test -l 300000 $file)
24150         echo $offset
24151         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24152         printf "Seeking data from 300000 ... "
24153         offset=$(lseek_test -d 300000 $file)
24154         echo $offset
24155         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24156
24157         # start at the first component but beyond end of object size
24158         printf "Seeking hole from 1000000 ... "
24159         offset=$(lseek_test -l 1000000 $file)
24160         echo $offset
24161         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24162         printf "Seeking data from 1000000 ... "
24163         offset=$(lseek_test -d 1000000 $file)
24164         echo $offset
24165         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24166
24167         # start at second component stripe 2 (empty file)
24168         printf "Seeking hole from 1500000 ... "
24169         offset=$(lseek_test -l 1500000 $file)
24170         echo $offset
24171         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24172         printf "Seeking data from 1500000 ... "
24173         offset=$(lseek_test -d 1500000 $file)
24174         echo $offset
24175         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24176
24177         # start at second component stripe 1 (all data)
24178         printf "Seeking hole from 3000000 ... "
24179         offset=$(lseek_test -l 3000000 $file)
24180         echo $offset
24181         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24182         printf "Seeking data from 3000000 ... "
24183         offset=$(lseek_test -d 3000000 $file)
24184         echo $offset
24185         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24186
24187         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24188                 error "2nd dd fails"
24189         echo "Add data block at 640K...1280K"
24190
24191         # start at before new data block, in hole
24192         printf "Seeking hole from 600000 ... "
24193         offset=$(lseek_test -l 600000 $file)
24194         echo $offset
24195         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24196         printf "Seeking data from 600000 ... "
24197         offset=$(lseek_test -d 600000 $file)
24198         echo $offset
24199         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24200
24201         # start at the first component new data block
24202         printf "Seeking hole from 1000000 ... "
24203         offset=$(lseek_test -l 1000000 $file)
24204         echo $offset
24205         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24206         printf "Seeking data from 1000000 ... "
24207         offset=$(lseek_test -d 1000000 $file)
24208         echo $offset
24209         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24210
24211         # start at second component stripe 2, new data
24212         printf "Seeking hole from 1200000 ... "
24213         offset=$(lseek_test -l 1200000 $file)
24214         echo $offset
24215         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24216         printf "Seeking data from 1200000 ... "
24217         offset=$(lseek_test -d 1200000 $file)
24218         echo $offset
24219         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24220
24221         # start beyond file end
24222         printf "Using offset > filesize ... "
24223         lseek_test -l 4000000 $file && error "lseek should fail"
24224         printf "Using offset > filesize ... "
24225         lseek_test -d 4000000 $file && error "lseek should fail"
24226
24227         printf "Done\n\n"
24228 }
24229
24230 test_430a() {
24231         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24232                 skip "MDT does not support SEEK_HOLE"
24233
24234         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24235                 skip "OST does not support SEEK_HOLE"
24236
24237         local file=$DIR/$tdir/$tfile
24238
24239         mkdir -p $DIR/$tdir
24240
24241         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24242         # OST stripe #1 will have continuous data at [1M, 3M)
24243         # OST stripe #2 is empty
24244         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24245         lseek_test_430 $file
24246         rm $file
24247         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24248         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24249         lseek_test_430 $file
24250         rm $file
24251         $LFS setstripe -c2 -S 512K $file
24252         echo "Two stripes, stripe size 512K"
24253         lseek_test_430 $file
24254         rm $file
24255         # FLR with stale mirror
24256         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24257                        -N -c2 -S 1M $file
24258         echo "Mirrored file:"
24259         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24260         echo "Plain 2 stripes 1M"
24261         lseek_test_430 $file
24262         rm $file
24263 }
24264 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24265
24266 test_430b() {
24267         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24268                 skip "OST does not support SEEK_HOLE"
24269
24270         local offset
24271         local file=$DIR/$tdir/$tfile
24272
24273         mkdir -p $DIR/$tdir
24274         # Empty layout lseek should fail
24275         $MCREATE $file
24276         # seek from 0
24277         printf "Seeking hole from 0 ... "
24278         lseek_test -l 0 $file && error "lseek should fail"
24279         printf "Seeking data from 0 ... "
24280         lseek_test -d 0 $file && error "lseek should fail"
24281         rm $file
24282
24283         # 1M-hole file
24284         $LFS setstripe -E 1M -c2 -E eof $file
24285         $TRUNCATE $file 1048576
24286         printf "Seeking hole from 1000000 ... "
24287         offset=$(lseek_test -l 1000000 $file)
24288         echo $offset
24289         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24290         printf "Seeking data from 1000000 ... "
24291         lseek_test -d 1000000 $file && error "lseek should fail"
24292         rm $file
24293
24294         # full component followed by non-inited one
24295         $LFS setstripe -E 1M -c2 -E eof $file
24296         dd if=/dev/urandom of=$file bs=1M count=1
24297         printf "Seeking hole from 1000000 ... "
24298         offset=$(lseek_test -l 1000000 $file)
24299         echo $offset
24300         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24301         printf "Seeking hole from 1048576 ... "
24302         lseek_test -l 1048576 $file && error "lseek should fail"
24303         # init second component and truncate back
24304         echo "123" >> $file
24305         $TRUNCATE $file 1048576
24306         printf "Seeking hole from 1000000 ... "
24307         offset=$(lseek_test -l 1000000 $file)
24308         echo $offset
24309         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24310         printf "Seeking hole from 1048576 ... "
24311         lseek_test -l 1048576 $file && error "lseek should fail"
24312         # boundary checks for big values
24313         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24314         offset=$(lseek_test -d 0 $file.10g)
24315         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24316         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24317         offset=$(lseek_test -d 0 $file.100g)
24318         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24319         return 0
24320 }
24321 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24322
24323 test_430c() {
24324         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24325                 skip "OST does not support SEEK_HOLE"
24326
24327         local file=$DIR/$tdir/$tfile
24328         local start
24329
24330         mkdir -p $DIR/$tdir
24331         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24332
24333         # cp version 8.33+ prefers lseek over fiemap
24334         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24335                 start=$SECONDS
24336                 time cp $file /dev/null
24337                 (( SECONDS - start < 5 )) ||
24338                         error "cp: too long runtime $((SECONDS - start))"
24339
24340         fi
24341         # tar version 1.29+ supports SEEK_HOLE/DATA
24342         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24343                 start=$SECONDS
24344                 time tar cS $file - | cat > /dev/null
24345                 (( SECONDS - start < 5 )) ||
24346                         error "tar: too long runtime $((SECONDS - start))"
24347         fi
24348 }
24349 run_test 430c "lseek: external tools check"
24350
24351 test_431() { # LU-14187
24352         local file=$DIR/$tdir/$tfile
24353
24354         mkdir -p $DIR/$tdir
24355         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24356         dd if=/dev/urandom of=$file bs=4k count=1
24357         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24358         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24359         #define OBD_FAIL_OST_RESTART_IO 0x251
24360         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24361         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24362         cp $file $file.0
24363         cancel_lru_locks
24364         sync_all_data
24365         echo 3 > /proc/sys/vm/drop_caches
24366         diff  $file $file.0 || error "data diff"
24367 }
24368 run_test 431 "Restart transaction for IO"
24369
24370 prep_801() {
24371         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24372         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24373                 skip "Need server version at least 2.9.55"
24374
24375         start_full_debug_logging
24376 }
24377
24378 post_801() {
24379         stop_full_debug_logging
24380 }
24381
24382 barrier_stat() {
24383         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24384                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24385                            awk '/The barrier for/ { print $7 }')
24386                 echo $st
24387         else
24388                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24389                 echo \'$st\'
24390         fi
24391 }
24392
24393 barrier_expired() {
24394         local expired
24395
24396         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24397                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24398                           awk '/will be expired/ { print $7 }')
24399         else
24400                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24401         fi
24402
24403         echo $expired
24404 }
24405
24406 test_801a() {
24407         prep_801
24408
24409         echo "Start barrier_freeze at: $(date)"
24410         #define OBD_FAIL_BARRIER_DELAY          0x2202
24411         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24412         # Do not reduce barrier time - See LU-11873
24413         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24414
24415         sleep 2
24416         local b_status=$(barrier_stat)
24417         echo "Got barrier status at: $(date)"
24418         [ "$b_status" = "'freezing_p1'" ] ||
24419                 error "(1) unexpected barrier status $b_status"
24420
24421         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24422         wait
24423         b_status=$(barrier_stat)
24424         [ "$b_status" = "'frozen'" ] ||
24425                 error "(2) unexpected barrier status $b_status"
24426
24427         local expired=$(barrier_expired)
24428         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24429         sleep $((expired + 3))
24430
24431         b_status=$(barrier_stat)
24432         [ "$b_status" = "'expired'" ] ||
24433                 error "(3) unexpected barrier status $b_status"
24434
24435         # Do not reduce barrier time - See LU-11873
24436         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24437                 error "(4) fail to freeze barrier"
24438
24439         b_status=$(barrier_stat)
24440         [ "$b_status" = "'frozen'" ] ||
24441                 error "(5) unexpected barrier status $b_status"
24442
24443         echo "Start barrier_thaw at: $(date)"
24444         #define OBD_FAIL_BARRIER_DELAY          0x2202
24445         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24446         do_facet mgs $LCTL barrier_thaw $FSNAME &
24447
24448         sleep 2
24449         b_status=$(barrier_stat)
24450         echo "Got barrier status at: $(date)"
24451         [ "$b_status" = "'thawing'" ] ||
24452                 error "(6) unexpected barrier status $b_status"
24453
24454         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24455         wait
24456         b_status=$(barrier_stat)
24457         [ "$b_status" = "'thawed'" ] ||
24458                 error "(7) unexpected barrier status $b_status"
24459
24460         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24461         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24462         do_facet mgs $LCTL barrier_freeze $FSNAME
24463
24464         b_status=$(barrier_stat)
24465         [ "$b_status" = "'failed'" ] ||
24466                 error "(8) unexpected barrier status $b_status"
24467
24468         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24469         do_facet mgs $LCTL barrier_thaw $FSNAME
24470
24471         post_801
24472 }
24473 run_test 801a "write barrier user interfaces and stat machine"
24474
24475 test_801b() {
24476         prep_801
24477
24478         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24479         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24480         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24481         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24482         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24483
24484         cancel_lru_locks mdc
24485
24486         # 180 seconds should be long enough
24487         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24488
24489         local b_status=$(barrier_stat)
24490         [ "$b_status" = "'frozen'" ] ||
24491                 error "(6) unexpected barrier status $b_status"
24492
24493         mkdir $DIR/$tdir/d0/d10 &
24494         mkdir_pid=$!
24495
24496         touch $DIR/$tdir/d1/f13 &
24497         touch_pid=$!
24498
24499         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24500         ln_pid=$!
24501
24502         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24503         mv_pid=$!
24504
24505         rm -f $DIR/$tdir/d4/f12 &
24506         rm_pid=$!
24507
24508         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24509
24510         # To guarantee taht the 'stat' is not blocked
24511         b_status=$(barrier_stat)
24512         [ "$b_status" = "'frozen'" ] ||
24513                 error "(8) unexpected barrier status $b_status"
24514
24515         # let above commands to run at background
24516         sleep 5
24517
24518         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24519         ps -p $touch_pid || error "(10) touch should be blocked"
24520         ps -p $ln_pid || error "(11) link should be blocked"
24521         ps -p $mv_pid || error "(12) rename should be blocked"
24522         ps -p $rm_pid || error "(13) unlink should be blocked"
24523
24524         b_status=$(barrier_stat)
24525         [ "$b_status" = "'frozen'" ] ||
24526                 error "(14) unexpected barrier status $b_status"
24527
24528         do_facet mgs $LCTL barrier_thaw $FSNAME
24529         b_status=$(barrier_stat)
24530         [ "$b_status" = "'thawed'" ] ||
24531                 error "(15) unexpected barrier status $b_status"
24532
24533         wait $mkdir_pid || error "(16) mkdir should succeed"
24534         wait $touch_pid || error "(17) touch should succeed"
24535         wait $ln_pid || error "(18) link should succeed"
24536         wait $mv_pid || error "(19) rename should succeed"
24537         wait $rm_pid || error "(20) unlink should succeed"
24538
24539         post_801
24540 }
24541 run_test 801b "modification will be blocked by write barrier"
24542
24543 test_801c() {
24544         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24545
24546         prep_801
24547
24548         stop mds2 || error "(1) Fail to stop mds2"
24549
24550         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24551
24552         local b_status=$(barrier_stat)
24553         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24554                 do_facet mgs $LCTL barrier_thaw $FSNAME
24555                 error "(2) unexpected barrier status $b_status"
24556         }
24557
24558         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24559                 error "(3) Fail to rescan barrier bitmap"
24560
24561         # Do not reduce barrier time - See LU-11873
24562         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24563
24564         b_status=$(barrier_stat)
24565         [ "$b_status" = "'frozen'" ] ||
24566                 error "(4) unexpected barrier status $b_status"
24567
24568         do_facet mgs $LCTL barrier_thaw $FSNAME
24569         b_status=$(barrier_stat)
24570         [ "$b_status" = "'thawed'" ] ||
24571                 error "(5) unexpected barrier status $b_status"
24572
24573         local devname=$(mdsdevname 2)
24574
24575         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24576
24577         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24578                 error "(7) Fail to rescan barrier bitmap"
24579
24580         post_801
24581 }
24582 run_test 801c "rescan barrier bitmap"
24583
24584 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24585 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24586 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24587 saved_MOUNT_OPTS=$MOUNT_OPTS
24588
24589 cleanup_802a() {
24590         trap 0
24591
24592         stopall
24593         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24594         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24595         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24596         MOUNT_OPTS=$saved_MOUNT_OPTS
24597         setupall
24598 }
24599
24600 test_802a() {
24601         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24602         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24603         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24604                 skip "Need server version at least 2.9.55"
24605
24606         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24607
24608         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24609
24610         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24611                 error "(2) Fail to copy"
24612
24613         trap cleanup_802a EXIT
24614
24615         # sync by force before remount as readonly
24616         sync; sync_all_data; sleep 3; sync_all_data
24617
24618         stopall
24619
24620         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24621         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24622         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24623
24624         echo "Mount the server as read only"
24625         setupall server_only || error "(3) Fail to start servers"
24626
24627         echo "Mount client without ro should fail"
24628         mount_client $MOUNT &&
24629                 error "(4) Mount client without 'ro' should fail"
24630
24631         echo "Mount client with ro should succeed"
24632         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24633         mount_client $MOUNT ||
24634                 error "(5) Mount client with 'ro' should succeed"
24635
24636         echo "Modify should be refused"
24637         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24638
24639         echo "Read should be allowed"
24640         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24641                 error "(7) Read should succeed under ro mode"
24642
24643         cleanup_802a
24644 }
24645 run_test 802a "simulate readonly device"
24646
24647 test_802b() {
24648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24649         remote_mds_nodsh && skip "remote MDS with nodsh"
24650
24651         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24652                 skip "readonly option not available"
24653
24654         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24655
24656         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24657                 error "(2) Fail to copy"
24658
24659         # write back all cached data before setting MDT to readonly
24660         cancel_lru_locks
24661         sync_all_data
24662
24663         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24664         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24665
24666         echo "Modify should be refused"
24667         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24668
24669         echo "Read should be allowed"
24670         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24671                 error "(7) Read should succeed under ro mode"
24672
24673         # disable readonly
24674         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24675 }
24676 run_test 802b "be able to set MDTs to readonly"
24677
24678 test_803a() {
24679         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24680         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24681                 skip "MDS needs to be newer than 2.10.54"
24682
24683         mkdir -p $DIR/$tdir
24684         # Create some objects on all MDTs to trigger related logs objects
24685         for idx in $(seq $MDSCOUNT); do
24686                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24687                         $DIR/$tdir/dir${idx} ||
24688                         error "Fail to create $DIR/$tdir/dir${idx}"
24689         done
24690
24691         sync; sleep 3
24692         wait_delete_completed # ensure old test cleanups are finished
24693         echo "before create:"
24694         $LFS df -i $MOUNT
24695         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24696
24697         for i in {1..10}; do
24698                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24699                         error "Fail to create $DIR/$tdir/foo$i"
24700         done
24701
24702         sync; sleep 3
24703         echo "after create:"
24704         $LFS df -i $MOUNT
24705         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24706
24707         # allow for an llog to be cleaned up during the test
24708         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24709                 error "before ($before_used) + 10 > after ($after_used)"
24710
24711         for i in {1..10}; do
24712                 rm -rf $DIR/$tdir/foo$i ||
24713                         error "Fail to remove $DIR/$tdir/foo$i"
24714         done
24715
24716         sleep 3 # avoid MDT return cached statfs
24717         wait_delete_completed
24718         echo "after unlink:"
24719         $LFS df -i $MOUNT
24720         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24721
24722         # allow for an llog to be created during the test
24723         [ $after_used -le $((before_used + 1)) ] ||
24724                 error "after ($after_used) > before ($before_used) + 1"
24725 }
24726 run_test 803a "verify agent object for remote object"
24727
24728 test_803b() {
24729         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24730         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24731                 skip "MDS needs to be newer than 2.13.56"
24732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24733
24734         for i in $(seq 0 $((MDSCOUNT - 1))); do
24735                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24736         done
24737
24738         local before=0
24739         local after=0
24740
24741         local tmp
24742
24743         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24744         for i in $(seq 0 $((MDSCOUNT - 1))); do
24745                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24746                         awk '/getattr/ { print $2 }')
24747                 before=$((before + tmp))
24748         done
24749         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24750         for i in $(seq 0 $((MDSCOUNT - 1))); do
24751                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24752                         awk '/getattr/ { print $2 }')
24753                 after=$((after + tmp))
24754         done
24755
24756         [ $before -eq $after ] || error "getattr count $before != $after"
24757 }
24758 run_test 803b "remote object can getattr from cache"
24759
24760 test_804() {
24761         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24762         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24763                 skip "MDS needs to be newer than 2.10.54"
24764         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24765
24766         mkdir -p $DIR/$tdir
24767         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24768                 error "Fail to create $DIR/$tdir/dir0"
24769
24770         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24771         local dev=$(mdsdevname 2)
24772
24773         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24774                 grep ${fid} || error "NOT found agent entry for dir0"
24775
24776         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24777                 error "Fail to create $DIR/$tdir/dir1"
24778
24779         touch $DIR/$tdir/dir1/foo0 ||
24780                 error "Fail to create $DIR/$tdir/dir1/foo0"
24781         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24782         local rc=0
24783
24784         for idx in $(seq $MDSCOUNT); do
24785                 dev=$(mdsdevname $idx)
24786                 do_facet mds${idx} \
24787                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24788                         grep ${fid} && rc=$idx
24789         done
24790
24791         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24792                 error "Fail to rename foo0 to foo1"
24793         if [ $rc -eq 0 ]; then
24794                 for idx in $(seq $MDSCOUNT); do
24795                         dev=$(mdsdevname $idx)
24796                         do_facet mds${idx} \
24797                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24798                         grep ${fid} && rc=$idx
24799                 done
24800         fi
24801
24802         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24803                 error "Fail to rename foo1 to foo2"
24804         if [ $rc -eq 0 ]; then
24805                 for idx in $(seq $MDSCOUNT); do
24806                         dev=$(mdsdevname $idx)
24807                         do_facet mds${idx} \
24808                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24809                         grep ${fid} && rc=$idx
24810                 done
24811         fi
24812
24813         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24814
24815         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24816                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24817         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24818                 error "Fail to rename foo2 to foo0"
24819         unlink $DIR/$tdir/dir1/foo0 ||
24820                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24821         rm -rf $DIR/$tdir/dir0 ||
24822                 error "Fail to rm $DIR/$tdir/dir0"
24823
24824         for idx in $(seq $MDSCOUNT); do
24825                 dev=$(mdsdevname $idx)
24826                 rc=0
24827
24828                 stop mds${idx}
24829                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24830                         rc=$?
24831                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24832                         error "mount mds$idx failed"
24833                 df $MOUNT > /dev/null 2>&1
24834
24835                 # e2fsck should not return error
24836                 [ $rc -eq 0 ] ||
24837                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24838         done
24839 }
24840 run_test 804 "verify agent entry for remote entry"
24841
24842 cleanup_805() {
24843         do_facet $SINGLEMDS zfs set quota=$old $fsset
24844         unlinkmany $DIR/$tdir/f- 1000000
24845         trap 0
24846 }
24847
24848 test_805() {
24849         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24850         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24851         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24852                 skip "netfree not implemented before 0.7"
24853         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24854                 skip "Need MDS version at least 2.10.57"
24855
24856         local fsset
24857         local freekb
24858         local usedkb
24859         local old
24860         local quota
24861         local pref="osd-zfs.$FSNAME-MDT0000."
24862
24863         # limit available space on MDS dataset to meet nospace issue
24864         # quickly. then ZFS 0.7.2 can use reserved space if asked
24865         # properly (using netfree flag in osd_declare_destroy()
24866         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24867         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24868                 gawk '{print $3}')
24869         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24870         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24871         let "usedkb=usedkb-freekb"
24872         let "freekb=freekb/2"
24873         if let "freekb > 5000"; then
24874                 let "freekb=5000"
24875         fi
24876         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24877         trap cleanup_805 EXIT
24878         mkdir $DIR/$tdir
24879         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24880                 error "Can't set PFL layout"
24881         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24882         rm -rf $DIR/$tdir || error "not able to remove"
24883         do_facet $SINGLEMDS zfs set quota=$old $fsset
24884         trap 0
24885 }
24886 run_test 805 "ZFS can remove from full fs"
24887
24888 # Size-on-MDS test
24889 check_lsom_data()
24890 {
24891         local file=$1
24892         local size=$($LFS getsom -s $file)
24893         local expect=$(stat -c %s $file)
24894
24895         [[ $size == $expect ]] ||
24896                 error "$file expected size: $expect, got: $size"
24897
24898         local blocks=$($LFS getsom -b $file)
24899         expect=$(stat -c %b $file)
24900         [[ $blocks == $expect ]] ||
24901                 error "$file expected blocks: $expect, got: $blocks"
24902 }
24903
24904 check_lsom_size()
24905 {
24906         local size=$($LFS getsom -s $1)
24907         local expect=$2
24908
24909         [[ $size == $expect ]] ||
24910                 error "$file expected size: $expect, got: $size"
24911 }
24912
24913 test_806() {
24914         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24915                 skip "Need MDS version at least 2.11.52"
24916
24917         local bs=1048576
24918
24919         touch $DIR/$tfile || error "touch $tfile failed"
24920
24921         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24922         save_lustre_params client "llite.*.xattr_cache" > $save
24923         lctl set_param llite.*.xattr_cache=0
24924         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24925
24926         # single-threaded write
24927         echo "Test SOM for single-threaded write"
24928         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24929                 error "write $tfile failed"
24930         check_lsom_size $DIR/$tfile $bs
24931
24932         local num=32
24933         local size=$(($num * $bs))
24934         local offset=0
24935         local i
24936
24937         echo "Test SOM for single client multi-threaded($num) write"
24938         $TRUNCATE $DIR/$tfile 0
24939         for ((i = 0; i < $num; i++)); do
24940                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24941                 local pids[$i]=$!
24942                 offset=$((offset + $bs))
24943         done
24944         for (( i=0; i < $num; i++ )); do
24945                 wait ${pids[$i]}
24946         done
24947         check_lsom_size $DIR/$tfile $size
24948
24949         $TRUNCATE $DIR/$tfile 0
24950         for ((i = 0; i < $num; i++)); do
24951                 offset=$((offset - $bs))
24952                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24953                 local pids[$i]=$!
24954         done
24955         for (( i=0; i < $num; i++ )); do
24956                 wait ${pids[$i]}
24957         done
24958         check_lsom_size $DIR/$tfile $size
24959
24960         # multi-client writes
24961         num=$(get_node_count ${CLIENTS//,/ })
24962         size=$(($num * $bs))
24963         offset=0
24964         i=0
24965
24966         echo "Test SOM for multi-client ($num) writes"
24967         $TRUNCATE $DIR/$tfile 0
24968         for client in ${CLIENTS//,/ }; do
24969                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24970                 local pids[$i]=$!
24971                 i=$((i + 1))
24972                 offset=$((offset + $bs))
24973         done
24974         for (( i=0; i < $num; i++ )); do
24975                 wait ${pids[$i]}
24976         done
24977         check_lsom_size $DIR/$tfile $offset
24978
24979         i=0
24980         $TRUNCATE $DIR/$tfile 0
24981         for client in ${CLIENTS//,/ }; do
24982                 offset=$((offset - $bs))
24983                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24984                 local pids[$i]=$!
24985                 i=$((i + 1))
24986         done
24987         for (( i=0; i < $num; i++ )); do
24988                 wait ${pids[$i]}
24989         done
24990         check_lsom_size $DIR/$tfile $size
24991
24992         # verify truncate
24993         echo "Test SOM for truncate"
24994         $TRUNCATE $DIR/$tfile 1048576
24995         check_lsom_size $DIR/$tfile 1048576
24996         $TRUNCATE $DIR/$tfile 1234
24997         check_lsom_size $DIR/$tfile 1234
24998
24999         # verify SOM blocks count
25000         echo "Verify SOM block count"
25001         $TRUNCATE $DIR/$tfile 0
25002         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25003                 error "failed to write file $tfile"
25004         check_lsom_data $DIR/$tfile
25005 }
25006 run_test 806 "Verify Lazy Size on MDS"
25007
25008 test_807() {
25009         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25010         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25011                 skip "Need MDS version at least 2.11.52"
25012
25013         # Registration step
25014         changelog_register || error "changelog_register failed"
25015         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25016         changelog_users $SINGLEMDS | grep -q $cl_user ||
25017                 error "User $cl_user not found in changelog_users"
25018
25019         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25020         save_lustre_params client "llite.*.xattr_cache" > $save
25021         lctl set_param llite.*.xattr_cache=0
25022         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25023
25024         rm -rf $DIR/$tdir || error "rm $tdir failed"
25025         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25026         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25027         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25028         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25029                 error "truncate $tdir/trunc failed"
25030
25031         local bs=1048576
25032         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25033                 error "write $tfile failed"
25034
25035         # multi-client wirtes
25036         local num=$(get_node_count ${CLIENTS//,/ })
25037         local offset=0
25038         local i=0
25039
25040         echo "Test SOM for multi-client ($num) writes"
25041         touch $DIR/$tfile || error "touch $tfile failed"
25042         $TRUNCATE $DIR/$tfile 0
25043         for client in ${CLIENTS//,/ }; do
25044                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25045                 local pids[$i]=$!
25046                 i=$((i + 1))
25047                 offset=$((offset + $bs))
25048         done
25049         for (( i=0; i < $num; i++ )); do
25050                 wait ${pids[$i]}
25051         done
25052
25053         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25054         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25055         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25056         check_lsom_data $DIR/$tdir/trunc
25057         check_lsom_data $DIR/$tdir/single_dd
25058         check_lsom_data $DIR/$tfile
25059
25060         rm -rf $DIR/$tdir
25061         # Deregistration step
25062         changelog_deregister || error "changelog_deregister failed"
25063 }
25064 run_test 807 "verify LSOM syncing tool"
25065
25066 check_som_nologged()
25067 {
25068         local lines=$($LFS changelog $FSNAME-MDT0000 |
25069                 grep 'x=trusted.som' | wc -l)
25070         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25071 }
25072
25073 test_808() {
25074         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25075                 skip "Need MDS version at least 2.11.55"
25076
25077         # Registration step
25078         changelog_register || error "changelog_register failed"
25079
25080         touch $DIR/$tfile || error "touch $tfile failed"
25081         check_som_nologged
25082
25083         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25084                 error "write $tfile failed"
25085         check_som_nologged
25086
25087         $TRUNCATE $DIR/$tfile 1234
25088         check_som_nologged
25089
25090         $TRUNCATE $DIR/$tfile 1048576
25091         check_som_nologged
25092
25093         # Deregistration step
25094         changelog_deregister || error "changelog_deregister failed"
25095 }
25096 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25097
25098 check_som_nodata()
25099 {
25100         $LFS getsom $1
25101         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25102 }
25103
25104 test_809() {
25105         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25106                 skip "Need MDS version at least 2.11.56"
25107
25108         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25109                 error "failed to create DoM-only file $DIR/$tfile"
25110         touch $DIR/$tfile || error "touch $tfile failed"
25111         check_som_nodata $DIR/$tfile
25112
25113         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25114                 error "write $tfile failed"
25115         check_som_nodata $DIR/$tfile
25116
25117         $TRUNCATE $DIR/$tfile 1234
25118         check_som_nodata $DIR/$tfile
25119
25120         $TRUNCATE $DIR/$tfile 4097
25121         check_som_nodata $DIR/$file
25122 }
25123 run_test 809 "Verify no SOM xattr store for DoM-only files"
25124
25125 test_810() {
25126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25127         $GSS && skip_env "could not run with gss"
25128         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25129                 skip "OST < 2.12.58 doesn't align checksum"
25130
25131         set_checksums 1
25132         stack_trap "set_checksums $ORIG_CSUM" EXIT
25133         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25134
25135         local csum
25136         local before
25137         local after
25138         for csum in $CKSUM_TYPES; do
25139                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25140                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25141                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25142                         eval set -- $i
25143                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25144                         before=$(md5sum $DIR/$tfile)
25145                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25146                         after=$(md5sum $DIR/$tfile)
25147                         [ "$before" == "$after" ] ||
25148                                 error "$csum: $before != $after bs=$1 seek=$2"
25149                 done
25150         done
25151 }
25152 run_test 810 "partial page writes on ZFS (LU-11663)"
25153
25154 test_812a() {
25155         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25156                 skip "OST < 2.12.51 doesn't support this fail_loc"
25157
25158         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25159         # ensure ost1 is connected
25160         stat $DIR/$tfile >/dev/null || error "can't stat"
25161         wait_osc_import_state client ost1 FULL
25162         # no locks, no reqs to let the connection idle
25163         cancel_lru_locks osc
25164
25165         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25166 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25167         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25168         wait_osc_import_state client ost1 CONNECTING
25169         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25170
25171         stat $DIR/$tfile >/dev/null || error "can't stat file"
25172 }
25173 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25174
25175 test_812b() { # LU-12378
25176         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25177                 skip "OST < 2.12.51 doesn't support this fail_loc"
25178
25179         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25180         # ensure ost1 is connected
25181         stat $DIR/$tfile >/dev/null || error "can't stat"
25182         wait_osc_import_state client ost1 FULL
25183         # no locks, no reqs to let the connection idle
25184         cancel_lru_locks osc
25185
25186         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25187 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25188         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25189         wait_osc_import_state client ost1 CONNECTING
25190         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25191
25192         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25193         wait_osc_import_state client ost1 IDLE
25194 }
25195 run_test 812b "do not drop no resend request for idle connect"
25196
25197 test_813() {
25198         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25199         [ -z "$file_heat_sav" ] && skip "no file heat support"
25200
25201         local readsample
25202         local writesample
25203         local readbyte
25204         local writebyte
25205         local readsample1
25206         local writesample1
25207         local readbyte1
25208         local writebyte1
25209
25210         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25211         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25212
25213         $LCTL set_param -n llite.*.file_heat=1
25214         echo "Turn on file heat"
25215         echo "Period second: $period_second, Decay percentage: $decay_pct"
25216
25217         echo "QQQQ" > $DIR/$tfile
25218         echo "QQQQ" > $DIR/$tfile
25219         echo "QQQQ" > $DIR/$tfile
25220         cat $DIR/$tfile > /dev/null
25221         cat $DIR/$tfile > /dev/null
25222         cat $DIR/$tfile > /dev/null
25223         cat $DIR/$tfile > /dev/null
25224
25225         local out=$($LFS heat_get $DIR/$tfile)
25226
25227         $LFS heat_get $DIR/$tfile
25228         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25229         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25230         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25231         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25232
25233         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25234         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25235         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25236         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25237
25238         sleep $((period_second + 3))
25239         echo "Sleep $((period_second + 3)) seconds..."
25240         # The recursion formula to calculate the heat of the file f is as
25241         # follow:
25242         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25243         # Where Hi is the heat value in the period between time points i*I and
25244         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25245         # to the weight of Ci.
25246         out=$($LFS heat_get $DIR/$tfile)
25247         $LFS heat_get $DIR/$tfile
25248         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25249         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25250         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25251         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25252
25253         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25254                 error "read sample ($readsample) is wrong"
25255         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25256                 error "write sample ($writesample) is wrong"
25257         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25258                 error "read bytes ($readbyte) is wrong"
25259         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25260                 error "write bytes ($writebyte) is wrong"
25261
25262         echo "QQQQ" > $DIR/$tfile
25263         echo "QQQQ" > $DIR/$tfile
25264         echo "QQQQ" > $DIR/$tfile
25265         cat $DIR/$tfile > /dev/null
25266         cat $DIR/$tfile > /dev/null
25267         cat $DIR/$tfile > /dev/null
25268         cat $DIR/$tfile > /dev/null
25269
25270         sleep $((period_second + 3))
25271         echo "Sleep $((period_second + 3)) seconds..."
25272
25273         out=$($LFS heat_get $DIR/$tfile)
25274         $LFS heat_get $DIR/$tfile
25275         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25276         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25277         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25278         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25279
25280         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25281                 4 * $decay_pct) / 100") -eq 1 ] ||
25282                 error "read sample ($readsample1) is wrong"
25283         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25284                 3 * $decay_pct) / 100") -eq 1 ] ||
25285                 error "write sample ($writesample1) is wrong"
25286         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25287                 20 * $decay_pct) / 100") -eq 1 ] ||
25288                 error "read bytes ($readbyte1) is wrong"
25289         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25290                 15 * $decay_pct) / 100") -eq 1 ] ||
25291                 error "write bytes ($writebyte1) is wrong"
25292
25293         echo "Turn off file heat for the file $DIR/$tfile"
25294         $LFS heat_set -o $DIR/$tfile
25295
25296         echo "QQQQ" > $DIR/$tfile
25297         echo "QQQQ" > $DIR/$tfile
25298         echo "QQQQ" > $DIR/$tfile
25299         cat $DIR/$tfile > /dev/null
25300         cat $DIR/$tfile > /dev/null
25301         cat $DIR/$tfile > /dev/null
25302         cat $DIR/$tfile > /dev/null
25303
25304         out=$($LFS heat_get $DIR/$tfile)
25305         $LFS heat_get $DIR/$tfile
25306         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25307         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25308         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25309         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25310
25311         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25312         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25313         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25314         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25315
25316         echo "Trun on file heat for the file $DIR/$tfile"
25317         $LFS heat_set -O $DIR/$tfile
25318
25319         echo "QQQQ" > $DIR/$tfile
25320         echo "QQQQ" > $DIR/$tfile
25321         echo "QQQQ" > $DIR/$tfile
25322         cat $DIR/$tfile > /dev/null
25323         cat $DIR/$tfile > /dev/null
25324         cat $DIR/$tfile > /dev/null
25325         cat $DIR/$tfile > /dev/null
25326
25327         out=$($LFS heat_get $DIR/$tfile)
25328         $LFS heat_get $DIR/$tfile
25329         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25330         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25331         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25332         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25333
25334         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25335         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25336         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25337         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25338
25339         $LFS heat_set -c $DIR/$tfile
25340         $LCTL set_param -n llite.*.file_heat=0
25341         echo "Turn off file heat support for the Lustre filesystem"
25342
25343         echo "QQQQ" > $DIR/$tfile
25344         echo "QQQQ" > $DIR/$tfile
25345         echo "QQQQ" > $DIR/$tfile
25346         cat $DIR/$tfile > /dev/null
25347         cat $DIR/$tfile > /dev/null
25348         cat $DIR/$tfile > /dev/null
25349         cat $DIR/$tfile > /dev/null
25350
25351         out=$($LFS heat_get $DIR/$tfile)
25352         $LFS heat_get $DIR/$tfile
25353         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25354         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25355         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25356         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25357
25358         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25359         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25360         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25361         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25362
25363         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25364         rm -f $DIR/$tfile
25365 }
25366 run_test 813 "File heat verfication"
25367
25368 test_814()
25369 {
25370         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25371         echo -n y >> $DIR/$tfile
25372         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25373         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25374 }
25375 run_test 814 "sparse cp works as expected (LU-12361)"
25376
25377 test_815()
25378 {
25379         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25380         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25381 }
25382 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25383
25384 test_816() {
25385         local ost1_imp=$(get_osc_import_name client ost1)
25386         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25387                          cut -d'.' -f2)
25388
25389         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25390         # ensure ost1 is connected
25391
25392         stat $DIR/$tfile >/dev/null || error "can't stat"
25393         wait_osc_import_state client ost1 FULL
25394         # no locks, no reqs to let the connection idle
25395         cancel_lru_locks osc
25396         lru_resize_disable osc
25397         local before
25398         local now
25399         before=$($LCTL get_param -n \
25400                  ldlm.namespaces.$imp_name.lru_size)
25401
25402         wait_osc_import_state client ost1 IDLE
25403         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25404         now=$($LCTL get_param -n \
25405               ldlm.namespaces.$imp_name.lru_size)
25406         [ $before == $now ] || error "lru_size changed $before != $now"
25407 }
25408 run_test 816 "do not reset lru_resize on idle reconnect"
25409
25410 cleanup_817() {
25411         umount $tmpdir
25412         exportfs -u localhost:$DIR/nfsexp
25413         rm -rf $DIR/nfsexp
25414 }
25415
25416 test_817() {
25417         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25418
25419         mkdir -p $DIR/nfsexp
25420         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25421                 error "failed to export nfs"
25422
25423         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25424         stack_trap cleanup_817 EXIT
25425
25426         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25427                 error "failed to mount nfs to $tmpdir"
25428
25429         cp /bin/true $tmpdir
25430         $DIR/nfsexp/true || error "failed to execute 'true' command"
25431 }
25432 run_test 817 "nfsd won't cache write lock for exec file"
25433
25434 test_818() {
25435         mkdir $DIR/$tdir
25436         $LFS setstripe -c1 -i0 $DIR/$tfile
25437         $LFS setstripe -c1 -i1 $DIR/$tfile
25438         stop $SINGLEMDS
25439         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25440         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25441         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25442                 error "start $SINGLEMDS failed"
25443         rm -rf $DIR/$tdir
25444 }
25445 run_test 818 "unlink with failed llog"
25446
25447 test_819a() {
25448         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25449         cancel_lru_locks osc
25450         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25451         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25452         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25453         rm -f $TDIR/$tfile
25454 }
25455 run_test 819a "too big niobuf in read"
25456
25457 test_819b() {
25458         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25459         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25460         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25461         cancel_lru_locks osc
25462         sleep 1
25463         rm -f $TDIR/$tfile
25464 }
25465 run_test 819b "too big niobuf in write"
25466
25467
25468 function test_820_start_ost() {
25469         sleep 5
25470
25471         for num in $(seq $OSTCOUNT); do
25472                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25473         done
25474 }
25475
25476 test_820() {
25477         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25478
25479         mkdir $DIR/$tdir
25480         umount_client $MOUNT || error "umount failed"
25481         for num in $(seq $OSTCOUNT); do
25482                 stop ost$num
25483         done
25484
25485         # mount client with no active OSTs
25486         # so that the client can't initialize max LOV EA size
25487         # from OSC notifications
25488         mount_client $MOUNT || error "mount failed"
25489         # delay OST starting to keep this 0 max EA size for a while
25490         test_820_start_ost &
25491
25492         # create a directory on MDS2
25493         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25494                 error "Failed to create directory"
25495         # open intent should update default EA size
25496         # see mdc_update_max_ea_from_body()
25497         # notice this is the very first RPC to MDS2
25498         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25499         ret=$?
25500         echo $out
25501         # With SSK, this situation can lead to -EPERM being returned.
25502         # In that case, simply retry.
25503         if [ $ret -ne 0 ] && $SHARED_KEY; then
25504                 if echo "$out" | grep -q "not permitted"; then
25505                         cp /etc/services $DIR/$tdir/mds2
25506                         ret=$?
25507                 fi
25508         fi
25509         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25510 }
25511 run_test 820 "update max EA from open intent"
25512
25513 test_822() {
25514         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25515
25516         save_lustre_params mds1 \
25517                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25518         do_facet $SINGLEMDS "$LCTL set_param -n \
25519                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25520         do_facet $SINGLEMDS "$LCTL set_param -n \
25521                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25522
25523         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25524         local maxage=$(do_facet mds1 $LCTL get_param -n \
25525                        osp.$FSNAME-OST0000*MDT0000.maxage)
25526         sleep $((maxage + 1))
25527
25528         #define OBD_FAIL_NET_ERROR_RPC          0x532
25529         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
25530
25531         stack_trap "restore_lustre_params < $p; rm $p"
25532
25533         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
25534                       osp.$FSNAME-OST0000*MDT0000.create_count")
25535         for i in $(seq 1 $count); do
25536                 touch $DIR/$tfile.${i} || error "touch failed"
25537         done
25538 }
25539 run_test 822 "test precreate failure"
25540
25541 #
25542 # tests that do cleanup/setup should be run at the end
25543 #
25544
25545 test_900() {
25546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25547         local ls
25548
25549         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25550         $LCTL set_param fail_loc=0x903
25551
25552         cancel_lru_locks MGC
25553
25554         FAIL_ON_ERROR=true cleanup
25555         FAIL_ON_ERROR=true setup
25556 }
25557 run_test 900 "umount should not race with any mgc requeue thread"
25558
25559 # LUS-6253/LU-11185
25560 test_901() {
25561         local oldc
25562         local newc
25563         local olds
25564         local news
25565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25566
25567         # some get_param have a bug to handle dot in param name
25568         cancel_lru_locks MGC
25569         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25570         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25571         umount_client $MOUNT || error "umount failed"
25572         mount_client $MOUNT || error "mount failed"
25573         cancel_lru_locks MGC
25574         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25575         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25576
25577         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25578         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25579
25580         return 0
25581 }
25582 run_test 901 "don't leak a mgc lock on client umount"
25583
25584 # LU-13377
25585 test_902() {
25586         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25587                 skip "client does not have LU-13377 fix"
25588         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25589         $LCTL set_param fail_loc=0x1415
25590         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25591         cancel_lru_locks osc
25592         rm -f $DIR/$tfile
25593 }
25594 run_test 902 "test short write doesn't hang lustre"
25595
25596 complete $SECONDS
25597 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25598 check_and_cleanup_lustre
25599 if [ "$I_MOUNTED" != "yes" ]; then
25600         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25601 fi
25602 exit_status