Whamcloud - gitweb
LU-14755 tests: create custom pools
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         mkdir_on_mdt0 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         mkdir_on_mdt0 $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange ||
2759                 error "pool_add_targets failed"
2760         test_mkdir $DIR/$tdir
2761         $LFS setstripe -p $pool $DIR/$tdir
2762         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2763         $LFS getstripe $DIR/$tdir/$tfile
2764 }
2765 run_test 27I "check that root dir striping does not break parent dir one"
2766
2767 test_27J() {
2768         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2769                 skip "Need MDS version newer than 2.12.51"
2770
2771         test_mkdir $DIR/$tdir
2772         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2773         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2774
2775         # create foreign file (raw way)
2776         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2777                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2778
2779         ! $LFS setstripe --foreign --flags foo \
2780                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2781                         error "creating $tfile with '--flags foo' should fail"
2782
2783         ! $LFS setstripe --foreign --flags 0xffffffff \
2784                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2785                         error "creating $tfile w/ 0xffffffff flags should fail"
2786
2787         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2788                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2789
2790         # verify foreign file (raw way)
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2794         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2796         parse_foreign_file -f $DIR/$tdir/$tfile |
2797                 grep "lov_foreign_size: 73" ||
2798                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2799         parse_foreign_file -f $DIR/$tdir/$tfile |
2800                 grep "lov_foreign_type: 1" ||
2801                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2802         parse_foreign_file -f $DIR/$tdir/$tfile |
2803                 grep "lov_foreign_flags: 0x0000DA08" ||
2804                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2805         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2806                 grep "lov_foreign_value: 0x" |
2807                 sed -e 's/lov_foreign_value: 0x//')
2808         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2809         [[ $lov = ${lov2// /} ]] ||
2810                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2811
2812         # create foreign file (lfs + API)
2813         $LFS setstripe --foreign=none --flags 0xda08 \
2814                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2815                 error "$DIR/$tdir/${tfile}2: create failed"
2816
2817         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2818                 grep "lfm_magic:.*0x0BD70BD0" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2820         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2821         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2823         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2824                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2825         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2826                 grep "lfm_flags:.*0x0000DA08" ||
2827                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2828         $LFS getstripe $DIR/$tdir/${tfile}2 |
2829                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2830                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2831
2832         # modify striping should fail
2833         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2834                 error "$DIR/$tdir/$tfile: setstripe should fail"
2835         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2837
2838         # R/W should fail
2839         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2840         cat $DIR/$tdir/${tfile}2 &&
2841                 error "$DIR/$tdir/${tfile}2: read should fail"
2842         cat /etc/passwd > $DIR/$tdir/$tfile &&
2843                 error "$DIR/$tdir/$tfile: write should fail"
2844         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2845                 error "$DIR/$tdir/${tfile}2: write should fail"
2846
2847         # chmod should work
2848         chmod 222 $DIR/$tdir/$tfile ||
2849                 error "$DIR/$tdir/$tfile: chmod failed"
2850         chmod 222 $DIR/$tdir/${tfile}2 ||
2851                 error "$DIR/$tdir/${tfile}2: chmod failed"
2852
2853         # chown should work
2854         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2855                 error "$DIR/$tdir/$tfile: chown failed"
2856         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2857                 error "$DIR/$tdir/${tfile}2: chown failed"
2858
2859         # rename should work
2860         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2861                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2862         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2863                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2864
2865         #remove foreign file
2866         rm $DIR/$tdir/${tfile}.new ||
2867                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2868         rm $DIR/$tdir/${tfile}2.new ||
2869                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2870 }
2871 run_test 27J "basic ops on file with foreign LOV"
2872
2873 test_27K() {
2874         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2875                 skip "Need MDS version newer than 2.12.49"
2876
2877         test_mkdir $DIR/$tdir
2878         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2879         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2880
2881         # create foreign dir (raw way)
2882         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2883                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2884
2885         ! $LFS setdirstripe --foreign --flags foo \
2886                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2887                         error "creating $tdir with '--flags foo' should fail"
2888
2889         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2890                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2891                         error "creating $tdir w/ 0xffffffff flags should fail"
2892
2893         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2894                 error "create_foreign_dir FAILED"
2895
2896         # verify foreign dir (raw way)
2897         parse_foreign_dir -d $DIR/$tdir/$tdir |
2898                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2899                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2900         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2902         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2903                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2904         parse_foreign_dir -d $DIR/$tdir/$tdir |
2905                 grep "lmv_foreign_flags: 55813$" ||
2906                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2907         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2908                 grep "lmv_foreign_value: 0x" |
2909                 sed 's/lmv_foreign_value: 0x//')
2910         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2911                 sed 's/ //g')
2912         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2913
2914         # create foreign dir (lfs + API)
2915         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2916                 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/$tdir/${tdir}2: create failed"
2918
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2920                 grep "lfm_magic:.*0x0CD50CD0" ||
2921                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2922         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2923         # - sizeof(lfm_type) - sizeof(lfm_flags)
2924         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2926         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2927                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2928         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2929                 grep "lfm_flags:.*0x0000DA05" ||
2930                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2931         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2932                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2933                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2934
2935         # file create in dir should fail
2936         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2937         touch $DIR/$tdir/${tdir}2/$tfile &&
2938                 "$DIR/${tdir}2: file create should fail"
2939
2940         # chmod should work
2941         chmod 777 $DIR/$tdir/$tdir ||
2942                 error "$DIR/$tdir: chmod failed"
2943         chmod 777 $DIR/$tdir/${tdir}2 ||
2944                 error "$DIR/${tdir}2: chmod failed"
2945
2946         # chown should work
2947         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2948                 error "$DIR/$tdir: chown failed"
2949         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2950                 error "$DIR/${tdir}2: chown failed"
2951
2952         # rename should work
2953         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2954                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2955         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2956                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2957
2958         #remove foreign dir
2959         rmdir $DIR/$tdir/${tdir}.new ||
2960                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2961         rmdir $DIR/$tdir/${tdir}2.new ||
2962                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2963 }
2964 run_test 27K "basic ops on dir with foreign LMV"
2965
2966 test_27L() {
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968
2969         local POOL=${POOL:-$TESTNAME}
2970
2971         pool_add $POOL || error "pool_add failed"
2972
2973         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2974                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2975                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2976 }
2977 run_test 27L "lfs pool_list gives correct pool name"
2978
2979 test_27M() {
2980         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2981                 skip "Need MDS version >= than 2.12.57"
2982         remote_mds_nodsh && skip "remote MDS with nodsh"
2983         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2984
2985         test_mkdir $DIR/$tdir
2986
2987         # Set default striping on directory
2988         $LFS setstripe -C 4 $DIR/$tdir
2989
2990         echo 1 > $DIR/$tdir/${tfile}.1
2991         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2992         local setcount=4
2993         [ $count -eq $setcount ] ||
2994                 error "(1) stripe count $count, should be $setcount"
2995
2996         # Capture existing append_stripe_count setting for restore
2997         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2998         local mdts=$(comma_list $(mdts_nodes))
2999         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3000
3001         local appendcount=$orig_count
3002         echo 1 >> $DIR/$tdir/${tfile}.2_append
3003         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3004         [ $count -eq $appendcount ] ||
3005                 error "(2)stripe count $count, should be $appendcount for append"
3006
3007         # Disable O_APPEND striping, verify it works
3008         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3009
3010         # Should now get the default striping, which is 4
3011         setcount=4
3012         echo 1 >> $DIR/$tdir/${tfile}.3_append
3013         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3014         [ $count -eq $setcount ] ||
3015                 error "(3) stripe count $count, should be $setcount"
3016
3017         # Try changing the stripe count for append files
3018         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3019
3020         # Append striping is now 2 (directory default is still 4)
3021         appendcount=2
3022         echo 1 >> $DIR/$tdir/${tfile}.4_append
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3024         [ $count -eq $appendcount ] ||
3025                 error "(4) stripe count $count, should be $appendcount for append"
3026
3027         # Test append stripe count of -1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3029         appendcount=$OSTCOUNT
3030         echo 1 >> $DIR/$tdir/${tfile}.5
3031         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3032         [ $count -eq $appendcount ] ||
3033                 error "(5) stripe count $count, should be $appendcount for append"
3034
3035         # Set append striping back to default of 1
3036         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3037
3038         # Try a new default striping, PFL + DOM
3039         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3040
3041         # Create normal DOM file, DOM returns stripe count == 0
3042         setcount=0
3043         touch $DIR/$tdir/${tfile}.6
3044         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3045         [ $count -eq $setcount ] ||
3046                 error "(6) stripe count $count, should be $setcount"
3047
3048         # Show
3049         appendcount=1
3050         echo 1 >> $DIR/$tdir/${tfile}.7_append
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3052         [ $count -eq $appendcount ] ||
3053                 error "(7) stripe count $count, should be $appendcount for append"
3054
3055         # Clean up DOM layout
3056         $LFS setstripe -d $DIR/$tdir
3057
3058         # Now test that append striping works when layout is from root
3059         $LFS setstripe -c 2 $MOUNT
3060         # Make a special directory for this
3061         mkdir $DIR/${tdir}/${tdir}.2
3062         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3063
3064         # Verify for normal file
3065         setcount=2
3066         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3067         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3068         [ $count -eq $setcount ] ||
3069                 error "(8) stripe count $count, should be $setcount"
3070
3071         appendcount=1
3072         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3073         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3074         [ $count -eq $appendcount ] ||
3075                 error "(9) stripe count $count, should be $appendcount for append"
3076
3077         # Now test O_APPEND striping with pools
3078         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3079         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3080
3081         # Create the pool
3082         pool_add $TESTNAME || error "pool creation failed"
3083         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3084
3085         echo 1 >> $DIR/$tdir/${tfile}.10_append
3086
3087         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3088         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3089
3090         # Check that count is still correct
3091         appendcount=1
3092         echo 1 >> $DIR/$tdir/${tfile}.11_append
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3094         [ $count -eq $appendcount ] ||
3095                 error "(11) stripe count $count, should be $appendcount for append"
3096
3097         # Disable O_APPEND stripe count, verify pool works separately
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3099
3100         echo 1 >> $DIR/$tdir/${tfile}.12_append
3101
3102         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3103         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3104
3105         # Remove pool setting, verify it's not applied
3106         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3107
3108         echo 1 >> $DIR/$tdir/${tfile}.13_append
3109
3110         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3111         [ "$pool" = "" ] || error "(13) pool found: $pool"
3112 }
3113 run_test 27M "test O_APPEND striping"
3114
3115 test_27N() {
3116         combined_mgs_mds && skip "needs separate MGS/MDT"
3117
3118         pool_add $TESTNAME || error "pool_add failed"
3119         do_facet mgs "$LCTL pool_list $FSNAME" |
3120                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3121                 error "lctl pool_list on MGS failed"
3122 }
3123 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3124
3125 clean_foreign_symlink() {
3126         trap 0
3127         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3128         for i in $DIR/$tdir/* ; do
3129                 $LFS unlink_foreign $i || true
3130         done
3131 }
3132
3133 test_27O() {
3134         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3135                 skip "Need MDS version newer than 2.12.51"
3136
3137         test_mkdir $DIR/$tdir
3138         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3139         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3140
3141         trap clean_foreign_symlink EXIT
3142
3143         # enable foreign_symlink behaviour
3144         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3145
3146         # foreign symlink LOV format is a partial path by default
3147
3148         # create foreign file (lfs + API)
3149         $LFS setstripe --foreign=symlink --flags 0xda05 \
3150                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3151                 error "$DIR/$tdir/${tfile}: create failed"
3152
3153         $LFS getstripe -v $DIR/$tdir/${tfile} |
3154                 grep "lfm_magic:.*0x0BD70BD0" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3156         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3158         $LFS getstripe -v $DIR/$tdir/${tfile} |
3159                 grep "lfm_flags:.*0x0000DA05" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3161         $LFS getstripe $DIR/$tdir/${tfile} |
3162                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3163                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3164
3165         # modify striping should fail
3166         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3167                 error "$DIR/$tdir/$tfile: setstripe should fail"
3168
3169         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3170         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3171         cat /etc/passwd > $DIR/$tdir/$tfile &&
3172                 error "$DIR/$tdir/$tfile: write should fail"
3173
3174         # rename should succeed
3175         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3176                 error "$DIR/$tdir/$tfile: rename has failed"
3177
3178         #remove foreign_symlink file should fail
3179         rm $DIR/$tdir/${tfile}.new &&
3180                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3181
3182         #test fake symlink
3183         mkdir /tmp/${uuid1} ||
3184                 error "/tmp/${uuid1}: mkdir has failed"
3185         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3186                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3188         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3190         #read should succeed now
3191         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3192                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3193         #write should succeed now
3194         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3196         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3198         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3199                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3200
3201         #check that getstripe still works
3202         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3203                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3204
3205         # chmod should still succeed
3206         chmod 644 $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3208
3209         # chown should still succeed
3210         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3211                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3212
3213         # rename should still succeed
3214         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3215                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3216
3217         #remove foreign_symlink file should still fail
3218         rm $DIR/$tdir/${tfile} &&
3219                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3220
3221         #use special ioctl() to unlink foreign_symlink file
3222         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3223                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3224
3225 }
3226 run_test 27O "basic ops on foreign file of symlink type"
3227
3228 test_27P() {
3229         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3230                 skip "Need MDS version newer than 2.12.49"
3231
3232         test_mkdir $DIR/$tdir
3233         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3234         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3235
3236         trap clean_foreign_symlink EXIT
3237
3238         # enable foreign_symlink behaviour
3239         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3240
3241         # foreign symlink LMV format is a partial path by default
3242
3243         # create foreign dir (lfs + API)
3244         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3245                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3246                 error "$DIR/$tdir/${tdir}: create failed"
3247
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3249                 grep "lfm_magic:.*0x0CD50CD0" ||
3250                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3251         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3253         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3254                 grep "lfm_flags:.*0x0000DA05" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3256         $LFS getdirstripe $DIR/$tdir/${tdir} |
3257                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3258                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3259
3260         # file create in dir should fail
3261         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3262         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3263
3264         # rename should succeed
3265         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3266                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3267
3268         #remove foreign_symlink dir should fail
3269         rmdir $DIR/$tdir/${tdir}.new &&
3270                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3271
3272         #test fake symlink
3273         mkdir -p /tmp/${uuid1}/${uuid2} ||
3274                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3275         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3276                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3277         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3278         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3279                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3280         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3281                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3282
3283         #check that getstripe fails now that foreign_symlink enabled
3284         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3285                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3286
3287         # file create in dir should work now
3288         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3289                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3290         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3291                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3292         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3293                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3294
3295         # chmod should still succeed
3296         chmod 755 $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3298
3299         # chown should still succeed
3300         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3301                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3302
3303         # rename should still succeed
3304         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3305                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3306
3307         #remove foreign_symlink dir should still fail
3308         rmdir $DIR/$tdir/${tdir} &&
3309                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3310
3311         #use special ioctl() to unlink foreign_symlink file
3312         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3313                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3314
3315         #created file should still exist
3316         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3317                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3318         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3319                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3320 }
3321 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3322
3323 test_27Q() {
3324         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3325         stack_trap "rm -f $TMP/$tfile*"
3326
3327         test_mkdir $DIR/$tdir-1
3328         test_mkdir $DIR/$tdir-2
3329
3330         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3331         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3334         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3335
3336         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3337         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3338
3339         # Create some bad symlinks and ensure that we don't loop
3340         # forever or something. These should return ELOOP (40) and
3341         # ENOENT (2) but I don't want to test for that because there's
3342         # always some weirdo architecture that needs to ruin
3343         # everything by defining these error numbers differently.
3344
3345         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3346         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3347
3348         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3349         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3350
3351         return 0
3352 }
3353 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3354
3355 # createtest also checks that device nodes are created and
3356 # then visible correctly (#2091)
3357 test_28() { # bug 2091
3358         test_mkdir $DIR/d28
3359         $CREATETEST $DIR/d28/ct || error "createtest failed"
3360 }
3361 run_test 28 "create/mknod/mkdir with bad file types ============"
3362
3363 test_29() {
3364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3365
3366         sync; sleep 1; sync # flush out any dirty pages from previous tests
3367         cancel_lru_locks
3368         test_mkdir $DIR/d29
3369         touch $DIR/d29/foo
3370         log 'first d29'
3371         ls -l $DIR/d29
3372
3373         declare -i LOCKCOUNTORIG=0
3374         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3375                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3376         done
3377         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3378
3379         declare -i LOCKUNUSEDCOUNTORIG=0
3380         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3381                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3382         done
3383
3384         log 'second d29'
3385         ls -l $DIR/d29
3386         log 'done'
3387
3388         declare -i LOCKCOUNTCURRENT=0
3389         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3390                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3391         done
3392
3393         declare -i LOCKUNUSEDCOUNTCURRENT=0
3394         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3395                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3396         done
3397
3398         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3399                 $LCTL set_param -n ldlm.dump_namespaces ""
3400                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3401                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3402                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3403                 return 2
3404         fi
3405         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3406                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3407                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3408                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3409                 return 3
3410         fi
3411 }
3412 run_test 29 "IT_GETATTR regression  ============================"
3413
3414 test_30a() { # was test_30
3415         cp $(which ls) $DIR || cp /bin/ls $DIR
3416         $DIR/ls / || error "Can't execute binary from lustre"
3417         rm $DIR/ls
3418 }
3419 run_test 30a "execute binary from Lustre (execve) =============="
3420
3421 test_30b() {
3422         cp `which ls` $DIR || cp /bin/ls $DIR
3423         chmod go+rx $DIR/ls
3424         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3425         rm $DIR/ls
3426 }
3427 run_test 30b "execute binary from Lustre as non-root ==========="
3428
3429 test_30c() { # b=22376
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431
3432         cp $(which ls) $DIR || cp /bin/ls $DIR
3433         chmod a-rw $DIR/ls
3434         cancel_lru_locks mdc
3435         cancel_lru_locks osc
3436         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3437         rm -f $DIR/ls
3438 }
3439 run_test 30c "execute binary from Lustre without read perms ===="
3440
3441 test_30d() {
3442         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3443
3444         for i in {1..10}; do
3445                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3446                 local PID=$!
3447                 sleep 1
3448                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3449                 wait $PID || error "executing dd from Lustre failed"
3450                 rm -f $DIR/$tfile
3451         done
3452
3453         rm -f $DIR/dd
3454 }
3455 run_test 30d "execute binary from Lustre while clear locks"
3456
3457 test_31a() {
3458         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3459         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3460 }
3461 run_test 31a "open-unlink file =================================="
3462
3463 test_31b() {
3464         touch $DIR/f31 || error "touch $DIR/f31 failed"
3465         ln $DIR/f31 $DIR/f31b || error "ln failed"
3466         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3467         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3468 }
3469 run_test 31b "unlink file with multiple links while open ======="
3470
3471 test_31c() {
3472         touch $DIR/f31 || error "touch $DIR/f31 failed"
3473         ln $DIR/f31 $DIR/f31c || error "ln failed"
3474         multiop_bg_pause $DIR/f31 O_uc ||
3475                 error "multiop_bg_pause for $DIR/f31 failed"
3476         MULTIPID=$!
3477         $MULTIOP $DIR/f31c Ouc
3478         kill -USR1 $MULTIPID
3479         wait $MULTIPID
3480 }
3481 run_test 31c "open-unlink file with multiple links ============="
3482
3483 test_31d() {
3484         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3485         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3486 }
3487 run_test 31d "remove of open directory ========================="
3488
3489 test_31e() { # bug 2904
3490         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3491 }
3492 run_test 31e "remove of open non-empty directory ==============="
3493
3494 test_31f() { # bug 4554
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         set -vx
3498         test_mkdir $DIR/d31f
3499         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3500         cp /etc/hosts $DIR/d31f
3501         ls -l $DIR/d31f
3502         $LFS getstripe $DIR/d31f/hosts
3503         multiop_bg_pause $DIR/d31f D_c || return 1
3504         MULTIPID=$!
3505
3506         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3507         test_mkdir $DIR/d31f
3508         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3509         cp /etc/hosts $DIR/d31f
3510         ls -l $DIR/d31f
3511         $LFS getstripe $DIR/d31f/hosts
3512         multiop_bg_pause $DIR/d31f D_c || return 1
3513         MULTIPID2=$!
3514
3515         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3516         wait $MULTIPID || error "first opendir $MULTIPID failed"
3517
3518         sleep 6
3519
3520         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3521         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3522         set +vx
3523 }
3524 run_test 31f "remove of open directory with open-unlink file ==="
3525
3526 test_31g() {
3527         echo "-- cross directory link --"
3528         test_mkdir -c1 $DIR/${tdir}ga
3529         test_mkdir -c1 $DIR/${tdir}gb
3530         touch $DIR/${tdir}ga/f
3531         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3532         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3533         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3534         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3535         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3536 }
3537 run_test 31g "cross directory link==============="
3538
3539 test_31h() {
3540         echo "-- cross directory link --"
3541         test_mkdir -c1 $DIR/${tdir}
3542         test_mkdir -c1 $DIR/${tdir}/dir
3543         touch $DIR/${tdir}/f
3544         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3545         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3546         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3547         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3548         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3549 }
3550 run_test 31h "cross directory link under child==============="
3551
3552 test_31i() {
3553         echo "-- cross directory link --"
3554         test_mkdir -c1 $DIR/$tdir
3555         test_mkdir -c1 $DIR/$tdir/dir
3556         touch $DIR/$tdir/dir/f
3557         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3558         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3559         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3560         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3561         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3562 }
3563 run_test 31i "cross directory link under parent==============="
3564
3565 test_31j() {
3566         test_mkdir -c1 -p $DIR/$tdir
3567         test_mkdir -c1 -p $DIR/$tdir/dir1
3568         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3569         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3571         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3572         return 0
3573 }
3574 run_test 31j "link for directory==============="
3575
3576 test_31k() {
3577         test_mkdir -c1 -p $DIR/$tdir
3578         touch $DIR/$tdir/s
3579         touch $DIR/$tdir/exist
3580         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3581         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3582         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3583         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3584         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3586         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3587         return 0
3588 }
3589 run_test 31k "link to file: the same, non-existing, dir==============="
3590
3591 test_31m() {
3592         mkdir $DIR/d31m
3593         touch $DIR/d31m/s
3594         mkdir $DIR/d31m2
3595         touch $DIR/d31m2/exist
3596         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3597         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3598         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3599         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3601         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3602         return 0
3603 }
3604 run_test 31m "link to file: the same, non-existing, dir==============="
3605
3606 test_31n() {
3607         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3608         nlink=$(stat --format=%h $DIR/$tfile)
3609         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3610         local fd=$(free_fd)
3611         local cmd="exec $fd<$DIR/$tfile"
3612         eval $cmd
3613         cmd="exec $fd<&-"
3614         trap "eval $cmd" EXIT
3615         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3616         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3617         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3618         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3619         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3620         eval $cmd
3621 }
3622 run_test 31n "check link count of unlinked file"
3623
3624 link_one() {
3625         local tempfile=$(mktemp $1_XXXXXX)
3626         mlink $tempfile $1 2> /dev/null &&
3627                 echo "$BASHPID: link $tempfile to $1 succeeded"
3628         munlink $tempfile
3629 }
3630
3631 test_31o() { # LU-2901
3632         test_mkdir $DIR/$tdir
3633         for LOOP in $(seq 100); do
3634                 rm -f $DIR/$tdir/$tfile*
3635                 for THREAD in $(seq 8); do
3636                         link_one $DIR/$tdir/$tfile.$LOOP &
3637                 done
3638                 wait
3639                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3640                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3641                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3642                         break || true
3643         done
3644 }
3645 run_test 31o "duplicate hard links with same filename"
3646
3647 test_31p() {
3648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3649
3650         test_mkdir $DIR/$tdir
3651         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3652         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3653
3654         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3655                 error "open unlink test1 failed"
3656         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3657                 error "open unlink test2 failed"
3658
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3660                 error "test1 still exists"
3661         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3662                 error "test2 still exists"
3663 }
3664 run_test 31p "remove of open striped directory"
3665
3666 test_31q() {
3667         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3668
3669         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3670         index=$($LFS getdirstripe -i $DIR/$tdir)
3671         [ $index -eq 3 ] || error "first stripe index $index != 3"
3672         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3673         [ $index -eq 1 ] || error "second stripe index $index != 1"
3674
3675         # when "-c <stripe_count>" is set, the number of MDTs specified after
3676         # "-i" should equal to the stripe count
3677         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3678 }
3679 run_test 31q "create striped directory on specific MDTs"
3680
3681 cleanup_test32_mount() {
3682         local rc=0
3683         trap 0
3684         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3685         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3686         losetup -d $loopdev || true
3687         rm -rf $DIR/$tdir
3688         return $rc
3689 }
3690
3691 test_32a() {
3692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3693
3694         echo "== more mountpoints and symlinks ================="
3695         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3696         trap cleanup_test32_mount EXIT
3697         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3698         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3699                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3700         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3701                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3702         cleanup_test32_mount
3703 }
3704 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3705
3706 test_32b() {
3707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3708
3709         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3710         trap cleanup_test32_mount EXIT
3711         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3712         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3713                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3714         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3715                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3716         cleanup_test32_mount
3717 }
3718 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3719
3720 test_32c() {
3721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3722
3723         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3724         trap cleanup_test32_mount EXIT
3725         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3726         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3727                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3728         test_mkdir -p $DIR/$tdir/d2/test_dir
3729         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3730                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3731         cleanup_test32_mount
3732 }
3733 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3734
3735 test_32d() {
3736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3737
3738         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3739         trap cleanup_test32_mount EXIT
3740         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3741         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3742                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3743         test_mkdir -p $DIR/$tdir/d2/test_dir
3744         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3745                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3746         cleanup_test32_mount
3747 }
3748 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3749
3750 test_32e() {
3751         rm -fr $DIR/$tdir
3752         test_mkdir -p $DIR/$tdir/tmp
3753         local tmp_dir=$DIR/$tdir/tmp
3754         ln -s $DIR/$tdir $tmp_dir/symlink11
3755         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3756         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3757         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3758 }
3759 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3760
3761 test_32f() {
3762         rm -fr $DIR/$tdir
3763         test_mkdir -p $DIR/$tdir/tmp
3764         local tmp_dir=$DIR/$tdir/tmp
3765         ln -s $DIR/$tdir $tmp_dir/symlink11
3766         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3767         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3768         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3769 }
3770 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3771
3772 test_32g() {
3773         local tmp_dir=$DIR/$tdir/tmp
3774         test_mkdir -p $tmp_dir
3775         test_mkdir $DIR/${tdir}2
3776         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3777         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3778         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3779         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3780         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3781         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3782 }
3783 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3784
3785 test_32h() {
3786         rm -fr $DIR/$tdir $DIR/${tdir}2
3787         tmp_dir=$DIR/$tdir/tmp
3788         test_mkdir -p $tmp_dir
3789         test_mkdir $DIR/${tdir}2
3790         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3791         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3792         ls $tmp_dir/symlink12 || error "listing symlink12"
3793         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3794 }
3795 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3796
3797 test_32i() {
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3801         trap cleanup_test32_mount EXIT
3802         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3803         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3804                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3805         touch $DIR/$tdir/test_file
3806         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3807                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3808         cleanup_test32_mount
3809 }
3810 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3811
3812 test_32j() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3816         trap cleanup_test32_mount EXIT
3817         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3818         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3819                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3820         touch $DIR/$tdir/test_file
3821         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3822                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3823         cleanup_test32_mount
3824 }
3825 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3826
3827 test_32k() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         test_mkdir -p $DIR/$tdir/d2
3836         touch $DIR/$tdir/d2/test_file || error "touch failed"
3837         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3838                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3839         cleanup_test32_mount
3840 }
3841 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3842
3843 test_32l() {
3844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3845
3846         rm -fr $DIR/$tdir
3847         trap cleanup_test32_mount EXIT
3848         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3849         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3850                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3851         test_mkdir -p $DIR/$tdir/d2
3852         touch $DIR/$tdir/d2/test_file || error "touch failed"
3853         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3854                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3855         cleanup_test32_mount
3856 }
3857 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3858
3859 test_32m() {
3860         rm -fr $DIR/d32m
3861         test_mkdir -p $DIR/d32m/tmp
3862         TMP_DIR=$DIR/d32m/tmp
3863         ln -s $DIR $TMP_DIR/symlink11
3864         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3865         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3866                 error "symlink11 not a link"
3867         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3868                 error "symlink01 not a link"
3869 }
3870 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3871
3872 test_32n() {
3873         rm -fr $DIR/d32n
3874         test_mkdir -p $DIR/d32n/tmp
3875         TMP_DIR=$DIR/d32n/tmp
3876         ln -s $DIR $TMP_DIR/symlink11
3877         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3878         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3879         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3880 }
3881 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3882
3883 test_32o() {
3884         touch $DIR/$tfile
3885         test_mkdir -p $DIR/d32o/tmp
3886         TMP_DIR=$DIR/d32o/tmp
3887         ln -s $DIR/$tfile $TMP_DIR/symlink12
3888         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3889         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3890                 error "symlink12 not a link"
3891         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3892         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3893                 error "$DIR/d32o/tmp/symlink12 not file type"
3894         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3895                 error "$DIR/d32o/symlink02 not file type"
3896 }
3897 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3898
3899 test_32p() {
3900         log 32p_1
3901         rm -fr $DIR/d32p
3902         log 32p_2
3903         rm -f $DIR/$tfile
3904         log 32p_3
3905         touch $DIR/$tfile
3906         log 32p_4
3907         test_mkdir -p $DIR/d32p/tmp
3908         log 32p_5
3909         TMP_DIR=$DIR/d32p/tmp
3910         log 32p_6
3911         ln -s $DIR/$tfile $TMP_DIR/symlink12
3912         log 32p_7
3913         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3914         log 32p_8
3915         cat $DIR/d32p/tmp/symlink12 ||
3916                 error "Can't open $DIR/d32p/tmp/symlink12"
3917         log 32p_9
3918         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3919         log 32p_10
3920 }
3921 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3922
3923 test_32q() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3927         trap cleanup_test32_mount EXIT
3928         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3929         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3933         cleanup_test32_mount
3934 }
3935 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3936
3937 test_32r() {
3938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3939
3940         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3941         trap cleanup_test32_mount EXIT
3942         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3943         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3947         cleanup_test32_mount
3948 }
3949 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3950
3951 test_33aa() {
3952         rm -f $DIR/$tfile
3953         touch $DIR/$tfile
3954         chmod 444 $DIR/$tfile
3955         chown $RUNAS_ID $DIR/$tfile
3956         log 33_1
3957         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3958         log 33_2
3959 }
3960 run_test 33aa "write file with mode 444 (should return error)"
3961
3962 test_33a() {
3963         rm -fr $DIR/$tdir
3964         test_mkdir $DIR/$tdir
3965         chown $RUNAS_ID $DIR/$tdir
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3967                 error "$RUNAS create $tdir/$tfile failed"
3968         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3969                 error "open RDWR" || true
3970 }
3971 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3972
3973 test_33b() {
3974         rm -fr $DIR/$tdir
3975         test_mkdir $DIR/$tdir
3976         chown $RUNAS_ID $DIR/$tdir
3977         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3978 }
3979 run_test 33b "test open file with malformed flags (No panic)"
3980
3981 test_33c() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983         remote_ost_nodsh && skip "remote OST with nodsh"
3984
3985         local ostnum
3986         local ostname
3987         local write_bytes
3988         local all_zeros
3989
3990         all_zeros=true
3991         test_mkdir $DIR/$tdir
3992         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3993
3994         sync
3995         for ostnum in $(seq $OSTCOUNT); do
3996                 # test-framework's OST numbering is one-based, while Lustre's
3997                 # is zero-based
3998                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3999                 # check if at least some write_bytes stats are counted
4000                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4001                               obdfilter.$ostname.stats |
4002                               awk '/^write_bytes/ {print $7}' )
4003                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4004                 if (( ${write_bytes:-0} > 0 )); then
4005                         all_zeros=false
4006                         break
4007                 fi
4008         done
4009
4010         $all_zeros || return 0
4011
4012         # Write four bytes
4013         echo foo > $DIR/$tdir/bar
4014         # Really write them
4015         sync
4016
4017         # Total up write_bytes after writing.  We'd better find non-zeros.
4018         for ostnum in $(seq $OSTCOUNT); do
4019                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4020                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4021                               obdfilter/$ostname/stats |
4022                               awk '/^write_bytes/ {print $7}' )
4023                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4024                 if (( ${write_bytes:-0} > 0 )); then
4025                         all_zeros=false
4026                         break
4027                 fi
4028         done
4029
4030         if $all_zeros; then
4031                 for ostnum in $(seq $OSTCOUNT); do
4032                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4033                         echo "Check write_bytes is in obdfilter.*.stats:"
4034                         do_facet ost$ostnum lctl get_param -n \
4035                                 obdfilter.$ostname.stats
4036                 done
4037                 error "OST not keeping write_bytes stats (b=22312)"
4038         fi
4039 }
4040 run_test 33c "test write_bytes stats"
4041
4042 test_33d() {
4043         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4045
4046         local MDTIDX=1
4047         local remote_dir=$DIR/$tdir/remote_dir
4048
4049         test_mkdir $DIR/$tdir
4050         $LFS mkdir -i $MDTIDX $remote_dir ||
4051                 error "create remote directory failed"
4052
4053         touch $remote_dir/$tfile
4054         chmod 444 $remote_dir/$tfile
4055         chown $RUNAS_ID $remote_dir/$tfile
4056
4057         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4058
4059         chown $RUNAS_ID $remote_dir
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4061                                         error "create" || true
4062         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4063                                     error "open RDWR" || true
4064         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4065 }
4066 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4067
4068 test_33e() {
4069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4070
4071         mkdir $DIR/$tdir
4072
4073         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4074         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4075         mkdir $DIR/$tdir/local_dir
4076
4077         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4078         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4079         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4080
4081         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4082                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4083
4084         rmdir $DIR/$tdir/* || error "rmdir failed"
4085
4086         umask 777
4087         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4088         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4089         mkdir $DIR/$tdir/local_dir
4090
4091         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4092         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4093         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4094
4095         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4096                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4097
4098         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4099
4100         umask 000
4101         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4102         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4103         mkdir $DIR/$tdir/local_dir
4104
4105         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4106         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4107         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4108
4109         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4110                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4111 }
4112 run_test 33e "mkdir and striped directory should have same mode"
4113
4114 cleanup_33f() {
4115         trap 0
4116         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4117 }
4118
4119 test_33f() {
4120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4121         remote_mds_nodsh && skip "remote MDS with nodsh"
4122
4123         mkdir $DIR/$tdir
4124         chmod go+rwx $DIR/$tdir
4125         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4126         trap cleanup_33f EXIT
4127
4128         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4129                 error "cannot create striped directory"
4130
4131         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4132                 error "cannot create files in striped directory"
4133
4134         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4135                 error "cannot remove files in striped directory"
4136
4137         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4138                 error "cannot remove striped directory"
4139
4140         cleanup_33f
4141 }
4142 run_test 33f "nonroot user can create, access, and remove a striped directory"
4143
4144 test_33g() {
4145         mkdir -p $DIR/$tdir/dir2
4146
4147         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4148         echo $err
4149         [[ $err =~ "exists" ]] || error "Not exists error"
4150 }
4151 run_test 33g "nonroot user create already existing root created file"
4152
4153 test_33h() {
4154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4155         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4156                 skip "Need MDS version at least 2.13.50"
4157
4158         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4159                 error "mkdir $tdir failed"
4160         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4161
4162         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4163         local index2
4164
4165         for fname in $DIR/$tdir/$tfile.bak \
4166                      $DIR/$tdir/$tfile.SAV \
4167                      $DIR/$tdir/$tfile.orig \
4168                      $DIR/$tdir/$tfile~; do
4169                 touch $fname  || error "touch $fname failed"
4170                 index2=$($LFS getstripe -m $fname)
4171                 [ $index -eq $index2 ] ||
4172                         error "$fname MDT index mismatch $index != $index2"
4173         done
4174
4175         local failed=0
4176         for i in {1..250}; do
4177                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4178                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4179                         touch $fname  || error "touch $fname failed"
4180                         index2=$($LFS getstripe -m $fname)
4181                         if [[ $index != $index2 ]]; then
4182                                 failed=$((failed + 1))
4183                                 echo "$fname MDT index mismatch $index != $index2"
4184                         fi
4185                 done
4186         done
4187         echo "$failed MDT index mismatches"
4188         (( failed < 20 )) || error "MDT index mismatch $failed times"
4189
4190 }
4191 run_test 33h "temp file is located on the same MDT as target"
4192
4193 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4194 test_34a() {
4195         rm -f $DIR/f34
4196         $MCREATE $DIR/f34 || error "mcreate failed"
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4198                 error "getstripe failed"
4199         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4200         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4201                 error "getstripe failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204 }
4205 run_test 34a "truncate file that has not been opened ==========="
4206
4207 test_34b() {
4208         [ ! -f $DIR/f34 ] && test_34a
4209         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4210                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4211         $OPENFILE -f O_RDONLY $DIR/f34
4212         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4213                 error "getstripe failed"
4214         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4215                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4216 }
4217 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4218
4219 test_34c() {
4220         [ ! -f $DIR/f34 ] && test_34a
4221         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4222                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4223         $OPENFILE -f O_RDWR $DIR/f34
4224         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4225                 error "$LFS getstripe failed"
4226         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4227                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4228 }
4229 run_test 34c "O_RDWR opening file-with-size works =============="
4230
4231 test_34d() {
4232         [ ! -f $DIR/f34 ] && test_34a
4233         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4234                 error "dd failed"
4235         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4236                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4237         rm $DIR/f34
4238 }
4239 run_test 34d "write to sparse file ============================="
4240
4241 test_34e() {
4242         rm -f $DIR/f34e
4243         $MCREATE $DIR/f34e || error "mcreate failed"
4244         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4245         $CHECKSTAT -s 1000 $DIR/f34e ||
4246                 error "Size of $DIR/f34e not equal to 1000 bytes"
4247         $OPENFILE -f O_RDWR $DIR/f34e
4248         $CHECKSTAT -s 1000 $DIR/f34e ||
4249                 error "Size of $DIR/f34e not equal to 1000 bytes"
4250 }
4251 run_test 34e "create objects, some with size and some without =="
4252
4253 test_34f() { # bug 6242, 6243
4254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4255
4256         SIZE34F=48000
4257         rm -f $DIR/f34f
4258         $MCREATE $DIR/f34f || error "mcreate failed"
4259         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4260         dd if=$DIR/f34f of=$TMP/f34f
4261         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4262         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4263         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4264         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4265         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4266 }
4267 run_test 34f "read from a file with no objects until EOF ======="
4268
4269 test_34g() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4273                 error "dd failed"
4274         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4275         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4276                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4277         cancel_lru_locks osc
4278         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4279                 error "wrong size after lock cancel"
4280
4281         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4282         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4283                 error "expanding truncate failed"
4284         cancel_lru_locks osc
4285         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4286                 error "wrong expanded size after lock cancel"
4287 }
4288 run_test 34g "truncate long file ==============================="
4289
4290 test_34h() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         local gid=10
4294         local sz=1000
4295
4296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4297         sync # Flush the cache so that multiop below does not block on cache
4298              # flush when getting the group lock
4299         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4300         MULTIPID=$!
4301
4302         # Since just timed wait is not good enough, let's do a sync write
4303         # that way we are sure enough time for a roundtrip + processing
4304         # passed + 2 seconds of extra margin.
4305         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4306         rm $DIR/${tfile}-1
4307         sleep 2
4308
4309         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4310                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4311                 kill -9 $MULTIPID
4312         fi
4313         wait $MULTIPID
4314         local nsz=`stat -c %s $DIR/$tfile`
4315         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4316 }
4317 run_test 34h "ftruncate file under grouplock should not block"
4318
4319 test_35a() {
4320         cp /bin/sh $DIR/f35a
4321         chmod 444 $DIR/f35a
4322         chown $RUNAS_ID $DIR/f35a
4323         $RUNAS $DIR/f35a && error || true
4324         rm $DIR/f35a
4325 }
4326 run_test 35a "exec file with mode 444 (should return and not leak)"
4327
4328 test_36a() {
4329         rm -f $DIR/f36
4330         utime $DIR/f36 || error "utime failed for MDS"
4331 }
4332 run_test 36a "MDS utime check (mknod, utime)"
4333
4334 test_36b() {
4335         echo "" > $DIR/f36
4336         utime $DIR/f36 || error "utime failed for OST"
4337 }
4338 run_test 36b "OST utime check (open, utime)"
4339
4340 test_36c() {
4341         rm -f $DIR/d36/f36
4342         test_mkdir $DIR/d36
4343         chown $RUNAS_ID $DIR/d36
4344         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4345 }
4346 run_test 36c "non-root MDS utime check (mknod, utime)"
4347
4348 test_36d() {
4349         [ ! -d $DIR/d36 ] && test_36c
4350         echo "" > $DIR/d36/f36
4351         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4352 }
4353 run_test 36d "non-root OST utime check (open, utime)"
4354
4355 test_36e() {
4356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4357
4358         test_mkdir $DIR/$tdir
4359         touch $DIR/$tdir/$tfile
4360         $RUNAS utime $DIR/$tdir/$tfile &&
4361                 error "utime worked, expected failure" || true
4362 }
4363 run_test 36e "utime on non-owned file (should return error)"
4364
4365 subr_36fh() {
4366         local fl="$1"
4367         local LANG_SAVE=$LANG
4368         local LC_LANG_SAVE=$LC_LANG
4369         export LANG=C LC_LANG=C # for date language
4370
4371         DATESTR="Dec 20  2000"
4372         test_mkdir $DIR/$tdir
4373         lctl set_param fail_loc=$fl
4374         date; date +%s
4375         cp /etc/hosts $DIR/$tdir/$tfile
4376         sync & # write RPC generated with "current" inode timestamp, but delayed
4377         sleep 1
4378         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4379         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4380         cancel_lru_locks $OSC
4381         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4382         date; date +%s
4383         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4384                 echo "BEFORE: $LS_BEFORE" && \
4385                 echo "AFTER : $LS_AFTER" && \
4386                 echo "WANT  : $DATESTR" && \
4387                 error "$DIR/$tdir/$tfile timestamps changed" || true
4388
4389         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4390 }
4391
4392 test_36f() {
4393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4394
4395         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4396         subr_36fh "0x80000214"
4397 }
4398 run_test 36f "utime on file racing with OST BRW write =========="
4399
4400 test_36g() {
4401         remote_ost_nodsh && skip "remote OST with nodsh"
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4404                 skip "Need MDS version at least 2.12.51"
4405
4406         local fmd_max_age
4407         local fmd
4408         local facet="ost1"
4409         local tgt="obdfilter"
4410
4411         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4412
4413         test_mkdir $DIR/$tdir
4414         fmd_max_age=$(do_facet $facet \
4415                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4416                 head -n 1")
4417
4418         echo "FMD max age: ${fmd_max_age}s"
4419         touch $DIR/$tdir/$tfile
4420         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4421                 gawk '{cnt=cnt+$1}  END{print cnt}')
4422         echo "FMD before: $fmd"
4423         [[ $fmd == 0 ]] &&
4424                 error "FMD wasn't create by touch"
4425         sleep $((fmd_max_age + 12))
4426         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4427                 gawk '{cnt=cnt+$1}  END{print cnt}')
4428         echo "FMD after: $fmd"
4429         [[ $fmd == 0 ]] ||
4430                 error "FMD wasn't expired by ping"
4431 }
4432 run_test 36g "FMD cache expiry ====================="
4433
4434 test_36h() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4438         subr_36fh "0x80000227"
4439 }
4440 run_test 36h "utime on file racing with OST BRW write =========="
4441
4442 test_36i() {
4443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4444
4445         test_mkdir $DIR/$tdir
4446         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4447
4448         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4449         local new_mtime=$((mtime + 200))
4450
4451         #change Modify time of striped dir
4452         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4453                         error "change mtime failed"
4454
4455         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4456
4457         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4458 }
4459 run_test 36i "change mtime on striped directory"
4460
4461 # test_37 - duplicate with tests 32q 32r
4462
4463 test_38() {
4464         local file=$DIR/$tfile
4465         touch $file
4466         openfile -f O_DIRECTORY $file
4467         local RC=$?
4468         local ENOTDIR=20
4469         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4470         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4471 }
4472 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4473
4474 test_39a() { # was test_39
4475         touch $DIR/$tfile
4476         touch $DIR/${tfile}2
4477 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4479 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4480         sleep 2
4481         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4482         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4483                 echo "mtime"
4484                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "atime"
4486                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4487                 echo "ctime"
4488                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4489                 error "O_TRUNC didn't change timestamps"
4490         fi
4491 }
4492 run_test 39a "mtime changed on create"
4493
4494 test_39b() {
4495         test_mkdir -c1 $DIR/$tdir
4496         cp -p /etc/passwd $DIR/$tdir/fopen
4497         cp -p /etc/passwd $DIR/$tdir/flink
4498         cp -p /etc/passwd $DIR/$tdir/funlink
4499         cp -p /etc/passwd $DIR/$tdir/frename
4500         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4501
4502         sleep 1
4503         echo "aaaaaa" >> $DIR/$tdir/fopen
4504         echo "aaaaaa" >> $DIR/$tdir/flink
4505         echo "aaaaaa" >> $DIR/$tdir/funlink
4506         echo "aaaaaa" >> $DIR/$tdir/frename
4507
4508         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4509         local link_new=`stat -c %Y $DIR/$tdir/flink`
4510         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4511         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4512
4513         cat $DIR/$tdir/fopen > /dev/null
4514         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4515         rm -f $DIR/$tdir/funlink2
4516         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4517
4518         for (( i=0; i < 2; i++ )) ; do
4519                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4520                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4521                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4522                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4523
4524                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4525                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4526                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4527                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4528
4529                 cancel_lru_locks $OSC
4530                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4531         done
4532 }
4533 run_test 39b "mtime change on open, link, unlink, rename  ======"
4534
4535 # this should be set to past
4536 TEST_39_MTIME=`date -d "1 year ago" +%s`
4537
4538 # bug 11063
4539 test_39c() {
4540         touch $DIR1/$tfile
4541         sleep 2
4542         local mtime0=`stat -c %Y $DIR1/$tfile`
4543
4544         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4545         local mtime1=`stat -c %Y $DIR1/$tfile`
4546         [ "$mtime1" = $TEST_39_MTIME ] || \
4547                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4548
4549         local d1=`date +%s`
4550         echo hello >> $DIR1/$tfile
4551         local d2=`date +%s`
4552         local mtime2=`stat -c %Y $DIR1/$tfile`
4553         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4554                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4555
4556         mv $DIR1/$tfile $DIR1/$tfile-1
4557
4558         for (( i=0; i < 2; i++ )) ; do
4559                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4560                 [ "$mtime2" = "$mtime3" ] || \
4561                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4562
4563                 cancel_lru_locks $OSC
4564                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4565         done
4566 }
4567 run_test 39c "mtime change on rename ==========================="
4568
4569 # bug 21114
4570 test_39d() {
4571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4572
4573         touch $DIR1/$tfile
4574         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4575
4576         for (( i=0; i < 2; i++ )) ; do
4577                 local mtime=`stat -c %Y $DIR1/$tfile`
4578                 [ $mtime = $TEST_39_MTIME ] || \
4579                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4580
4581                 cancel_lru_locks $OSC
4582                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4583         done
4584 }
4585 run_test 39d "create, utime, stat =============================="
4586
4587 # bug 21114
4588 test_39e() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         touch $DIR1/$tfile
4592         local mtime1=`stat -c %Y $DIR1/$tfile`
4593
4594         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4595
4596         for (( i=0; i < 2; i++ )) ; do
4597                 local mtime2=`stat -c %Y $DIR1/$tfile`
4598                 [ $mtime2 = $TEST_39_MTIME ] || \
4599                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4600
4601                 cancel_lru_locks $OSC
4602                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4603         done
4604 }
4605 run_test 39e "create, stat, utime, stat ========================"
4606
4607 # bug 21114
4608 test_39f() {
4609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4610
4611         touch $DIR1/$tfile
4612         mtime1=`stat -c %Y $DIR1/$tfile`
4613
4614         sleep 2
4615         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4616
4617         for (( i=0; i < 2; i++ )) ; do
4618                 local mtime2=`stat -c %Y $DIR1/$tfile`
4619                 [ $mtime2 = $TEST_39_MTIME ] || \
4620                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4621
4622                 cancel_lru_locks $OSC
4623                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4624         done
4625 }
4626 run_test 39f "create, stat, sleep, utime, stat ================="
4627
4628 # bug 11063
4629 test_39g() {
4630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4631
4632         echo hello >> $DIR1/$tfile
4633         local mtime1=`stat -c %Y $DIR1/$tfile`
4634
4635         sleep 2
4636         chmod o+r $DIR1/$tfile
4637
4638         for (( i=0; i < 2; i++ )) ; do
4639                 local mtime2=`stat -c %Y $DIR1/$tfile`
4640                 [ "$mtime1" = "$mtime2" ] || \
4641                         error "lost mtime: $mtime2, should be $mtime1"
4642
4643                 cancel_lru_locks $OSC
4644                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645         done
4646 }
4647 run_test 39g "write, chmod, stat ==============================="
4648
4649 # bug 11063
4650 test_39h() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         local d1=`date`
4657         echo hello >> $DIR1/$tfile
4658         local mtime1=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local d2=`date`
4662         if [ "$d1" != "$d2" ]; then
4663                 echo "write and touch not within one second"
4664         else
4665                 for (( i=0; i < 2; i++ )) ; do
4666                         local mtime2=`stat -c %Y $DIR1/$tfile`
4667                         [ "$mtime2" = $TEST_39_MTIME ] || \
4668                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4669
4670                         cancel_lru_locks $OSC
4671                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4672                 done
4673         fi
4674 }
4675 run_test 39h "write, utime within one second, stat ============="
4676
4677 test_39i() {
4678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4679
4680         touch $DIR1/$tfile
4681         sleep 1
4682
4683         echo hello >> $DIR1/$tfile
4684         local mtime1=`stat -c %Y $DIR1/$tfile`
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4690
4691                 [ "$mtime1" = "$mtime2" ] || \
4692                         error "lost mtime: $mtime2, should be $mtime1"
4693
4694                 cancel_lru_locks $OSC
4695                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4696         done
4697 }
4698 run_test 39i "write, rename, stat =============================="
4699
4700 test_39j() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         start_full_debug_logging
4704         touch $DIR1/$tfile
4705         sleep 1
4706
4707         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4708         lctl set_param fail_loc=0x80000412
4709         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4710                 error "multiop failed"
4711         local multipid=$!
4712         local mtime1=`stat -c %Y $DIR1/$tfile`
4713
4714         mv $DIR1/$tfile $DIR1/$tfile-1
4715
4716         kill -USR1 $multipid
4717         wait $multipid || error "multiop close failed"
4718
4719         for (( i=0; i < 2; i++ )) ; do
4720                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4721                 [ "$mtime1" = "$mtime2" ] ||
4722                         error "mtime is lost on close: $mtime2, " \
4723                               "should be $mtime1"
4724
4725                 cancel_lru_locks
4726                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4727         done
4728         lctl set_param fail_loc=0
4729         stop_full_debug_logging
4730 }
4731 run_test 39j "write, rename, close, stat ======================="
4732
4733 test_39k() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         touch $DIR1/$tfile
4737         sleep 1
4738
4739         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4740         local multipid=$!
4741         local mtime1=`stat -c %Y $DIR1/$tfile`
4742
4743         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4744
4745         kill -USR1 $multipid
4746         wait $multipid || error "multiop close failed"
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local mtime2=`stat -c %Y $DIR1/$tfile`
4750
4751                 [ "$mtime2" = $TEST_39_MTIME ] || \
4752                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4753
4754                 cancel_lru_locks
4755                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4756         done
4757 }
4758 run_test 39k "write, utime, close, stat ========================"
4759
4760 # this should be set to future
4761 TEST_39_ATIME=`date -d "1 year" +%s`
4762
4763 test_39l() {
4764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4765         remote_mds_nodsh && skip "remote MDS with nodsh"
4766
4767         local atime_diff=$(do_facet $SINGLEMDS \
4768                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4769         rm -rf $DIR/$tdir
4770         mkdir_on_mdt0 $DIR/$tdir
4771
4772         # test setting directory atime to future
4773         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4774         local atime=$(stat -c %X $DIR/$tdir)
4775         [ "$atime" = $TEST_39_ATIME ] ||
4776                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4777
4778         # test setting directory atime from future to now
4779         local now=$(date +%s)
4780         touch -a -d @$now $DIR/$tdir
4781
4782         atime=$(stat -c %X $DIR/$tdir)
4783         [ "$atime" -eq "$now"  ] ||
4784                 error "atime is not updated from future: $atime, $now"
4785
4786         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4787         sleep 3
4788
4789         # test setting directory atime when now > dir atime + atime_diff
4790         local d1=$(date +%s)
4791         ls $DIR/$tdir
4792         local d2=$(date +%s)
4793         cancel_lru_locks mdc
4794         atime=$(stat -c %X $DIR/$tdir)
4795         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4796                 error "atime is not updated  : $atime, should be $d2"
4797
4798         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4799         sleep 3
4800
4801         # test not setting directory atime when now < dir atime + atime_diff
4802         ls $DIR/$tdir
4803         cancel_lru_locks mdc
4804         atime=$(stat -c %X $DIR/$tdir)
4805         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4806                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4807
4808         do_facet $SINGLEMDS \
4809                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4810 }
4811 run_test 39l "directory atime update ==========================="
4812
4813 test_39m() {
4814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4815
4816         touch $DIR1/$tfile
4817         sleep 2
4818         local far_past_mtime=$(date -d "May 29 1953" +%s)
4819         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4820
4821         touch -m -d @$far_past_mtime $DIR1/$tfile
4822         touch -a -d @$far_past_atime $DIR1/$tfile
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4826                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4827                         error "atime or mtime set incorrectly"
4828
4829                 cancel_lru_locks $OSC
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832 }
4833 run_test 39m "test atime and mtime before 1970"
4834
4835 test_39n() { # LU-3832
4836         remote_mds_nodsh && skip "remote MDS with nodsh"
4837
4838         local atime_diff=$(do_facet $SINGLEMDS \
4839                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4840         local atime0
4841         local atime1
4842         local atime2
4843
4844         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4845
4846         rm -rf $DIR/$tfile
4847         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4848         atime0=$(stat -c %X $DIR/$tfile)
4849
4850         sleep 5
4851         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4852         atime1=$(stat -c %X $DIR/$tfile)
4853
4854         sleep 5
4855         cancel_lru_locks mdc
4856         cancel_lru_locks osc
4857         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4858         atime2=$(stat -c %X $DIR/$tfile)
4859
4860         do_facet $SINGLEMDS \
4861                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4862
4863         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4864         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4865 }
4866 run_test 39n "check that O_NOATIME is honored"
4867
4868 test_39o() {
4869         TESTDIR=$DIR/$tdir/$tfile
4870         [ -e $TESTDIR ] && rm -rf $TESTDIR
4871         mkdir -p $TESTDIR
4872         cd $TESTDIR
4873         links1=2
4874         ls
4875         mkdir a b
4876         ls
4877         links2=$(stat -c %h .)
4878         [ $(($links1 + 2)) != $links2 ] &&
4879                 error "wrong links count $(($links1 + 2)) != $links2"
4880         rmdir b
4881         links3=$(stat -c %h .)
4882         [ $(($links1 + 1)) != $links3 ] &&
4883                 error "wrong links count $links1 != $links3"
4884         return 0
4885 }
4886 run_test 39o "directory cached attributes updated after create"
4887
4888 test_39p() {
4889         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4890
4891         local MDTIDX=1
4892         TESTDIR=$DIR/$tdir/$tdir
4893         [ -e $TESTDIR ] && rm -rf $TESTDIR
4894         test_mkdir -p $TESTDIR
4895         cd $TESTDIR
4896         links1=2
4897         ls
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4899         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4900         ls
4901         links2=$(stat -c %h .)
4902         [ $(($links1 + 2)) != $links2 ] &&
4903                 error "wrong links count $(($links1 + 2)) != $links2"
4904         rmdir remote_dir2
4905         links3=$(stat -c %h .)
4906         [ $(($links1 + 1)) != $links3 ] &&
4907                 error "wrong links count $links1 != $links3"
4908         return 0
4909 }
4910 run_test 39p "remote directory cached attributes updated after create ========"
4911
4912 test_39r() {
4913         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4914                 skip "no atime update on old OST"
4915         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4916                 skip_env "ldiskfs only test"
4917         fi
4918
4919         local saved_adiff
4920         saved_adiff=$(do_facet ost1 \
4921                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4922         stack_trap "do_facet ost1 \
4923                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4924
4925         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4926
4927         $LFS setstripe -i 0 $DIR/$tfile
4928         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4929                 error "can't write initial file"
4930         cancel_lru_locks osc
4931
4932         # exceed atime_diff and access file
4933         sleep 6
4934         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4935                 error "can't udpate atime"
4936
4937         local atime_cli=$(stat -c %X $DIR/$tfile)
4938         echo "client atime: $atime_cli"
4939         # allow atime update to be written to device
4940         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4941         sleep 5
4942
4943         local ostdev=$(ostdevname 1)
4944         local fid=($(lfs getstripe -y $DIR/$tfile |
4945                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4946         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4947         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4948
4949         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4950         local atime_ost=$(do_facet ost1 "$cmd" |&
4951                           awk -F'[: ]' '/atime:/ { print $4 }')
4952         (( atime_cli == atime_ost )) ||
4953                 error "atime on client $atime_cli != ost $atime_ost"
4954 }
4955 run_test 39r "lazy atime update on OST"
4956
4957 test_39q() { # LU-8041
4958         local testdir=$DIR/$tdir
4959         mkdir -p $testdir
4960         multiop_bg_pause $testdir D_c || error "multiop failed"
4961         local multipid=$!
4962         cancel_lru_locks mdc
4963         kill -USR1 $multipid
4964         local atime=$(stat -c %X $testdir)
4965         [ "$atime" -ne 0 ] || error "atime is zero"
4966 }
4967 run_test 39q "close won't zero out atime"
4968
4969 test_40() {
4970         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4971         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4972                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4973         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4974                 error "$tfile is not 4096 bytes in size"
4975 }
4976 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4977
4978 test_41() {
4979         # bug 1553
4980         small_write $DIR/f41 18
4981 }
4982 run_test 41 "test small file write + fstat ====================="
4983
4984 count_ost_writes() {
4985         lctl get_param -n ${OSC}.*.stats |
4986                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4987                         END { printf("%0.0f", writes) }'
4988 }
4989
4990 # decent default
4991 WRITEBACK_SAVE=500
4992 DIRTY_RATIO_SAVE=40
4993 MAX_DIRTY_RATIO=50
4994 BG_DIRTY_RATIO_SAVE=10
4995 MAX_BG_DIRTY_RATIO=25
4996
4997 start_writeback() {
4998         trap 0
4999         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5000         # dirty_ratio, dirty_background_ratio
5001         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5002                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5003                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5004                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5005         else
5006                 # if file not here, we are a 2.4 kernel
5007                 kill -CONT `pidof kupdated`
5008         fi
5009 }
5010
5011 stop_writeback() {
5012         # setup the trap first, so someone cannot exit the test at the
5013         # exact wrong time and mess up a machine
5014         trap start_writeback EXIT
5015         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5016         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5017                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 sysctl -w vm.dirty_writeback_centisecs=0
5020                 # save and increase /proc/sys/vm/dirty_ratio
5021                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5022                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5023                 # save and increase /proc/sys/vm/dirty_background_ratio
5024                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5025                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5026         else
5027                 # if file not here, we are a 2.4 kernel
5028                 kill -STOP `pidof kupdated`
5029         fi
5030 }
5031
5032 # ensure that all stripes have some grant before we test client-side cache
5033 setup_test42() {
5034         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5035                 dd if=/dev/zero of=$i bs=4k count=1
5036                 rm $i
5037         done
5038 }
5039
5040 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5041 # file truncation, and file removal.
5042 test_42a() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         setup_test42
5046         cancel_lru_locks $OSC
5047         stop_writeback
5048         sync; sleep 1; sync # just to be safe
5049         BEFOREWRITES=`count_ost_writes`
5050         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5051         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5052         AFTERWRITES=`count_ost_writes`
5053         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5054                 error "$BEFOREWRITES < $AFTERWRITES"
5055         start_writeback
5056 }
5057 run_test 42a "ensure that we don't flush on close"
5058
5059 test_42b() {
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         setup_test42
5063         cancel_lru_locks $OSC
5064         stop_writeback
5065         sync
5066         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5067         BEFOREWRITES=$(count_ost_writes)
5068         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5069         AFTERWRITES=$(count_ost_writes)
5070         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5071                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5072         fi
5073         BEFOREWRITES=$(count_ost_writes)
5074         sync || error "sync: $?"
5075         AFTERWRITES=$(count_ost_writes)
5076         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5077                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5078         fi
5079         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5080         start_writeback
5081         return 0
5082 }
5083 run_test 42b "test destroy of file with cached dirty data ======"
5084
5085 # if these tests just want to test the effect of truncation,
5086 # they have to be very careful.  consider:
5087 # - the first open gets a {0,EOF}PR lock
5088 # - the first write conflicts and gets a {0, count-1}PW
5089 # - the rest of the writes are under {count,EOF}PW
5090 # - the open for truncate tries to match a {0,EOF}PR
5091 #   for the filesize and cancels the PWs.
5092 # any number of fixes (don't get {0,EOF} on open, match
5093 # composite locks, do smarter file size management) fix
5094 # this, but for now we want these tests to verify that
5095 # the cancellation with truncate intent works, so we
5096 # start the file with a full-file pw lock to match against
5097 # until the truncate.
5098 trunc_test() {
5099         test=$1
5100         file=$DIR/$test
5101         offset=$2
5102         cancel_lru_locks $OSC
5103         stop_writeback
5104         # prime the file with 0,EOF PW to match
5105         touch $file
5106         $TRUNCATE $file 0
5107         sync; sync
5108         # now the real test..
5109         dd if=/dev/zero of=$file bs=1024 count=100
5110         BEFOREWRITES=`count_ost_writes`
5111         $TRUNCATE $file $offset
5112         cancel_lru_locks $OSC
5113         AFTERWRITES=`count_ost_writes`
5114         start_writeback
5115 }
5116
5117 test_42c() {
5118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5119
5120         trunc_test 42c 1024
5121         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5122                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5123         rm $file
5124 }
5125 run_test 42c "test partial truncate of file with cached dirty data"
5126
5127 test_42d() {
5128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5129
5130         trunc_test 42d 0
5131         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5132                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5133         rm $file
5134 }
5135 run_test 42d "test complete truncate of file with cached dirty data"
5136
5137 test_42e() { # bug22074
5138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5139
5140         local TDIR=$DIR/${tdir}e
5141         local pages=16 # hardcoded 16 pages, don't change it.
5142         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5143         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5144         local max_dirty_mb
5145         local warmup_files
5146
5147         test_mkdir $DIR/${tdir}e
5148         $LFS setstripe -c 1 $TDIR
5149         createmany -o $TDIR/f $files
5150
5151         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5152
5153         # we assume that with $OSTCOUNT files, at least one of them will
5154         # be allocated on OST0.
5155         warmup_files=$((OSTCOUNT * max_dirty_mb))
5156         createmany -o $TDIR/w $warmup_files
5157
5158         # write a large amount of data into one file and sync, to get good
5159         # avail_grant number from OST.
5160         for ((i=0; i<$warmup_files; i++)); do
5161                 idx=$($LFS getstripe -i $TDIR/w$i)
5162                 [ $idx -ne 0 ] && continue
5163                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5164                 break
5165         done
5166         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5167         sync
5168         $LCTL get_param $proc_osc0/cur_dirty_bytes
5169         $LCTL get_param $proc_osc0/cur_grant_bytes
5170
5171         # create as much dirty pages as we can while not to trigger the actual
5172         # RPCs directly. but depends on the env, VFS may trigger flush during this
5173         # period, hopefully we are good.
5174         for ((i=0; i<$warmup_files; i++)); do
5175                 idx=$($LFS getstripe -i $TDIR/w$i)
5176                 [ $idx -ne 0 ] && continue
5177                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5178         done
5179         $LCTL get_param $proc_osc0/cur_dirty_bytes
5180         $LCTL get_param $proc_osc0/cur_grant_bytes
5181
5182         # perform the real test
5183         $LCTL set_param $proc_osc0/rpc_stats 0
5184         for ((;i<$files; i++)); do
5185                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5186                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5187         done
5188         sync
5189         $LCTL get_param $proc_osc0/rpc_stats
5190
5191         local percent=0
5192         local have_ppr=false
5193         $LCTL get_param $proc_osc0/rpc_stats |
5194                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5195                         # skip lines until we are at the RPC histogram data
5196                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5197                         $have_ppr || continue
5198
5199                         # we only want the percent stat for < 16 pages
5200                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5201
5202                         percent=$((percent + WPCT))
5203                         if [[ $percent -gt 15 ]]; then
5204                                 error "less than 16-pages write RPCs" \
5205                                       "$percent% > 15%"
5206                                 break
5207                         fi
5208                 done
5209         rm -rf $TDIR
5210 }
5211 run_test 42e "verify sub-RPC writes are not done synchronously"
5212
5213 test_43A() { # was test_43
5214         test_mkdir $DIR/$tdir
5215         cp -p /bin/ls $DIR/$tdir/$tfile
5216         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5217         pid=$!
5218         # give multiop a chance to open
5219         sleep 1
5220
5221         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5222         kill -USR1 $pid
5223         # Wait for multiop to exit
5224         wait $pid
5225 }
5226 run_test 43A "execution of file opened for write should return -ETXTBSY"
5227
5228 test_43a() {
5229         test_mkdir $DIR/$tdir
5230         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5231         $DIR/$tdir/sleep 60 &
5232         SLEEP_PID=$!
5233         # Make sure exec of $tdir/sleep wins race with truncate
5234         sleep 1
5235         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5236         kill $SLEEP_PID
5237 }
5238 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5239
5240 test_43b() {
5241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5242
5243         test_mkdir $DIR/$tdir
5244         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5245         $DIR/$tdir/sleep 60 &
5246         SLEEP_PID=$!
5247         # Make sure exec of $tdir/sleep wins race with truncate
5248         sleep 1
5249         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5250         kill $SLEEP_PID
5251 }
5252 run_test 43b "truncate of file being executed should return -ETXTBSY"
5253
5254 test_43c() {
5255         local testdir="$DIR/$tdir"
5256         test_mkdir $testdir
5257         cp $SHELL $testdir/
5258         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5259                 ( cd $testdir && md5sum -c )
5260 }
5261 run_test 43c "md5sum of copy into lustre"
5262
5263 test_44A() { # was test_44
5264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5265
5266         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5267         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5268 }
5269 run_test 44A "zero length read from a sparse stripe"
5270
5271 test_44a() {
5272         local nstripe=$($LFS getstripe -c -d $DIR)
5273         [ -z "$nstripe" ] && skip "can't get stripe info"
5274         [[ $nstripe -gt $OSTCOUNT ]] &&
5275                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5276
5277         local stride=$($LFS getstripe -S -d $DIR)
5278         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5279                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5280         fi
5281
5282         OFFSETS="0 $((stride/2)) $((stride-1))"
5283         for offset in $OFFSETS; do
5284                 for i in $(seq 0 $((nstripe-1))); do
5285                         local GLOBALOFFSETS=""
5286                         # size in Bytes
5287                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5288                         local myfn=$DIR/d44a-$size
5289                         echo "--------writing $myfn at $size"
5290                         ll_sparseness_write $myfn $size ||
5291                                 error "ll_sparseness_write"
5292                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5293                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5294                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5295
5296                         for j in $(seq 0 $((nstripe-1))); do
5297                                 # size in Bytes
5298                                 size=$((((j + $nstripe )*$stride + $offset)))
5299                                 ll_sparseness_write $myfn $size ||
5300                                         error "ll_sparseness_write"
5301                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5302                         done
5303                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5304                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5305                         rm -f $myfn
5306                 done
5307         done
5308 }
5309 run_test 44a "test sparse pwrite ==============================="
5310
5311 dirty_osc_total() {
5312         tot=0
5313         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5314                 tot=$(($tot + $d))
5315         done
5316         echo $tot
5317 }
5318 do_dirty_record() {
5319         before=`dirty_osc_total`
5320         echo executing "\"$*\""
5321         eval $*
5322         after=`dirty_osc_total`
5323         echo before $before, after $after
5324 }
5325 test_45() {
5326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5327
5328         f="$DIR/f45"
5329         # Obtain grants from OST if it supports it
5330         echo blah > ${f}_grant
5331         stop_writeback
5332         sync
5333         do_dirty_record "echo blah > $f"
5334         [[ $before -eq $after ]] && error "write wasn't cached"
5335         do_dirty_record "> $f"
5336         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5337         do_dirty_record "echo blah > $f"
5338         [[ $before -eq $after ]] && error "write wasn't cached"
5339         do_dirty_record "sync"
5340         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5341         do_dirty_record "echo blah > $f"
5342         [[ $before -eq $after ]] && error "write wasn't cached"
5343         do_dirty_record "cancel_lru_locks osc"
5344         [[ $before -gt $after ]] ||
5345                 error "lock cancellation didn't lower dirty count"
5346         start_writeback
5347 }
5348 run_test 45 "osc io page accounting ============================"
5349
5350 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5351 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5352 # objects offset and an assert hit when an rpc was built with 1023's mapped
5353 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5354 test_46() {
5355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5356
5357         f="$DIR/f46"
5358         stop_writeback
5359         sync
5360         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5361         sync
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5363         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5364         sync
5365         start_writeback
5366 }
5367 run_test 46 "dirtying a previously written page ================"
5368
5369 # test_47 is removed "Device nodes check" is moved to test_28
5370
5371 test_48a() { # bug 2399
5372         [ "$mds1_FSTYPE" = "zfs" ] &&
5373         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5374                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5375
5376         test_mkdir $DIR/$tdir
5377         cd $DIR/$tdir
5378         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5379         test_mkdir $DIR/$tdir
5380         touch foo || error "'touch foo' failed after recreating cwd"
5381         test_mkdir bar
5382         touch .foo || error "'touch .foo' failed after recreating cwd"
5383         test_mkdir .bar
5384         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5385         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5386         cd . || error "'cd .' failed after recreating cwd"
5387         mkdir . && error "'mkdir .' worked after recreating cwd"
5388         rmdir . && error "'rmdir .' worked after recreating cwd"
5389         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5390         cd .. || error "'cd ..' failed after recreating cwd"
5391 }
5392 run_test 48a "Access renamed working dir (should return errors)="
5393
5394 test_48b() { # bug 2399
5395         rm -rf $DIR/$tdir
5396         test_mkdir $DIR/$tdir
5397         cd $DIR/$tdir
5398         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5399         touch foo && error "'touch foo' worked after removing cwd"
5400         mkdir foo && error "'mkdir foo' worked after removing cwd"
5401         touch .foo && error "'touch .foo' worked after removing cwd"
5402         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5403         ls . > /dev/null && error "'ls .' worked after removing cwd"
5404         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5405         mkdir . && error "'mkdir .' worked after removing cwd"
5406         rmdir . && error "'rmdir .' worked after removing cwd"
5407         ln -s . foo && error "'ln -s .' worked after removing cwd"
5408         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5409 }
5410 run_test 48b "Access removed working dir (should return errors)="
5411
5412 test_48c() { # bug 2350
5413         #lctl set_param debug=-1
5414         #set -vx
5415         rm -rf $DIR/$tdir
5416         test_mkdir -p $DIR/$tdir/dir
5417         cd $DIR/$tdir/dir
5418         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5419         $TRACE touch foo && error "touch foo worked after removing cwd"
5420         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5421         touch .foo && error "touch .foo worked after removing cwd"
5422         mkdir .foo && error "mkdir .foo worked after removing cwd"
5423         $TRACE ls . && error "'ls .' worked after removing cwd"
5424         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5425         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5426         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5427         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5428         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5429 }
5430 run_test 48c "Access removed working subdir (should return errors)"
5431
5432 test_48d() { # bug 2350
5433         #lctl set_param debug=-1
5434         #set -vx
5435         rm -rf $DIR/$tdir
5436         test_mkdir -p $DIR/$tdir/dir
5437         cd $DIR/$tdir/dir
5438         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5439         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5440         $TRACE touch foo && error "'touch foo' worked after removing parent"
5441         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5442         touch .foo && error "'touch .foo' worked after removing parent"
5443         mkdir .foo && error "mkdir .foo worked after removing parent"
5444         $TRACE ls . && error "'ls .' worked after removing parent"
5445         $TRACE ls .. && error "'ls ..' worked after removing parent"
5446         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5447         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5448         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5449         true
5450 }
5451 run_test 48d "Access removed parent subdir (should return errors)"
5452
5453 test_48e() { # bug 4134
5454         #lctl set_param debug=-1
5455         #set -vx
5456         rm -rf $DIR/$tdir
5457         test_mkdir -p $DIR/$tdir/dir
5458         cd $DIR/$tdir/dir
5459         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5460         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5461         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5462         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5463         # On a buggy kernel addition of "touch foo" after cd .. will
5464         # produce kernel oops in lookup_hash_it
5465         touch ../foo && error "'cd ..' worked after recreate parent"
5466         cd $DIR
5467         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5468 }
5469 run_test 48e "Access to recreated parent subdir (should return errors)"
5470
5471 test_48f() {
5472         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5473                 skip "need MDS >= 2.13.55"
5474         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5475         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5476                 skip "needs different host for mdt1 mdt2"
5477         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5478
5479         $LFS mkdir -i0 $DIR/$tdir
5480         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5481
5482         for d in sub1 sub2 sub3; do
5483                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5484                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5485                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5486         done
5487
5488         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5489 }
5490 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5491
5492 test_49() { # LU-1030
5493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5494         remote_ost_nodsh && skip "remote OST with nodsh"
5495
5496         # get ost1 size - $FSNAME-OST0000
5497         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5498                 awk '{ print $4 }')
5499         # write 800M at maximum
5500         [[ $ost1_size -lt 2 ]] && ost1_size=2
5501         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5502
5503         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5504         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5505         local dd_pid=$!
5506
5507         # change max_pages_per_rpc while writing the file
5508         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5509         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5510         # loop until dd process exits
5511         while ps ax -opid | grep -wq $dd_pid; do
5512                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5513                 sleep $((RANDOM % 5 + 1))
5514         done
5515         # restore original max_pages_per_rpc
5516         $LCTL set_param $osc1_mppc=$orig_mppc
5517         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5518 }
5519 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5520
5521 test_50() {
5522         # bug 1485
5523         test_mkdir $DIR/$tdir
5524         cd $DIR/$tdir
5525         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5526 }
5527 run_test 50 "special situations: /proc symlinks  ==============="
5528
5529 test_51a() {    # was test_51
5530         # bug 1516 - create an empty entry right after ".." then split dir
5531         test_mkdir -c1 $DIR/$tdir
5532         touch $DIR/$tdir/foo
5533         $MCREATE $DIR/$tdir/bar
5534         rm $DIR/$tdir/foo
5535         createmany -m $DIR/$tdir/longfile 201
5536         FNUM=202
5537         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5538                 $MCREATE $DIR/$tdir/longfile$FNUM
5539                 FNUM=$(($FNUM + 1))
5540                 echo -n "+"
5541         done
5542         echo
5543         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5544 }
5545 run_test 51a "special situations: split htree with empty entry =="
5546
5547 cleanup_print_lfs_df () {
5548         trap 0
5549         $LFS df
5550         $LFS df -i
5551 }
5552
5553 test_51b() {
5554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5555
5556         local dir=$DIR/$tdir
5557         local nrdirs=$((65536 + 100))
5558
5559         # cleanup the directory
5560         rm -fr $dir
5561
5562         test_mkdir -c1 $dir
5563
5564         $LFS df
5565         $LFS df -i
5566         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5567         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5568         [[ $numfree -lt $nrdirs ]] &&
5569                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5570
5571         # need to check free space for the directories as well
5572         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5573         numfree=$(( blkfree / $(fs_inode_ksize) ))
5574         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5575
5576         trap cleanup_print_lfs_df EXIT
5577
5578         # create files
5579         createmany -d $dir/d $nrdirs || {
5580                 unlinkmany $dir/d $nrdirs
5581                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5582         }
5583
5584         # really created :
5585         nrdirs=$(ls -U $dir | wc -l)
5586
5587         # unlink all but 100 subdirectories, then check it still works
5588         local left=100
5589         local delete=$((nrdirs - left))
5590
5591         $LFS df
5592         $LFS df -i
5593
5594         # for ldiskfs the nlink count should be 1, but this is OSD specific
5595         # and so this is listed for informational purposes only
5596         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5597         unlinkmany -d $dir/d $delete ||
5598                 error "unlink of first $delete subdirs failed"
5599
5600         echo "nlink between: $(stat -c %h $dir)"
5601         local found=$(ls -U $dir | wc -l)
5602         [ $found -ne $left ] &&
5603                 error "can't find subdirs: found only $found, expected $left"
5604
5605         unlinkmany -d $dir/d $delete $left ||
5606                 error "unlink of second $left subdirs failed"
5607         # regardless of whether the backing filesystem tracks nlink accurately
5608         # or not, the nlink count shouldn't be more than "." and ".." here
5609         local after=$(stat -c %h $dir)
5610         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5611                 echo "nlink after: $after"
5612
5613         cleanup_print_lfs_df
5614 }
5615 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5616
5617 test_51d() {
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5620
5621         test_mkdir $DIR/$tdir
5622         createmany -o $DIR/$tdir/t- 1000
5623         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5624         for N in $(seq 0 $((OSTCOUNT - 1))); do
5625                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5626                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5627                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5628                         '($1 == '$N') { objs += 1 } \
5629                         END { printf("%0.0f", objs) }')
5630                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5631         done
5632         unlinkmany $DIR/$tdir/t- 1000
5633
5634         NLAST=0
5635         for N in $(seq 1 $((OSTCOUNT - 1))); do
5636                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5637                         error "OST $N has less objects vs OST $NLAST" \
5638                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5639                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5640                         error "OST $N has less objects vs OST $NLAST" \
5641                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5642
5643                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5644                         error "OST $N has less #0 objects vs OST $NLAST" \
5645                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5646                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5647                         error "OST $N has less #0 objects vs OST $NLAST" \
5648                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5649                 NLAST=$N
5650         done
5651         rm -f $TMP/$tfile
5652 }
5653 run_test 51d "check object distribution"
5654
5655 test_51e() {
5656         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5657                 skip_env "ldiskfs only test"
5658         fi
5659
5660         test_mkdir -c1 $DIR/$tdir
5661         test_mkdir -c1 $DIR/$tdir/d0
5662
5663         touch $DIR/$tdir/d0/foo
5664         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5665                 error "file exceed 65000 nlink limit!"
5666         unlinkmany $DIR/$tdir/d0/f- 65001
5667         return 0
5668 }
5669 run_test 51e "check file nlink limit"
5670
5671 test_51f() {
5672         test_mkdir $DIR/$tdir
5673
5674         local max=100000
5675         local ulimit_old=$(ulimit -n)
5676         local spare=20 # number of spare fd's for scripts/libraries, etc.
5677         local mdt=$($LFS getstripe -m $DIR/$tdir)
5678         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5679
5680         echo "MDT$mdt numfree=$numfree, max=$max"
5681         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5682         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5683                 while ! ulimit -n $((numfree + spare)); do
5684                         numfree=$((numfree * 3 / 4))
5685                 done
5686                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5687         else
5688                 echo "left ulimit at $ulimit_old"
5689         fi
5690
5691         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5692                 unlinkmany $DIR/$tdir/f $numfree
5693                 error "create+open $numfree files in $DIR/$tdir failed"
5694         }
5695         ulimit -n $ulimit_old
5696
5697         # if createmany exits at 120s there will be fewer than $numfree files
5698         unlinkmany $DIR/$tdir/f $numfree || true
5699 }
5700 run_test 51f "check many open files limit"
5701
5702 test_52a() {
5703         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5704         test_mkdir $DIR/$tdir
5705         touch $DIR/$tdir/foo
5706         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5707         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5708         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5709         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5710         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5711                                         error "link worked"
5712         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5713         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5714         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5715                                                      error "lsattr"
5716         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5717         cp -r $DIR/$tdir $TMP/
5718         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5719 }
5720 run_test 52a "append-only flag test (should return errors)"
5721
5722 test_52b() {
5723         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5724         test_mkdir $DIR/$tdir
5725         touch $DIR/$tdir/foo
5726         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5727         cat test > $DIR/$tdir/foo && error "cat test worked"
5728         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5729         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5730         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5731                                         error "link worked"
5732         echo foo >> $DIR/$tdir/foo && error "echo worked"
5733         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5734         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5735         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5736         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5737                                                         error "lsattr"
5738         chattr -i $DIR/$tdir/foo || error "chattr failed"
5739
5740         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5741 }
5742 run_test 52b "immutable flag test (should return errors) ======="
5743
5744 test_53() {
5745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5746         remote_mds_nodsh && skip "remote MDS with nodsh"
5747         remote_ost_nodsh && skip "remote OST with nodsh"
5748
5749         local param
5750         local param_seq
5751         local ostname
5752         local mds_last
5753         local mds_last_seq
5754         local ost_last
5755         local ost_last_seq
5756         local ost_last_id
5757         local ostnum
5758         local node
5759         local found=false
5760         local support_last_seq=true
5761
5762         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5763                 support_last_seq=false
5764
5765         # only test MDT0000
5766         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5767         local value
5768         for value in $(do_facet $SINGLEMDS \
5769                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5770                 param=$(echo ${value[0]} | cut -d "=" -f1)
5771                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5772
5773                 if $support_last_seq; then
5774                         param_seq=$(echo $param |
5775                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5776                         mds_last_seq=$(do_facet $SINGLEMDS \
5777                                        $LCTL get_param -n $param_seq)
5778                 fi
5779                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5780
5781                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5782                 node=$(facet_active_host ost$((ostnum+1)))
5783                 param="obdfilter.$ostname.last_id"
5784                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5785                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5786                         ost_last_id=$ost_last
5787
5788                         if $support_last_seq; then
5789                                 ost_last_id=$(echo $ost_last |
5790                                               awk -F':' '{print $2}' |
5791                                               sed -e "s/^0x//g")
5792                                 ost_last_seq=$(echo $ost_last |
5793                                                awk -F':' '{print $1}')
5794                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5795                         fi
5796
5797                         if [[ $ost_last_id != $mds_last ]]; then
5798                                 error "$ost_last_id != $mds_last"
5799                         else
5800                                 found=true
5801                                 break
5802                         fi
5803                 done
5804         done
5805         $found || error "can not match last_seq/last_id for $mdtosc"
5806         return 0
5807 }
5808 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5809
5810 test_54a() {
5811         perl -MSocket -e ';' || skip "no Socket perl module installed"
5812
5813         $SOCKETSERVER $DIR/socket ||
5814                 error "$SOCKETSERVER $DIR/socket failed: $?"
5815         $SOCKETCLIENT $DIR/socket ||
5816                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5817         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5818 }
5819 run_test 54a "unix domain socket test =========================="
5820
5821 test_54b() {
5822         f="$DIR/f54b"
5823         mknod $f c 1 3
5824         chmod 0666 $f
5825         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5826 }
5827 run_test 54b "char device works in lustre ======================"
5828
5829 find_loop_dev() {
5830         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5831         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5832         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5833
5834         for i in $(seq 3 7); do
5835                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5836                 LOOPDEV=$LOOPBASE$i
5837                 LOOPNUM=$i
5838                 break
5839         done
5840 }
5841
5842 cleanup_54c() {
5843         local rc=0
5844         loopdev="$DIR/loop54c"
5845
5846         trap 0
5847         $UMOUNT $DIR/$tdir || rc=$?
5848         losetup -d $loopdev || true
5849         losetup -d $LOOPDEV || true
5850         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5851         return $rc
5852 }
5853
5854 test_54c() {
5855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5856
5857         loopdev="$DIR/loop54c"
5858
5859         find_loop_dev
5860         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5861         trap cleanup_54c EXIT
5862         mknod $loopdev b 7 $LOOPNUM
5863         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5864         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5865         losetup $loopdev $DIR/$tfile ||
5866                 error "can't set up $loopdev for $DIR/$tfile"
5867         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5868         test_mkdir $DIR/$tdir
5869         mount -t ext2 $loopdev $DIR/$tdir ||
5870                 error "error mounting $loopdev on $DIR/$tdir"
5871         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5872                 error "dd write"
5873         df $DIR/$tdir
5874         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5875                 error "dd read"
5876         cleanup_54c
5877 }
5878 run_test 54c "block device works in lustre ====================="
5879
5880 test_54d() {
5881         f="$DIR/f54d"
5882         string="aaaaaa"
5883         mknod $f p
5884         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5885 }
5886 run_test 54d "fifo device works in lustre ======================"
5887
5888 test_54e() {
5889         f="$DIR/f54e"
5890         string="aaaaaa"
5891         cp -aL /dev/console $f
5892         echo $string > $f || error "echo $string to $f failed"
5893 }
5894 run_test 54e "console/tty device works in lustre ======================"
5895
5896 test_56a() {
5897         local numfiles=3
5898         local numdirs=2
5899         local dir=$DIR/$tdir
5900
5901         rm -rf $dir
5902         test_mkdir -p $dir/dir
5903         for i in $(seq $numfiles); do
5904                 touch $dir/file$i
5905                 touch $dir/dir/file$i
5906         done
5907
5908         local numcomp=$($LFS getstripe --component-count $dir)
5909
5910         [[ $numcomp == 0 ]] && numcomp=1
5911
5912         # test lfs getstripe with --recursive
5913         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5914
5915         [[ $filenum -eq $((numfiles * 2)) ]] ||
5916                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5917         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5918         [[ $filenum -eq $numfiles ]] ||
5919                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5920         echo "$LFS getstripe showed obdidx or l_ost_idx"
5921
5922         # test lfs getstripe with file instead of dir
5923         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5924         [[ $filenum -eq 1 ]] ||
5925                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5926         echo "$LFS getstripe file1 passed"
5927
5928         #test lfs getstripe with --verbose
5929         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5930         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5931                 error "$LFS getstripe --verbose $dir: "\
5932                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5933         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5934                 error "$LFS getstripe $dir: showed lmm_magic"
5935
5936         #test lfs getstripe with -v prints lmm_fid
5937         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5938         local countfids=$((numdirs + numfiles * numcomp))
5939         [[ $filenum -eq $countfids ]] ||
5940                 error "$LFS getstripe -v $dir: "\
5941                       "got $filenum want $countfids lmm_fid"
5942         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5943                 error "$LFS getstripe $dir: showed lmm_fid by default"
5944         echo "$LFS getstripe --verbose passed"
5945
5946         #check for FID information
5947         local fid1=$($LFS getstripe --fid $dir/file1)
5948         local fid2=$($LFS getstripe --verbose $dir/file1 |
5949                      awk '/lmm_fid: / { print $2; exit; }')
5950         local fid3=$($LFS path2fid $dir/file1)
5951
5952         [ "$fid1" != "$fid2" ] &&
5953                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5954         [ "$fid1" != "$fid3" ] &&
5955                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5956         echo "$LFS getstripe --fid passed"
5957
5958         #test lfs getstripe with --obd
5959         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5960                 error "$LFS getstripe --obd wrong_uuid: should return error"
5961
5962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5963
5964         local ostidx=1
5965         local obduuid=$(ostuuid_from_index $ostidx)
5966         local found=$($LFS getstripe -r --obd $obduuid $dir |
5967                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5968
5969         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5970         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5971                 ((filenum--))
5972         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5973                 ((filenum--))
5974
5975         [[ $found -eq $filenum ]] ||
5976                 error "$LFS getstripe --obd: found $found expect $filenum"
5977         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5978                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5979                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5980                 error "$LFS getstripe --obd: should not show file on other obd"
5981         echo "$LFS getstripe --obd passed"
5982 }
5983 run_test 56a "check $LFS getstripe"
5984
5985 test_56b() {
5986         local dir=$DIR/$tdir
5987         local numdirs=3
5988
5989         test_mkdir $dir
5990         for i in $(seq $numdirs); do
5991                 test_mkdir $dir/dir$i
5992         done
5993
5994         # test lfs getdirstripe default mode is non-recursion, which is
5995         # different from lfs getstripe
5996         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5997
5998         [[ $dircnt -eq 1 ]] ||
5999                 error "$LFS getdirstripe: found $dircnt, not 1"
6000         dircnt=$($LFS getdirstripe --recursive $dir |
6001                 grep -c lmv_stripe_count)
6002         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6003                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6004 }
6005 run_test 56b "check $LFS getdirstripe"
6006
6007 test_56c() {
6008         remote_ost_nodsh && skip "remote OST with nodsh"
6009
6010         local ost_idx=0
6011         local ost_name=$(ostname_from_index $ost_idx)
6012         local old_status=$(ost_dev_status $ost_idx)
6013         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6014
6015         [[ -z "$old_status" ]] ||
6016                 skip_env "OST $ost_name is in $old_status status"
6017
6018         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6019         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6020                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6021         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6022                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6023                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6024         fi
6025
6026         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6027                 error "$LFS df -v showing inactive devices"
6028         sleep_maxage
6029
6030         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6031
6032         [[ "$new_status" =~ "D" ]] ||
6033                 error "$ost_name status is '$new_status', missing 'D'"
6034         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6035                 [[ "$new_status" =~ "N" ]] ||
6036                         error "$ost_name status is '$new_status', missing 'N'"
6037         fi
6038         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6039                 [[ "$new_status" =~ "f" ]] ||
6040                         error "$ost_name status is '$new_status', missing 'f'"
6041         fi
6042
6043         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6044         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6045                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6046         [[ -z "$p" ]] && restore_lustre_params < $p || true
6047         sleep_maxage
6048
6049         new_status=$(ost_dev_status $ost_idx)
6050         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6051                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6052         # can't check 'f' as devices may actually be on flash
6053 }
6054 run_test 56c "check 'lfs df' showing device status"
6055
6056 test_56d() {
6057         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6058         local osts=$($LFS df -v $MOUNT | grep -c OST)
6059
6060         $LFS df $MOUNT
6061
6062         (( mdts == MDSCOUNT )) ||
6063                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6064         (( osts == OSTCOUNT )) ||
6065                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6066 }
6067 run_test 56d "'lfs df -v' prints only configured devices"
6068
6069 NUMFILES=3
6070 NUMDIRS=3
6071 setup_56() {
6072         local local_tdir="$1"
6073         local local_numfiles="$2"
6074         local local_numdirs="$3"
6075         local dir_params="$4"
6076         local dir_stripe_params="$5"
6077
6078         if [ ! -d "$local_tdir" ] ; then
6079                 test_mkdir -p $dir_stripe_params $local_tdir
6080                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6081                 for i in $(seq $local_numfiles) ; do
6082                         touch $local_tdir/file$i
6083                 done
6084                 for i in $(seq $local_numdirs) ; do
6085                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6086                         for j in $(seq $local_numfiles) ; do
6087                                 touch $local_tdir/dir$i/file$j
6088                         done
6089                 done
6090         fi
6091 }
6092
6093 setup_56_special() {
6094         local local_tdir=$1
6095         local local_numfiles=$2
6096         local local_numdirs=$3
6097
6098         setup_56 $local_tdir $local_numfiles $local_numdirs
6099
6100         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6101                 for i in $(seq $local_numfiles) ; do
6102                         mknod $local_tdir/loop${i}b b 7 $i
6103                         mknod $local_tdir/null${i}c c 1 3
6104                         ln -s $local_tdir/file1 $local_tdir/link${i}
6105                 done
6106                 for i in $(seq $local_numdirs) ; do
6107                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6108                         mknod $local_tdir/dir$i/null${i}c c 1 3
6109                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6110                 done
6111         fi
6112 }
6113
6114 test_56g() {
6115         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6116         local expected=$(($NUMDIRS + 2))
6117
6118         setup_56 $dir $NUMFILES $NUMDIRS
6119
6120         # test lfs find with -name
6121         for i in $(seq $NUMFILES) ; do
6122                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6123
6124                 [ $nums -eq $expected ] ||
6125                         error "lfs find -name '*$i' $dir wrong: "\
6126                               "found $nums, expected $expected"
6127         done
6128 }
6129 run_test 56g "check lfs find -name"
6130
6131 test_56h() {
6132         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6133         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6134
6135         setup_56 $dir $NUMFILES $NUMDIRS
6136
6137         # test lfs find with ! -name
6138         for i in $(seq $NUMFILES) ; do
6139                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6140
6141                 [ $nums -eq $expected ] ||
6142                         error "lfs find ! -name '*$i' $dir wrong: "\
6143                               "found $nums, expected $expected"
6144         done
6145 }
6146 run_test 56h "check lfs find ! -name"
6147
6148 test_56i() {
6149         local dir=$DIR/$tdir
6150
6151         test_mkdir $dir
6152
6153         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6154         local out=$($cmd)
6155
6156         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6157 }
6158 run_test 56i "check 'lfs find -ost UUID' skips directories"
6159
6160 test_56j() {
6161         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6162
6163         setup_56_special $dir $NUMFILES $NUMDIRS
6164
6165         local expected=$((NUMDIRS + 1))
6166         local cmd="$LFS find -type d $dir"
6167         local nums=$($cmd | wc -l)
6168
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171 }
6172 run_test 56j "check lfs find -type d"
6173
6174 test_56k() {
6175         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6176
6177         setup_56_special $dir $NUMFILES $NUMDIRS
6178
6179         local expected=$(((NUMDIRS + 1) * NUMFILES))
6180         local cmd="$LFS find -type f $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185 }
6186 run_test 56k "check lfs find -type f"
6187
6188 test_56l() {
6189         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6190
6191         setup_56_special $dir $NUMFILES $NUMDIRS
6192
6193         local expected=$((NUMDIRS + NUMFILES))
6194         local cmd="$LFS find -type b $dir"
6195         local nums=$($cmd | wc -l)
6196
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199 }
6200 run_test 56l "check lfs find -type b"
6201
6202 test_56m() {
6203         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6204
6205         setup_56_special $dir $NUMFILES $NUMDIRS
6206
6207         local expected=$((NUMDIRS + NUMFILES))
6208         local cmd="$LFS find -type c $dir"
6209         local nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212 }
6213 run_test 56m "check lfs find -type c"
6214
6215 test_56n() {
6216         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6217         setup_56_special $dir $NUMFILES $NUMDIRS
6218
6219         local expected=$((NUMDIRS + NUMFILES))
6220         local cmd="$LFS find -type l $dir"
6221         local nums=$($cmd | wc -l)
6222
6223         [ $nums -eq $expected ] ||
6224                 error "'$cmd' wrong: found $nums, expected $expected"
6225 }
6226 run_test 56n "check lfs find -type l"
6227
6228 test_56o() {
6229         local dir=$DIR/$tdir
6230
6231         setup_56 $dir $NUMFILES $NUMDIRS
6232         utime $dir/file1 > /dev/null || error "utime (1)"
6233         utime $dir/file2 > /dev/null || error "utime (2)"
6234         utime $dir/dir1 > /dev/null || error "utime (3)"
6235         utime $dir/dir2 > /dev/null || error "utime (4)"
6236         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6237         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6238
6239         local expected=4
6240         local nums=$($LFS find -mtime +0 $dir | wc -l)
6241
6242         [ $nums -eq $expected ] ||
6243                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6244
6245         expected=12
6246         cmd="$LFS find -mtime 0 $dir"
6247         nums=$($cmd | wc -l)
6248         [ $nums -eq $expected ] ||
6249                 error "'$cmd' wrong: found $nums, expected $expected"
6250 }
6251 run_test 56o "check lfs find -mtime for old files"
6252
6253 test_56ob() {
6254         local dir=$DIR/$tdir
6255         local expected=1
6256         local count=0
6257
6258         # just to make sure there is something that won't be found
6259         test_mkdir $dir
6260         touch $dir/$tfile.now
6261
6262         for age in year week day hour min; do
6263                 count=$((count + 1))
6264
6265                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6266                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6267                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6268
6269                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6270                 local nums=$($cmd | wc -l)
6271                 [ $nums -eq $expected ] ||
6272                         error "'$cmd' wrong: found $nums, expected $expected"
6273
6274                 cmd="$LFS find $dir -atime $count${age:0:1}"
6275                 nums=$($cmd | wc -l)
6276                 [ $nums -eq $expected ] ||
6277                         error "'$cmd' wrong: found $nums, expected $expected"
6278         done
6279
6280         sleep 2
6281         cmd="$LFS find $dir -ctime +1s -type f"
6282         nums=$($cmd | wc -l)
6283         (( $nums == $count * 2 + 1)) ||
6284                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6285 }
6286 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6287
6288 test_newerXY_base() {
6289         local x=$1
6290         local y=$2
6291         local dir=$DIR/$tdir
6292         local ref
6293         local negref
6294
6295         if [ $y == "t" ]; then
6296                 if [ $x == "b" ]; then
6297                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6298                 else
6299                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6300                 fi
6301         else
6302                 ref=$DIR/$tfile.newer.$x$y
6303                 touch $ref || error "touch $ref failed"
6304         fi
6305
6306         echo "before = $ref"
6307         sleep 2
6308         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6309         sleep 2
6310         if [ $y == "t" ]; then
6311                 if [ $x == "b" ]; then
6312                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6313                 else
6314                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6315                 fi
6316         else
6317                 negref=$DIR/$tfile.negnewer.$x$y
6318                 touch $negref || error "touch $negref failed"
6319         fi
6320
6321         echo "after = $negref"
6322         local cmd="$LFS find $dir -newer$x$y $ref"
6323         local nums=$(eval $cmd | wc -l)
6324         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6325
6326         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6327                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6328
6329         cmd="$LFS find $dir ! -newer$x$y $negref"
6330         nums=$(eval $cmd | wc -l)
6331         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6332                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6333
6334         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6335         nums=$(eval $cmd | wc -l)
6336         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6337                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6338
6339         rm -rf $DIR/*
6340 }
6341
6342 test_56oc() {
6343         test_newerXY_base "a" "a"
6344         test_newerXY_base "a" "m"
6345         test_newerXY_base "a" "c"
6346         test_newerXY_base "m" "a"
6347         test_newerXY_base "m" "m"
6348         test_newerXY_base "m" "c"
6349         test_newerXY_base "c" "a"
6350         test_newerXY_base "c" "m"
6351         test_newerXY_base "c" "c"
6352
6353         [[ -n "$sles_version" ]] &&
6354                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6355
6356         test_newerXY_base "a" "t"
6357         test_newerXY_base "m" "t"
6358         test_newerXY_base "c" "t"
6359
6360         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6361            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6362                 ! btime_supported && echo "btime unsupported" && return 0
6363
6364         test_newerXY_base "b" "b"
6365         test_newerXY_base "b" "t"
6366 }
6367 run_test 56oc "check lfs find -newerXY work"
6368
6369 btime_supported() {
6370         local dir=$DIR/$tdir
6371         local rc
6372
6373         mkdir -p $dir
6374         touch $dir/$tfile
6375         $LFS find $dir -btime -1d -type f
6376         rc=$?
6377         rm -rf $dir
6378         return $rc
6379 }
6380
6381 test_56od() {
6382         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6383                 ! btime_supported && skip "btime unsupported on MDS"
6384
6385         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6386                 ! btime_supported && skip "btime unsupported on clients"
6387
6388         local dir=$DIR/$tdir
6389         local ref=$DIR/$tfile.ref
6390         local negref=$DIR/$tfile.negref
6391
6392         mkdir $dir || error "mkdir $dir failed"
6393         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6394         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6395         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6396         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6397         touch $ref || error "touch $ref failed"
6398         # sleep 3 seconds at least
6399         sleep 3
6400
6401         local before=$(do_facet mds1 date +%s)
6402         local skew=$(($(date +%s) - before + 1))
6403
6404         if (( skew < 0 && skew > -5 )); then
6405                 sleep $((0 - skew + 1))
6406                 skew=0
6407         fi
6408
6409         # Set the dir stripe params to limit files all on MDT0,
6410         # otherwise we need to calc the max clock skew between
6411         # the client and MDTs.
6412         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6413         sleep 2
6414         touch $negref || error "touch $negref failed"
6415
6416         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6417         local nums=$($cmd | wc -l)
6418         local expected=$(((NUMFILES + 1) * NUMDIRS))
6419
6420         [ $nums -eq $expected ] ||
6421                 error "'$cmd' wrong: found $nums, expected $expected"
6422
6423         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6424         nums=$($cmd | wc -l)
6425         expected=$((NUMFILES + 1))
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         [ $skew -lt 0 ] && return
6430
6431         local after=$(do_facet mds1 date +%s)
6432         local age=$((after - before + 1 + skew))
6433
6434         cmd="$LFS find $dir -btime -${age}s -type f"
6435         nums=$($cmd | wc -l)
6436         expected=$(((NUMFILES + 1) * NUMDIRS))
6437
6438         echo "Clock skew between client and server: $skew, age:$age"
6439         [ $nums -eq $expected ] ||
6440                 error "'$cmd' wrong: found $nums, expected $expected"
6441
6442         expected=$(($NUMDIRS + 1))
6443         cmd="$LFS find $dir -btime -${age}s -type d"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447         rm -f $ref $negref || error "Failed to remove $ref $negref"
6448 }
6449 run_test 56od "check lfs find -btime with units"
6450
6451 test_56p() {
6452         [ $RUNAS_ID -eq $UID ] &&
6453                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6454
6455         local dir=$DIR/$tdir
6456
6457         setup_56 $dir $NUMFILES $NUMDIRS
6458         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6459
6460         local expected=$NUMFILES
6461         local cmd="$LFS find -uid $RUNAS_ID $dir"
6462         local nums=$($cmd | wc -l)
6463
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6468         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6469         nums=$($cmd | wc -l)
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472 }
6473 run_test 56p "check lfs find -uid and ! -uid"
6474
6475 test_56q() {
6476         [ $RUNAS_ID -eq $UID ] &&
6477                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6478
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6483
6484         local expected=$NUMFILES
6485         local cmd="$LFS find -gid $RUNAS_GID $dir"
6486         local nums=$($cmd | wc -l)
6487
6488         [ $nums -eq $expected ] ||
6489                 error "'$cmd' wrong: found $nums, expected $expected"
6490
6491         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6492         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6493         nums=$($cmd | wc -l)
6494         [ $nums -eq $expected ] ||
6495                 error "'$cmd' wrong: found $nums, expected $expected"
6496 }
6497 run_test 56q "check lfs find -gid and ! -gid"
6498
6499 test_56r() {
6500         local dir=$DIR/$tdir
6501
6502         setup_56 $dir $NUMFILES $NUMDIRS
6503
6504         local expected=12
6505         local cmd="$LFS find -size 0 -type f -lazy $dir"
6506         local nums=$($cmd | wc -l)
6507
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510         cmd="$LFS find -size 0 -type f $dir"
6511         nums=$($cmd | wc -l)
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         expected=0
6516         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520         cmd="$LFS find ! -size 0 -type f $dir"
6521         nums=$($cmd | wc -l)
6522         [ $nums -eq $expected ] ||
6523                 error "'$cmd' wrong: found $nums, expected $expected"
6524
6525         echo "test" > $dir/$tfile
6526         echo "test2" > $dir/$tfile.2 && sync
6527         expected=1
6528         cmd="$LFS find -size 5 -type f -lazy $dir"
6529         nums=$($cmd | wc -l)
6530         [ $nums -eq $expected ] ||
6531                 error "'$cmd' wrong: found $nums, expected $expected"
6532         cmd="$LFS find -size 5 -type f $dir"
6533         nums=$($cmd | wc -l)
6534         [ $nums -eq $expected ] ||
6535                 error "'$cmd' wrong: found $nums, expected $expected"
6536
6537         expected=1
6538         cmd="$LFS find -size +5 -type f -lazy $dir"
6539         nums=$($cmd | wc -l)
6540         [ $nums -eq $expected ] ||
6541                 error "'$cmd' wrong: found $nums, expected $expected"
6542         cmd="$LFS find -size +5 -type f $dir"
6543         nums=$($cmd | wc -l)
6544         [ $nums -eq $expected ] ||
6545                 error "'$cmd' wrong: found $nums, expected $expected"
6546
6547         expected=2
6548         cmd="$LFS find -size +0 -type f -lazy $dir"
6549         nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552         cmd="$LFS find -size +0 -type f $dir"
6553         nums=$($cmd | wc -l)
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         expected=2
6558         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6559         nums=$($cmd | wc -l)
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562         cmd="$LFS find ! -size -5 -type f $dir"
6563         nums=$($cmd | wc -l)
6564         [ $nums -eq $expected ] ||
6565                 error "'$cmd' wrong: found $nums, expected $expected"
6566
6567         expected=12
6568         cmd="$LFS find -size -5 -type f -lazy $dir"
6569         nums=$($cmd | wc -l)
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572         cmd="$LFS find -size -5 -type f $dir"
6573         nums=$($cmd | wc -l)
6574         [ $nums -eq $expected ] ||
6575                 error "'$cmd' wrong: found $nums, expected $expected"
6576 }
6577 run_test 56r "check lfs find -size works"
6578
6579 test_56ra_sub() {
6580         local expected=$1
6581         local glimpses=$2
6582         local cmd="$3"
6583
6584         cancel_lru_locks $OSC
6585
6586         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6587         local nums=$($cmd | wc -l)
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591
6592         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6593
6594         if (( rpcs_before + glimpses != rpcs_after )); then
6595                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6596                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6597
6598                 if [[ $glimpses == 0 ]]; then
6599                         error "'$cmd' should not send glimpse RPCs to OST"
6600                 else
6601                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6602                 fi
6603         fi
6604 }
6605
6606 test_56ra() {
6607         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6608                 skip "MDS < 2.12.58 doesn't return LSOM data"
6609         local dir=$DIR/$tdir
6610         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6611
6612         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6613
6614         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6615         $LCTL set_param -n llite.*.statahead_agl=0
6616         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6617
6618         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6619         # open and close all files to ensure LSOM is updated
6620         cancel_lru_locks $OSC
6621         find $dir -type f | xargs cat > /dev/null
6622
6623         #   expect_found  glimpse_rpcs  command_to_run
6624         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6625         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6626         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6627         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6628
6629         echo "test" > $dir/$tfile
6630         echo "test2" > $dir/$tfile.2 && sync
6631         cancel_lru_locks $OSC
6632         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6633
6634         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6635         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6636         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6637         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6638
6639         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6640         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6641         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6642         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6643         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6644         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6645 }
6646 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6647
6648 test_56rb() {
6649         local dir=$DIR/$tdir
6650         local tmp=$TMP/$tfile.log
6651         local mdt_idx;
6652
6653         test_mkdir -p $dir || error "failed to mkdir $dir"
6654         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6655                 error "failed to setstripe $dir/$tfile"
6656         mdt_idx=$($LFS getdirstripe -i $dir)
6657         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6658
6659         stack_trap "rm -f $tmp" EXIT
6660         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6661         ! grep -q obd_uuid $tmp ||
6662                 error "failed to find --size +100K --ost 0 $dir"
6663         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6664         ! grep -q obd_uuid $tmp ||
6665                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6666 }
6667 run_test 56rb "check lfs find --size --ost/--mdt works"
6668
6669 test_56rc() {
6670         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6671         local dir=$DIR/$tdir
6672         local found
6673
6674         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6675         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6676         (( $MDSCOUNT > 2 )) &&
6677                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6678         mkdir $dir/$tdir-{1..10}
6679         touch $dir/$tfile-{1..10}
6680
6681         found=$($LFS find $dir --mdt-count 2 | wc -l)
6682         expect=11
6683         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6684
6685         found=$($LFS find $dir -T +1 | wc -l)
6686         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6687         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6688
6689         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6690         expect=11
6691         (( $found == $expect )) || error "found $found all_char, expect $expect"
6692
6693         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6694         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6695         (( $found == $expect )) || error "found $found all_char, expect $expect"
6696 }
6697 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6698
6699 test_56s() { # LU-611 #LU-9369
6700         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6701
6702         local dir=$DIR/$tdir
6703         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6706         for i in $(seq $NUMDIRS); do
6707                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6708         done
6709
6710         local expected=$NUMDIRS
6711         local cmd="$LFS find -c $OSTCOUNT $dir"
6712         local nums=$($cmd | wc -l)
6713
6714         [ $nums -eq $expected ] || {
6715                 $LFS getstripe -R $dir
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717         }
6718
6719         expected=$((NUMDIRS + onestripe))
6720         cmd="$LFS find -stripe-count +0 -type f $dir"
6721         nums=$($cmd | wc -l)
6722         [ $nums -eq $expected ] || {
6723                 $LFS getstripe -R $dir
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725         }
6726
6727         expected=$onestripe
6728         cmd="$LFS find -stripe-count 1 -type f $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] || {
6731                 $LFS getstripe -R $dir
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         }
6734
6735         cmd="$LFS find -stripe-count -2 -type f $dir"
6736         nums=$($cmd | wc -l)
6737         [ $nums -eq $expected ] || {
6738                 $LFS getstripe -R $dir
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740         }
6741
6742         expected=0
6743         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] || {
6746                 $LFS getstripe -R $dir
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748         }
6749 }
6750 run_test 56s "check lfs find -stripe-count works"
6751
6752 test_56t() { # LU-611 #LU-9369
6753         local dir=$DIR/$tdir
6754
6755         setup_56 $dir 0 $NUMDIRS
6756         for i in $(seq $NUMDIRS); do
6757                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6758         done
6759
6760         local expected=$NUMDIRS
6761         local cmd="$LFS find -S 8M $dir"
6762         local nums=$($cmd | wc -l)
6763
6764         [ $nums -eq $expected ] || {
6765                 $LFS getstripe -R $dir
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767         }
6768         rm -rf $dir
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6771
6772         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6773
6774         expected=$(((NUMDIRS + 1) * NUMFILES))
6775         cmd="$LFS find -stripe-size 512k -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         cmd="$LFS find -stripe-size +320k -type f $dir"
6781         nums=$($cmd | wc -l)
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784
6785         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6786         cmd="$LFS find -stripe-size +200k -type f $dir"
6787         nums=$($cmd | wc -l)
6788         [ $nums -eq $expected ] ||
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790
6791         cmd="$LFS find -stripe-size -640k -type f $dir"
6792         nums=$($cmd | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795
6796         expected=4
6797         cmd="$LFS find -stripe-size 256k -type f $dir"
6798         nums=$($cmd | wc -l)
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         cmd="$LFS find -stripe-size -320k -type f $dir"
6803         nums=$($cmd | wc -l)
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806
6807         expected=0
6808         cmd="$LFS find -stripe-size 1024k -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812 }
6813 run_test 56t "check lfs find -stripe-size works"
6814
6815 test_56u() { # LU-611
6816         local dir=$DIR/$tdir
6817
6818         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6819
6820         if [[ $OSTCOUNT -gt 1 ]]; then
6821                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6822                 onestripe=4
6823         else
6824                 onestripe=0
6825         fi
6826
6827         local expected=$(((NUMDIRS + 1) * NUMFILES))
6828         local cmd="$LFS find -stripe-index 0 -type f $dir"
6829         local nums=$($cmd | wc -l)
6830
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         expected=$onestripe
6835         cmd="$LFS find -stripe-index 1 -type f $dir"
6836         nums=$($cmd | wc -l)
6837         [ $nums -eq $expected ] ||
6838                 error "'$cmd' wrong: found $nums, expected $expected"
6839
6840         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         expected=0
6846         # This should produce an error and not return any files
6847         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6848         nums=$($cmd 2>/dev/null | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851
6852         if [[ $OSTCOUNT -gt 1 ]]; then
6853                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6854                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6855                 nums=$($cmd | wc -l)
6856                 [ $nums -eq $expected ] ||
6857                         error "'$cmd' wrong: found $nums, expected $expected"
6858         fi
6859 }
6860 run_test 56u "check lfs find -stripe-index works"
6861
6862 test_56v() {
6863         local mdt_idx=0
6864         local dir=$DIR/$tdir
6865
6866         setup_56 $dir $NUMFILES $NUMDIRS
6867
6868         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6869         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6870
6871         for file in $($LFS find -m $UUID $dir); do
6872                 file_midx=$($LFS getstripe -m $file)
6873                 [ $file_midx -eq $mdt_idx ] ||
6874                         error "lfs find -m $UUID != getstripe -m $file_midx"
6875         done
6876 }
6877 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6878
6879 test_56w() {
6880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6882
6883         local dir=$DIR/$tdir
6884
6885         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6886
6887         local stripe_size=$($LFS getstripe -S -d $dir) ||
6888                 error "$LFS getstripe -S -d $dir failed"
6889         stripe_size=${stripe_size%% *}
6890
6891         local file_size=$((stripe_size * OSTCOUNT))
6892         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6893         local required_space=$((file_num * file_size))
6894         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6895                            head -n1)
6896         [[ $free_space -le $((required_space / 1024)) ]] &&
6897                 skip_env "need $required_space, have $free_space kbytes"
6898
6899         local dd_bs=65536
6900         local dd_count=$((file_size / dd_bs))
6901
6902         # write data into the files
6903         local i
6904         local j
6905         local file
6906
6907         for i in $(seq $NUMFILES); do
6908                 file=$dir/file$i
6909                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6910                         error "write data into $file failed"
6911         done
6912         for i in $(seq $NUMDIRS); do
6913                 for j in $(seq $NUMFILES); do
6914                         file=$dir/dir$i/file$j
6915                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6916                                 error "write data into $file failed"
6917                 done
6918         done
6919
6920         # $LFS_MIGRATE will fail if hard link migration is unsupported
6921         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6922                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6923                         error "creating links to $dir/dir1/file1 failed"
6924         fi
6925
6926         local expected=-1
6927
6928         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6929
6930         # lfs_migrate file
6931         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6932
6933         echo "$cmd"
6934         eval $cmd || error "$cmd failed"
6935
6936         check_stripe_count $dir/file1 $expected
6937
6938         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6939         then
6940                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6941                 # OST 1 if it is on OST 0. This file is small enough to
6942                 # be on only one stripe.
6943                 file=$dir/migr_1_ost
6944                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6945                         error "write data into $file failed"
6946                 local obdidx=$($LFS getstripe -i $file)
6947                 local oldmd5=$(md5sum $file)
6948                 local newobdidx=0
6949
6950                 [[ $obdidx -eq 0 ]] && newobdidx=1
6951                 cmd="$LFS migrate -i $newobdidx $file"
6952                 echo $cmd
6953                 eval $cmd || error "$cmd failed"
6954
6955                 local realobdix=$($LFS getstripe -i $file)
6956                 local newmd5=$(md5sum $file)
6957
6958                 [[ $newobdidx -ne $realobdix ]] &&
6959                         error "new OST is different (was=$obdidx, "\
6960                               "wanted=$newobdidx, got=$realobdix)"
6961                 [[ "$oldmd5" != "$newmd5" ]] &&
6962                         error "md5sum differ: $oldmd5, $newmd5"
6963         fi
6964
6965         # lfs_migrate dir
6966         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6967         echo "$cmd"
6968         eval $cmd || error "$cmd failed"
6969
6970         for j in $(seq $NUMFILES); do
6971                 check_stripe_count $dir/dir1/file$j $expected
6972         done
6973
6974         # lfs_migrate works with lfs find
6975         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6976              $LFS_MIGRATE -y -c $expected"
6977         echo "$cmd"
6978         eval $cmd || error "$cmd failed"
6979
6980         for i in $(seq 2 $NUMFILES); do
6981                 check_stripe_count $dir/file$i $expected
6982         done
6983         for i in $(seq 2 $NUMDIRS); do
6984                 for j in $(seq $NUMFILES); do
6985                 check_stripe_count $dir/dir$i/file$j $expected
6986                 done
6987         done
6988 }
6989 run_test 56w "check lfs_migrate -c stripe_count works"
6990
6991 test_56wb() {
6992         local file1=$DIR/$tdir/file1
6993         local create_pool=false
6994         local initial_pool=$($LFS getstripe -p $DIR)
6995         local pool_list=()
6996         local pool=""
6997
6998         echo -n "Creating test dir..."
6999         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7000         echo "done."
7001
7002         echo -n "Creating test file..."
7003         touch $file1 || error "cannot create file"
7004         echo "done."
7005
7006         echo -n "Detecting existing pools..."
7007         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7008
7009         if [ ${#pool_list[@]} -gt 0 ]; then
7010                 echo "${pool_list[@]}"
7011                 for thispool in "${pool_list[@]}"; do
7012                         if [[ -z "$initial_pool" ||
7013                               "$initial_pool" != "$thispool" ]]; then
7014                                 pool="$thispool"
7015                                 echo "Using existing pool '$pool'"
7016                                 break
7017                         fi
7018                 done
7019         else
7020                 echo "none detected."
7021         fi
7022         if [ -z "$pool" ]; then
7023                 pool=${POOL:-testpool}
7024                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7025                 echo -n "Creating pool '$pool'..."
7026                 create_pool=true
7027                 pool_add $pool &> /dev/null ||
7028                         error "pool_add failed"
7029                 echo "done."
7030
7031                 echo -n "Adding target to pool..."
7032                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7033                         error "pool_add_targets failed"
7034                 echo "done."
7035         fi
7036
7037         echo -n "Setting pool using -p option..."
7038         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7039                 error "migrate failed rc = $?"
7040         echo "done."
7041
7042         echo -n "Verifying test file is in pool after migrating..."
7043         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7044                 error "file was not migrated to pool $pool"
7045         echo "done."
7046
7047         echo -n "Removing test file from pool '$pool'..."
7048         # "lfs migrate $file" won't remove the file from the pool
7049         # until some striping information is changed.
7050         $LFS migrate -c 1 $file1 &> /dev/null ||
7051                 error "cannot remove from pool"
7052         [ "$($LFS getstripe -p $file1)" ] &&
7053                 error "pool still set"
7054         echo "done."
7055
7056         echo -n "Setting pool using --pool option..."
7057         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7058                 error "migrate failed rc = $?"
7059         echo "done."
7060
7061         # Clean up
7062         rm -f $file1
7063         if $create_pool; then
7064                 destroy_test_pools 2> /dev/null ||
7065                         error "destroy test pools failed"
7066         fi
7067 }
7068 run_test 56wb "check lfs_migrate pool support"
7069
7070 test_56wc() {
7071         local file1="$DIR/$tdir/file1"
7072         local parent_ssize
7073         local parent_scount
7074         local cur_ssize
7075         local cur_scount
7076         local orig_ssize
7077
7078         echo -n "Creating test dir..."
7079         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7080         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7081                 error "cannot set stripe by '-S 1M -c 1'"
7082         echo "done"
7083
7084         echo -n "Setting initial stripe for test file..."
7085         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7086                 error "cannot set stripe"
7087         cur_ssize=$($LFS getstripe -S "$file1")
7088         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7089         echo "done."
7090
7091         # File currently set to -S 512K -c 1
7092
7093         # Ensure -c and -S options are rejected when -R is set
7094         echo -n "Verifying incompatible options are detected..."
7095         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7096                 error "incompatible -c and -R options not detected"
7097         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7098                 error "incompatible -S and -R options not detected"
7099         echo "done."
7100
7101         # Ensure unrecognized options are passed through to 'lfs migrate'
7102         echo -n "Verifying -S option is passed through to lfs migrate..."
7103         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7104                 error "migration failed"
7105         cur_ssize=$($LFS getstripe -S "$file1")
7106         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7107         echo "done."
7108
7109         # File currently set to -S 1M -c 1
7110
7111         # Ensure long options are supported
7112         echo -n "Verifying long options supported..."
7113         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7114                 error "long option without argument not supported"
7115         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7116                 error "long option with argument not supported"
7117         cur_ssize=$($LFS getstripe -S "$file1")
7118         [ $cur_ssize -eq 524288 ] ||
7119                 error "migrate --stripe-size $cur_ssize != 524288"
7120         echo "done."
7121
7122         # File currently set to -S 512K -c 1
7123
7124         if [ "$OSTCOUNT" -gt 1 ]; then
7125                 echo -n "Verifying explicit stripe count can be set..."
7126                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7127                         error "migrate failed"
7128                 cur_scount=$($LFS getstripe -c "$file1")
7129                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7130                 echo "done."
7131         fi
7132
7133         # File currently set to -S 512K -c 1 or -S 512K -c 2
7134
7135         # Ensure parent striping is used if -R is set, and no stripe
7136         # count or size is specified
7137         echo -n "Setting stripe for parent directory..."
7138         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7139                 error "cannot set stripe '-S 2M -c 1'"
7140         echo "done."
7141
7142         echo -n "Verifying restripe option uses parent stripe settings..."
7143         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7144         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7145         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7146                 error "migrate failed"
7147         cur_ssize=$($LFS getstripe -S "$file1")
7148         [ $cur_ssize -eq $parent_ssize ] ||
7149                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7150         cur_scount=$($LFS getstripe -c "$file1")
7151         [ $cur_scount -eq $parent_scount ] ||
7152                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7153         echo "done."
7154
7155         # File currently set to -S 1M -c 1
7156
7157         # Ensure striping is preserved if -R is not set, and no stripe
7158         # count or size is specified
7159         echo -n "Verifying striping size preserved when not specified..."
7160         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7161         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7162                 error "cannot set stripe on parent directory"
7163         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7164                 error "migrate failed"
7165         cur_ssize=$($LFS getstripe -S "$file1")
7166         [ $cur_ssize -eq $orig_ssize ] ||
7167                 error "migrate by default $cur_ssize != $orig_ssize"
7168         echo "done."
7169
7170         # Ensure file name properly detected when final option has no argument
7171         echo -n "Verifying file name properly detected..."
7172         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7173                 error "file name interpreted as option argument"
7174         echo "done."
7175
7176         # Clean up
7177         rm -f "$file1"
7178 }
7179 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7180
7181 test_56wd() {
7182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7183
7184         local file1=$DIR/$tdir/file1
7185
7186         echo -n "Creating test dir..."
7187         test_mkdir $DIR/$tdir || error "cannot create dir"
7188         echo "done."
7189
7190         echo -n "Creating test file..."
7191         touch $file1
7192         echo "done."
7193
7194         # Ensure 'lfs migrate' will fail by using a non-existent option,
7195         # and make sure rsync is not called to recover
7196         echo -n "Make sure --no-rsync option works..."
7197         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7198                 grep -q 'refusing to fall back to rsync' ||
7199                 error "rsync was called with --no-rsync set"
7200         echo "done."
7201
7202         # Ensure rsync is called without trying 'lfs migrate' first
7203         echo -n "Make sure --rsync option works..."
7204         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7205                 grep -q 'falling back to rsync' &&
7206                 error "lfs migrate was called with --rsync set"
7207         echo "done."
7208
7209         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7210         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7211                 grep -q 'at the same time' ||
7212                 error "--rsync and --no-rsync accepted concurrently"
7213         echo "done."
7214
7215         # Clean up
7216         rm -f $file1
7217 }
7218 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7219
7220 test_56we() {
7221         local td=$DIR/$tdir
7222         local tf=$td/$tfile
7223
7224         test_mkdir $td || error "cannot create $td"
7225         touch $tf || error "cannot touch $tf"
7226
7227         echo -n "Make sure --non-direct|-D works..."
7228         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7229                 grep -q "lfs migrate --non-direct" ||
7230                 error "--non-direct option cannot work correctly"
7231         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7232                 grep -q "lfs migrate -D" ||
7233                 error "-D option cannot work correctly"
7234         echo "done."
7235 }
7236 run_test 56we "check lfs_migrate --non-direct|-D support"
7237
7238 test_56x() {
7239         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7240         check_swap_layouts_support
7241
7242         local dir=$DIR/$tdir
7243         local ref1=/etc/passwd
7244         local file1=$dir/file1
7245
7246         test_mkdir $dir || error "creating dir $dir"
7247         $LFS setstripe -c 2 $file1
7248         cp $ref1 $file1
7249         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7250         stripe=$($LFS getstripe -c $file1)
7251         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7252         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7253
7254         # clean up
7255         rm -f $file1
7256 }
7257 run_test 56x "lfs migration support"
7258
7259 test_56xa() {
7260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7261         check_swap_layouts_support
7262
7263         local dir=$DIR/$tdir/$testnum
7264
7265         test_mkdir -p $dir
7266
7267         local ref1=/etc/passwd
7268         local file1=$dir/file1
7269
7270         $LFS setstripe -c 2 $file1
7271         cp $ref1 $file1
7272         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7273
7274         local stripe=$($LFS getstripe -c $file1)
7275
7276         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7277         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7278
7279         # clean up
7280         rm -f $file1
7281 }
7282 run_test 56xa "lfs migration --block support"
7283
7284 check_migrate_links() {
7285         local dir="$1"
7286         local file1="$dir/file1"
7287         local begin="$2"
7288         local count="$3"
7289         local runas="$4"
7290         local total_count=$(($begin + $count - 1))
7291         local symlink_count=10
7292         local uniq_count=10
7293
7294         if [ ! -f "$file1" ]; then
7295                 echo -n "creating initial file..."
7296                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7297                         error "cannot setstripe initial file"
7298                 echo "done"
7299
7300                 echo -n "creating symlinks..."
7301                 for s in $(seq 1 $symlink_count); do
7302                         ln -s "$file1" "$dir/slink$s" ||
7303                                 error "cannot create symlinks"
7304                 done
7305                 echo "done"
7306
7307                 echo -n "creating nonlinked files..."
7308                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7309                         error "cannot create nonlinked files"
7310                 echo "done"
7311         fi
7312
7313         # create hard links
7314         if [ ! -f "$dir/file$total_count" ]; then
7315                 echo -n "creating hard links $begin:$total_count..."
7316                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7317                         /dev/null || error "cannot create hard links"
7318                 echo "done"
7319         fi
7320
7321         echo -n "checking number of hard links listed in xattrs..."
7322         local fid=$($LFS getstripe -F "$file1")
7323         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7324
7325         echo "${#paths[*]}"
7326         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7327                         skip "hard link list has unexpected size, skipping test"
7328         fi
7329         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7330                         error "link names should exceed xattrs size"
7331         fi
7332
7333         echo -n "migrating files..."
7334         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7335         local rc=$?
7336         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7337         echo "done"
7338
7339         # make sure all links have been properly migrated
7340         echo -n "verifying files..."
7341         fid=$($LFS getstripe -F "$file1") ||
7342                 error "cannot get fid for file $file1"
7343         for i in $(seq 2 $total_count); do
7344                 local fid2=$($LFS getstripe -F $dir/file$i)
7345
7346                 [ "$fid2" == "$fid" ] ||
7347                         error "migrated hard link has mismatched FID"
7348         done
7349
7350         # make sure hard links were properly detected, and migration was
7351         # performed only once for the entire link set; nonlinked files should
7352         # also be migrated
7353         local actual=$(grep -c 'done' <<< "$migrate_out")
7354         local expected=$(($uniq_count + 1))
7355
7356         [ "$actual" -eq  "$expected" ] ||
7357                 error "hard links individually migrated ($actual != $expected)"
7358
7359         # make sure the correct number of hard links are present
7360         local hardlinks=$(stat -c '%h' "$file1")
7361
7362         [ $hardlinks -eq $total_count ] ||
7363                 error "num hard links $hardlinks != $total_count"
7364         echo "done"
7365
7366         return 0
7367 }
7368
7369 test_56xb() {
7370         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7371                 skip "Need MDS version at least 2.10.55"
7372
7373         local dir="$DIR/$tdir"
7374
7375         test_mkdir "$dir" || error "cannot create dir $dir"
7376
7377         echo "testing lfs migrate mode when all links fit within xattrs"
7378         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7379
7380         echo "testing rsync mode when all links fit within xattrs"
7381         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7382
7383         echo "testing lfs migrate mode when all links do not fit within xattrs"
7384         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7385
7386         echo "testing rsync mode when all links do not fit within xattrs"
7387         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7388
7389         chown -R $RUNAS_ID $dir
7390         echo "testing non-root lfs migrate mode when not all links are in xattr"
7391         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7392
7393         # clean up
7394         rm -rf $dir
7395 }
7396 run_test 56xb "lfs migration hard link support"
7397
7398 test_56xc() {
7399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7400
7401         local dir="$DIR/$tdir"
7402
7403         test_mkdir "$dir" || error "cannot create dir $dir"
7404
7405         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7406         echo -n "Setting initial stripe for 20MB test file..."
7407         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7408                 error "cannot setstripe 20MB file"
7409         echo "done"
7410         echo -n "Sizing 20MB test file..."
7411         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7412         echo "done"
7413         echo -n "Verifying small file autostripe count is 1..."
7414         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7415                 error "cannot migrate 20MB file"
7416         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7417                 error "cannot get stripe for $dir/20mb"
7418         [ $stripe_count -eq 1 ] ||
7419                 error "unexpected stripe count $stripe_count for 20MB file"
7420         rm -f "$dir/20mb"
7421         echo "done"
7422
7423         # Test 2: File is small enough to fit within the available space on
7424         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7425         # have at least an additional 1KB for each desired stripe for test 3
7426         echo -n "Setting stripe for 1GB test file..."
7427         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7428         echo "done"
7429         echo -n "Sizing 1GB test file..."
7430         # File size is 1GB + 3KB
7431         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7432         echo "done"
7433
7434         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7435         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7436         if (( avail > 524288 * OSTCOUNT )); then
7437                 echo -n "Migrating 1GB file..."
7438                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7439                         error "cannot migrate 1GB file"
7440                 echo "done"
7441                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7442                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7443                         error "cannot getstripe for 1GB file"
7444                 [ $stripe_count -eq 2 ] ||
7445                         error "unexpected stripe count $stripe_count != 2"
7446                 echo "done"
7447         fi
7448
7449         # Test 3: File is too large to fit within the available space on
7450         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7451         if [ $OSTCOUNT -ge 3 ]; then
7452                 # The required available space is calculated as
7453                 # file size (1GB + 3KB) / OST count (3).
7454                 local kb_per_ost=349526
7455
7456                 echo -n "Migrating 1GB file with limit..."
7457                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7458                         error "cannot migrate 1GB file with limit"
7459                 echo "done"
7460
7461                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7462                 echo -n "Verifying 1GB autostripe count with limited space..."
7463                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7464                         error "unexpected stripe count $stripe_count (min 3)"
7465                 echo "done"
7466         fi
7467
7468         # clean up
7469         rm -rf $dir
7470 }
7471 run_test 56xc "lfs migration autostripe"
7472
7473 test_56xd() {
7474         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7475
7476         local dir=$DIR/$tdir
7477         local f_mgrt=$dir/$tfile.mgrt
7478         local f_yaml=$dir/$tfile.yaml
7479         local f_copy=$dir/$tfile.copy
7480         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7481         local layout_copy="-c 2 -S 2M -i 1"
7482         local yamlfile=$dir/yamlfile
7483         local layout_before;
7484         local layout_after;
7485
7486         test_mkdir "$dir" || error "cannot create dir $dir"
7487         $LFS setstripe $layout_yaml $f_yaml ||
7488                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7489         $LFS getstripe --yaml $f_yaml > $yamlfile
7490         $LFS setstripe $layout_copy $f_copy ||
7491                 error "cannot setstripe $f_copy with layout $layout_copy"
7492         touch $f_mgrt
7493         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7494
7495         # 1. test option --yaml
7496         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7497                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7498         layout_before=$(get_layout_param $f_yaml)
7499         layout_after=$(get_layout_param $f_mgrt)
7500         [ "$layout_after" == "$layout_before" ] ||
7501                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7502
7503         # 2. test option --copy
7504         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7505                 error "cannot migrate $f_mgrt with --copy $f_copy"
7506         layout_before=$(get_layout_param $f_copy)
7507         layout_after=$(get_layout_param $f_mgrt)
7508         [ "$layout_after" == "$layout_before" ] ||
7509                 error "lfs_migrate --copy: $layout_after != $layout_before"
7510 }
7511 run_test 56xd "check lfs_migrate --yaml and --copy support"
7512
7513 test_56xe() {
7514         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7515
7516         local dir=$DIR/$tdir
7517         local f_comp=$dir/$tfile
7518         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7519         local layout_before=""
7520         local layout_after=""
7521
7522         test_mkdir "$dir" || error "cannot create dir $dir"
7523         $LFS setstripe $layout $f_comp ||
7524                 error "cannot setstripe $f_comp with layout $layout"
7525         layout_before=$(get_layout_param $f_comp)
7526         dd if=/dev/zero of=$f_comp bs=1M count=4
7527
7528         # 1. migrate a comp layout file by lfs_migrate
7529         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7530         layout_after=$(get_layout_param $f_comp)
7531         [ "$layout_before" == "$layout_after" ] ||
7532                 error "lfs_migrate: $layout_before != $layout_after"
7533
7534         # 2. migrate a comp layout file by lfs migrate
7535         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7536         layout_after=$(get_layout_param $f_comp)
7537         [ "$layout_before" == "$layout_after" ] ||
7538                 error "lfs migrate: $layout_before != $layout_after"
7539 }
7540 run_test 56xe "migrate a composite layout file"
7541
7542 test_56xf() {
7543         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7544
7545         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7546                 skip "Need server version at least 2.13.53"
7547
7548         local dir=$DIR/$tdir
7549         local f_comp=$dir/$tfile
7550         local layout="-E 1M -c1 -E -1 -c2"
7551         local fid_before=""
7552         local fid_after=""
7553
7554         test_mkdir "$dir" || error "cannot create dir $dir"
7555         $LFS setstripe $layout $f_comp ||
7556                 error "cannot setstripe $f_comp with layout $layout"
7557         fid_before=$($LFS getstripe --fid $f_comp)
7558         dd if=/dev/zero of=$f_comp bs=1M count=4
7559
7560         # 1. migrate a comp layout file to a comp layout
7561         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7562         fid_after=$($LFS getstripe --fid $f_comp)
7563         [ "$fid_before" == "$fid_after" ] ||
7564                 error "comp-to-comp migrate: $fid_before != $fid_after"
7565
7566         # 2. migrate a comp layout file to a plain layout
7567         $LFS migrate -c2 $f_comp ||
7568                 error "cannot migrate $f_comp by lfs migrate"
7569         fid_after=$($LFS getstripe --fid $f_comp)
7570         [ "$fid_before" == "$fid_after" ] ||
7571                 error "comp-to-plain migrate: $fid_before != $fid_after"
7572
7573         # 3. migrate a plain layout file to a comp layout
7574         $LFS migrate $layout $f_comp ||
7575                 error "cannot migrate $f_comp by lfs migrate"
7576         fid_after=$($LFS getstripe --fid $f_comp)
7577         [ "$fid_before" == "$fid_after" ] ||
7578                 error "plain-to-comp migrate: $fid_before != $fid_after"
7579 }
7580 run_test 56xf "FID is not lost during migration of a composite layout file"
7581
7582 test_56y() {
7583         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7584                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7585
7586         local res=""
7587         local dir=$DIR/$tdir
7588         local f1=$dir/file1
7589         local f2=$dir/file2
7590
7591         test_mkdir -p $dir || error "creating dir $dir"
7592         touch $f1 || error "creating std file $f1"
7593         $MULTIOP $f2 H2c || error "creating released file $f2"
7594
7595         # a directory can be raid0, so ask only for files
7596         res=$($LFS find $dir -L raid0 -type f | wc -l)
7597         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7598
7599         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7600         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7601
7602         # only files can be released, so no need to force file search
7603         res=$($LFS find $dir -L released)
7604         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7605
7606         res=$($LFS find $dir -type f \! -L released)
7607         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7608 }
7609 run_test 56y "lfs find -L raid0|released"
7610
7611 test_56z() { # LU-4824
7612         # This checks to make sure 'lfs find' continues after errors
7613         # There are two classes of errors that should be caught:
7614         # - If multiple paths are provided, all should be searched even if one
7615         #   errors out
7616         # - If errors are encountered during the search, it should not terminate
7617         #   early
7618         local dir=$DIR/$tdir
7619         local i
7620
7621         test_mkdir $dir
7622         for i in d{0..9}; do
7623                 test_mkdir $dir/$i
7624                 touch $dir/$i/$tfile
7625         done
7626         $LFS find $DIR/non_existent_dir $dir &&
7627                 error "$LFS find did not return an error"
7628         # Make a directory unsearchable. This should NOT be the last entry in
7629         # directory order.  Arbitrarily pick the 6th entry
7630         chmod 700 $($LFS find $dir -type d | sed '6!d')
7631
7632         $RUNAS $LFS find $DIR/non_existent $dir
7633         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7634
7635         # The user should be able to see 10 directories and 9 files
7636         (( count == 19 )) ||
7637                 error "$LFS find found $count != 19 entries after error"
7638 }
7639 run_test 56z "lfs find should continue after an error"
7640
7641 test_56aa() { # LU-5937
7642         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7643
7644         local dir=$DIR/$tdir
7645
7646         mkdir $dir
7647         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7648
7649         createmany -o $dir/striped_dir/${tfile}- 1024
7650         local dirs=$($LFS find --size +8k $dir/)
7651
7652         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7653 }
7654 run_test 56aa "lfs find --size under striped dir"
7655
7656 test_56ab() { # LU-10705
7657         test_mkdir $DIR/$tdir
7658         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7659         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7660         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7661         # Flush writes to ensure valid blocks.  Need to be more thorough for
7662         # ZFS, since blocks are not allocated/returned to client immediately.
7663         sync_all_data
7664         wait_zfs_commit ost1 2
7665         cancel_lru_locks osc
7666         ls -ls $DIR/$tdir
7667
7668         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7669
7670         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7671
7672         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7673         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7674
7675         rm -f $DIR/$tdir/$tfile.[123]
7676 }
7677 run_test 56ab "lfs find --blocks"
7678
7679 # LU-11188
7680 test_56aca() {
7681         local dir="$DIR/$tdir"
7682         local perms=(001 002 003 004 005 006 007
7683                      010 020 030 040 050 060 070
7684                      100 200 300 400 500 600 700
7685                      111 222 333 444 555 666 777)
7686         local perm_minus=(8 8 4 8 4 4 2
7687                           8 8 4 8 4 4 2
7688                           8 8 4 8 4 4 2
7689                           4 4 2 4 2 2 1)
7690         local perm_slash=(8  8 12  8 12 12 14
7691                           8  8 12  8 12 12 14
7692                           8  8 12  8 12 12 14
7693                          16 16 24 16 24 24 28)
7694
7695         test_mkdir "$dir"
7696         for perm in ${perms[*]}; do
7697                 touch "$dir/$tfile.$perm"
7698                 chmod $perm "$dir/$tfile.$perm"
7699         done
7700
7701         for ((i = 0; i < ${#perms[*]}; i++)); do
7702                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7703                 (( $num == 1 )) ||
7704                         error "lfs find -perm ${perms[i]}:"\
7705                               "$num != 1"
7706
7707                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7708                 (( $num == ${perm_minus[i]} )) ||
7709                         error "lfs find -perm -${perms[i]}:"\
7710                               "$num != ${perm_minus[i]}"
7711
7712                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7713                 (( $num == ${perm_slash[i]} )) ||
7714                         error "lfs find -perm /${perms[i]}:"\
7715                               "$num != ${perm_slash[i]}"
7716         done
7717 }
7718 run_test 56aca "check lfs find -perm with octal representation"
7719
7720 test_56acb() {
7721         local dir=$DIR/$tdir
7722         # p is the permission of write and execute for user, group and other
7723         # without the umask. It is used to test +wx.
7724         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7725         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7726         local symbolic=(+t  a+t u+t g+t o+t
7727                         g+s u+s o+s +s o+sr
7728                         o=r,ug+o,u+w
7729                         u+ g+ o+ a+ ugo+
7730                         u- g- o- a- ugo-
7731                         u= g= o= a= ugo=
7732                         o=r,ug+o,u+w u=r,a+u,u+w
7733                         g=r,ugo=g,u+w u+x,+X +X
7734                         u+x,u+X u+X u+x,g+X o+r,+X
7735                         u+x,go+X +wx +rwx)
7736
7737         test_mkdir $dir
7738         for perm in ${perms[*]}; do
7739                 touch "$dir/$tfile.$perm"
7740                 chmod $perm "$dir/$tfile.$perm"
7741         done
7742
7743         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7744                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7745
7746                 (( $num == 1 )) ||
7747                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7748         done
7749 }
7750 run_test 56acb "check lfs find -perm with symbolic representation"
7751
7752 test_56acc() {
7753         local dir=$DIR/$tdir
7754         local tests="17777 787 789 abcd
7755                 ug=uu ug=a ug=gu uo=ou urw
7756                 u+xg+x a=r,u+x,"
7757
7758         test_mkdir $dir
7759         for err in $tests; do
7760                 if $LFS find $dir -perm $err 2>/dev/null; then
7761                         error "lfs find -perm $err: parsing should have failed"
7762                 fi
7763         done
7764 }
7765 run_test 56acc "check parsing error for lfs find -perm"
7766
7767 test_56ba() {
7768         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7769                 skip "Need MDS version at least 2.10.50"
7770
7771         # Create composite files with one component
7772         local dir=$DIR/$tdir
7773
7774         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7775         # Create composite files with three components
7776         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7777         # Create non-composite files
7778         createmany -o $dir/${tfile}- 10
7779
7780         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7781
7782         [[ $nfiles == 10 ]] ||
7783                 error "lfs find -E 1M found $nfiles != 10 files"
7784
7785         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7786         [[ $nfiles == 25 ]] ||
7787                 error "lfs find ! -E 1M found $nfiles != 25 files"
7788
7789         # All files have a component that starts at 0
7790         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7791         [[ $nfiles == 35 ]] ||
7792                 error "lfs find --component-start 0 - $nfiles != 35 files"
7793
7794         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7795         [[ $nfiles == 15 ]] ||
7796                 error "lfs find --component-start 2M - $nfiles != 15 files"
7797
7798         # All files created here have a componenet that does not starts at 2M
7799         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7800         [[ $nfiles == 35 ]] ||
7801                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7802
7803         # Find files with a specified number of components
7804         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7805         [[ $nfiles == 15 ]] ||
7806                 error "lfs find --component-count 3 - $nfiles != 15 files"
7807
7808         # Remember non-composite files have a component count of zero
7809         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7810         [[ $nfiles == 10 ]] ||
7811                 error "lfs find --component-count 0 - $nfiles != 10 files"
7812
7813         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7814         [[ $nfiles == 20 ]] ||
7815                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7816
7817         # All files have a flag called "init"
7818         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7819         [[ $nfiles == 35 ]] ||
7820                 error "lfs find --component-flags init - $nfiles != 35 files"
7821
7822         # Multi-component files will have a component not initialized
7823         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7824         [[ $nfiles == 15 ]] ||
7825                 error "lfs find !--component-flags init - $nfiles != 15 files"
7826
7827         rm -rf $dir
7828
7829 }
7830 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7831
7832 test_56ca() {
7833         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7834                 skip "Need MDS version at least 2.10.57"
7835
7836         local td=$DIR/$tdir
7837         local tf=$td/$tfile
7838         local dir
7839         local nfiles
7840         local cmd
7841         local i
7842         local j
7843
7844         # create mirrored directories and mirrored files
7845         mkdir $td || error "mkdir $td failed"
7846         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7847         createmany -o $tf- 10 || error "create $tf- failed"
7848
7849         for i in $(seq 2); do
7850                 dir=$td/dir$i
7851                 mkdir $dir || error "mkdir $dir failed"
7852                 $LFS mirror create -N$((3 + i)) $dir ||
7853                         error "create mirrored dir $dir failed"
7854                 createmany -o $dir/$tfile- 10 ||
7855                         error "create $dir/$tfile- failed"
7856         done
7857
7858         # change the states of some mirrored files
7859         echo foo > $tf-6
7860         for i in $(seq 2); do
7861                 dir=$td/dir$i
7862                 for j in $(seq 4 9); do
7863                         echo foo > $dir/$tfile-$j
7864                 done
7865         done
7866
7867         # find mirrored files with specific mirror count
7868         cmd="$LFS find --mirror-count 3 --type f $td"
7869         nfiles=$($cmd | wc -l)
7870         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7871
7872         cmd="$LFS find ! --mirror-count 3 --type f $td"
7873         nfiles=$($cmd | wc -l)
7874         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7875
7876         cmd="$LFS find --mirror-count +2 --type f $td"
7877         nfiles=$($cmd | wc -l)
7878         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7879
7880         cmd="$LFS find --mirror-count -6 --type f $td"
7881         nfiles=$($cmd | wc -l)
7882         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7883
7884         # find mirrored files with specific file state
7885         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7886         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7887
7888         cmd="$LFS find --mirror-state=ro --type f $td"
7889         nfiles=$($cmd | wc -l)
7890         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7891
7892         cmd="$LFS find ! --mirror-state=ro --type f $td"
7893         nfiles=$($cmd | wc -l)
7894         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7895
7896         cmd="$LFS find --mirror-state=wp --type f $td"
7897         nfiles=$($cmd | wc -l)
7898         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7899
7900         cmd="$LFS find ! --mirror-state=sp --type f $td"
7901         nfiles=$($cmd | wc -l)
7902         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7903 }
7904 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7905
7906 test_56da() { # LU-14179
7907         local path=$DIR/$tdir
7908
7909         test_mkdir $path
7910         cd $path
7911
7912         local longdir=$(str_repeat 'a' 255)
7913
7914         for i in {1..15}; do
7915                 path=$path/$longdir
7916                 test_mkdir $longdir
7917                 cd $longdir
7918         done
7919
7920         local len=${#path}
7921         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7922
7923         test_mkdir $lastdir
7924         cd $lastdir
7925         # PATH_MAX-1
7926         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7927
7928         # NAME_MAX
7929         touch $(str_repeat 'f' 255)
7930
7931         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7932                 error "lfs find reported an error"
7933
7934         rm -rf $DIR/$tdir
7935 }
7936 run_test 56da "test lfs find with long paths"
7937
7938 test_57a() {
7939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7940         # note test will not do anything if MDS is not local
7941         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7942                 skip_env "ldiskfs only test"
7943         fi
7944         remote_mds_nodsh && skip "remote MDS with nodsh"
7945
7946         local MNTDEV="osd*.*MDT*.mntdev"
7947         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7948         [ -z "$DEV" ] && error "can't access $MNTDEV"
7949         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7950                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7951                         error "can't access $DEV"
7952                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7953                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7954                 rm $TMP/t57a.dump
7955         done
7956 }
7957 run_test 57a "verify MDS filesystem created with large inodes =="
7958
7959 test_57b() {
7960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7961         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7962                 skip_env "ldiskfs only test"
7963         fi
7964         remote_mds_nodsh && skip "remote MDS with nodsh"
7965
7966         local dir=$DIR/$tdir
7967         local filecount=100
7968         local file1=$dir/f1
7969         local fileN=$dir/f$filecount
7970
7971         rm -rf $dir || error "removing $dir"
7972         test_mkdir -c1 $dir
7973         local mdtidx=$($LFS getstripe -m $dir)
7974         local mdtname=MDT$(printf %04x $mdtidx)
7975         local facet=mds$((mdtidx + 1))
7976
7977         echo "mcreating $filecount files"
7978         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7979
7980         # verify that files do not have EAs yet
7981         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7982                 error "$file1 has an EA"
7983         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7984                 error "$fileN has an EA"
7985
7986         sync
7987         sleep 1
7988         df $dir  #make sure we get new statfs data
7989         local mdsfree=$(do_facet $facet \
7990                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7991         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7992         local file
7993
7994         echo "opening files to create objects/EAs"
7995         for file in $(seq -f $dir/f%g 1 $filecount); do
7996                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7997                         error "opening $file"
7998         done
7999
8000         # verify that files have EAs now
8001         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8002         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8003
8004         sleep 1  #make sure we get new statfs data
8005         df $dir
8006         local mdsfree2=$(do_facet $facet \
8007                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8008         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8009
8010         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8011                 if [ "$mdsfree" != "$mdsfree2" ]; then
8012                         error "MDC before $mdcfree != after $mdcfree2"
8013                 else
8014                         echo "MDC before $mdcfree != after $mdcfree2"
8015                         echo "unable to confirm if MDS has large inodes"
8016                 fi
8017         fi
8018         rm -rf $dir
8019 }
8020 run_test 57b "default LOV EAs are stored inside large inodes ==="
8021
8022 test_58() {
8023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8024         [ -z "$(which wiretest 2>/dev/null)" ] &&
8025                         skip_env "could not find wiretest"
8026
8027         wiretest
8028 }
8029 run_test 58 "verify cross-platform wire constants =============="
8030
8031 test_59() {
8032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8033
8034         echo "touch 130 files"
8035         createmany -o $DIR/f59- 130
8036         echo "rm 130 files"
8037         unlinkmany $DIR/f59- 130
8038         sync
8039         # wait for commitment of removal
8040         wait_delete_completed
8041 }
8042 run_test 59 "verify cancellation of llog records async ========="
8043
8044 TEST60_HEAD="test_60 run $RANDOM"
8045 test_60a() {
8046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8047         remote_mgs_nodsh && skip "remote MGS with nodsh"
8048         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8049                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8050                         skip_env "missing subtest run-llog.sh"
8051
8052         log "$TEST60_HEAD - from kernel mode"
8053         do_facet mgs "$LCTL dk > /dev/null"
8054         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8055         do_facet mgs $LCTL dk > $TMP/$tfile
8056
8057         # LU-6388: test llog_reader
8058         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8059         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8060         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8061                         skip_env "missing llog_reader"
8062         local fstype=$(facet_fstype mgs)
8063         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8064                 skip_env "Only for ldiskfs or zfs type mgs"
8065
8066         local mntpt=$(facet_mntpt mgs)
8067         local mgsdev=$(mgsdevname 1)
8068         local fid_list
8069         local fid
8070         local rec_list
8071         local rec
8072         local rec_type
8073         local obj_file
8074         local path
8075         local seq
8076         local oid
8077         local pass=true
8078
8079         #get fid and record list
8080         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8081                 tail -n 4))
8082         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8083                 tail -n 4))
8084         #remount mgs as ldiskfs or zfs type
8085         stop mgs || error "stop mgs failed"
8086         mount_fstype mgs || error "remount mgs failed"
8087         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8088                 fid=${fid_list[i]}
8089                 rec=${rec_list[i]}
8090                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8091                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8092                 oid=$((16#$oid))
8093
8094                 case $fstype in
8095                         ldiskfs )
8096                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8097                         zfs )
8098                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8099                 esac
8100                 echo "obj_file is $obj_file"
8101                 do_facet mgs $llog_reader $obj_file
8102
8103                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8104                         awk '{ print $3 }' | sed -e "s/^type=//g")
8105                 if [ $rec_type != $rec ]; then
8106                         echo "FAILED test_60a wrong record type $rec_type," \
8107                               "should be $rec"
8108                         pass=false
8109                         break
8110                 fi
8111
8112                 #check obj path if record type is LLOG_LOGID_MAGIC
8113                 if [ "$rec" == "1064553b" ]; then
8114                         path=$(do_facet mgs $llog_reader $obj_file |
8115                                 grep "path=" | awk '{ print $NF }' |
8116                                 sed -e "s/^path=//g")
8117                         if [ $obj_file != $mntpt/$path ]; then
8118                                 echo "FAILED test_60a wrong obj path" \
8119                                       "$montpt/$path, should be $obj_file"
8120                                 pass=false
8121                                 break
8122                         fi
8123                 fi
8124         done
8125         rm -f $TMP/$tfile
8126         #restart mgs before "error", otherwise it will block the next test
8127         stop mgs || error "stop mgs failed"
8128         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8129         $pass || error "test failed, see FAILED test_60a messages for specifics"
8130 }
8131 run_test 60a "llog_test run from kernel module and test llog_reader"
8132
8133 test_60b() { # bug 6411
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         dmesg > $DIR/$tfile
8137         LLOG_COUNT=$(do_facet mgs dmesg |
8138                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8139                           /llog_[a-z]*.c:[0-9]/ {
8140                                 if (marker)
8141                                         from_marker++
8142                                 from_begin++
8143                           }
8144                           END {
8145                                 if (marker)
8146                                         print from_marker
8147                                 else
8148                                         print from_begin
8149                           }")
8150
8151         [[ $LLOG_COUNT -gt 120 ]] &&
8152                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8153 }
8154 run_test 60b "limit repeated messages from CERROR/CWARN"
8155
8156 test_60c() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158
8159         echo "create 5000 files"
8160         createmany -o $DIR/f60c- 5000
8161 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8162         lctl set_param fail_loc=0x80000137
8163         unlinkmany $DIR/f60c- 5000
8164         lctl set_param fail_loc=0
8165 }
8166 run_test 60c "unlink file when mds full"
8167
8168 test_60d() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         SAVEPRINTK=$(lctl get_param -n printk)
8172         # verify "lctl mark" is even working"
8173         MESSAGE="test message ID $RANDOM $$"
8174         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8175         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8176
8177         lctl set_param printk=0 || error "set lnet.printk failed"
8178         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8179         MESSAGE="new test message ID $RANDOM $$"
8180         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8181         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8182         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8183
8184         lctl set_param -n printk="$SAVEPRINTK"
8185 }
8186 run_test 60d "test printk console message masking"
8187
8188 test_60e() {
8189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8190         remote_mds_nodsh && skip "remote MDS with nodsh"
8191
8192         touch $DIR/$tfile
8193 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8194         do_facet mds1 lctl set_param fail_loc=0x15b
8195         rm $DIR/$tfile
8196 }
8197 run_test 60e "no space while new llog is being created"
8198
8199 test_60f() {
8200         local old_path=$($LCTL get_param -n debug_path)
8201
8202         stack_trap "$LCTL set_param debug_path=$old_path"
8203         stack_trap "rm -f $TMP/$tfile*"
8204         rm -f $TMP/$tfile* 2> /dev/null
8205         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8206         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8207         test_mkdir $DIR/$tdir
8208         # retry in case the open is cached and not released
8209         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8210                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8211                 sleep 0.1
8212         done
8213         ls $TMP/$tfile*
8214         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8215 }
8216 run_test 60f "change debug_path works"
8217
8218 test_60g() {
8219         local pid
8220         local i
8221
8222         test_mkdir -c $MDSCOUNT $DIR/$tdir
8223
8224         (
8225                 local index=0
8226                 while true; do
8227                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8228                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8229                                 2>/dev/null
8230                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8231                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8232                         index=$((index + 1))
8233                 done
8234         ) &
8235
8236         pid=$!
8237
8238         for i in {0..100}; do
8239                 # define OBD_FAIL_OSD_TXN_START    0x19a
8240                 local index=$((i % MDSCOUNT + 1))
8241
8242                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8243                         > /dev/null
8244                 sleep 0.01
8245         done
8246
8247         kill -9 $pid
8248
8249         for i in $(seq $MDSCOUNT); do
8250                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8251         done
8252
8253         mkdir $DIR/$tdir/new || error "mkdir failed"
8254         rmdir $DIR/$tdir/new || error "rmdir failed"
8255
8256         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8257                 -t namespace
8258         for i in $(seq $MDSCOUNT); do
8259                 wait_update_facet mds$i "$LCTL get_param -n \
8260                         mdd.$(facet_svc mds$i).lfsck_namespace |
8261                         awk '/^status/ { print \\\$2 }'" "completed"
8262         done
8263
8264         ls -R $DIR/$tdir || error "ls failed"
8265         rm -rf $DIR/$tdir || error "rmdir failed"
8266 }
8267 run_test 60g "transaction abort won't cause MDT hung"
8268
8269 test_60h() {
8270         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8271                 skip "Need MDS version at least 2.12.52"
8272         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8273
8274         local f
8275
8276         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8277         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8278         for fail_loc in 0x80000188 0x80000189; do
8279                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8280                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8281                         error "mkdir $dir-$fail_loc failed"
8282                 for i in {0..10}; do
8283                         # create may fail on missing stripe
8284                         echo $i > $DIR/$tdir-$fail_loc/$i
8285                 done
8286                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8287                         error "getdirstripe $tdir-$fail_loc failed"
8288                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8289                         error "migrate $tdir-$fail_loc failed"
8290                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8291                         error "getdirstripe $tdir-$fail_loc failed"
8292                 pushd $DIR/$tdir-$fail_loc
8293                 for f in *; do
8294                         echo $f | cmp $f - || error "$f data mismatch"
8295                 done
8296                 popd
8297                 rm -rf $DIR/$tdir-$fail_loc
8298         done
8299 }
8300 run_test 60h "striped directory with missing stripes can be accessed"
8301
8302 function t60i_load() {
8303         mkdir $DIR/$tdir
8304         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8305         $LCTL set_param fail_loc=0x131c fail_val=1
8306         for ((i=0; i<5000; i++)); do
8307                 touch $DIR/$tdir/f$i
8308         done
8309 }
8310
8311 test_60i() {
8312         changelog_register || error "changelog_register failed"
8313         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8314         changelog_users $SINGLEMDS | grep -q $cl_user ||
8315                 error "User $cl_user not found in changelog_users"
8316         changelog_chmask "ALL"
8317         t60i_load &
8318         local PID=$!
8319         for((i=0; i<100; i++)); do
8320                 changelog_dump >/dev/null ||
8321                         error "can't read changelog"
8322         done
8323         kill $PID
8324         wait $PID
8325         changelog_deregister || error "changelog_deregister failed"
8326         $LCTL set_param fail_loc=0
8327 }
8328 run_test 60i "llog: new record vs reader race"
8329
8330 test_61a() {
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332
8333         f="$DIR/f61"
8334         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8335         cancel_lru_locks osc
8336         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8337         sync
8338 }
8339 run_test 61a "mmap() writes don't make sync hang ================"
8340
8341 test_61b() {
8342         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8343 }
8344 run_test 61b "mmap() of unstriped file is successful"
8345
8346 # bug 2330 - insufficient obd_match error checking causes LBUG
8347 test_62() {
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         f="$DIR/f62"
8351         echo foo > $f
8352         cancel_lru_locks osc
8353         lctl set_param fail_loc=0x405
8354         cat $f && error "cat succeeded, expect -EIO"
8355         lctl set_param fail_loc=0
8356 }
8357 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8358 # match every page all of the time.
8359 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8360
8361 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8362 # Though this test is irrelevant anymore, it helped to reveal some
8363 # other grant bugs (LU-4482), let's keep it.
8364 test_63a() {   # was test_63
8365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8366
8367         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8368
8369         for i in `seq 10` ; do
8370                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8371                 sleep 5
8372                 kill $!
8373                 sleep 1
8374         done
8375
8376         rm -f $DIR/f63 || true
8377 }
8378 run_test 63a "Verify oig_wait interruption does not crash ======="
8379
8380 # bug 2248 - async write errors didn't return to application on sync
8381 # bug 3677 - async write errors left page locked
8382 test_63b() {
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384
8385         debugsave
8386         lctl set_param debug=-1
8387
8388         # ensure we have a grant to do async writes
8389         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8390         rm $DIR/$tfile
8391
8392         sync    # sync lest earlier test intercept the fail_loc
8393
8394         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8395         lctl set_param fail_loc=0x80000406
8396         $MULTIOP $DIR/$tfile Owy && \
8397                 error "sync didn't return ENOMEM"
8398         sync; sleep 2; sync     # do a real sync this time to flush page
8399         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8400                 error "locked page left in cache after async error" || true
8401         debugrestore
8402 }
8403 run_test 63b "async write errors should be returned to fsync ==="
8404
8405 test_64a () {
8406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8407
8408         lfs df $DIR
8409         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8410 }
8411 run_test 64a "verify filter grant calculations (in kernel) ====="
8412
8413 test_64b () {
8414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8415
8416         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8417 }
8418 run_test 64b "check out-of-space detection on client"
8419
8420 test_64c() {
8421         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8422 }
8423 run_test 64c "verify grant shrink"
8424
8425 import_param() {
8426         local tgt=$1
8427         local param=$2
8428
8429         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8430 }
8431
8432 # this does exactly what osc_request.c:osc_announce_cached() does in
8433 # order to calculate max amount of grants to ask from server
8434 want_grant() {
8435         local tgt=$1
8436
8437         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8438         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8439
8440         ((rpc_in_flight++));
8441         nrpages=$((nrpages * rpc_in_flight))
8442
8443         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8444
8445         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8446
8447         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8448         local undirty=$((nrpages * PAGE_SIZE))
8449
8450         local max_extent_pages
8451         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8452         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8453         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8454         local grant_extent_tax
8455         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8456
8457         undirty=$((undirty + nrextents * grant_extent_tax))
8458
8459         echo $undirty
8460 }
8461
8462 # this is size of unit for grant allocation. It should be equal to
8463 # what tgt_grant.c:tgt_grant_chunk() calculates
8464 grant_chunk() {
8465         local tgt=$1
8466         local max_brw_size
8467         local grant_extent_tax
8468
8469         max_brw_size=$(import_param $tgt max_brw_size)
8470
8471         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8472
8473         echo $(((max_brw_size + grant_extent_tax) * 2))
8474 }
8475
8476 test_64d() {
8477         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8478                 skip "OST < 2.10.55 doesn't limit grants enough"
8479
8480         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8481
8482         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8483                 skip "no grant_param connect flag"
8484
8485         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8486
8487         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8488         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8489
8490
8491         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8492         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8493
8494         $LFS setstripe $DIR/$tfile -i 0 -c 1
8495         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8496         ddpid=$!
8497
8498         while kill -0 $ddpid; do
8499                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8500
8501                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8502                         kill $ddpid
8503                         error "cur_grant $cur_grant > $max_cur_granted"
8504                 fi
8505
8506                 sleep 1
8507         done
8508 }
8509 run_test 64d "check grant limit exceed"
8510
8511 check_grants() {
8512         local tgt=$1
8513         local expected=$2
8514         local msg=$3
8515         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8516
8517         ((cur_grants == expected)) ||
8518                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8519 }
8520
8521 round_up_p2() {
8522         echo $((($1 + $2 - 1) & ~($2 - 1)))
8523 }
8524
8525 test_64e() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8528                 skip "Need OSS version at least 2.11.56"
8529
8530         # Remount client to reset grant
8531         remount_client $MOUNT || error "failed to remount client"
8532         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8533
8534         local init_grants=$(import_param $osc_tgt initial_grant)
8535
8536         check_grants $osc_tgt $init_grants "init grants"
8537
8538         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8539         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8540         local gbs=$(import_param $osc_tgt grant_block_size)
8541
8542         # write random number of bytes from max_brw_size / 4 to max_brw_size
8543         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8544         # align for direct io
8545         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8546         # round to grant consumption unit
8547         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8548
8549         local grants=$((wb_round_up + extent_tax))
8550
8551         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8552
8553         # define OBD_FAIL_TGT_NO_GRANT 0x725
8554         # make the server not grant more back
8555         do_facet ost1 $LCTL set_param fail_loc=0x725
8556         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8557
8558         do_facet ost1 $LCTL set_param fail_loc=0
8559
8560         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8561
8562         rm -f $DIR/$tfile || error "rm failed"
8563
8564         # Remount client to reset grant
8565         remount_client $MOUNT || error "failed to remount client"
8566         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8567
8568         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8569
8570         # define OBD_FAIL_TGT_NO_GRANT 0x725
8571         # make the server not grant more back
8572         do_facet ost1 $LCTL set_param fail_loc=0x725
8573         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8574         do_facet ost1 $LCTL set_param fail_loc=0
8575
8576         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8577 }
8578 run_test 64e "check grant consumption (no grant allocation)"
8579
8580 test_64f() {
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         # Remount client to reset grant
8584         remount_client $MOUNT || error "failed to remount client"
8585         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8586
8587         local init_grants=$(import_param $osc_tgt initial_grant)
8588         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8589         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8590         local gbs=$(import_param $osc_tgt grant_block_size)
8591         local chunk=$(grant_chunk $osc_tgt)
8592
8593         # write random number of bytes from max_brw_size / 4 to max_brw_size
8594         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8595         # align for direct io
8596         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8597         # round to grant consumption unit
8598         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8599
8600         local grants=$((wb_round_up + extent_tax))
8601
8602         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8603         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8604                 error "error writing to $DIR/$tfile"
8605
8606         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8607                 "direct io with grant allocation"
8608
8609         rm -f $DIR/$tfile || error "rm failed"
8610
8611         # Remount client to reset grant
8612         remount_client $MOUNT || error "failed to remount client"
8613         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8614
8615         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8616
8617         local cmd="oO_WRONLY:w${write_bytes}_yc"
8618
8619         $MULTIOP $DIR/$tfile $cmd &
8620         MULTIPID=$!
8621         sleep 1
8622
8623         check_grants $osc_tgt $((init_grants - grants)) \
8624                 "buffered io, not write rpc"
8625
8626         kill -USR1 $MULTIPID
8627         wait
8628
8629         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8630                 "buffered io, one RPC"
8631 }
8632 run_test 64f "check grant consumption (with grant allocation)"
8633
8634 # bug 1414 - set/get directories' stripe info
8635 test_65a() {
8636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8637
8638         test_mkdir $DIR/$tdir
8639         touch $DIR/$tdir/f1
8640         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8641 }
8642 run_test 65a "directory with no stripe info"
8643
8644 test_65b() {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646
8647         test_mkdir $DIR/$tdir
8648         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8649
8650         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8651                                                 error "setstripe"
8652         touch $DIR/$tdir/f2
8653         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8654 }
8655 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8656
8657 test_65c() {
8658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8659         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8660
8661         test_mkdir $DIR/$tdir
8662         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8663
8664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8666         touch $DIR/$tdir/f3
8667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8668 }
8669 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8670
8671 test_65d() {
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         test_mkdir $DIR/$tdir
8675         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8676         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8677
8678         if [[ $STRIPECOUNT -le 0 ]]; then
8679                 sc=1
8680         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8681                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8682                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8683         else
8684                 sc=$(($STRIPECOUNT - 1))
8685         fi
8686         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8687         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8688         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8689                 error "lverify failed"
8690 }
8691 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8692
8693 test_65e() {
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695
8696         test_mkdir $DIR/$tdir
8697
8698         $LFS setstripe $DIR/$tdir || error "setstripe"
8699         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8700                                         error "no stripe info failed"
8701         touch $DIR/$tdir/f6
8702         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8703 }
8704 run_test 65e "directory setstripe defaults"
8705
8706 test_65f() {
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         test_mkdir $DIR/${tdir}f
8710         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8711                 error "setstripe succeeded" || true
8712 }
8713 run_test 65f "dir setstripe permission (should return error) ==="
8714
8715 test_65g() {
8716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8717
8718         test_mkdir $DIR/$tdir
8719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8720
8721         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8722                 error "setstripe -S failed"
8723         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8724         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8725                 error "delete default stripe failed"
8726 }
8727 run_test 65g "directory setstripe -d"
8728
8729 test_65h() {
8730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8731
8732         test_mkdir $DIR/$tdir
8733         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8734
8735         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8736                 error "setstripe -S failed"
8737         test_mkdir $DIR/$tdir/dd1
8738         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8739                 error "stripe info inherit failed"
8740 }
8741 run_test 65h "directory stripe info inherit ===================="
8742
8743 test_65i() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745
8746         save_layout_restore_at_exit $MOUNT
8747
8748         # bug6367: set non-default striping on root directory
8749         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8750
8751         # bug12836: getstripe on -1 default directory striping
8752         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8753
8754         # bug12836: getstripe -v on -1 default directory striping
8755         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8756
8757         # bug12836: new find on -1 default directory striping
8758         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8759 }
8760 run_test 65i "various tests to set root directory striping"
8761
8762 test_65j() { # bug6367
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764
8765         sync; sleep 1
8766
8767         # if we aren't already remounting for each test, do so for this test
8768         if [ "$I_MOUNTED" = "yes" ]; then
8769                 cleanup || error "failed to unmount"
8770                 setup
8771         fi
8772
8773         save_layout_restore_at_exit $MOUNT
8774
8775         $LFS setstripe -d $MOUNT || error "setstripe failed"
8776 }
8777 run_test 65j "set default striping on root directory (bug 6367)="
8778
8779 cleanup_65k() {
8780         rm -rf $DIR/$tdir
8781         wait_delete_completed
8782         do_facet $SINGLEMDS "lctl set_param -n \
8783                 osp.$ost*MDT0000.max_create_count=$max_count"
8784         do_facet $SINGLEMDS "lctl set_param -n \
8785                 osp.$ost*MDT0000.create_count=$count"
8786         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8787         echo $INACTIVE_OSC "is Activate"
8788
8789         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8790 }
8791
8792 test_65k() { # bug11679
8793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8795         remote_mds_nodsh && skip "remote MDS with nodsh"
8796
8797         local disable_precreate=true
8798         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8799                 disable_precreate=false
8800
8801         echo "Check OST status: "
8802         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8803                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8804
8805         for OSC in $MDS_OSCS; do
8806                 echo $OSC "is active"
8807                 do_facet $SINGLEMDS lctl --device %$OSC activate
8808         done
8809
8810         for INACTIVE_OSC in $MDS_OSCS; do
8811                 local ost=$(osc_to_ost $INACTIVE_OSC)
8812                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8813                                lov.*md*.target_obd |
8814                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8815
8816                 mkdir -p $DIR/$tdir
8817                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8818                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8819
8820                 echo "Deactivate: " $INACTIVE_OSC
8821                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8822
8823                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8824                               osp.$ost*MDT0000.create_count")
8825                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8826                                   osp.$ost*MDT0000.max_create_count")
8827                 $disable_precreate &&
8828                         do_facet $SINGLEMDS "lctl set_param -n \
8829                                 osp.$ost*MDT0000.max_create_count=0"
8830
8831                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8832                         [ -f $DIR/$tdir/$idx ] && continue
8833                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8834                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8835                                 { cleanup_65k;
8836                                   error "setstripe $idx should succeed"; }
8837                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8838                 done
8839                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8840                 rmdir $DIR/$tdir
8841
8842                 do_facet $SINGLEMDS "lctl set_param -n \
8843                         osp.$ost*MDT0000.max_create_count=$max_count"
8844                 do_facet $SINGLEMDS "lctl set_param -n \
8845                         osp.$ost*MDT0000.create_count=$count"
8846                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8847                 echo $INACTIVE_OSC "is Activate"
8848
8849                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8850         done
8851 }
8852 run_test 65k "validate manual striping works properly with deactivated OSCs"
8853
8854 test_65l() { # bug 12836
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856
8857         test_mkdir -p $DIR/$tdir/test_dir
8858         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8859         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8860 }
8861 run_test 65l "lfs find on -1 stripe dir ========================"
8862
8863 test_65m() {
8864         local layout=$(save_layout $MOUNT)
8865         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8866                 restore_layout $MOUNT $layout
8867                 error "setstripe should fail by non-root users"
8868         }
8869         true
8870 }
8871 run_test 65m "normal user can't set filesystem default stripe"
8872
8873 test_65n() {
8874         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8875         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8876                 skip "Need MDS version at least 2.12.50"
8877         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8878
8879         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8880         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8881         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8882
8883         save_layout_restore_at_exit $MOUNT
8884
8885         # new subdirectory under root directory should not inherit
8886         # the default layout from root
8887         local dir1=$MOUNT/$tdir-1
8888         mkdir $dir1 || error "mkdir $dir1 failed"
8889         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8890                 error "$dir1 shouldn't have LOV EA"
8891
8892         # delete the default layout on root directory
8893         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8894
8895         local dir2=$MOUNT/$tdir-2
8896         mkdir $dir2 || error "mkdir $dir2 failed"
8897         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8898                 error "$dir2 shouldn't have LOV EA"
8899
8900         # set a new striping pattern on root directory
8901         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8902         local new_def_stripe_size=$((def_stripe_size * 2))
8903         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8904                 error "set stripe size on $MOUNT failed"
8905
8906         # new file created in $dir2 should inherit the new stripe size from
8907         # the filesystem default
8908         local file2=$dir2/$tfile-2
8909         touch $file2 || error "touch $file2 failed"
8910
8911         local file2_stripe_size=$($LFS getstripe -S $file2)
8912         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8913         {
8914                 echo "file2_stripe_size: '$file2_stripe_size'"
8915                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8916                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8917         }
8918
8919         local dir3=$MOUNT/$tdir-3
8920         mkdir $dir3 || error "mkdir $dir3 failed"
8921         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8922         # the root layout, which is the actual default layout that will be used
8923         # when new files are created in $dir3.
8924         local dir3_layout=$(get_layout_param $dir3)
8925         local root_dir_layout=$(get_layout_param $MOUNT)
8926         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8927         {
8928                 echo "dir3_layout: '$dir3_layout'"
8929                 echo "root_dir_layout: '$root_dir_layout'"
8930                 error "$dir3 should show the default layout from $MOUNT"
8931         }
8932
8933         # set OST pool on root directory
8934         local pool=$TESTNAME
8935         pool_add $pool || error "add $pool failed"
8936         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8937                 error "add targets to $pool failed"
8938
8939         $LFS setstripe -p $pool $MOUNT ||
8940                 error "set OST pool on $MOUNT failed"
8941
8942         # new file created in $dir3 should inherit the pool from
8943         # the filesystem default
8944         local file3=$dir3/$tfile-3
8945         touch $file3 || error "touch $file3 failed"
8946
8947         local file3_pool=$($LFS getstripe -p $file3)
8948         [[ "$file3_pool" = "$pool" ]] ||
8949                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8950
8951         local dir4=$MOUNT/$tdir-4
8952         mkdir $dir4 || error "mkdir $dir4 failed"
8953         local dir4_layout=$(get_layout_param $dir4)
8954         root_dir_layout=$(get_layout_param $MOUNT)
8955         echo "$LFS getstripe -d $dir4"
8956         $LFS getstripe -d $dir4
8957         echo "$LFS getstripe -d $MOUNT"
8958         $LFS getstripe -d $MOUNT
8959         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8960         {
8961                 echo "dir4_layout: '$dir4_layout'"
8962                 echo "root_dir_layout: '$root_dir_layout'"
8963                 error "$dir4 should show the default layout from $MOUNT"
8964         }
8965
8966         # new file created in $dir4 should inherit the pool from
8967         # the filesystem default
8968         local file4=$dir4/$tfile-4
8969         touch $file4 || error "touch $file4 failed"
8970
8971         local file4_pool=$($LFS getstripe -p $file4)
8972         [[ "$file4_pool" = "$pool" ]] ||
8973                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8974
8975         # new subdirectory under non-root directory should inherit
8976         # the default layout from its parent directory
8977         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8978                 error "set directory layout on $dir4 failed"
8979
8980         local dir5=$dir4/$tdir-5
8981         mkdir $dir5 || error "mkdir $dir5 failed"
8982
8983         dir4_layout=$(get_layout_param $dir4)
8984         local dir5_layout=$(get_layout_param $dir5)
8985         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8986         {
8987                 echo "dir4_layout: '$dir4_layout'"
8988                 echo "dir5_layout: '$dir5_layout'"
8989                 error "$dir5 should inherit the default layout from $dir4"
8990         }
8991
8992         # though subdir under ROOT doesn't inherit default layout, but
8993         # its sub dir/file should be created with default layout.
8994         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8995         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8996                 skip "Need MDS version at least 2.12.59"
8997
8998         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8999         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9000         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9001
9002         if [ $default_lmv_hash == "none" ]; then
9003                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9004         else
9005                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9006                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9007         fi
9008
9009         $LFS setdirstripe -D -c 2 $MOUNT ||
9010                 error "setdirstripe -D -c 2 failed"
9011         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9012         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9013         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9014 }
9015 run_test 65n "don't inherit default layout from root for new subdirectories"
9016
9017 # bug 2543 - update blocks count on client
9018 test_66() {
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020
9021         COUNT=${COUNT:-8}
9022         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9023         sync; sync_all_data; sync; sync_all_data
9024         cancel_lru_locks osc
9025         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9026         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9027 }
9028 run_test 66 "update inode blocks count on client ==============="
9029
9030 meminfo() {
9031         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9032 }
9033
9034 swap_used() {
9035         swapon -s | awk '($1 == "'$1'") { print $4 }'
9036 }
9037
9038 # bug5265, obdfilter oa2dentry return -ENOENT
9039 # #define OBD_FAIL_SRV_ENOENT 0x217
9040 test_69() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         remote_ost_nodsh && skip "remote OST with nodsh"
9043
9044         f="$DIR/$tfile"
9045         $LFS setstripe -c 1 -i 0 $f
9046
9047         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9048
9049         do_facet ost1 lctl set_param fail_loc=0x217
9050         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9051         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9052
9053         do_facet ost1 lctl set_param fail_loc=0
9054         $DIRECTIO write $f 0 2 || error "write error"
9055
9056         cancel_lru_locks osc
9057         $DIRECTIO read $f 0 1 || error "read error"
9058
9059         do_facet ost1 lctl set_param fail_loc=0x217
9060         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9061
9062         do_facet ost1 lctl set_param fail_loc=0
9063         rm -f $f
9064 }
9065 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9066
9067 test_71() {
9068         test_mkdir $DIR/$tdir
9069         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9070         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9071 }
9072 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9073
9074 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9076         [ "$RUNAS_ID" = "$UID" ] &&
9077                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9078         # Check that testing environment is properly set up. Skip if not
9079         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9080                 skip_env "User $RUNAS_ID does not exist - skipping"
9081
9082         touch $DIR/$tfile
9083         chmod 777 $DIR/$tfile
9084         chmod ug+s $DIR/$tfile
9085         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9086                 error "$RUNAS dd $DIR/$tfile failed"
9087         # See if we are still setuid/sgid
9088         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9089                 error "S/gid is not dropped on write"
9090         # Now test that MDS is updated too
9091         cancel_lru_locks mdc
9092         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9093                 error "S/gid is not dropped on MDS"
9094         rm -f $DIR/$tfile
9095 }
9096 run_test 72a "Test that remove suid works properly (bug5695) ===="
9097
9098 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9099         local perm
9100
9101         [ "$RUNAS_ID" = "$UID" ] &&
9102                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9103         [ "$RUNAS_ID" -eq 0 ] &&
9104                 skip_env "RUNAS_ID = 0 -- skipping"
9105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9106         # Check that testing environment is properly set up. Skip if not
9107         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9108                 skip_env "User $RUNAS_ID does not exist - skipping"
9109
9110         touch $DIR/${tfile}-f{g,u}
9111         test_mkdir $DIR/${tfile}-dg
9112         test_mkdir $DIR/${tfile}-du
9113         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9114         chmod g+s $DIR/${tfile}-{f,d}g
9115         chmod u+s $DIR/${tfile}-{f,d}u
9116         for perm in 777 2777 4777; do
9117                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9118                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9119                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9120                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9121         done
9122         true
9123 }
9124 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9125
9126 # bug 3462 - multiple simultaneous MDC requests
9127 test_73() {
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129
9130         test_mkdir $DIR/d73-1
9131         test_mkdir $DIR/d73-2
9132         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9133         pid1=$!
9134
9135         lctl set_param fail_loc=0x80000129
9136         $MULTIOP $DIR/d73-1/f73-2 Oc &
9137         sleep 1
9138         lctl set_param fail_loc=0
9139
9140         $MULTIOP $DIR/d73-2/f73-3 Oc &
9141         pid3=$!
9142
9143         kill -USR1 $pid1
9144         wait $pid1 || return 1
9145
9146         sleep 25
9147
9148         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9149         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9150         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9151
9152         rm -rf $DIR/d73-*
9153 }
9154 run_test 73 "multiple MDC requests (should not deadlock)"
9155
9156 test_74a() { # bug 6149, 6184
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158
9159         touch $DIR/f74a
9160         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9161         #
9162         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9163         # will spin in a tight reconnection loop
9164         $LCTL set_param fail_loc=0x8000030e
9165         # get any lock that won't be difficult - lookup works.
9166         ls $DIR/f74a
9167         $LCTL set_param fail_loc=0
9168         rm -f $DIR/f74a
9169         true
9170 }
9171 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9172
9173 test_74b() { # bug 13310
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175
9176         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9177         #
9178         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9179         # will spin in a tight reconnection loop
9180         $LCTL set_param fail_loc=0x8000030e
9181         # get a "difficult" lock
9182         touch $DIR/f74b
9183         $LCTL set_param fail_loc=0
9184         rm -f $DIR/f74b
9185         true
9186 }
9187 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9188
9189 test_74c() {
9190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9191
9192         #define OBD_FAIL_LDLM_NEW_LOCK
9193         $LCTL set_param fail_loc=0x319
9194         touch $DIR/$tfile && error "touch successful"
9195         $LCTL set_param fail_loc=0
9196         true
9197 }
9198 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9199
9200 slab_lic=/sys/kernel/slab/lustre_inode_cache
9201 num_objects() {
9202         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9203         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9204                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9205 }
9206
9207 test_76a() { # Now for b=20433, added originally in b=1443
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         cancel_lru_locks osc
9211         # there may be some slab objects cached per core
9212         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9213         local before=$(num_objects)
9214         local count=$((512 * cpus))
9215         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9216         local margin=$((count / 10))
9217         if [[ -f $slab_lic/aliases ]]; then
9218                 local aliases=$(cat $slab_lic/aliases)
9219                 (( aliases > 0 )) && margin=$((margin * aliases))
9220         fi
9221
9222         echo "before slab objects: $before"
9223         for i in $(seq $count); do
9224                 touch $DIR/$tfile
9225                 rm -f $DIR/$tfile
9226         done
9227         cancel_lru_locks osc
9228         local after=$(num_objects)
9229         echo "created: $count, after slab objects: $after"
9230         # shared slab counts are not very accurate, allow significant margin
9231         # the main goal is that the cache growth is not permanently > $count
9232         while (( after > before + margin )); do
9233                 sleep 1
9234                 after=$(num_objects)
9235                 wait=$((wait + 1))
9236                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9237                 if (( wait > 60 )); then
9238                         error "inode slab grew from $before+$margin to $after"
9239                 fi
9240         done
9241 }
9242 run_test 76a "confirm clients recycle inodes properly ===="
9243
9244 test_76b() {
9245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9246         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9247
9248         local count=512
9249         local before=$(num_objects)
9250
9251         for i in $(seq $count); do
9252                 mkdir $DIR/$tdir
9253                 rmdir $DIR/$tdir
9254         done
9255
9256         local after=$(num_objects)
9257         local wait=0
9258
9259         while (( after > before )); do
9260                 sleep 1
9261                 after=$(num_objects)
9262                 wait=$((wait + 1))
9263                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9264                 if (( wait > 60 )); then
9265                         error "inode slab grew from $before to $after"
9266                 fi
9267         done
9268
9269         echo "slab objects before: $before, after: $after"
9270 }
9271 run_test 76b "confirm clients recycle directory inodes properly ===="
9272
9273 export ORIG_CSUM=""
9274 set_checksums()
9275 {
9276         # Note: in sptlrpc modes which enable its own bulk checksum, the
9277         # original crc32_le bulk checksum will be automatically disabled,
9278         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9279         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9280         # In this case set_checksums() will not be no-op, because sptlrpc
9281         # bulk checksum will be enabled all through the test.
9282
9283         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9284         lctl set_param -n osc.*.checksums $1
9285         return 0
9286 }
9287
9288 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9289                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9290 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9291                              tr -d [] | head -n1)}
9292 set_checksum_type()
9293 {
9294         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9295         rc=$?
9296         log "set checksum type to $1, rc = $rc"
9297         return $rc
9298 }
9299
9300 get_osc_checksum_type()
9301 {
9302         # arugment 1: OST name, like OST0000
9303         ost=$1
9304         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9305                         sed 's/.*\[\(.*\)\].*/\1/g')
9306         rc=$?
9307         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9308         echo $checksum_type
9309 }
9310
9311 F77_TMP=$TMP/f77-temp
9312 F77SZ=8
9313 setup_f77() {
9314         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9315                 error "error writing to $F77_TMP"
9316 }
9317
9318 test_77a() { # bug 10889
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320         $GSS && skip_env "could not run with gss"
9321
9322         [ ! -f $F77_TMP ] && setup_f77
9323         set_checksums 1
9324         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9325         set_checksums 0
9326         rm -f $DIR/$tfile
9327 }
9328 run_test 77a "normal checksum read/write operation"
9329
9330 test_77b() { # bug 10889
9331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9332         $GSS && skip_env "could not run with gss"
9333
9334         [ ! -f $F77_TMP ] && setup_f77
9335         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9336         $LCTL set_param fail_loc=0x80000409
9337         set_checksums 1
9338
9339         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9340                 error "dd error: $?"
9341         $LCTL set_param fail_loc=0
9342
9343         for algo in $CKSUM_TYPES; do
9344                 cancel_lru_locks osc
9345                 set_checksum_type $algo
9346                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9347                 $LCTL set_param fail_loc=0x80000408
9348                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9349                 $LCTL set_param fail_loc=0
9350         done
9351         set_checksums 0
9352         set_checksum_type $ORIG_CSUM_TYPE
9353         rm -f $DIR/$tfile
9354 }
9355 run_test 77b "checksum error on client write, read"
9356
9357 cleanup_77c() {
9358         trap 0
9359         set_checksums 0
9360         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9361         $check_ost &&
9362                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9363         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9364         $check_ost && [ -n "$ost_file_prefix" ] &&
9365                 do_facet ost1 rm -f ${ost_file_prefix}\*
9366 }
9367
9368 test_77c() {
9369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9370         $GSS && skip_env "could not run with gss"
9371         remote_ost_nodsh && skip "remote OST with nodsh"
9372
9373         local bad1
9374         local osc_file_prefix
9375         local osc_file
9376         local check_ost=false
9377         local ost_file_prefix
9378         local ost_file
9379         local orig_cksum
9380         local dump_cksum
9381         local fid
9382
9383         # ensure corruption will occur on first OSS/OST
9384         $LFS setstripe -i 0 $DIR/$tfile
9385
9386         [ ! -f $F77_TMP ] && setup_f77
9387         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9388                 error "dd write error: $?"
9389         fid=$($LFS path2fid $DIR/$tfile)
9390
9391         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9392         then
9393                 check_ost=true
9394                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9395                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9396         else
9397                 echo "OSS do not support bulk pages dump upon error"
9398         fi
9399
9400         osc_file_prefix=$($LCTL get_param -n debug_path)
9401         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9402
9403         trap cleanup_77c EXIT
9404
9405         set_checksums 1
9406         # enable bulk pages dump upon error on Client
9407         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9408         # enable bulk pages dump upon error on OSS
9409         $check_ost &&
9410                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9411
9412         # flush Client cache to allow next read to reach OSS
9413         cancel_lru_locks osc
9414
9415         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9416         $LCTL set_param fail_loc=0x80000408
9417         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9418         $LCTL set_param fail_loc=0
9419
9420         rm -f $DIR/$tfile
9421
9422         # check cksum dump on Client
9423         osc_file=$(ls ${osc_file_prefix}*)
9424         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9425         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9426         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9427         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9428         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9429                      cksum)
9430         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9431         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9432                 error "dump content does not match on Client"
9433
9434         $check_ost || skip "No need to check cksum dump on OSS"
9435
9436         # check cksum dump on OSS
9437         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9438         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9439         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9440         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9441         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9442                 error "dump content does not match on OSS"
9443
9444         cleanup_77c
9445 }
9446 run_test 77c "checksum error on client read with debug"
9447
9448 test_77d() { # bug 10889
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450         $GSS && skip_env "could not run with gss"
9451
9452         stack_trap "rm -f $DIR/$tfile"
9453         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9454         $LCTL set_param fail_loc=0x80000409
9455         set_checksums 1
9456         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9457                 error "direct write: rc=$?"
9458         $LCTL set_param fail_loc=0
9459         set_checksums 0
9460
9461         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9462         $LCTL set_param fail_loc=0x80000408
9463         set_checksums 1
9464         cancel_lru_locks osc
9465         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9466                 error "direct read: rc=$?"
9467         $LCTL set_param fail_loc=0
9468         set_checksums 0
9469 }
9470 run_test 77d "checksum error on OST direct write, read"
9471
9472 test_77f() { # bug 10889
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         $GSS && skip_env "could not run with gss"
9475
9476         set_checksums 1
9477         stack_trap "rm -f $DIR/$tfile"
9478         for algo in $CKSUM_TYPES; do
9479                 cancel_lru_locks osc
9480                 set_checksum_type $algo
9481                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9482                 $LCTL set_param fail_loc=0x409
9483                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9484                         error "direct write succeeded"
9485                 $LCTL set_param fail_loc=0
9486         done
9487         set_checksum_type $ORIG_CSUM_TYPE
9488         set_checksums 0
9489 }
9490 run_test 77f "repeat checksum error on write (expect error)"
9491
9492 test_77g() { # bug 10889
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494         $GSS && skip_env "could not run with gss"
9495         remote_ost_nodsh && skip "remote OST with nodsh"
9496
9497         [ ! -f $F77_TMP ] && setup_f77
9498
9499         local file=$DIR/$tfile
9500         stack_trap "rm -f $file" EXIT
9501
9502         $LFS setstripe -c 1 -i 0 $file
9503         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9504         do_facet ost1 lctl set_param fail_loc=0x8000021a
9505         set_checksums 1
9506         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9507                 error "write error: rc=$?"
9508         do_facet ost1 lctl set_param fail_loc=0
9509         set_checksums 0
9510
9511         cancel_lru_locks osc
9512         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9513         do_facet ost1 lctl set_param fail_loc=0x8000021b
9514         set_checksums 1
9515         cmp $F77_TMP $file || error "file compare failed"
9516         do_facet ost1 lctl set_param fail_loc=0
9517         set_checksums 0
9518 }
9519 run_test 77g "checksum error on OST write, read"
9520
9521 test_77k() { # LU-10906
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523         $GSS && skip_env "could not run with gss"
9524
9525         local cksum_param="osc.$FSNAME*.checksums"
9526         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9527         local checksum
9528         local i
9529
9530         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9531         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9532         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9533
9534         for i in 0 1; do
9535                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9536                         error "failed to set checksum=$i on MGS"
9537                 wait_update $HOSTNAME "$get_checksum" $i
9538                 #remount
9539                 echo "remount client, checksum should be $i"
9540                 remount_client $MOUNT || error "failed to remount client"
9541                 checksum=$(eval $get_checksum)
9542                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9543         done
9544         # remove persistent param to avoid races with checksum mountopt below
9545         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9546                 error "failed to delete checksum on MGS"
9547
9548         for opt in "checksum" "nochecksum"; do
9549                 #remount with mount option
9550                 echo "remount client with option $opt, checksum should be $i"
9551                 umount_client $MOUNT || error "failed to umount client"
9552                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9553                         error "failed to mount client with option '$opt'"
9554                 checksum=$(eval $get_checksum)
9555                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9556                 i=$((i - 1))
9557         done
9558
9559         remount_client $MOUNT || error "failed to remount client"
9560 }
9561 run_test 77k "enable/disable checksum correctly"
9562
9563 test_77l() {
9564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9565         $GSS && skip_env "could not run with gss"
9566
9567         set_checksums 1
9568         stack_trap "set_checksums $ORIG_CSUM" EXIT
9569         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9570
9571         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9572
9573         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9574         for algo in $CKSUM_TYPES; do
9575                 set_checksum_type $algo || error "fail to set checksum type $algo"
9576                 osc_algo=$(get_osc_checksum_type OST0000)
9577                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9578
9579                 # no locks, no reqs to let the connection idle
9580                 cancel_lru_locks osc
9581                 lru_resize_disable osc
9582                 wait_osc_import_state client ost1 IDLE
9583
9584                 # ensure ost1 is connected
9585                 stat $DIR/$tfile >/dev/null || error "can't stat"
9586                 wait_osc_import_state client ost1 FULL
9587
9588                 osc_algo=$(get_osc_checksum_type OST0000)
9589                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9590         done
9591         return 0
9592 }
9593 run_test 77l "preferred checksum type is remembered after reconnected"
9594
9595 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9596 rm -f $F77_TMP
9597 unset F77_TMP
9598
9599 cleanup_test_78() {
9600         trap 0
9601         rm -f $DIR/$tfile
9602 }
9603
9604 test_78() { # bug 10901
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         remote_ost || skip_env "local OST"
9607
9608         NSEQ=5
9609         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9610         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9611         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9612         echo "MemTotal: $MEMTOTAL"
9613
9614         # reserve 256MB of memory for the kernel and other running processes,
9615         # and then take 1/2 of the remaining memory for the read/write buffers.
9616         if [ $MEMTOTAL -gt 512 ] ;then
9617                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9618         else
9619                 # for those poor memory-starved high-end clusters...
9620                 MEMTOTAL=$((MEMTOTAL / 2))
9621         fi
9622         echo "Mem to use for directio: $MEMTOTAL"
9623
9624         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9625         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9626         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9627         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9628                 head -n1)
9629         echo "Smallest OST: $SMALLESTOST"
9630         [[ $SMALLESTOST -lt 10240 ]] &&
9631                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9632
9633         trap cleanup_test_78 EXIT
9634
9635         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9636                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9637
9638         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9639         echo "File size: $F78SIZE"
9640         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9641         for i in $(seq 1 $NSEQ); do
9642                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9643                 echo directIO rdwr round $i of $NSEQ
9644                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9645         done
9646
9647         cleanup_test_78
9648 }
9649 run_test 78 "handle large O_DIRECT writes correctly ============"
9650
9651 test_79() { # bug 12743
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         wait_delete_completed
9655
9656         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9657         BKFREE=$(calc_osc_kbytes kbytesfree)
9658         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9659
9660         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9661         DFTOTAL=`echo $STRING | cut -d, -f1`
9662         DFUSED=`echo $STRING  | cut -d, -f2`
9663         DFAVAIL=`echo $STRING | cut -d, -f3`
9664         DFFREE=$(($DFTOTAL - $DFUSED))
9665
9666         ALLOWANCE=$((64 * $OSTCOUNT))
9667
9668         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9669            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9670                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9671         fi
9672         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9673            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9674                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9675         fi
9676         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9677            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9678                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9679         fi
9680 }
9681 run_test 79 "df report consistency check ======================="
9682
9683 test_80() { # bug 10718
9684         remote_ost_nodsh && skip "remote OST with nodsh"
9685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9686
9687         # relax strong synchronous semantics for slow backends like ZFS
9688         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9689                 local soc="obdfilter.*.sync_lock_cancel"
9690                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9691
9692                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9693                 if [ -z "$save" ]; then
9694                         soc="obdfilter.*.sync_on_lock_cancel"
9695                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9696                 fi
9697
9698                 if [ "$save" != "never" ]; then
9699                         local hosts=$(comma_list $(osts_nodes))
9700
9701                         do_nodes $hosts $LCTL set_param $soc=never
9702                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9703                 fi
9704         fi
9705
9706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9707         sync; sleep 1; sync
9708         local before=$(date +%s)
9709         cancel_lru_locks osc
9710         local after=$(date +%s)
9711         local diff=$((after - before))
9712         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9713
9714         rm -f $DIR/$tfile
9715 }
9716 run_test 80 "Page eviction is equally fast at high offsets too"
9717
9718 test_81a() { # LU-456
9719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9720         remote_ost_nodsh && skip "remote OST with nodsh"
9721
9722         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9723         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9724         do_facet ost1 lctl set_param fail_loc=0x80000228
9725
9726         # write should trigger a retry and success
9727         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9728         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9729         RC=$?
9730         if [ $RC -ne 0 ] ; then
9731                 error "write should success, but failed for $RC"
9732         fi
9733 }
9734 run_test 81a "OST should retry write when get -ENOSPC ==============="
9735
9736 test_81b() { # LU-456
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         remote_ost_nodsh && skip "remote OST with nodsh"
9739
9740         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9741         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9742         do_facet ost1 lctl set_param fail_loc=0x228
9743
9744         # write should retry several times and return -ENOSPC finally
9745         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9747         RC=$?
9748         ENOSPC=28
9749         if [ $RC -ne $ENOSPC ] ; then
9750                 error "dd should fail for -ENOSPC, but succeed."
9751         fi
9752 }
9753 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9754
9755 test_99() {
9756         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9757
9758         test_mkdir $DIR/$tdir.cvsroot
9759         chown $RUNAS_ID $DIR/$tdir.cvsroot
9760
9761         cd $TMP
9762         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9763
9764         cd /etc/init.d
9765         # some versions of cvs import exit(1) when asked to import links or
9766         # files they can't read.  ignore those files.
9767         local toignore=$(find . -type l -printf '-I %f\n' -o \
9768                          ! -perm /4 -printf '-I %f\n')
9769         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9770                 $tdir.reposname vtag rtag
9771
9772         cd $DIR
9773         test_mkdir $DIR/$tdir.reposname
9774         chown $RUNAS_ID $DIR/$tdir.reposname
9775         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9776
9777         cd $DIR/$tdir.reposname
9778         $RUNAS touch foo99
9779         $RUNAS cvs add -m 'addmsg' foo99
9780         $RUNAS cvs update
9781         $RUNAS cvs commit -m 'nomsg' foo99
9782         rm -fr $DIR/$tdir.cvsroot
9783 }
9784 run_test 99 "cvs strange file/directory operations"
9785
9786 test_100() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788         [[ "$NETTYPE" =~ tcp ]] ||
9789                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9790         remote_ost_nodsh && skip "remote OST with nodsh"
9791         remote_mds_nodsh && skip "remote MDS with nodsh"
9792         remote_servers ||
9793                 skip "useless for local single node setup"
9794
9795         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9796                 [ "$PROT" != "tcp" ] && continue
9797                 RPORT=$(echo $REMOTE | cut -d: -f2)
9798                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9799
9800                 rc=0
9801                 LPORT=`echo $LOCAL | cut -d: -f2`
9802                 if [ $LPORT -ge 1024 ]; then
9803                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9804                         netstat -tna
9805                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9806                 fi
9807         done
9808         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9809 }
9810 run_test 100 "check local port using privileged port ==========="
9811
9812 function get_named_value()
9813 {
9814     local tag=$1
9815
9816     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9817 }
9818
9819 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9820                    awk '/^max_cached_mb/ { print $2 }')
9821
9822 cleanup_101a() {
9823         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9824         trap 0
9825 }
9826
9827 test_101a() {
9828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9829
9830         local s
9831         local discard
9832         local nreads=10000
9833         local cache_limit=32
9834
9835         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9836         trap cleanup_101a EXIT
9837         $LCTL set_param -n llite.*.read_ahead_stats=0
9838         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9839
9840         #
9841         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9842         #
9843         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9844         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9845
9846         discard=0
9847         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9848                    get_named_value 'read.but.discarded'); do
9849                         discard=$(($discard + $s))
9850         done
9851         cleanup_101a
9852
9853         $LCTL get_param osc.*-osc*.rpc_stats
9854         $LCTL get_param llite.*.read_ahead_stats
9855
9856         # Discard is generally zero, but sometimes a few random reads line up
9857         # and trigger larger readahead, which is wasted & leads to discards.
9858         if [[ $(($discard)) -gt $nreads ]]; then
9859                 error "too many ($discard) discarded pages"
9860         fi
9861         rm -f $DIR/$tfile || true
9862 }
9863 run_test 101a "check read-ahead for random reads"
9864
9865 setup_test101bc() {
9866         test_mkdir $DIR/$tdir
9867         local ssize=$1
9868         local FILE_LENGTH=$2
9869         STRIPE_OFFSET=0
9870
9871         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9872
9873         local list=$(comma_list $(osts_nodes))
9874         set_osd_param $list '' read_cache_enable 0
9875         set_osd_param $list '' writethrough_cache_enable 0
9876
9877         trap cleanup_test101bc EXIT
9878         # prepare the read-ahead file
9879         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9880
9881         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9882                                 count=$FILE_SIZE_MB 2> /dev/null
9883
9884 }
9885
9886 cleanup_test101bc() {
9887         trap 0
9888         rm -rf $DIR/$tdir
9889         rm -f $DIR/$tfile
9890
9891         local list=$(comma_list $(osts_nodes))
9892         set_osd_param $list '' read_cache_enable 1
9893         set_osd_param $list '' writethrough_cache_enable 1
9894 }
9895
9896 calc_total() {
9897         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9898 }
9899
9900 ra_check_101() {
9901         local READ_SIZE=$1
9902         local STRIPE_SIZE=$2
9903         local FILE_LENGTH=$3
9904         local RA_INC=1048576
9905         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9906         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9907                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9908         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9909                   get_named_value 'read.but.discarded' | calc_total)
9910         if [[ $DISCARD -gt $discard_limit ]]; then
9911                 $LCTL get_param llite.*.read_ahead_stats
9912                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9913         else
9914                 echo "Read-ahead success for size ${READ_SIZE}"
9915         fi
9916 }
9917
9918 test_101b() {
9919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9921
9922         local STRIPE_SIZE=1048576
9923         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9924
9925         if [ $SLOW == "yes" ]; then
9926                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9927         else
9928                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9929         fi
9930
9931         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9932
9933         # prepare the read-ahead file
9934         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9935         cancel_lru_locks osc
9936         for BIDX in 2 4 8 16 32 64 128 256
9937         do
9938                 local BSIZE=$((BIDX*4096))
9939                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9940                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9941                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9942                 $LCTL set_param -n llite.*.read_ahead_stats=0
9943                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9944                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9945                 cancel_lru_locks osc
9946                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9947         done
9948         cleanup_test101bc
9949         true
9950 }
9951 run_test 101b "check stride-io mode read-ahead ================="
9952
9953 test_101c() {
9954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9955
9956         local STRIPE_SIZE=1048576
9957         local FILE_LENGTH=$((STRIPE_SIZE*100))
9958         local nreads=10000
9959         local rsize=65536
9960         local osc_rpc_stats
9961
9962         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9963
9964         cancel_lru_locks osc
9965         $LCTL set_param osc.*.rpc_stats=0
9966         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9967         $LCTL get_param osc.*.rpc_stats
9968         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9969                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9970                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9971                 local size
9972
9973                 if [ $lines -le 20 ]; then
9974                         echo "continue debug"
9975                         continue
9976                 fi
9977                 for size in 1 2 4 8; do
9978                         local rpc=$(echo "$stats" |
9979                                     awk '($1 == "'$size':") {print $2; exit; }')
9980                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9981                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9982                 done
9983                 echo "$osc_rpc_stats check passed!"
9984         done
9985         cleanup_test101bc
9986         true
9987 }
9988 run_test 101c "check stripe_size aligned read-ahead"
9989
9990 test_101d() {
9991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9992
9993         local file=$DIR/$tfile
9994         local sz_MB=${FILESIZE_101d:-80}
9995         local ra_MB=${READAHEAD_MB:-40}
9996
9997         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9998         [ $free_MB -lt $sz_MB ] &&
9999                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10000
10001         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10002         $LFS setstripe -c -1 $file || error "setstripe failed"
10003
10004         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10005         echo Cancel LRU locks on lustre client to flush the client cache
10006         cancel_lru_locks osc
10007
10008         echo Disable read-ahead
10009         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10010         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10011         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10012         $LCTL get_param -n llite.*.max_read_ahead_mb
10013
10014         echo "Reading the test file $file with read-ahead disabled"
10015         local sz_KB=$((sz_MB * 1024 / 4))
10016         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10017         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10018         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10019                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10020
10021         echo "Cancel LRU locks on lustre client to flush the client cache"
10022         cancel_lru_locks osc
10023         echo Enable read-ahead with ${ra_MB}MB
10024         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10025
10026         echo "Reading the test file $file with read-ahead enabled"
10027         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10028                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10029
10030         echo "read-ahead disabled time read $raOFF"
10031         echo "read-ahead enabled time read $raON"
10032
10033         rm -f $file
10034         wait_delete_completed
10035
10036         # use awk for this check instead of bash because it handles decimals
10037         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10038                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10039 }
10040 run_test 101d "file read with and without read-ahead enabled"
10041
10042 test_101e() {
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044
10045         local file=$DIR/$tfile
10046         local size_KB=500  #KB
10047         local count=100
10048         local bsize=1024
10049
10050         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10051         local need_KB=$((count * size_KB))
10052         [[ $free_KB -le $need_KB ]] &&
10053                 skip_env "Need free space $need_KB, have $free_KB"
10054
10055         echo "Creating $count ${size_KB}K test files"
10056         for ((i = 0; i < $count; i++)); do
10057                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10058         done
10059
10060         echo "Cancel LRU locks on lustre client to flush the client cache"
10061         cancel_lru_locks $OSC
10062
10063         echo "Reset readahead stats"
10064         $LCTL set_param -n llite.*.read_ahead_stats=0
10065
10066         for ((i = 0; i < $count; i++)); do
10067                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10068         done
10069
10070         $LCTL get_param llite.*.max_cached_mb
10071         $LCTL get_param llite.*.read_ahead_stats
10072         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10073                      get_named_value 'misses' | calc_total)
10074
10075         for ((i = 0; i < $count; i++)); do
10076                 rm -rf $file.$i 2>/dev/null
10077         done
10078
10079         #10000 means 20% reads are missing in readahead
10080         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10081 }
10082 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10083
10084 test_101f() {
10085         which iozone || skip_env "no iozone installed"
10086
10087         local old_debug=$($LCTL get_param debug)
10088         old_debug=${old_debug#*=}
10089         $LCTL set_param debug="reada mmap"
10090
10091         # create a test file
10092         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10093
10094         echo Cancel LRU locks on lustre client to flush the client cache
10095         cancel_lru_locks osc
10096
10097         echo Reset readahead stats
10098         $LCTL set_param -n llite.*.read_ahead_stats=0
10099
10100         echo mmap read the file with small block size
10101         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10102                 > /dev/null 2>&1
10103
10104         echo checking missing pages
10105         $LCTL get_param llite.*.read_ahead_stats
10106         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10107                         get_named_value 'misses' | calc_total)
10108
10109         $LCTL set_param debug="$old_debug"
10110         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10111         rm -f $DIR/$tfile
10112 }
10113 run_test 101f "check mmap read performance"
10114
10115 test_101g_brw_size_test() {
10116         local mb=$1
10117         local pages=$((mb * 1048576 / PAGE_SIZE))
10118         local file=$DIR/$tfile
10119
10120         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10121                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10122         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10123                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10124                         return 2
10125         done
10126
10127         stack_trap "rm -f $file" EXIT
10128         $LCTL set_param -n osc.*.rpc_stats=0
10129
10130         # 10 RPCs should be enough for the test
10131         local count=10
10132         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10133                 { error "dd write ${mb} MB blocks failed"; return 3; }
10134         cancel_lru_locks osc
10135         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10136                 { error "dd write ${mb} MB blocks failed"; return 4; }
10137
10138         # calculate number of full-sized read and write RPCs
10139         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10140                 sed -n '/pages per rpc/,/^$/p' |
10141                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10142                 END { print reads,writes }'))
10143         # allow one extra full-sized read RPC for async readahead
10144         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10145                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10146         [[ ${rpcs[1]} == $count ]] ||
10147                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10148 }
10149
10150 test_101g() {
10151         remote_ost_nodsh && skip "remote OST with nodsh"
10152
10153         local rpcs
10154         local osts=$(get_facets OST)
10155         local list=$(comma_list $(osts_nodes))
10156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10157         local brw_size="obdfilter.*.brw_size"
10158
10159         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10160
10161         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10162
10163         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10164                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10165                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10166            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10167                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10168                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10169
10170                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10171                         suffix="M"
10172
10173                 if [[ $orig_mb -lt 16 ]]; then
10174                         save_lustre_params $osts "$brw_size" > $p
10175                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10176                                 error "set 16MB RPC size failed"
10177
10178                         echo "remount client to enable new RPC size"
10179                         remount_client $MOUNT || error "remount_client failed"
10180                 fi
10181
10182                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10183                 # should be able to set brw_size=12, but no rpc_stats for that
10184                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10185         fi
10186
10187         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10188
10189         if [[ $orig_mb -lt 16 ]]; then
10190                 restore_lustre_params < $p
10191                 remount_client $MOUNT || error "remount_client restore failed"
10192         fi
10193
10194         rm -f $p $DIR/$tfile
10195 }
10196 run_test 101g "Big bulk(4/16 MiB) readahead"
10197
10198 test_101h() {
10199         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10200
10201         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10202                 error "dd 70M file failed"
10203         echo Cancel LRU locks on lustre client to flush the client cache
10204         cancel_lru_locks osc
10205
10206         echo "Reset readahead stats"
10207         $LCTL set_param -n llite.*.read_ahead_stats 0
10208
10209         echo "Read 10M of data but cross 64M bundary"
10210         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10211         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10212                      get_named_value 'misses' | calc_total)
10213         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10214         rm -f $p $DIR/$tfile
10215 }
10216 run_test 101h "Readahead should cover current read window"
10217
10218 test_101i() {
10219         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10220                 error "dd 10M file failed"
10221
10222         local max_per_file_mb=$($LCTL get_param -n \
10223                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10224         cancel_lru_locks osc
10225         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10226         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10227                 error "set max_read_ahead_per_file_mb to 1 failed"
10228
10229         echo "Reset readahead stats"
10230         $LCTL set_param llite.*.read_ahead_stats=0
10231
10232         dd if=$DIR/$tfile of=/dev/null bs=2M
10233
10234         $LCTL get_param llite.*.read_ahead_stats
10235         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10236                      awk '/misses/ { print $2 }')
10237         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10238         rm -f $DIR/$tfile
10239 }
10240 run_test 101i "allow current readahead to exceed reservation"
10241
10242 test_101j() {
10243         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10244                 error "setstripe $DIR/$tfile failed"
10245         local file_size=$((1048576 * 16))
10246         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10247         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10248
10249         echo Disable read-ahead
10250         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10251
10252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10253         for blk in $PAGE_SIZE 1048576 $file_size; do
10254                 cancel_lru_locks osc
10255                 echo "Reset readahead stats"
10256                 $LCTL set_param -n llite.*.read_ahead_stats=0
10257                 local count=$(($file_size / $blk))
10258                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10259                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10260                              get_named_value 'failed.to.fast.read' | calc_total)
10261                 $LCTL get_param -n llite.*.read_ahead_stats
10262                 [ $miss -eq $count ] || error "expected $count got $miss"
10263         done
10264
10265         rm -f $p $DIR/$tfile
10266 }
10267 run_test 101j "A complete read block should be submitted when no RA"
10268
10269 setup_test102() {
10270         test_mkdir $DIR/$tdir
10271         chown $RUNAS_ID $DIR/$tdir
10272         STRIPE_SIZE=65536
10273         STRIPE_OFFSET=1
10274         STRIPE_COUNT=$OSTCOUNT
10275         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10276
10277         trap cleanup_test102 EXIT
10278         cd $DIR
10279         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10280         cd $DIR/$tdir
10281         for num in 1 2 3 4; do
10282                 for count in $(seq 1 $STRIPE_COUNT); do
10283                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10284                                 local size=`expr $STRIPE_SIZE \* $num`
10285                                 local file=file"$num-$idx-$count"
10286                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10287                         done
10288                 done
10289         done
10290
10291         cd $DIR
10292         $1 tar cf $TMP/f102.tar $tdir --xattrs
10293 }
10294
10295 cleanup_test102() {
10296         trap 0
10297         rm -f $TMP/f102.tar
10298         rm -rf $DIR/d0.sanity/d102
10299 }
10300
10301 test_102a() {
10302         [ "$UID" != 0 ] && skip "must run as root"
10303         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10304                 skip_env "must have user_xattr"
10305
10306         [ -z "$(which setfattr 2>/dev/null)" ] &&
10307                 skip_env "could not find setfattr"
10308
10309         local testfile=$DIR/$tfile
10310
10311         touch $testfile
10312         echo "set/get xattr..."
10313         setfattr -n trusted.name1 -v value1 $testfile ||
10314                 error "setfattr -n trusted.name1=value1 $testfile failed"
10315         getfattr -n trusted.name1 $testfile 2> /dev/null |
10316           grep "trusted.name1=.value1" ||
10317                 error "$testfile missing trusted.name1=value1"
10318
10319         setfattr -n user.author1 -v author1 $testfile ||
10320                 error "setfattr -n user.author1=author1 $testfile failed"
10321         getfattr -n user.author1 $testfile 2> /dev/null |
10322           grep "user.author1=.author1" ||
10323                 error "$testfile missing trusted.author1=author1"
10324
10325         echo "listxattr..."
10326         setfattr -n trusted.name2 -v value2 $testfile ||
10327                 error "$testfile unable to set trusted.name2"
10328         setfattr -n trusted.name3 -v value3 $testfile ||
10329                 error "$testfile unable to set trusted.name3"
10330         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10331             grep "trusted.name" | wc -l) -eq 3 ] ||
10332                 error "$testfile missing 3 trusted.name xattrs"
10333
10334         setfattr -n user.author2 -v author2 $testfile ||
10335                 error "$testfile unable to set user.author2"
10336         setfattr -n user.author3 -v author3 $testfile ||
10337                 error "$testfile unable to set user.author3"
10338         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10339             grep "user.author" | wc -l) -eq 3 ] ||
10340                 error "$testfile missing 3 user.author xattrs"
10341
10342         echo "remove xattr..."
10343         setfattr -x trusted.name1 $testfile ||
10344                 error "$testfile error deleting trusted.name1"
10345         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10346                 error "$testfile did not delete trusted.name1 xattr"
10347
10348         setfattr -x user.author1 $testfile ||
10349                 error "$testfile error deleting user.author1"
10350         echo "set lustre special xattr ..."
10351         $LFS setstripe -c1 $testfile
10352         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10353                 awk -F "=" '/trusted.lov/ { print $2 }' )
10354         setfattr -n "trusted.lov" -v $lovea $testfile ||
10355                 error "$testfile doesn't ignore setting trusted.lov again"
10356         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10357                 error "$testfile allow setting invalid trusted.lov"
10358         rm -f $testfile
10359 }
10360 run_test 102a "user xattr test =================================="
10361
10362 check_102b_layout() {
10363         local layout="$*"
10364         local testfile=$DIR/$tfile
10365
10366         echo "test layout '$layout'"
10367         $LFS setstripe $layout $testfile || error "setstripe failed"
10368         $LFS getstripe -y $testfile
10369
10370         echo "get/set/list trusted.lov xattr ..." # b=10930
10371         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10372         [[ "$value" =~ "trusted.lov" ]] ||
10373                 error "can't get trusted.lov from $testfile"
10374         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10375                 error "getstripe failed"
10376
10377         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10378
10379         value=$(cut -d= -f2 <<<$value)
10380         # LU-13168: truncated xattr should fail if short lov_user_md header
10381         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10382                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10383         for len in $lens; do
10384                 echo "setfattr $len $testfile.2"
10385                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10386                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10387         done
10388         local stripe_size=$($LFS getstripe -S $testfile.2)
10389         local stripe_count=$($LFS getstripe -c $testfile.2)
10390         [[ $stripe_size -eq 65536 ]] ||
10391                 error "stripe size $stripe_size != 65536"
10392         [[ $stripe_count -eq $stripe_count_orig ]] ||
10393                 error "stripe count $stripe_count != $stripe_count_orig"
10394         rm $testfile $testfile.2
10395 }
10396
10397 test_102b() {
10398         [ -z "$(which setfattr 2>/dev/null)" ] &&
10399                 skip_env "could not find setfattr"
10400         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10401
10402         # check plain layout
10403         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10404
10405         # and also check composite layout
10406         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10407
10408 }
10409 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10410
10411 test_102c() {
10412         [ -z "$(which setfattr 2>/dev/null)" ] &&
10413                 skip_env "could not find setfattr"
10414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10415
10416         # b10930: get/set/list lustre.lov xattr
10417         echo "get/set/list lustre.lov xattr ..."
10418         test_mkdir $DIR/$tdir
10419         chown $RUNAS_ID $DIR/$tdir
10420         local testfile=$DIR/$tdir/$tfile
10421         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10422                 error "setstripe failed"
10423         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10424                 error "getstripe failed"
10425         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10426         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10427
10428         local testfile2=${testfile}2
10429         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10430                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10431
10432         $RUNAS $MCREATE $testfile2
10433         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10434         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10435         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10436         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10437         [ $stripe_count -eq $STRIPECOUNT ] ||
10438                 error "stripe count $stripe_count != $STRIPECOUNT"
10439 }
10440 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10441
10442 compare_stripe_info1() {
10443         local stripe_index_all_zero=true
10444
10445         for num in 1 2 3 4; do
10446                 for count in $(seq 1 $STRIPE_COUNT); do
10447                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10448                                 local size=$((STRIPE_SIZE * num))
10449                                 local file=file"$num-$offset-$count"
10450                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10451                                 [[ $stripe_size -ne $size ]] &&
10452                                     error "$file: size $stripe_size != $size"
10453                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10454                                 # allow fewer stripes to be created, ORI-601
10455                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10456                                     error "$file: count $stripe_count != $count"
10457                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10458                                 [[ $stripe_index -ne 0 ]] &&
10459                                         stripe_index_all_zero=false
10460                         done
10461                 done
10462         done
10463         $stripe_index_all_zero &&
10464                 error "all files are being extracted starting from OST index 0"
10465         return 0
10466 }
10467
10468 have_xattrs_include() {
10469         tar --help | grep -q xattrs-include &&
10470                 echo --xattrs-include="lustre.*"
10471 }
10472
10473 test_102d() {
10474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10475         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10476
10477         XINC=$(have_xattrs_include)
10478         setup_test102
10479         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10480         cd $DIR/$tdir/$tdir
10481         compare_stripe_info1
10482 }
10483 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10484
10485 test_102f() {
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10488
10489         XINC=$(have_xattrs_include)
10490         setup_test102
10491         test_mkdir $DIR/$tdir.restore
10492         cd $DIR
10493         tar cf - --xattrs $tdir | tar xf - \
10494                 -C $DIR/$tdir.restore --xattrs $XINC
10495         cd $DIR/$tdir.restore/$tdir
10496         compare_stripe_info1
10497 }
10498 run_test 102f "tar copy files, not keep osts"
10499
10500 grow_xattr() {
10501         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10502                 skip "must have user_xattr"
10503         [ -z "$(which setfattr 2>/dev/null)" ] &&
10504                 skip_env "could not find setfattr"
10505         [ -z "$(which getfattr 2>/dev/null)" ] &&
10506                 skip_env "could not find getfattr"
10507
10508         local xsize=${1:-1024}  # in bytes
10509         local file=$DIR/$tfile
10510         local value="$(generate_string $xsize)"
10511         local xbig=trusted.big
10512         local toobig=$2
10513
10514         touch $file
10515         log "save $xbig on $file"
10516         if [ -z "$toobig" ]
10517         then
10518                 setfattr -n $xbig -v $value $file ||
10519                         error "saving $xbig on $file failed"
10520         else
10521                 setfattr -n $xbig -v $value $file &&
10522                         error "saving $xbig on $file succeeded"
10523                 return 0
10524         fi
10525
10526         local orig=$(get_xattr_value $xbig $file)
10527         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10528
10529         local xsml=trusted.sml
10530         log "save $xsml on $file"
10531         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10532
10533         local new=$(get_xattr_value $xbig $file)
10534         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10535
10536         log "grow $xsml on $file"
10537         setfattr -n $xsml -v "$value" $file ||
10538                 error "growing $xsml on $file failed"
10539
10540         new=$(get_xattr_value $xbig $file)
10541         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10542         log "$xbig still valid after growing $xsml"
10543
10544         rm -f $file
10545 }
10546
10547 test_102h() { # bug 15777
10548         grow_xattr 1024
10549 }
10550 run_test 102h "grow xattr from inside inode to external block"
10551
10552 test_102ha() {
10553         large_xattr_enabled || skip_env "ea_inode feature disabled"
10554
10555         echo "setting xattr of max xattr size: $(max_xattr_size)"
10556         grow_xattr $(max_xattr_size)
10557
10558         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10559         echo "This should fail:"
10560         grow_xattr $(($(max_xattr_size) + 10)) 1
10561 }
10562 run_test 102ha "grow xattr from inside inode to external inode"
10563
10564 test_102i() { # bug 17038
10565         [ -z "$(which getfattr 2>/dev/null)" ] &&
10566                 skip "could not find getfattr"
10567
10568         touch $DIR/$tfile
10569         ln -s $DIR/$tfile $DIR/${tfile}link
10570         getfattr -n trusted.lov $DIR/$tfile ||
10571                 error "lgetxattr on $DIR/$tfile failed"
10572         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10573                 grep -i "no such attr" ||
10574                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10575         rm -f $DIR/$tfile $DIR/${tfile}link
10576 }
10577 run_test 102i "lgetxattr test on symbolic link ============"
10578
10579 test_102j() {
10580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10582
10583         XINC=$(have_xattrs_include)
10584         setup_test102 "$RUNAS"
10585         chown $RUNAS_ID $DIR/$tdir
10586         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10587         cd $DIR/$tdir/$tdir
10588         compare_stripe_info1 "$RUNAS"
10589 }
10590 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10591
10592 test_102k() {
10593         [ -z "$(which setfattr 2>/dev/null)" ] &&
10594                 skip "could not find setfattr"
10595
10596         touch $DIR/$tfile
10597         # b22187 just check that does not crash for regular file.
10598         setfattr -n trusted.lov $DIR/$tfile
10599         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10600         local test_kdir=$DIR/$tdir
10601         test_mkdir $test_kdir
10602         local default_size=$($LFS getstripe -S $test_kdir)
10603         local default_count=$($LFS getstripe -c $test_kdir)
10604         local default_offset=$($LFS getstripe -i $test_kdir)
10605         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10606                 error 'dir setstripe failed'
10607         setfattr -n trusted.lov $test_kdir
10608         local stripe_size=$($LFS getstripe -S $test_kdir)
10609         local stripe_count=$($LFS getstripe -c $test_kdir)
10610         local stripe_offset=$($LFS getstripe -i $test_kdir)
10611         [ $stripe_size -eq $default_size ] ||
10612                 error "stripe size $stripe_size != $default_size"
10613         [ $stripe_count -eq $default_count ] ||
10614                 error "stripe count $stripe_count != $default_count"
10615         [ $stripe_offset -eq $default_offset ] ||
10616                 error "stripe offset $stripe_offset != $default_offset"
10617         rm -rf $DIR/$tfile $test_kdir
10618 }
10619 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10620
10621 test_102l() {
10622         [ -z "$(which getfattr 2>/dev/null)" ] &&
10623                 skip "could not find getfattr"
10624
10625         # LU-532 trusted. xattr is invisible to non-root
10626         local testfile=$DIR/$tfile
10627
10628         touch $testfile
10629
10630         echo "listxattr as user..."
10631         chown $RUNAS_ID $testfile
10632         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10633             grep -q "trusted" &&
10634                 error "$testfile trusted xattrs are user visible"
10635
10636         return 0;
10637 }
10638 run_test 102l "listxattr size test =================================="
10639
10640 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10641         local path=$DIR/$tfile
10642         touch $path
10643
10644         listxattr_size_check $path || error "listattr_size_check $path failed"
10645 }
10646 run_test 102m "Ensure listxattr fails on small bufffer ========"
10647
10648 cleanup_test102
10649
10650 getxattr() { # getxattr path name
10651         # Return the base64 encoding of the value of xattr name on path.
10652         local path=$1
10653         local name=$2
10654
10655         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10656         # file: $path
10657         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10658         #
10659         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10660
10661         getfattr --absolute-names --encoding=base64 --name=$name $path |
10662                 awk -F= -v name=$name '$1 == name {
10663                         print substr($0, index($0, "=") + 1);
10664         }'
10665 }
10666
10667 test_102n() { # LU-4101 mdt: protect internal xattrs
10668         [ -z "$(which setfattr 2>/dev/null)" ] &&
10669                 skip "could not find setfattr"
10670         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10671         then
10672                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10673         fi
10674
10675         local file0=$DIR/$tfile.0
10676         local file1=$DIR/$tfile.1
10677         local xattr0=$TMP/$tfile.0
10678         local xattr1=$TMP/$tfile.1
10679         local namelist="lov lma lmv link fid version som hsm"
10680         local name
10681         local value
10682
10683         rm -rf $file0 $file1 $xattr0 $xattr1
10684         touch $file0 $file1
10685
10686         # Get 'before' xattrs of $file1.
10687         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10688
10689         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10690                 namelist+=" lfsck_namespace"
10691         for name in $namelist; do
10692                 # Try to copy xattr from $file0 to $file1.
10693                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10694
10695                 setfattr --name=trusted.$name --value="$value" $file1 ||
10696                         error "setxattr 'trusted.$name' failed"
10697
10698                 # Try to set a garbage xattr.
10699                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10700
10701                 if [[ x$name == "xlov" ]]; then
10702                         setfattr --name=trusted.lov --value="$value" $file1 &&
10703                         error "setxattr invalid 'trusted.lov' success"
10704                 else
10705                         setfattr --name=trusted.$name --value="$value" $file1 ||
10706                                 error "setxattr invalid 'trusted.$name' failed"
10707                 fi
10708
10709                 # Try to remove the xattr from $file1. We don't care if this
10710                 # appears to succeed or fail, we just don't want there to be
10711                 # any changes or crashes.
10712                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10713         done
10714
10715         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10716         then
10717                 name="lfsck_ns"
10718                 # Try to copy xattr from $file0 to $file1.
10719                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10720
10721                 setfattr --name=trusted.$name --value="$value" $file1 ||
10722                         error "setxattr 'trusted.$name' failed"
10723
10724                 # Try to set a garbage xattr.
10725                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10726
10727                 setfattr --name=trusted.$name --value="$value" $file1 ||
10728                         error "setxattr 'trusted.$name' failed"
10729
10730                 # Try to remove the xattr from $file1. We don't care if this
10731                 # appears to succeed or fail, we just don't want there to be
10732                 # any changes or crashes.
10733                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10734         fi
10735
10736         # Get 'after' xattrs of file1.
10737         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10738
10739         if ! diff $xattr0 $xattr1; then
10740                 error "before and after xattrs of '$file1' differ"
10741         fi
10742
10743         rm -rf $file0 $file1 $xattr0 $xattr1
10744
10745         return 0
10746 }
10747 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10748
10749 test_102p() { # LU-4703 setxattr did not check ownership
10750         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10751                 skip "MDS needs to be at least 2.5.56"
10752
10753         local testfile=$DIR/$tfile
10754
10755         touch $testfile
10756
10757         echo "setfacl as user..."
10758         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10759         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10760
10761         echo "setfattr as user..."
10762         setfacl -m "u:$RUNAS_ID:---" $testfile
10763         $RUNAS setfattr -x system.posix_acl_access $testfile
10764         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10765 }
10766 run_test 102p "check setxattr(2) correctly fails without permission"
10767
10768 test_102q() {
10769         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10770                 skip "MDS needs to be at least 2.6.92"
10771
10772         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10773 }
10774 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10775
10776 test_102r() {
10777         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10778                 skip "MDS needs to be at least 2.6.93"
10779
10780         touch $DIR/$tfile || error "touch"
10781         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10782         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10783         rm $DIR/$tfile || error "rm"
10784
10785         #normal directory
10786         mkdir -p $DIR/$tdir || error "mkdir"
10787         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10788         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10789         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10790                 error "$testfile error deleting user.author1"
10791         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10792                 grep "user.$(basename $tdir)" &&
10793                 error "$tdir did not delete user.$(basename $tdir)"
10794         rmdir $DIR/$tdir || error "rmdir"
10795
10796         #striped directory
10797         test_mkdir $DIR/$tdir
10798         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10799         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10800         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10801                 error "$testfile error deleting user.author1"
10802         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10803                 grep "user.$(basename $tdir)" &&
10804                 error "$tdir did not delete user.$(basename $tdir)"
10805         rmdir $DIR/$tdir || error "rm striped dir"
10806 }
10807 run_test 102r "set EAs with empty values"
10808
10809 test_102s() {
10810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10811                 skip "MDS needs to be at least 2.11.52"
10812
10813         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10814
10815         save_lustre_params client "llite.*.xattr_cache" > $save
10816
10817         for cache in 0 1; do
10818                 lctl set_param llite.*.xattr_cache=$cache
10819
10820                 rm -f $DIR/$tfile
10821                 touch $DIR/$tfile || error "touch"
10822                 for prefix in lustre security system trusted user; do
10823                         # Note getxattr() may fail with 'Operation not
10824                         # supported' or 'No such attribute' depending
10825                         # on prefix and cache.
10826                         getfattr -n $prefix.n102s $DIR/$tfile &&
10827                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10828                 done
10829         done
10830
10831         restore_lustre_params < $save
10832 }
10833 run_test 102s "getting nonexistent xattrs should fail"
10834
10835 test_102t() {
10836         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10837                 skip "MDS needs to be at least 2.11.52"
10838
10839         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10840
10841         save_lustre_params client "llite.*.xattr_cache" > $save
10842
10843         for cache in 0 1; do
10844                 lctl set_param llite.*.xattr_cache=$cache
10845
10846                 for buf_size in 0 256; do
10847                         rm -f $DIR/$tfile
10848                         touch $DIR/$tfile || error "touch"
10849                         setfattr -n user.multiop $DIR/$tfile
10850                         $MULTIOP $DIR/$tfile oa$buf_size ||
10851                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10852                 done
10853         done
10854
10855         restore_lustre_params < $save
10856 }
10857 run_test 102t "zero length xattr values handled correctly"
10858
10859 run_acl_subtest()
10860 {
10861     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10862     return $?
10863 }
10864
10865 test_103a() {
10866         [ "$UID" != 0 ] && skip "must run as root"
10867         $GSS && skip_env "could not run under gss"
10868         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10869                 skip_env "must have acl enabled"
10870         [ -z "$(which setfacl 2>/dev/null)" ] &&
10871                 skip_env "could not find setfacl"
10872         remote_mds_nodsh && skip "remote MDS with nodsh"
10873
10874         gpasswd -a daemon bin                           # LU-5641
10875         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10876
10877         declare -a identity_old
10878
10879         for num in $(seq $MDSCOUNT); do
10880                 switch_identity $num true || identity_old[$num]=$?
10881         done
10882
10883         SAVE_UMASK=$(umask)
10884         umask 0022
10885         mkdir -p $DIR/$tdir
10886         cd $DIR/$tdir
10887
10888         echo "performing cp ..."
10889         run_acl_subtest cp || error "run_acl_subtest cp failed"
10890         echo "performing getfacl-noacl..."
10891         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10892         echo "performing misc..."
10893         run_acl_subtest misc || error  "misc test failed"
10894         echo "performing permissions..."
10895         run_acl_subtest permissions || error "permissions failed"
10896         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10897         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10898                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10899                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10900         then
10901                 echo "performing permissions xattr..."
10902                 run_acl_subtest permissions_xattr ||
10903                         error "permissions_xattr failed"
10904         fi
10905         echo "performing setfacl..."
10906         run_acl_subtest setfacl || error  "setfacl test failed"
10907
10908         # inheritance test got from HP
10909         echo "performing inheritance..."
10910         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10911         chmod +x make-tree || error "chmod +x failed"
10912         run_acl_subtest inheritance || error "inheritance test failed"
10913         rm -f make-tree
10914
10915         echo "LU-974 ignore umask when acl is enabled..."
10916         run_acl_subtest 974 || error "LU-974 umask test failed"
10917         if [ $MDSCOUNT -ge 2 ]; then
10918                 run_acl_subtest 974_remote ||
10919                         error "LU-974 umask test failed under remote dir"
10920         fi
10921
10922         echo "LU-2561 newly created file is same size as directory..."
10923         if [ "$mds1_FSTYPE" != "zfs" ]; then
10924                 run_acl_subtest 2561 || error "LU-2561 test failed"
10925         else
10926                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10927         fi
10928
10929         run_acl_subtest 4924 || error "LU-4924 test failed"
10930
10931         cd $SAVE_PWD
10932         umask $SAVE_UMASK
10933
10934         for num in $(seq $MDSCOUNT); do
10935                 if [ "${identity_old[$num]}" = 1 ]; then
10936                         switch_identity $num false || identity_old[$num]=$?
10937                 fi
10938         done
10939 }
10940 run_test 103a "acl test"
10941
10942 test_103b() {
10943         declare -a pids
10944         local U
10945
10946         for U in {0..511}; do
10947                 {
10948                 local O=$(printf "%04o" $U)
10949
10950                 umask $(printf "%04o" $((511 ^ $O)))
10951                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10952                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10953
10954                 (( $S == ($O & 0666) )) ||
10955                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10956
10957                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10958                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10959                 (( $S == ($O & 0666) )) ||
10960                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10961
10962                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10963                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10964                 (( $S == ($O & 0666) )) ||
10965                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10966                 rm -f $DIR/$tfile.[smp]$0
10967                 } &
10968                 local pid=$!
10969
10970                 # limit the concurrently running threads to 64. LU-11878
10971                 local idx=$((U % 64))
10972                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10973                 pids[idx]=$pid
10974         done
10975         wait
10976 }
10977 run_test 103b "umask lfs setstripe"
10978
10979 test_103c() {
10980         mkdir -p $DIR/$tdir
10981         cp -rp $DIR/$tdir $DIR/$tdir.bak
10982
10983         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10984                 error "$DIR/$tdir shouldn't contain default ACL"
10985         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10986                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10987         true
10988 }
10989 run_test 103c "'cp -rp' won't set empty acl"
10990
10991 test_103e() {
10992         local numacl
10993         local fileacl
10994         local saved_debug=$($LCTL get_param -n debug)
10995
10996         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10997                 skip "MDS needs to be at least 2.14.0"
10998
10999         large_xattr_enabled || skip_env "ea_inode feature disabled"
11000
11001         mkdir -p $DIR/$tdir
11002         # add big LOV EA to cause reply buffer overflow earlier
11003         $LFS setstripe -C 1000 $DIR/$tdir
11004         lctl set_param mdc.*-mdc*.stats=clear
11005
11006         $LCTL set_param debug=0
11007         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11008         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11009
11010         # add a large number of default ACLs (expect 8000+ for 2.13+)
11011         for U in {2..7000}; do
11012                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11013                         error "Able to add just $U default ACLs"
11014         done
11015         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11016         echo "$numacl default ACLs created"
11017
11018         stat $DIR/$tdir || error "Cannot stat directory"
11019         # check file creation
11020         touch $DIR/$tdir/$tfile ||
11021                 error "failed to create $tfile with $numacl default ACLs"
11022         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11023         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11024         echo "$fileacl ACLs were inherited"
11025         (( $fileacl == $numacl )) ||
11026                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11027         # check that new ACLs creation adds new ACLs to inherited ACLs
11028         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11029                 error "Cannot set new ACL"
11030         numacl=$((numacl + 1))
11031         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11032         (( $fileacl == $numacl )) ||
11033                 error "failed to add new ACL: $fileacl != $numacl as expected"
11034         # adds more ACLs to a file to reach their maximum at 8000+
11035         numacl=0
11036         for U in {20000..25000}; do
11037                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11038                 numacl=$((numacl + 1))
11039         done
11040         echo "Added $numacl more ACLs to the file"
11041         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11042         echo "Total $fileacl ACLs in file"
11043         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11044         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11045         rmdir $DIR/$tdir || error "Cannot remove directory"
11046 }
11047 run_test 103e "inheritance of big amount of default ACLs"
11048
11049 test_103f() {
11050         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11051                 skip "MDS needs to be at least 2.14.51"
11052
11053         large_xattr_enabled || skip_env "ea_inode feature disabled"
11054
11055         # enable changelog to consume more internal MDD buffers
11056         changelog_register
11057
11058         mkdir -p $DIR/$tdir
11059         # add big LOV EA
11060         $LFS setstripe -C 1000 $DIR/$tdir
11061         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11062         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11063         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11064         rmdir $DIR/$tdir || error "Cannot remove directory"
11065 }
11066 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11067
11068 test_104a() {
11069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11070
11071         touch $DIR/$tfile
11072         lfs df || error "lfs df failed"
11073         lfs df -ih || error "lfs df -ih failed"
11074         lfs df -h $DIR || error "lfs df -h $DIR failed"
11075         lfs df -i $DIR || error "lfs df -i $DIR failed"
11076         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11077         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11078
11079         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11080         lctl --device %$OSC deactivate
11081         lfs df || error "lfs df with deactivated OSC failed"
11082         lctl --device %$OSC activate
11083         # wait the osc back to normal
11084         wait_osc_import_ready client ost
11085
11086         lfs df || error "lfs df with reactivated OSC failed"
11087         rm -f $DIR/$tfile
11088 }
11089 run_test 104a "lfs df [-ih] [path] test ========================="
11090
11091 test_104b() {
11092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11093         [ $RUNAS_ID -eq $UID ] &&
11094                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11095
11096         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11097                         grep "Permission denied" | wc -l)))
11098         if [ $denied_cnt -ne 0 ]; then
11099                 error "lfs check servers test failed"
11100         fi
11101 }
11102 run_test 104b "$RUNAS lfs check servers test ===================="
11103
11104 #
11105 # Verify $1 is within range of $2.
11106 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11107 # $1 is <= 2% of $2. Else Fail.
11108 #
11109 value_in_range() {
11110         # Strip all units (M, G, T)
11111         actual=$(echo $1 | tr -d A-Z)
11112         expect=$(echo $2 | tr -d A-Z)
11113
11114         expect_lo=$(($expect * 98 / 100)) # 2% below
11115         expect_hi=$(($expect * 102 / 100)) # 2% above
11116
11117         # permit 2% drift above and below
11118         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11119 }
11120
11121 test_104c() {
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11124
11125         local ost_param="osd-zfs.$FSNAME-OST0000."
11126         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11127         local ofacets=$(get_facets OST)
11128         local mfacets=$(get_facets MDS)
11129         local saved_ost_blocks=
11130         local saved_mdt_blocks=
11131
11132         echo "Before recordsize change"
11133         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11134         df=($(df -h | grep "/mnt/lustre"$))
11135
11136         # For checking.
11137         echo "lfs output : ${lfs_df[*]}"
11138         echo "df  output : ${df[*]}"
11139
11140         for facet in ${ofacets//,/ }; do
11141                 if [ -z $saved_ost_blocks ]; then
11142                         saved_ost_blocks=$(do_facet $facet \
11143                                 lctl get_param -n $ost_param.blocksize)
11144                         echo "OST Blocksize: $saved_ost_blocks"
11145                 fi
11146                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11147                 do_facet $facet zfs set recordsize=32768 $ost
11148         done
11149
11150         # BS too small. Sufficient for functional testing.
11151         for facet in ${mfacets//,/ }; do
11152                 if [ -z $saved_mdt_blocks ]; then
11153                         saved_mdt_blocks=$(do_facet $facet \
11154                                 lctl get_param -n $mdt_param.blocksize)
11155                         echo "MDT Blocksize: $saved_mdt_blocks"
11156                 fi
11157                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11158                 do_facet $facet zfs set recordsize=32768 $mdt
11159         done
11160
11161         # Give new values chance to reflect change
11162         sleep 2
11163
11164         echo "After recordsize change"
11165         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11166         df_after=($(df -h | grep "/mnt/lustre"$))
11167
11168         # For checking.
11169         echo "lfs output : ${lfs_df_after[*]}"
11170         echo "df  output : ${df_after[*]}"
11171
11172         # Verify lfs df
11173         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11174                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11175         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11176                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11177         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11178                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11179
11180         # Verify df
11181         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11182                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11183         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11184                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11185         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11186                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11187
11188         # Restore MDT recordize back to original
11189         for facet in ${mfacets//,/ }; do
11190                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11191                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11192         done
11193
11194         # Restore OST recordize back to original
11195         for facet in ${ofacets//,/ }; do
11196                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11197                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11198         done
11199
11200         return 0
11201 }
11202 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11203
11204 test_105a() {
11205         # doesn't work on 2.4 kernels
11206         touch $DIR/$tfile
11207         if $(flock_is_enabled); then
11208                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11209         else
11210                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11211         fi
11212         rm -f $DIR/$tfile
11213 }
11214 run_test 105a "flock when mounted without -o flock test ========"
11215
11216 test_105b() {
11217         touch $DIR/$tfile
11218         if $(flock_is_enabled); then
11219                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11220         else
11221                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11222         fi
11223         rm -f $DIR/$tfile
11224 }
11225 run_test 105b "fcntl when mounted without -o flock test ========"
11226
11227 test_105c() {
11228         touch $DIR/$tfile
11229         if $(flock_is_enabled); then
11230                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11231         else
11232                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11233         fi
11234         rm -f $DIR/$tfile
11235 }
11236 run_test 105c "lockf when mounted without -o flock test"
11237
11238 test_105d() { # bug 15924
11239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11240
11241         test_mkdir $DIR/$tdir
11242         flock_is_enabled || skip_env "mount w/o flock enabled"
11243         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11244         $LCTL set_param fail_loc=0x80000315
11245         flocks_test 2 $DIR/$tdir
11246 }
11247 run_test 105d "flock race (should not freeze) ========"
11248
11249 test_105e() { # bug 22660 && 22040
11250         flock_is_enabled || skip_env "mount w/o flock enabled"
11251
11252         touch $DIR/$tfile
11253         flocks_test 3 $DIR/$tfile
11254 }
11255 run_test 105e "Two conflicting flocks from same process"
11256
11257 test_106() { #bug 10921
11258         test_mkdir $DIR/$tdir
11259         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11260         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11261 }
11262 run_test 106 "attempt exec of dir followed by chown of that dir"
11263
11264 test_107() {
11265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11266
11267         CDIR=`pwd`
11268         local file=core
11269
11270         cd $DIR
11271         rm -f $file
11272
11273         local save_pattern=$(sysctl -n kernel.core_pattern)
11274         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11275         sysctl -w kernel.core_pattern=$file
11276         sysctl -w kernel.core_uses_pid=0
11277
11278         ulimit -c unlimited
11279         sleep 60 &
11280         SLEEPPID=$!
11281
11282         sleep 1
11283
11284         kill -s 11 $SLEEPPID
11285         wait $SLEEPPID
11286         if [ -e $file ]; then
11287                 size=`stat -c%s $file`
11288                 [ $size -eq 0 ] && error "Fail to create core file $file"
11289         else
11290                 error "Fail to create core file $file"
11291         fi
11292         rm -f $file
11293         sysctl -w kernel.core_pattern=$save_pattern
11294         sysctl -w kernel.core_uses_pid=$save_uses_pid
11295         cd $CDIR
11296 }
11297 run_test 107 "Coredump on SIG"
11298
11299 test_110() {
11300         test_mkdir $DIR/$tdir
11301         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11302         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11303                 error "mkdir with 256 char should fail, but did not"
11304         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11305                 error "create with 255 char failed"
11306         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11307                 error "create with 256 char should fail, but did not"
11308
11309         ls -l $DIR/$tdir
11310         rm -rf $DIR/$tdir
11311 }
11312 run_test 110 "filename length checking"
11313
11314 #
11315 # Purpose: To verify dynamic thread (OSS) creation.
11316 #
11317 test_115() {
11318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11319         remote_ost_nodsh && skip "remote OST with nodsh"
11320
11321         # Lustre does not stop service threads once they are started.
11322         # Reset number of running threads to default.
11323         stopall
11324         setupall
11325
11326         local OSTIO_pre
11327         local save_params="$TMP/sanity-$TESTNAME.parameters"
11328
11329         # Get ll_ost_io count before I/O
11330         OSTIO_pre=$(do_facet ost1 \
11331                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11332         # Exit if lustre is not running (ll_ost_io not running).
11333         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11334
11335         echo "Starting with $OSTIO_pre threads"
11336         local thread_max=$((OSTIO_pre * 2))
11337         local rpc_in_flight=$((thread_max * 2))
11338         # Number of I/O Process proposed to be started.
11339         local nfiles
11340         local facets=$(get_facets OST)
11341
11342         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11343         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11344
11345         # Set in_flight to $rpc_in_flight
11346         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11347                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11348         nfiles=${rpc_in_flight}
11349         # Set ost thread_max to $thread_max
11350         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11351
11352         # 5 Minutes should be sufficient for max number of OSS
11353         # threads(thread_max) to be created.
11354         local timeout=300
11355
11356         # Start I/O.
11357         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11358         test_mkdir $DIR/$tdir
11359         for i in $(seq $nfiles); do
11360                 local file=$DIR/$tdir/${tfile}-$i
11361                 $LFS setstripe -c -1 -i 0 $file
11362                 ($WTL $file $timeout)&
11363         done
11364
11365         # I/O Started - Wait for thread_started to reach thread_max or report
11366         # error if thread_started is more than thread_max.
11367         echo "Waiting for thread_started to reach thread_max"
11368         local thread_started=0
11369         local end_time=$((SECONDS + timeout))
11370
11371         while [ $SECONDS -le $end_time ] ; do
11372                 echo -n "."
11373                 # Get ost i/o thread_started count.
11374                 thread_started=$(do_facet ost1 \
11375                         "$LCTL get_param \
11376                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11377                 # Break out if thread_started is equal/greater than thread_max
11378                 if [[ $thread_started -ge $thread_max ]]; then
11379                         echo ll_ost_io thread_started $thread_started, \
11380                                 equal/greater than thread_max $thread_max
11381                         break
11382                 fi
11383                 sleep 1
11384         done
11385
11386         # Cleanup - We have the numbers, Kill i/o jobs if running.
11387         jobcount=($(jobs -p))
11388         for i in $(seq 0 $((${#jobcount[@]}-1)))
11389         do
11390                 kill -9 ${jobcount[$i]}
11391                 if [ $? -ne 0 ] ; then
11392                         echo Warning: \
11393                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11394                 fi
11395         done
11396
11397         # Cleanup files left by WTL binary.
11398         for i in $(seq $nfiles); do
11399                 local file=$DIR/$tdir/${tfile}-$i
11400                 rm -rf $file
11401                 if [ $? -ne 0 ] ; then
11402                         echo "Warning: Failed to delete file $file"
11403                 fi
11404         done
11405
11406         restore_lustre_params <$save_params
11407         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11408
11409         # Error out if no new thread has started or Thread started is greater
11410         # than thread max.
11411         if [[ $thread_started -le $OSTIO_pre ||
11412                         $thread_started -gt $thread_max ]]; then
11413                 error "ll_ost_io: thread_started $thread_started" \
11414                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11415                       "No new thread started or thread started greater " \
11416                       "than thread_max."
11417         fi
11418 }
11419 run_test 115 "verify dynamic thread creation===================="
11420
11421 free_min_max () {
11422         wait_delete_completed
11423         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11424         echo "OST kbytes available: ${AVAIL[@]}"
11425         MAXV=${AVAIL[0]}
11426         MAXI=0
11427         MINV=${AVAIL[0]}
11428         MINI=0
11429         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11430                 #echo OST $i: ${AVAIL[i]}kb
11431                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11432                         MAXV=${AVAIL[i]}
11433                         MAXI=$i
11434                 fi
11435                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11436                         MINV=${AVAIL[i]}
11437                         MINI=$i
11438                 fi
11439         done
11440         echo "Min free space: OST $MINI: $MINV"
11441         echo "Max free space: OST $MAXI: $MAXV"
11442 }
11443
11444 test_116a() { # was previously test_116()
11445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11446         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11447         remote_mds_nodsh && skip "remote MDS with nodsh"
11448
11449         echo -n "Free space priority "
11450         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11451                 head -n1
11452         declare -a AVAIL
11453         free_min_max
11454
11455         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11456         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11457         trap simple_cleanup_common EXIT
11458
11459         # Check if we need to generate uneven OSTs
11460         test_mkdir -p $DIR/$tdir/OST${MINI}
11461         local FILL=$((MINV / 4))
11462         local DIFF=$((MAXV - MINV))
11463         local DIFF2=$((DIFF * 100 / MINV))
11464
11465         local threshold=$(do_facet $SINGLEMDS \
11466                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11467         threshold=${threshold%%%}
11468         echo -n "Check for uneven OSTs: "
11469         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11470
11471         if [[ $DIFF2 -gt $threshold ]]; then
11472                 echo "ok"
11473                 echo "Don't need to fill OST$MINI"
11474         else
11475                 # generate uneven OSTs. Write 2% over the QOS threshold value
11476                 echo "no"
11477                 DIFF=$((threshold - DIFF2 + 2))
11478                 DIFF2=$((MINV * DIFF / 100))
11479                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11480                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11481                         error "setstripe failed"
11482                 DIFF=$((DIFF2 / 2048))
11483                 i=0
11484                 while [ $i -lt $DIFF ]; do
11485                         i=$((i + 1))
11486                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11487                                 bs=2M count=1 2>/dev/null
11488                         echo -n .
11489                 done
11490                 echo .
11491                 sync
11492                 sleep_maxage
11493                 free_min_max
11494         fi
11495
11496         DIFF=$((MAXV - MINV))
11497         DIFF2=$((DIFF * 100 / MINV))
11498         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11499         if [ $DIFF2 -gt $threshold ]; then
11500                 echo "ok"
11501         else
11502                 echo "failed - QOS mode won't be used"
11503                 simple_cleanup_common
11504                 skip "QOS imbalance criteria not met"
11505         fi
11506
11507         MINI1=$MINI
11508         MINV1=$MINV
11509         MAXI1=$MAXI
11510         MAXV1=$MAXV
11511
11512         # now fill using QOS
11513         $LFS setstripe -c 1 $DIR/$tdir
11514         FILL=$((FILL / 200))
11515         if [ $FILL -gt 600 ]; then
11516                 FILL=600
11517         fi
11518         echo "writing $FILL files to QOS-assigned OSTs"
11519         i=0
11520         while [ $i -lt $FILL ]; do
11521                 i=$((i + 1))
11522                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11523                         count=1 2>/dev/null
11524                 echo -n .
11525         done
11526         echo "wrote $i 200k files"
11527         sync
11528         sleep_maxage
11529
11530         echo "Note: free space may not be updated, so measurements might be off"
11531         free_min_max
11532         DIFF2=$((MAXV - MINV))
11533         echo "free space delta: orig $DIFF final $DIFF2"
11534         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11535         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11536         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11537         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11538         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11539         if [[ $DIFF -gt 0 ]]; then
11540                 FILL=$((DIFF2 * 100 / DIFF - 100))
11541                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11542         fi
11543
11544         # Figure out which files were written where
11545         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11546                awk '/'$MINI1': / {print $2; exit}')
11547         echo $UUID
11548         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11549         echo "$MINC files created on smaller OST $MINI1"
11550         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11551                awk '/'$MAXI1': / {print $2; exit}')
11552         echo $UUID
11553         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11554         echo "$MAXC files created on larger OST $MAXI1"
11555         if [[ $MINC -gt 0 ]]; then
11556                 FILL=$((MAXC * 100 / MINC - 100))
11557                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11558         fi
11559         [[ $MAXC -gt $MINC ]] ||
11560                 error_ignore LU-9 "stripe QOS didn't balance free space"
11561         simple_cleanup_common
11562 }
11563 run_test 116a "stripe QOS: free space balance ==================="
11564
11565 test_116b() { # LU-2093
11566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11567         remote_mds_nodsh && skip "remote MDS with nodsh"
11568
11569 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11570         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11571                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11572         [ -z "$old_rr" ] && skip "no QOS"
11573         do_facet $SINGLEMDS lctl set_param \
11574                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11575         mkdir -p $DIR/$tdir
11576         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11577         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11578         do_facet $SINGLEMDS lctl set_param fail_loc=0
11579         rm -rf $DIR/$tdir
11580         do_facet $SINGLEMDS lctl set_param \
11581                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11582 }
11583 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11584
11585 test_117() # bug 10891
11586 {
11587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11588
11589         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11590         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11591         lctl set_param fail_loc=0x21e
11592         > $DIR/$tfile || error "truncate failed"
11593         lctl set_param fail_loc=0
11594         echo "Truncate succeeded."
11595         rm -f $DIR/$tfile
11596 }
11597 run_test 117 "verify osd extend =========="
11598
11599 NO_SLOW_RESENDCOUNT=4
11600 export OLD_RESENDCOUNT=""
11601 set_resend_count () {
11602         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11603         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11604         lctl set_param -n $PROC_RESENDCOUNT $1
11605         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11606 }
11607
11608 # for reduce test_118* time (b=14842)
11609 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11610
11611 # Reset async IO behavior after error case
11612 reset_async() {
11613         FILE=$DIR/reset_async
11614
11615         # Ensure all OSCs are cleared
11616         $LFS setstripe -c -1 $FILE
11617         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11618         sync
11619         rm $FILE
11620 }
11621
11622 test_118a() #bug 11710
11623 {
11624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11625
11626         reset_async
11627
11628         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11629         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11630         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11631
11632         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11633                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11634                 return 1;
11635         fi
11636         rm -f $DIR/$tfile
11637 }
11638 run_test 118a "verify O_SYNC works =========="
11639
11640 test_118b()
11641 {
11642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11643         remote_ost_nodsh && skip "remote OST with nodsh"
11644
11645         reset_async
11646
11647         #define OBD_FAIL_SRV_ENOENT 0x217
11648         set_nodes_failloc "$(osts_nodes)" 0x217
11649         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11650         RC=$?
11651         set_nodes_failloc "$(osts_nodes)" 0
11652         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11653         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11654                     grep -c writeback)
11655
11656         if [[ $RC -eq 0 ]]; then
11657                 error "Must return error due to dropped pages, rc=$RC"
11658                 return 1;
11659         fi
11660
11661         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11662                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11663                 return 1;
11664         fi
11665
11666         echo "Dirty pages not leaked on ENOENT"
11667
11668         # Due to the above error the OSC will issue all RPCs syncronously
11669         # until a subsequent RPC completes successfully without error.
11670         $MULTIOP $DIR/$tfile Ow4096yc
11671         rm -f $DIR/$tfile
11672
11673         return 0
11674 }
11675 run_test 118b "Reclaim dirty pages on fatal error =========="
11676
11677 test_118c()
11678 {
11679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11680
11681         # for 118c, restore the original resend count, LU-1940
11682         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11683                                 set_resend_count $OLD_RESENDCOUNT
11684         remote_ost_nodsh && skip "remote OST with nodsh"
11685
11686         reset_async
11687
11688         #define OBD_FAIL_OST_EROFS               0x216
11689         set_nodes_failloc "$(osts_nodes)" 0x216
11690
11691         # multiop should block due to fsync until pages are written
11692         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11693         MULTIPID=$!
11694         sleep 1
11695
11696         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11697                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11698         fi
11699
11700         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11701                     grep -c writeback)
11702         if [[ $WRITEBACK -eq 0 ]]; then
11703                 error "No page in writeback, writeback=$WRITEBACK"
11704         fi
11705
11706         set_nodes_failloc "$(osts_nodes)" 0
11707         wait $MULTIPID
11708         RC=$?
11709         if [[ $RC -ne 0 ]]; then
11710                 error "Multiop fsync failed, rc=$RC"
11711         fi
11712
11713         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11714         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11715                     grep -c writeback)
11716         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11717                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11718         fi
11719
11720         rm -f $DIR/$tfile
11721         echo "Dirty pages flushed via fsync on EROFS"
11722         return 0
11723 }
11724 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11725
11726 # continue to use small resend count to reduce test_118* time (b=14842)
11727 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11728
11729 test_118d()
11730 {
11731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11732         remote_ost_nodsh && skip "remote OST with nodsh"
11733
11734         reset_async
11735
11736         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11737         set_nodes_failloc "$(osts_nodes)" 0x214
11738         # multiop should block due to fsync until pages are written
11739         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11740         MULTIPID=$!
11741         sleep 1
11742
11743         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11744                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11745         fi
11746
11747         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11748                     grep -c writeback)
11749         if [[ $WRITEBACK -eq 0 ]]; then
11750                 error "No page in writeback, writeback=$WRITEBACK"
11751         fi
11752
11753         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11754         set_nodes_failloc "$(osts_nodes)" 0
11755
11756         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11757         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11758                     grep -c writeback)
11759         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11760                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11761         fi
11762
11763         rm -f $DIR/$tfile
11764         echo "Dirty pages gaurenteed flushed via fsync"
11765         return 0
11766 }
11767 run_test 118d "Fsync validation inject a delay of the bulk =========="
11768
11769 test_118f() {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771
11772         reset_async
11773
11774         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11775         lctl set_param fail_loc=0x8000040a
11776
11777         # Should simulate EINVAL error which is fatal
11778         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11779         RC=$?
11780         if [[ $RC -eq 0 ]]; then
11781                 error "Must return error due to dropped pages, rc=$RC"
11782         fi
11783
11784         lctl set_param fail_loc=0x0
11785
11786         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11787         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11788         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11789                     grep -c writeback)
11790         if [[ $LOCKED -ne 0 ]]; then
11791                 error "Locked pages remain in cache, locked=$LOCKED"
11792         fi
11793
11794         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11795                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11796         fi
11797
11798         rm -f $DIR/$tfile
11799         echo "No pages locked after fsync"
11800
11801         reset_async
11802         return 0
11803 }
11804 run_test 118f "Simulate unrecoverable OSC side error =========="
11805
11806 test_118g() {
11807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11808
11809         reset_async
11810
11811         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11812         lctl set_param fail_loc=0x406
11813
11814         # simulate local -ENOMEM
11815         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11816         RC=$?
11817
11818         lctl set_param fail_loc=0
11819         if [[ $RC -eq 0 ]]; then
11820                 error "Must return error due to dropped pages, rc=$RC"
11821         fi
11822
11823         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11824         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11825         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11826                         grep -c writeback)
11827         if [[ $LOCKED -ne 0 ]]; then
11828                 error "Locked pages remain in cache, locked=$LOCKED"
11829         fi
11830
11831         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11832                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11833         fi
11834
11835         rm -f $DIR/$tfile
11836         echo "No pages locked after fsync"
11837
11838         reset_async
11839         return 0
11840 }
11841 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11842
11843 test_118h() {
11844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11845         remote_ost_nodsh && skip "remote OST with nodsh"
11846
11847         reset_async
11848
11849         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11850         set_nodes_failloc "$(osts_nodes)" 0x20e
11851         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11853         RC=$?
11854
11855         set_nodes_failloc "$(osts_nodes)" 0
11856         if [[ $RC -eq 0 ]]; then
11857                 error "Must return error due to dropped pages, rc=$RC"
11858         fi
11859
11860         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11861         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11862         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11863                     grep -c writeback)
11864         if [[ $LOCKED -ne 0 ]]; then
11865                 error "Locked pages remain in cache, locked=$LOCKED"
11866         fi
11867
11868         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11869                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11870         fi
11871
11872         rm -f $DIR/$tfile
11873         echo "No pages locked after fsync"
11874
11875         return 0
11876 }
11877 run_test 118h "Verify timeout in handling recoverables errors  =========="
11878
11879 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11880
11881 test_118i() {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883         remote_ost_nodsh && skip "remote OST with nodsh"
11884
11885         reset_async
11886
11887         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11888         set_nodes_failloc "$(osts_nodes)" 0x20e
11889
11890         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11891         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11892         PID=$!
11893         sleep 5
11894         set_nodes_failloc "$(osts_nodes)" 0
11895
11896         wait $PID
11897         RC=$?
11898         if [[ $RC -ne 0 ]]; then
11899                 error "got error, but should be not, rc=$RC"
11900         fi
11901
11902         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11903         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11905         if [[ $LOCKED -ne 0 ]]; then
11906                 error "Locked pages remain in cache, locked=$LOCKED"
11907         fi
11908
11909         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11910                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11911         fi
11912
11913         rm -f $DIR/$tfile
11914         echo "No pages locked after fsync"
11915
11916         return 0
11917 }
11918 run_test 118i "Fix error before timeout in recoverable error  =========="
11919
11920 [ "$SLOW" = "no" ] && set_resend_count 4
11921
11922 test_118j() {
11923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11924         remote_ost_nodsh && skip "remote OST with nodsh"
11925
11926         reset_async
11927
11928         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11929         set_nodes_failloc "$(osts_nodes)" 0x220
11930
11931         # return -EIO from OST
11932         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11933         RC=$?
11934         set_nodes_failloc "$(osts_nodes)" 0x0
11935         if [[ $RC -eq 0 ]]; then
11936                 error "Must return error due to dropped pages, rc=$RC"
11937         fi
11938
11939         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11940         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11941         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11942         if [[ $LOCKED -ne 0 ]]; then
11943                 error "Locked pages remain in cache, locked=$LOCKED"
11944         fi
11945
11946         # in recoverable error on OST we want resend and stay until it finished
11947         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11948                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11949         fi
11950
11951         rm -f $DIR/$tfile
11952         echo "No pages locked after fsync"
11953
11954         return 0
11955 }
11956 run_test 118j "Simulate unrecoverable OST side error =========="
11957
11958 test_118k()
11959 {
11960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11961         remote_ost_nodsh && skip "remote OSTs with nodsh"
11962
11963         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11964         set_nodes_failloc "$(osts_nodes)" 0x20e
11965         test_mkdir $DIR/$tdir
11966
11967         for ((i=0;i<10;i++)); do
11968                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11969                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11970                 SLEEPPID=$!
11971                 sleep 0.500s
11972                 kill $SLEEPPID
11973                 wait $SLEEPPID
11974         done
11975
11976         set_nodes_failloc "$(osts_nodes)" 0
11977         rm -rf $DIR/$tdir
11978 }
11979 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11980
11981 test_118l() # LU-646
11982 {
11983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11984
11985         test_mkdir $DIR/$tdir
11986         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11987         rm -rf $DIR/$tdir
11988 }
11989 run_test 118l "fsync dir"
11990
11991 test_118m() # LU-3066
11992 {
11993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11994
11995         test_mkdir $DIR/$tdir
11996         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11997         rm -rf $DIR/$tdir
11998 }
11999 run_test 118m "fdatasync dir ========="
12000
12001 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12002
12003 test_118n()
12004 {
12005         local begin
12006         local end
12007
12008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12009         remote_ost_nodsh && skip "remote OSTs with nodsh"
12010
12011         # Sleep to avoid a cached response.
12012         #define OBD_STATFS_CACHE_SECONDS 1
12013         sleep 2
12014
12015         # Inject a 10 second delay in the OST_STATFS handler.
12016         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12017         set_nodes_failloc "$(osts_nodes)" 0x242
12018
12019         begin=$SECONDS
12020         stat --file-system $MOUNT > /dev/null
12021         end=$SECONDS
12022
12023         set_nodes_failloc "$(osts_nodes)" 0
12024
12025         if ((end - begin > 20)); then
12026             error "statfs took $((end - begin)) seconds, expected 10"
12027         fi
12028 }
12029 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12030
12031 test_119a() # bug 11737
12032 {
12033         BSIZE=$((512 * 1024))
12034         directio write $DIR/$tfile 0 1 $BSIZE
12035         # We ask to read two blocks, which is more than a file size.
12036         # directio will indicate an error when requested and actual
12037         # sizes aren't equeal (a normal situation in this case) and
12038         # print actual read amount.
12039         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12040         if [ "$NOB" != "$BSIZE" ]; then
12041                 error "read $NOB bytes instead of $BSIZE"
12042         fi
12043         rm -f $DIR/$tfile
12044 }
12045 run_test 119a "Short directIO read must return actual read amount"
12046
12047 test_119b() # bug 11737
12048 {
12049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12050
12051         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12053         sync
12054         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12055                 error "direct read failed"
12056         rm -f $DIR/$tfile
12057 }
12058 run_test 119b "Sparse directIO read must return actual read amount"
12059
12060 test_119c() # bug 13099
12061 {
12062         BSIZE=1048576
12063         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12064         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12065         rm -f $DIR/$tfile
12066 }
12067 run_test 119c "Testing for direct read hitting hole"
12068
12069 test_119d() # bug 15950
12070 {
12071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12072
12073         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12074         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12075         BSIZE=1048576
12076         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12077         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12078         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12079         lctl set_param fail_loc=0x40d
12080         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12081         pid_dio=$!
12082         sleep 1
12083         cat $DIR/$tfile > /dev/null &
12084         lctl set_param fail_loc=0
12085         pid_reads=$!
12086         wait $pid_dio
12087         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12088         sleep 2
12089         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12090         error "the read rpcs have not completed in 2s"
12091         rm -f $DIR/$tfile
12092         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12093 }
12094 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12095
12096 test_120a() {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         remote_mds_nodsh && skip "remote MDS with nodsh"
12099         test_mkdir -i0 -c1 $DIR/$tdir
12100         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12101                 skip_env "no early lock cancel on server"
12102
12103         lru_resize_disable mdc
12104         lru_resize_disable osc
12105         cancel_lru_locks mdc
12106         # asynchronous object destroy at MDT could cause bl ast to client
12107         cancel_lru_locks osc
12108
12109         stat $DIR/$tdir > /dev/null
12110         can1=$(do_facet mds1 \
12111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12112                awk '/ldlm_cancel/ {print $2}')
12113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12114                awk '/ldlm_bl_callback/ {print $2}')
12115         test_mkdir -i0 -c1 $DIR/$tdir/d1
12116         can2=$(do_facet mds1 \
12117                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12118                awk '/ldlm_cancel/ {print $2}')
12119         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12120                awk '/ldlm_bl_callback/ {print $2}')
12121         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12122         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12123         lru_resize_enable mdc
12124         lru_resize_enable osc
12125 }
12126 run_test 120a "Early Lock Cancel: mkdir test"
12127
12128 test_120b() {
12129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12130         remote_mds_nodsh && skip "remote MDS with nodsh"
12131         test_mkdir $DIR/$tdir
12132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12133                 skip_env "no early lock cancel on server"
12134
12135         lru_resize_disable mdc
12136         lru_resize_disable osc
12137         cancel_lru_locks mdc
12138         stat $DIR/$tdir > /dev/null
12139         can1=$(do_facet $SINGLEMDS \
12140                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12141                awk '/ldlm_cancel/ {print $2}')
12142         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12143                awk '/ldlm_bl_callback/ {print $2}')
12144         touch $DIR/$tdir/f1
12145         can2=$(do_facet $SINGLEMDS \
12146                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12147                awk '/ldlm_cancel/ {print $2}')
12148         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12149                awk '/ldlm_bl_callback/ {print $2}')
12150         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12151         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12152         lru_resize_enable mdc
12153         lru_resize_enable osc
12154 }
12155 run_test 120b "Early Lock Cancel: create test"
12156
12157 test_120c() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         remote_mds_nodsh && skip "remote MDS with nodsh"
12160         test_mkdir -i0 -c1 $DIR/$tdir
12161         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12162                 skip "no early lock cancel on server"
12163
12164         lru_resize_disable mdc
12165         lru_resize_disable osc
12166         test_mkdir -i0 -c1 $DIR/$tdir/d1
12167         test_mkdir -i0 -c1 $DIR/$tdir/d2
12168         touch $DIR/$tdir/d1/f1
12169         cancel_lru_locks mdc
12170         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12171         can1=$(do_facet mds1 \
12172                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12173                awk '/ldlm_cancel/ {print $2}')
12174         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12175                awk '/ldlm_bl_callback/ {print $2}')
12176         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12177         can2=$(do_facet mds1 \
12178                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12179                awk '/ldlm_cancel/ {print $2}')
12180         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12181                awk '/ldlm_bl_callback/ {print $2}')
12182         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12183         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12184         lru_resize_enable mdc
12185         lru_resize_enable osc
12186 }
12187 run_test 120c "Early Lock Cancel: link test"
12188
12189 test_120d() {
12190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12191         remote_mds_nodsh && skip "remote MDS with nodsh"
12192         test_mkdir -i0 -c1 $DIR/$tdir
12193         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12194                 skip_env "no early lock cancel on server"
12195
12196         lru_resize_disable mdc
12197         lru_resize_disable osc
12198         touch $DIR/$tdir
12199         cancel_lru_locks mdc
12200         stat $DIR/$tdir > /dev/null
12201         can1=$(do_facet mds1 \
12202                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12203                awk '/ldlm_cancel/ {print $2}')
12204         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12205                awk '/ldlm_bl_callback/ {print $2}')
12206         chmod a+x $DIR/$tdir
12207         can2=$(do_facet mds1 \
12208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12209                awk '/ldlm_cancel/ {print $2}')
12210         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12211                awk '/ldlm_bl_callback/ {print $2}')
12212         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12213         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12214         lru_resize_enable mdc
12215         lru_resize_enable osc
12216 }
12217 run_test 120d "Early Lock Cancel: setattr test"
12218
12219 test_120e() {
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12222                 skip_env "no early lock cancel on server"
12223         remote_mds_nodsh && skip "remote MDS with nodsh"
12224
12225         local dlmtrace_set=false
12226
12227         test_mkdir -i0 -c1 $DIR/$tdir
12228         lru_resize_disable mdc
12229         lru_resize_disable osc
12230         ! $LCTL get_param debug | grep -q dlmtrace &&
12231                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12232         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12233         cancel_lru_locks mdc
12234         cancel_lru_locks osc
12235         dd if=$DIR/$tdir/f1 of=/dev/null
12236         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12237         # XXX client can not do early lock cancel of OST lock
12238         # during unlink (LU-4206), so cancel osc lock now.
12239         sleep 2
12240         cancel_lru_locks osc
12241         can1=$(do_facet mds1 \
12242                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12243                awk '/ldlm_cancel/ {print $2}')
12244         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12245                awk '/ldlm_bl_callback/ {print $2}')
12246         unlink $DIR/$tdir/f1
12247         sleep 5
12248         can2=$(do_facet mds1 \
12249                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12250                awk '/ldlm_cancel/ {print $2}')
12251         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12252                awk '/ldlm_bl_callback/ {print $2}')
12253         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12254                 $LCTL dk $TMP/cancel.debug.txt
12255         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12256                 $LCTL dk $TMP/blocking.debug.txt
12257         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12258         lru_resize_enable mdc
12259         lru_resize_enable osc
12260 }
12261 run_test 120e "Early Lock Cancel: unlink test"
12262
12263 test_120f() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12266                 skip_env "no early lock cancel on server"
12267         remote_mds_nodsh && skip "remote MDS with nodsh"
12268
12269         test_mkdir -i0 -c1 $DIR/$tdir
12270         lru_resize_disable mdc
12271         lru_resize_disable osc
12272         test_mkdir -i0 -c1 $DIR/$tdir/d1
12273         test_mkdir -i0 -c1 $DIR/$tdir/d2
12274         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12275         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12276         cancel_lru_locks mdc
12277         cancel_lru_locks osc
12278         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12279         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12280         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12281         # XXX client can not do early lock cancel of OST lock
12282         # during rename (LU-4206), so cancel osc lock now.
12283         sleep 2
12284         cancel_lru_locks osc
12285         can1=$(do_facet mds1 \
12286                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12287                awk '/ldlm_cancel/ {print $2}')
12288         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12289                awk '/ldlm_bl_callback/ {print $2}')
12290         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12291         sleep 5
12292         can2=$(do_facet mds1 \
12293                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12294                awk '/ldlm_cancel/ {print $2}')
12295         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12296                awk '/ldlm_bl_callback/ {print $2}')
12297         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12298         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12299         lru_resize_enable mdc
12300         lru_resize_enable osc
12301 }
12302 run_test 120f "Early Lock Cancel: rename test"
12303
12304 test_120g() {
12305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12306         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12307                 skip_env "no early lock cancel on server"
12308         remote_mds_nodsh && skip "remote MDS with nodsh"
12309
12310         lru_resize_disable mdc
12311         lru_resize_disable osc
12312         count=10000
12313         echo create $count files
12314         test_mkdir $DIR/$tdir
12315         cancel_lru_locks mdc
12316         cancel_lru_locks osc
12317         t0=$(date +%s)
12318
12319         can0=$(do_facet $SINGLEMDS \
12320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12321                awk '/ldlm_cancel/ {print $2}')
12322         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12323                awk '/ldlm_bl_callback/ {print $2}')
12324         createmany -o $DIR/$tdir/f $count
12325         sync
12326         can1=$(do_facet $SINGLEMDS \
12327                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12328                awk '/ldlm_cancel/ {print $2}')
12329         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12330                awk '/ldlm_bl_callback/ {print $2}')
12331         t1=$(date +%s)
12332         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12333         echo rm $count files
12334         rm -r $DIR/$tdir
12335         sync
12336         can2=$(do_facet $SINGLEMDS \
12337                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12338                awk '/ldlm_cancel/ {print $2}')
12339         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12340                awk '/ldlm_bl_callback/ {print $2}')
12341         t2=$(date +%s)
12342         echo total: $count removes in $((t2-t1))
12343         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12344         sleep 2
12345         # wait for commitment of removal
12346         lru_resize_enable mdc
12347         lru_resize_enable osc
12348 }
12349 run_test 120g "Early Lock Cancel: performance test"
12350
12351 test_121() { #bug #10589
12352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12353
12354         rm -rf $DIR/$tfile
12355         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12356 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12357         lctl set_param fail_loc=0x310
12358         cancel_lru_locks osc > /dev/null
12359         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12360         lctl set_param fail_loc=0
12361         [[ $reads -eq $writes ]] ||
12362                 error "read $reads blocks, must be $writes blocks"
12363 }
12364 run_test 121 "read cancel race ========="
12365
12366 test_123a_base() { # was test 123, statahead(bug 11401)
12367         local lsx="$1"
12368
12369         SLOWOK=0
12370         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12371                 log "testing UP system. Performance may be lower than expected."
12372                 SLOWOK=1
12373         fi
12374
12375         rm -rf $DIR/$tdir
12376         test_mkdir $DIR/$tdir
12377         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12378         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12379         MULT=10
12380         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12381                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12382
12383                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12384                 lctl set_param -n llite.*.statahead_max 0
12385                 lctl get_param llite.*.statahead_max
12386                 cancel_lru_locks mdc
12387                 cancel_lru_locks osc
12388                 stime=$(date +%s)
12389                 time $lsx $DIR/$tdir | wc -l
12390                 etime=$(date +%s)
12391                 delta=$((etime - stime))
12392                 log "$lsx $i files without statahead: $delta sec"
12393                 lctl set_param llite.*.statahead_max=$max
12394
12395                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12396                         grep "statahead wrong:" | awk '{print $3}')
12397                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12398                 cancel_lru_locks mdc
12399                 cancel_lru_locks osc
12400                 stime=$(date +%s)
12401                 time $lsx $DIR/$tdir | wc -l
12402                 etime=$(date +%s)
12403                 delta_sa=$((etime - stime))
12404                 log "$lsx $i files with statahead: $delta_sa sec"
12405                 lctl get_param -n llite.*.statahead_stats
12406                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12407                         grep "statahead wrong:" | awk '{print $3}')
12408
12409                 [[ $swrong -lt $ewrong ]] &&
12410                         log "statahead was stopped, maybe too many locks held!"
12411                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12412
12413                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12414                         max=$(lctl get_param -n llite.*.statahead_max |
12415                                 head -n 1)
12416                         lctl set_param -n llite.*.statahead_max 0
12417                         lctl get_param llite.*.statahead_max
12418                         cancel_lru_locks mdc
12419                         cancel_lru_locks osc
12420                         stime=$(date +%s)
12421                         time $lsx $DIR/$tdir | wc -l
12422                         etime=$(date +%s)
12423                         delta=$((etime - stime))
12424                         log "$lsx $i files again without statahead: $delta sec"
12425                         lctl set_param llite.*.statahead_max=$max
12426                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12427                                 if [  $SLOWOK -eq 0 ]; then
12428                                         error "$lsx $i files is slower with statahead!"
12429                                 else
12430                                         log "$lsx $i files is slower with statahead!"
12431                                 fi
12432                                 break
12433                         fi
12434                 fi
12435
12436                 [ $delta -gt 20 ] && break
12437                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12438                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12439         done
12440         log "$lsx done"
12441
12442         stime=$(date +%s)
12443         rm -r $DIR/$tdir
12444         sync
12445         etime=$(date +%s)
12446         delta=$((etime - stime))
12447         log "rm -r $DIR/$tdir/: $delta seconds"
12448         log "rm done"
12449         lctl get_param -n llite.*.statahead_stats
12450 }
12451
12452 test_123aa() {
12453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12454
12455         test_123a_base "ls -l"
12456 }
12457 run_test 123aa "verify statahead work"
12458
12459 test_123ab() {
12460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12461
12462         statx_supported || skip_env "Test must be statx() syscall supported"
12463
12464         test_123a_base "$STATX -l"
12465 }
12466 run_test 123ab "verify statahead work by using statx"
12467
12468 test_123ac() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470
12471         statx_supported || skip_env "Test must be statx() syscall supported"
12472
12473         local rpcs_before
12474         local rpcs_after
12475         local agl_before
12476         local agl_after
12477
12478         cancel_lru_locks $OSC
12479         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12480         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12481                 awk '/agl.total:/ {print $3}')
12482         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12483         test_123a_base "$STATX --cached=always -D"
12484         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12485                 awk '/agl.total:/ {print $3}')
12486         [ $agl_before -eq $agl_after ] ||
12487                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12488         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12489         [ $rpcs_after -eq $rpcs_before ] ||
12490                 error "$STATX should not send glimpse RPCs to $OSC"
12491 }
12492 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12493
12494 test_123b () { # statahead(bug 15027)
12495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12496
12497         test_mkdir $DIR/$tdir
12498         createmany -o $DIR/$tdir/$tfile-%d 1000
12499
12500         cancel_lru_locks mdc
12501         cancel_lru_locks osc
12502
12503 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12504         lctl set_param fail_loc=0x80000803
12505         ls -lR $DIR/$tdir > /dev/null
12506         log "ls done"
12507         lctl set_param fail_loc=0x0
12508         lctl get_param -n llite.*.statahead_stats
12509         rm -r $DIR/$tdir
12510         sync
12511
12512 }
12513 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12514
12515 test_123c() {
12516         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12517
12518         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12519         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12520         touch $DIR/$tdir.1/{1..3}
12521         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12522
12523         remount_client $MOUNT
12524
12525         $MULTIOP $DIR/$tdir.0 Q
12526
12527         # let statahead to complete
12528         ls -l $DIR/$tdir.0 > /dev/null
12529
12530         testid=$(echo $TESTNAME | tr '_' ' ')
12531         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12532                 error "statahead warning" || true
12533 }
12534 run_test 123c "Can not initialize inode warning on DNE statahead"
12535
12536 test_124a() {
12537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12538         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12539                 skip_env "no lru resize on server"
12540
12541         local NR=2000
12542
12543         test_mkdir $DIR/$tdir
12544
12545         log "create $NR files at $DIR/$tdir"
12546         createmany -o $DIR/$tdir/f $NR ||
12547                 error "failed to create $NR files in $DIR/$tdir"
12548
12549         cancel_lru_locks mdc
12550         ls -l $DIR/$tdir > /dev/null
12551
12552         local NSDIR=""
12553         local LRU_SIZE=0
12554         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12555                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12556                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12557                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12558                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12559                         log "NSDIR=$NSDIR"
12560                         log "NS=$(basename $NSDIR)"
12561                         break
12562                 fi
12563         done
12564
12565         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12566                 skip "Not enough cached locks created!"
12567         fi
12568         log "LRU=$LRU_SIZE"
12569
12570         local SLEEP=30
12571
12572         # We know that lru resize allows one client to hold $LIMIT locks
12573         # for 10h. After that locks begin to be killed by client.
12574         local MAX_HRS=10
12575         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12576         log "LIMIT=$LIMIT"
12577         if [ $LIMIT -lt $LRU_SIZE ]; then
12578                 skip "Limit is too small $LIMIT"
12579         fi
12580
12581         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12582         # killing locks. Some time was spent for creating locks. This means
12583         # that up to the moment of sleep finish we must have killed some of
12584         # them (10-100 locks). This depends on how fast ther were created.
12585         # Many of them were touched in almost the same moment and thus will
12586         # be killed in groups.
12587         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12588
12589         # Use $LRU_SIZE_B here to take into account real number of locks
12590         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12591         local LRU_SIZE_B=$LRU_SIZE
12592         log "LVF=$LVF"
12593         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12594         log "OLD_LVF=$OLD_LVF"
12595         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12596
12597         # Let's make sure that we really have some margin. Client checks
12598         # cached locks every 10 sec.
12599         SLEEP=$((SLEEP+20))
12600         log "Sleep ${SLEEP} sec"
12601         local SEC=0
12602         while ((SEC<$SLEEP)); do
12603                 echo -n "..."
12604                 sleep 5
12605                 SEC=$((SEC+5))
12606                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12607                 echo -n "$LRU_SIZE"
12608         done
12609         echo ""
12610         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12611         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12612
12613         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12614                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12615                 unlinkmany $DIR/$tdir/f $NR
12616                 return
12617         }
12618
12619         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12620         log "unlink $NR files at $DIR/$tdir"
12621         unlinkmany $DIR/$tdir/f $NR
12622 }
12623 run_test 124a "lru resize ======================================="
12624
12625 get_max_pool_limit()
12626 {
12627         local limit=$($LCTL get_param \
12628                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12629         local max=0
12630         for l in $limit; do
12631                 if [[ $l -gt $max ]]; then
12632                         max=$l
12633                 fi
12634         done
12635         echo $max
12636 }
12637
12638 test_124b() {
12639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12640         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12641                 skip_env "no lru resize on server"
12642
12643         LIMIT=$(get_max_pool_limit)
12644
12645         NR=$(($(default_lru_size)*20))
12646         if [[ $NR -gt $LIMIT ]]; then
12647                 log "Limit lock number by $LIMIT locks"
12648                 NR=$LIMIT
12649         fi
12650
12651         IFree=$(mdsrate_inodes_available)
12652         if [ $IFree -lt $NR ]; then
12653                 log "Limit lock number by $IFree inodes"
12654                 NR=$IFree
12655         fi
12656
12657         lru_resize_disable mdc
12658         test_mkdir -p $DIR/$tdir/disable_lru_resize
12659
12660         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12661         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12662         cancel_lru_locks mdc
12663         stime=`date +%s`
12664         PID=""
12665         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12666         PID="$PID $!"
12667         sleep 2
12668         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12669         PID="$PID $!"
12670         sleep 2
12671         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12672         PID="$PID $!"
12673         wait $PID
12674         etime=`date +%s`
12675         nolruresize_delta=$((etime-stime))
12676         log "ls -la time: $nolruresize_delta seconds"
12677         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12678         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12679
12680         lru_resize_enable mdc
12681         test_mkdir -p $DIR/$tdir/enable_lru_resize
12682
12683         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12684         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12685         cancel_lru_locks mdc
12686         stime=`date +%s`
12687         PID=""
12688         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12689         PID="$PID $!"
12690         sleep 2
12691         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12692         PID="$PID $!"
12693         sleep 2
12694         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12695         PID="$PID $!"
12696         wait $PID
12697         etime=`date +%s`
12698         lruresize_delta=$((etime-stime))
12699         log "ls -la time: $lruresize_delta seconds"
12700         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12701
12702         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12703                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12704         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12705                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12706         else
12707                 log "lru resize performs the same with no lru resize"
12708         fi
12709         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12710 }
12711 run_test 124b "lru resize (performance test) ======================="
12712
12713 test_124c() {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12716                 skip_env "no lru resize on server"
12717
12718         # cache ununsed locks on client
12719         local nr=100
12720         cancel_lru_locks mdc
12721         test_mkdir $DIR/$tdir
12722         createmany -o $DIR/$tdir/f $nr ||
12723                 error "failed to create $nr files in $DIR/$tdir"
12724         ls -l $DIR/$tdir > /dev/null
12725
12726         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12727         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12728         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12729         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12730         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12731
12732         # set lru_max_age to 1 sec
12733         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12734         echo "sleep $((recalc_p * 2)) seconds..."
12735         sleep $((recalc_p * 2))
12736
12737         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12738         # restore lru_max_age
12739         $LCTL set_param -n $nsdir.lru_max_age $max_age
12740         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12741         unlinkmany $DIR/$tdir/f $nr
12742 }
12743 run_test 124c "LRUR cancel very aged locks"
12744
12745 test_124d() {
12746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12747         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12748                 skip_env "no lru resize on server"
12749
12750         # cache ununsed locks on client
12751         local nr=100
12752
12753         lru_resize_disable mdc
12754         stack_trap "lru_resize_enable mdc" EXIT
12755
12756         cancel_lru_locks mdc
12757
12758         # asynchronous object destroy at MDT could cause bl ast to client
12759         test_mkdir $DIR/$tdir
12760         createmany -o $DIR/$tdir/f $nr ||
12761                 error "failed to create $nr files in $DIR/$tdir"
12762         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12763
12764         ls -l $DIR/$tdir > /dev/null
12765
12766         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12767         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12768         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12769         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12770
12771         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12772
12773         # set lru_max_age to 1 sec
12774         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12775         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12776
12777         echo "sleep $((recalc_p * 2)) seconds..."
12778         sleep $((recalc_p * 2))
12779
12780         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12781
12782         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12783 }
12784 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12785
12786 test_125() { # 13358
12787         $LCTL get_param -n llite.*.client_type | grep -q local ||
12788                 skip "must run as local client"
12789         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12790                 skip_env "must have acl enabled"
12791         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12792
12793         test_mkdir $DIR/$tdir
12794         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12795         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12796         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12797 }
12798 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12799
12800 test_126() { # bug 12829/13455
12801         $GSS && skip_env "must run as gss disabled"
12802         $LCTL get_param -n llite.*.client_type | grep -q local ||
12803                 skip "must run as local client"
12804         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12805
12806         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12807         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12808         rm -f $DIR/$tfile
12809         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12810 }
12811 run_test 126 "check that the fsgid provided by the client is taken into account"
12812
12813 test_127a() { # bug 15521
12814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12815         local name count samp unit min max sum sumsq
12816
12817         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12818         echo "stats before reset"
12819         $LCTL get_param osc.*.stats
12820         $LCTL set_param osc.*.stats=0
12821         local fsize=$((2048 * 1024))
12822
12823         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12824         cancel_lru_locks osc
12825         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12826
12827         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12828         stack_trap "rm -f $TMP/$tfile.tmp"
12829         while read name count samp unit min max sum sumsq; do
12830                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12831                 [ ! $min ] && error "Missing min value for $name proc entry"
12832                 eval $name=$count || error "Wrong proc format"
12833
12834                 case $name in
12835                 read_bytes|write_bytes)
12836                         [[ "$unit" =~ "bytes" ]] ||
12837                                 error "unit is not 'bytes': $unit"
12838                         (( $min >= 4096 )) || error "min is too small: $min"
12839                         (( $min <= $fsize )) || error "min is too big: $min"
12840                         (( $max >= 4096 )) || error "max is too small: $max"
12841                         (( $max <= $fsize )) || error "max is too big: $max"
12842                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12843                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12844                                 error "sumsquare is too small: $sumsq"
12845                         (( $sumsq <= $fsize * $fsize )) ||
12846                                 error "sumsquare is too big: $sumsq"
12847                         ;;
12848                 ost_read|ost_write)
12849                         [[ "$unit" =~ "usec" ]] ||
12850                                 error "unit is not 'usec': $unit"
12851                         ;;
12852                 *)      ;;
12853                 esac
12854         done < $DIR/$tfile.tmp
12855
12856         #check that we actually got some stats
12857         [ "$read_bytes" ] || error "Missing read_bytes stats"
12858         [ "$write_bytes" ] || error "Missing write_bytes stats"
12859         [ "$read_bytes" != 0 ] || error "no read done"
12860         [ "$write_bytes" != 0 ] || error "no write done"
12861 }
12862 run_test 127a "verify the client stats are sane"
12863
12864 test_127b() { # bug LU-333
12865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12866         local name count samp unit min max sum sumsq
12867
12868         echo "stats before reset"
12869         $LCTL get_param llite.*.stats
12870         $LCTL set_param llite.*.stats=0
12871
12872         # perform 2 reads and writes so MAX is different from SUM.
12873         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12874         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12875         cancel_lru_locks osc
12876         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12877         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12878
12879         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12880         stack_trap "rm -f $TMP/$tfile.tmp"
12881         while read name count samp unit min max sum sumsq; do
12882                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12883                 eval $name=$count || error "Wrong proc format"
12884
12885                 case $name in
12886                 read_bytes|write_bytes)
12887                         [[ "$unit" =~ "bytes" ]] ||
12888                                 error "unit is not 'bytes': $unit"
12889                         (( $count == 2 )) || error "count is not 2: $count"
12890                         (( $min == $PAGE_SIZE )) ||
12891                                 error "min is not $PAGE_SIZE: $min"
12892                         (( $max == $PAGE_SIZE )) ||
12893                                 error "max is not $PAGE_SIZE: $max"
12894                         (( $sum == $PAGE_SIZE * 2 )) ||
12895                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12896                         ;;
12897                 read|write)
12898                         [[ "$unit" =~ "usec" ]] ||
12899                                 error "unit is not 'usec': $unit"
12900                         ;;
12901                 *)      ;;
12902                 esac
12903         done < $TMP/$tfile.tmp
12904
12905         #check that we actually got some stats
12906         [ "$read_bytes" ] || error "Missing read_bytes stats"
12907         [ "$write_bytes" ] || error "Missing write_bytes stats"
12908         [ "$read_bytes" != 0 ] || error "no read done"
12909         [ "$write_bytes" != 0 ] || error "no write done"
12910 }
12911 run_test 127b "verify the llite client stats are sane"
12912
12913 test_127c() { # LU-12394
12914         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12915         local size
12916         local bsize
12917         local reads
12918         local writes
12919         local count
12920
12921         $LCTL set_param llite.*.extents_stats=1
12922         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12923
12924         # Use two stripes so there is enough space in default config
12925         $LFS setstripe -c 2 $DIR/$tfile
12926
12927         # Extent stats start at 0-4K and go in power of two buckets
12928         # LL_HIST_START = 12 --> 2^12 = 4K
12929         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12930         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12931         # small configs
12932         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12933                 do
12934                 # Write and read, 2x each, second time at a non-zero offset
12935                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12936                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12937                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12938                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12939                 rm -f $DIR/$tfile
12940         done
12941
12942         $LCTL get_param llite.*.extents_stats
12943
12944         count=2
12945         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12946                 do
12947                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12948                                 grep -m 1 $bsize)
12949                 reads=$(echo $bucket | awk '{print $5}')
12950                 writes=$(echo $bucket | awk '{print $9}')
12951                 [ "$reads" -eq $count ] ||
12952                         error "$reads reads in < $bsize bucket, expect $count"
12953                 [ "$writes" -eq $count ] ||
12954                         error "$writes writes in < $bsize bucket, expect $count"
12955         done
12956
12957         # Test mmap write and read
12958         $LCTL set_param llite.*.extents_stats=c
12959         size=512
12960         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12961         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12962         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12963
12964         $LCTL get_param llite.*.extents_stats
12965
12966         count=$(((size*1024) / PAGE_SIZE))
12967
12968         bsize=$((2 * PAGE_SIZE / 1024))K
12969
12970         bucket=$($LCTL get_param -n llite.*.extents_stats |
12971                         grep -m 1 $bsize)
12972         reads=$(echo $bucket | awk '{print $5}')
12973         writes=$(echo $bucket | awk '{print $9}')
12974         # mmap writes fault in the page first, creating an additonal read
12975         [ "$reads" -eq $((2 * count)) ] ||
12976                 error "$reads reads in < $bsize bucket, expect $count"
12977         [ "$writes" -eq $count ] ||
12978                 error "$writes writes in < $bsize bucket, expect $count"
12979 }
12980 run_test 127c "test llite extent stats with regular & mmap i/o"
12981
12982 test_128() { # bug 15212
12983         touch $DIR/$tfile
12984         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12985                 find $DIR/$tfile
12986                 find $DIR/$tfile
12987         EOF
12988
12989         result=$(grep error $TMP/$tfile.log)
12990         rm -f $DIR/$tfile $TMP/$tfile.log
12991         [ -z "$result" ] ||
12992                 error "consecutive find's under interactive lfs failed"
12993 }
12994 run_test 128 "interactive lfs for 2 consecutive find's"
12995
12996 set_dir_limits () {
12997         local mntdev
12998         local canondev
12999         local node
13000
13001         local ldproc=/proc/fs/ldiskfs
13002         local facets=$(get_facets MDS)
13003
13004         for facet in ${facets//,/ }; do
13005                 canondev=$(ldiskfs_canon \
13006                            *.$(convert_facet2label $facet).mntdev $facet)
13007                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13008                         ldproc=/sys/fs/ldiskfs
13009                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13010                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13011         done
13012 }
13013
13014 check_mds_dmesg() {
13015         local facets=$(get_facets MDS)
13016         for facet in ${facets//,/ }; do
13017                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13018         done
13019         return 1
13020 }
13021
13022 test_129() {
13023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13024         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13025                 skip "Need MDS version with at least 2.5.56"
13026         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13027                 skip_env "ldiskfs only test"
13028         fi
13029         remote_mds_nodsh && skip "remote MDS with nodsh"
13030
13031         local ENOSPC=28
13032         local has_warning=false
13033
13034         rm -rf $DIR/$tdir
13035         mkdir -p $DIR/$tdir
13036
13037         # block size of mds1
13038         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13039         set_dir_limits $maxsize $((maxsize * 6 / 8))
13040         stack_trap "set_dir_limits 0 0"
13041         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13042         local dirsize=$(stat -c%s "$DIR/$tdir")
13043         local nfiles=0
13044         while (( $dirsize <= $maxsize )); do
13045                 $MCREATE $DIR/$tdir/file_base_$nfiles
13046                 rc=$?
13047                 # check two errors:
13048                 # ENOSPC for ext4 max_dir_size, which has been used since
13049                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13050                 if (( rc == ENOSPC )); then
13051                         set_dir_limits 0 0
13052                         echo "rc=$rc returned as expected after $nfiles files"
13053
13054                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13055                                 error "create failed w/o dir size limit"
13056
13057                         # messages may be rate limited if test is run repeatedly
13058                         check_mds_dmesg '"is approaching max"' ||
13059                                 echo "warning message should be output"
13060                         check_mds_dmesg '"has reached max"' ||
13061                                 echo "reached message should be output"
13062
13063                         dirsize=$(stat -c%s "$DIR/$tdir")
13064
13065                         [[ $dirsize -ge $maxsize ]] && return 0
13066                         error "dirsize $dirsize < $maxsize after $nfiles files"
13067                 elif (( rc != 0 )); then
13068                         break
13069                 fi
13070                 nfiles=$((nfiles + 1))
13071                 dirsize=$(stat -c%s "$DIR/$tdir")
13072         done
13073
13074         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13075 }
13076 run_test 129 "test directory size limit ========================"
13077
13078 OLDIFS="$IFS"
13079 cleanup_130() {
13080         trap 0
13081         IFS="$OLDIFS"
13082 }
13083
13084 test_130a() {
13085         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13086         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13087
13088         trap cleanup_130 EXIT RETURN
13089
13090         local fm_file=$DIR/$tfile
13091         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13092         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13093                 error "dd failed for $fm_file"
13094
13095         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13096         filefrag -ves $fm_file
13097         RC=$?
13098         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13099                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13100         [ $RC != 0 ] && error "filefrag $fm_file failed"
13101
13102         filefrag_op=$(filefrag -ve -k $fm_file |
13103                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13104         lun=$($LFS getstripe -i $fm_file)
13105
13106         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13107         IFS=$'\n'
13108         tot_len=0
13109         for line in $filefrag_op
13110         do
13111                 frag_lun=`echo $line | cut -d: -f5`
13112                 ext_len=`echo $line | cut -d: -f4`
13113                 if (( $frag_lun != $lun )); then
13114                         cleanup_130
13115                         error "FIEMAP on 1-stripe file($fm_file) failed"
13116                         return
13117                 fi
13118                 (( tot_len += ext_len ))
13119         done
13120
13121         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13122                 cleanup_130
13123                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13124                 return
13125         fi
13126
13127         cleanup_130
13128
13129         echo "FIEMAP on single striped file succeeded"
13130 }
13131 run_test 130a "FIEMAP (1-stripe file)"
13132
13133 test_130b() {
13134         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13135
13136         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13137         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13138
13139         trap cleanup_130 EXIT RETURN
13140
13141         local fm_file=$DIR/$tfile
13142         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13143                         error "setstripe on $fm_file"
13144         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13145                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13146
13147         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13148                 error "dd failed on $fm_file"
13149
13150         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13151         filefrag_op=$(filefrag -ve -k $fm_file |
13152                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13153
13154         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13155                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13156
13157         IFS=$'\n'
13158         tot_len=0
13159         num_luns=1
13160         for line in $filefrag_op
13161         do
13162                 frag_lun=$(echo $line | cut -d: -f5 |
13163                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13164                 ext_len=$(echo $line | cut -d: -f4)
13165                 if (( $frag_lun != $last_lun )); then
13166                         if (( tot_len != 1024 )); then
13167                                 cleanup_130
13168                                 error "FIEMAP on $fm_file failed; returned " \
13169                                 "len $tot_len for OST $last_lun instead of 1024"
13170                                 return
13171                         else
13172                                 (( num_luns += 1 ))
13173                                 tot_len=0
13174                         fi
13175                 fi
13176                 (( tot_len += ext_len ))
13177                 last_lun=$frag_lun
13178         done
13179         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13180                 cleanup_130
13181                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13182                         "luns or wrong len for OST $last_lun"
13183                 return
13184         fi
13185
13186         cleanup_130
13187
13188         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13189 }
13190 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13191
13192 test_130c() {
13193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13194
13195         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13196         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13197
13198         trap cleanup_130 EXIT RETURN
13199
13200         local fm_file=$DIR/$tfile
13201         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13202         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13203                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13204
13205         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13206                         error "dd failed on $fm_file"
13207
13208         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13209         filefrag_op=$(filefrag -ve -k $fm_file |
13210                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13211
13212         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13213                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13214
13215         IFS=$'\n'
13216         tot_len=0
13217         num_luns=1
13218         for line in $filefrag_op
13219         do
13220                 frag_lun=$(echo $line | cut -d: -f5 |
13221                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13222                 ext_len=$(echo $line | cut -d: -f4)
13223                 if (( $frag_lun != $last_lun )); then
13224                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13225                         if (( logical != 512 )); then
13226                                 cleanup_130
13227                                 error "FIEMAP on $fm_file failed; returned " \
13228                                 "logical start for lun $logical instead of 512"
13229                                 return
13230                         fi
13231                         if (( tot_len != 512 )); then
13232                                 cleanup_130
13233                                 error "FIEMAP on $fm_file failed; returned " \
13234                                 "len $tot_len for OST $last_lun instead of 1024"
13235                                 return
13236                         else
13237                                 (( num_luns += 1 ))
13238                                 tot_len=0
13239                         fi
13240                 fi
13241                 (( tot_len += ext_len ))
13242                 last_lun=$frag_lun
13243         done
13244         if (( num_luns != 2 || tot_len != 512 )); then
13245                 cleanup_130
13246                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13247                         "luns or wrong len for OST $last_lun"
13248                 return
13249         fi
13250
13251         cleanup_130
13252
13253         echo "FIEMAP on 2-stripe file with hole succeeded"
13254 }
13255 run_test 130c "FIEMAP (2-stripe file with hole)"
13256
13257 test_130d() {
13258         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13259
13260         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13261         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13262
13263         trap cleanup_130 EXIT RETURN
13264
13265         local fm_file=$DIR/$tfile
13266         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13267                         error "setstripe on $fm_file"
13268         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13269                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13270
13271         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13272         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13273                 error "dd failed on $fm_file"
13274
13275         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13276         filefrag_op=$(filefrag -ve -k $fm_file |
13277                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13278
13279         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13280                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13281
13282         IFS=$'\n'
13283         tot_len=0
13284         num_luns=1
13285         for line in $filefrag_op
13286         do
13287                 frag_lun=$(echo $line | cut -d: -f5 |
13288                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13289                 ext_len=$(echo $line | cut -d: -f4)
13290                 if (( $frag_lun != $last_lun )); then
13291                         if (( tot_len != 1024 )); then
13292                                 cleanup_130
13293                                 error "FIEMAP on $fm_file failed; returned " \
13294                                 "len $tot_len for OST $last_lun instead of 1024"
13295                                 return
13296                         else
13297                                 (( num_luns += 1 ))
13298                                 tot_len=0
13299                         fi
13300                 fi
13301                 (( tot_len += ext_len ))
13302                 last_lun=$frag_lun
13303         done
13304         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13305                 cleanup_130
13306                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13307                         "luns or wrong len for OST $last_lun"
13308                 return
13309         fi
13310
13311         cleanup_130
13312
13313         echo "FIEMAP on N-stripe file succeeded"
13314 }
13315 run_test 130d "FIEMAP (N-stripe file)"
13316
13317 test_130e() {
13318         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13319
13320         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13321         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13322
13323         trap cleanup_130 EXIT RETURN
13324
13325         local fm_file=$DIR/$tfile
13326         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13327
13328         NUM_BLKS=512
13329         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13330         for ((i = 0; i < $NUM_BLKS; i++)); do
13331                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13332                         conv=notrunc > /dev/null 2>&1
13333         done
13334
13335         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13336         filefrag_op=$(filefrag -ve -k $fm_file |
13337                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13338
13339         last_lun=$(echo $filefrag_op | cut -d: -f5)
13340
13341         IFS=$'\n'
13342         tot_len=0
13343         num_luns=1
13344         for line in $filefrag_op; do
13345                 frag_lun=$(echo $line | cut -d: -f5)
13346                 ext_len=$(echo $line | cut -d: -f4)
13347                 if [[ "$frag_lun" != "$last_lun" ]]; then
13348                         if (( tot_len != $EXPECTED_LEN )); then
13349                                 cleanup_130
13350                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13351                         else
13352                                 (( num_luns += 1 ))
13353                                 tot_len=0
13354                         fi
13355                 fi
13356                 (( tot_len += ext_len ))
13357                 last_lun=$frag_lun
13358         done
13359         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13360                 cleanup_130
13361                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13362         fi
13363
13364         echo "FIEMAP with continuation calls succeeded"
13365 }
13366 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13367
13368 test_130f() {
13369         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13370         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13371
13372         local fm_file=$DIR/$tfile
13373         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13374                 error "multiop create with lov_delay_create on $fm_file"
13375
13376         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13377         filefrag_extents=$(filefrag -vek $fm_file |
13378                            awk '/extents? found/ { print $2 }')
13379         if [[ "$filefrag_extents" != "0" ]]; then
13380                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13381         fi
13382
13383         rm -f $fm_file
13384 }
13385 run_test 130f "FIEMAP (unstriped file)"
13386
13387 test_130g() {
13388         local file=$DIR/$tfile
13389         local nr=$((OSTCOUNT * 100))
13390
13391         $LFS setstripe -C $nr $file ||
13392                 error "failed to setstripe -C $nr $file"
13393
13394         dd if=/dev/zero of=$file count=$nr bs=1M
13395         sync
13396         nr=$($LFS getstripe -c $file)
13397
13398         local extents=$(filefrag -v $file |
13399                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13400
13401         echo "filefrag list $extents extents in file with stripecount $nr"
13402         if (( extents < nr )); then
13403                 $LFS getstripe $file
13404                 filefrag -v $file
13405                 error "filefrag printed $extents < $nr extents"
13406         fi
13407
13408         rm -f $file
13409 }
13410 run_test 130g "FIEMAP (overstripe file)"
13411
13412 # Test for writev/readv
13413 test_131a() {
13414         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13415                 error "writev test failed"
13416         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13417                 error "readv failed"
13418         rm -f $DIR/$tfile
13419 }
13420 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13421
13422 test_131b() {
13423         local fsize=$((524288 + 1048576 + 1572864))
13424         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13425                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13426                         error "append writev test failed"
13427
13428         ((fsize += 1572864 + 1048576))
13429         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13430                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13431                         error "append writev test failed"
13432         rm -f $DIR/$tfile
13433 }
13434 run_test 131b "test append writev"
13435
13436 test_131c() {
13437         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13438         error "NOT PASS"
13439 }
13440 run_test 131c "test read/write on file w/o objects"
13441
13442 test_131d() {
13443         rwv -f $DIR/$tfile -w -n 1 1572864
13444         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13445         if [ "$NOB" != 1572864 ]; then
13446                 error "Short read filed: read $NOB bytes instead of 1572864"
13447         fi
13448         rm -f $DIR/$tfile
13449 }
13450 run_test 131d "test short read"
13451
13452 test_131e() {
13453         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13454         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13455         error "read hitting hole failed"
13456         rm -f $DIR/$tfile
13457 }
13458 run_test 131e "test read hitting hole"
13459
13460 check_stats() {
13461         local facet=$1
13462         local op=$2
13463         local want=${3:-0}
13464         local res
13465
13466         case $facet in
13467         mds*) res=$(do_facet $facet \
13468                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13469                  ;;
13470         ost*) res=$(do_facet $facet \
13471                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13472                  ;;
13473         *) error "Wrong facet '$facet'" ;;
13474         esac
13475         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13476         # if the argument $3 is zero, it means any stat increment is ok.
13477         if [[ $want -gt 0 ]]; then
13478                 local count=$(echo $res | awk '{ print $2 }')
13479                 [[ $count -ne $want ]] &&
13480                         error "The $op counter on $facet is $count, not $want"
13481         fi
13482 }
13483
13484 test_133a() {
13485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13486         remote_ost_nodsh && skip "remote OST with nodsh"
13487         remote_mds_nodsh && skip "remote MDS with nodsh"
13488         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13489                 skip_env "MDS doesn't support rename stats"
13490
13491         local testdir=$DIR/${tdir}/stats_testdir
13492
13493         mkdir -p $DIR/${tdir}
13494
13495         # clear stats.
13496         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13497         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13498
13499         # verify mdt stats first.
13500         mkdir ${testdir} || error "mkdir failed"
13501         check_stats $SINGLEMDS "mkdir" 1
13502         touch ${testdir}/${tfile} || error "touch failed"
13503         check_stats $SINGLEMDS "open" 1
13504         check_stats $SINGLEMDS "close" 1
13505         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13506                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13507                 check_stats $SINGLEMDS "mknod" 2
13508         }
13509         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13510         check_stats $SINGLEMDS "unlink" 1
13511         rm -f ${testdir}/${tfile} || error "file remove failed"
13512         check_stats $SINGLEMDS "unlink" 2
13513
13514         # remove working dir and check mdt stats again.
13515         rmdir ${testdir} || error "rmdir failed"
13516         check_stats $SINGLEMDS "rmdir" 1
13517
13518         local testdir1=$DIR/${tdir}/stats_testdir1
13519         mkdir -p ${testdir}
13520         mkdir -p ${testdir1}
13521         touch ${testdir1}/test1
13522         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13523         check_stats $SINGLEMDS "crossdir_rename" 1
13524
13525         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13526         check_stats $SINGLEMDS "samedir_rename" 1
13527
13528         rm -rf $DIR/${tdir}
13529 }
13530 run_test 133a "Verifying MDT stats ========================================"
13531
13532 test_133b() {
13533         local res
13534
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         remote_ost_nodsh && skip "remote OST with nodsh"
13537         remote_mds_nodsh && skip "remote MDS with nodsh"
13538
13539         local testdir=$DIR/${tdir}/stats_testdir
13540
13541         mkdir -p ${testdir} || error "mkdir failed"
13542         touch ${testdir}/${tfile} || error "touch failed"
13543         cancel_lru_locks mdc
13544
13545         # clear stats.
13546         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13547         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13548
13549         # extra mdt stats verification.
13550         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13551         check_stats $SINGLEMDS "setattr" 1
13552         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13553         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13554         then            # LU-1740
13555                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13556                 check_stats $SINGLEMDS "getattr" 1
13557         fi
13558         rm -rf $DIR/${tdir}
13559
13560         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13561         # so the check below is not reliable
13562         [ $MDSCOUNT -eq 1 ] || return 0
13563
13564         # Sleep to avoid a cached response.
13565         #define OBD_STATFS_CACHE_SECONDS 1
13566         sleep 2
13567         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13568         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13569         $LFS df || error "lfs failed"
13570         check_stats $SINGLEMDS "statfs" 1
13571
13572         # check aggregated statfs (LU-10018)
13573         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13574                 return 0
13575         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13576                 return 0
13577         sleep 2
13578         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13579         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13580         df $DIR
13581         check_stats $SINGLEMDS "statfs" 1
13582
13583         # We want to check that the client didn't send OST_STATFS to
13584         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13585         # extra care is needed here.
13586         if remote_mds; then
13587                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13588                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13589
13590                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13591                 [ "$res" ] && error "OST got STATFS"
13592         fi
13593
13594         return 0
13595 }
13596 run_test 133b "Verifying extra MDT stats =================================="
13597
13598 test_133c() {
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600         remote_ost_nodsh && skip "remote OST with nodsh"
13601         remote_mds_nodsh && skip "remote MDS with nodsh"
13602
13603         local testdir=$DIR/$tdir/stats_testdir
13604
13605         test_mkdir -p $testdir
13606
13607         # verify obdfilter stats.
13608         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13609         sync
13610         cancel_lru_locks osc
13611         wait_delete_completed
13612
13613         # clear stats.
13614         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13615         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13616
13617         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13618                 error "dd failed"
13619         sync
13620         cancel_lru_locks osc
13621         check_stats ost1 "write" 1
13622
13623         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13624         check_stats ost1 "read" 1
13625
13626         > $testdir/$tfile || error "truncate failed"
13627         check_stats ost1 "punch" 1
13628
13629         rm -f $testdir/$tfile || error "file remove failed"
13630         wait_delete_completed
13631         check_stats ost1 "destroy" 1
13632
13633         rm -rf $DIR/$tdir
13634 }
13635 run_test 133c "Verifying OST stats ========================================"
13636
13637 order_2() {
13638         local value=$1
13639         local orig=$value
13640         local order=1
13641
13642         while [ $value -ge 2 ]; do
13643                 order=$((order*2))
13644                 value=$((value/2))
13645         done
13646
13647         if [ $orig -gt $order ]; then
13648                 order=$((order*2))
13649         fi
13650         echo $order
13651 }
13652
13653 size_in_KMGT() {
13654     local value=$1
13655     local size=('K' 'M' 'G' 'T');
13656     local i=0
13657     local size_string=$value
13658
13659     while [ $value -ge 1024 ]; do
13660         if [ $i -gt 3 ]; then
13661             #T is the biggest unit we get here, if that is bigger,
13662             #just return XXXT
13663             size_string=${value}T
13664             break
13665         fi
13666         value=$((value >> 10))
13667         if [ $value -lt 1024 ]; then
13668             size_string=${value}${size[$i]}
13669             break
13670         fi
13671         i=$((i + 1))
13672     done
13673
13674     echo $size_string
13675 }
13676
13677 get_rename_size() {
13678         local size=$1
13679         local context=${2:-.}
13680         local sample=$(do_facet $SINGLEMDS $LCTL \
13681                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13682                 grep -A1 $context |
13683                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13684         echo $sample
13685 }
13686
13687 test_133d() {
13688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13689         remote_ost_nodsh && skip "remote OST with nodsh"
13690         remote_mds_nodsh && skip "remote MDS with nodsh"
13691         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13692                 skip_env "MDS doesn't support rename stats"
13693
13694         local testdir1=$DIR/${tdir}/stats_testdir1
13695         local testdir2=$DIR/${tdir}/stats_testdir2
13696         mkdir -p $DIR/${tdir}
13697
13698         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13699
13700         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13701         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13702
13703         createmany -o $testdir1/test 512 || error "createmany failed"
13704
13705         # check samedir rename size
13706         mv ${testdir1}/test0 ${testdir1}/test_0
13707
13708         local testdir1_size=$(ls -l $DIR/${tdir} |
13709                 awk '/stats_testdir1/ {print $5}')
13710         local testdir2_size=$(ls -l $DIR/${tdir} |
13711                 awk '/stats_testdir2/ {print $5}')
13712
13713         testdir1_size=$(order_2 $testdir1_size)
13714         testdir2_size=$(order_2 $testdir2_size)
13715
13716         testdir1_size=$(size_in_KMGT $testdir1_size)
13717         testdir2_size=$(size_in_KMGT $testdir2_size)
13718
13719         echo "source rename dir size: ${testdir1_size}"
13720         echo "target rename dir size: ${testdir2_size}"
13721
13722         local cmd="do_facet $SINGLEMDS $LCTL "
13723         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13724
13725         eval $cmd || error "$cmd failed"
13726         local samedir=$($cmd | grep 'same_dir')
13727         local same_sample=$(get_rename_size $testdir1_size)
13728         [ -z "$samedir" ] && error "samedir_rename_size count error"
13729         [[ $same_sample -eq 1 ]] ||
13730                 error "samedir_rename_size error $same_sample"
13731         echo "Check same dir rename stats success"
13732
13733         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13734
13735         # check crossdir rename size
13736         mv ${testdir1}/test_0 ${testdir2}/test_0
13737
13738         testdir1_size=$(ls -l $DIR/${tdir} |
13739                 awk '/stats_testdir1/ {print $5}')
13740         testdir2_size=$(ls -l $DIR/${tdir} |
13741                 awk '/stats_testdir2/ {print $5}')
13742
13743         testdir1_size=$(order_2 $testdir1_size)
13744         testdir2_size=$(order_2 $testdir2_size)
13745
13746         testdir1_size=$(size_in_KMGT $testdir1_size)
13747         testdir2_size=$(size_in_KMGT $testdir2_size)
13748
13749         echo "source rename dir size: ${testdir1_size}"
13750         echo "target rename dir size: ${testdir2_size}"
13751
13752         eval $cmd || error "$cmd failed"
13753         local crossdir=$($cmd | grep 'crossdir')
13754         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13755         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13756         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13757         [[ $src_sample -eq 1 ]] ||
13758                 error "crossdir_rename_size error $src_sample"
13759         [[ $tgt_sample -eq 1 ]] ||
13760                 error "crossdir_rename_size error $tgt_sample"
13761         echo "Check cross dir rename stats success"
13762         rm -rf $DIR/${tdir}
13763 }
13764 run_test 133d "Verifying rename_stats ========================================"
13765
13766 test_133e() {
13767         remote_mds_nodsh && skip "remote MDS with nodsh"
13768         remote_ost_nodsh && skip "remote OST with nodsh"
13769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13770
13771         local testdir=$DIR/${tdir}/stats_testdir
13772         local ctr f0 f1 bs=32768 count=42 sum
13773
13774         mkdir -p ${testdir} || error "mkdir failed"
13775
13776         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13777
13778         for ctr in {write,read}_bytes; do
13779                 sync
13780                 cancel_lru_locks osc
13781
13782                 do_facet ost1 $LCTL set_param -n \
13783                         "obdfilter.*.exports.clear=clear"
13784
13785                 if [ $ctr = write_bytes ]; then
13786                         f0=/dev/zero
13787                         f1=${testdir}/${tfile}
13788                 else
13789                         f0=${testdir}/${tfile}
13790                         f1=/dev/null
13791                 fi
13792
13793                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13794                         error "dd failed"
13795                 sync
13796                 cancel_lru_locks osc
13797
13798                 sum=$(do_facet ost1 $LCTL get_param \
13799                         "obdfilter.*.exports.*.stats" |
13800                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13801                                 $1 == ctr { sum += $7 }
13802                                 END { printf("%0.0f", sum) }')
13803
13804                 if ((sum != bs * count)); then
13805                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13806                 fi
13807         done
13808
13809         rm -rf $DIR/${tdir}
13810 }
13811 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13812
13813 test_133f() {
13814         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13815                 skip "too old lustre for get_param -R ($facet_ver)"
13816
13817         # verifying readability.
13818         $LCTL get_param -R '*' &> /dev/null
13819
13820         # Verifing writability with badarea_io.
13821         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13822                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13823                 error "client badarea_io failed"
13824
13825         # remount the FS in case writes/reads /proc break the FS
13826         cleanup || error "failed to unmount"
13827         setup || error "failed to setup"
13828 }
13829 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13830
13831 test_133g() {
13832         remote_mds_nodsh && skip "remote MDS with nodsh"
13833         remote_ost_nodsh && skip "remote OST with nodsh"
13834
13835         local facet
13836         for facet in mds1 ost1; do
13837                 local facet_ver=$(lustre_version_code $facet)
13838                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13839                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13840                 else
13841                         log "$facet: too old lustre for get_param -R"
13842                 fi
13843                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13844                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13845                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13846                                 xargs badarea_io" ||
13847                                         error "$facet badarea_io failed"
13848                 else
13849                         skip_noexit "$facet: too old lustre for get_param -R"
13850                 fi
13851         done
13852
13853         # remount the FS in case writes/reads /proc break the FS
13854         cleanup || error "failed to unmount"
13855         setup || error "failed to setup"
13856 }
13857 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13858
13859 test_133h() {
13860         remote_mds_nodsh && skip "remote MDS with nodsh"
13861         remote_ost_nodsh && skip "remote OST with nodsh"
13862         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13863                 skip "Need MDS version at least 2.9.54"
13864
13865         local facet
13866         for facet in client mds1 ost1; do
13867                 # Get the list of files that are missing the terminating newline
13868                 local plist=$(do_facet $facet
13869                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13870                 local ent
13871                 for ent in $plist; do
13872                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13873                                 awk -v FS='\v' -v RS='\v\v' \
13874                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13875                                         print FILENAME}'" 2>/dev/null)
13876                         [ -z $missing ] || {
13877                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13878                                 error "file does not end with newline: $facet-$ent"
13879                         }
13880                 done
13881         done
13882 }
13883 run_test 133h "Proc files should end with newlines"
13884
13885 test_134a() {
13886         remote_mds_nodsh && skip "remote MDS with nodsh"
13887         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13888                 skip "Need MDS version at least 2.7.54"
13889
13890         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13891         cancel_lru_locks mdc
13892
13893         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13894         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13895         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13896
13897         local nr=1000
13898         createmany -o $DIR/$tdir/f $nr ||
13899                 error "failed to create $nr files in $DIR/$tdir"
13900         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13901
13902         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13903         do_facet mds1 $LCTL set_param fail_loc=0x327
13904         do_facet mds1 $LCTL set_param fail_val=500
13905         touch $DIR/$tdir/m
13906
13907         echo "sleep 10 seconds ..."
13908         sleep 10
13909         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13910
13911         do_facet mds1 $LCTL set_param fail_loc=0
13912         do_facet mds1 $LCTL set_param fail_val=0
13913         [ $lck_cnt -lt $unused ] ||
13914                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13915
13916         rm $DIR/$tdir/m
13917         unlinkmany $DIR/$tdir/f $nr
13918 }
13919 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13920
13921 test_134b() {
13922         remote_mds_nodsh && skip "remote MDS with nodsh"
13923         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13924                 skip "Need MDS version at least 2.7.54"
13925
13926         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13927         cancel_lru_locks mdc
13928
13929         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13930                         ldlm.lock_reclaim_threshold_mb)
13931         # disable reclaim temporarily
13932         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13933
13934         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13935         do_facet mds1 $LCTL set_param fail_loc=0x328
13936         do_facet mds1 $LCTL set_param fail_val=500
13937
13938         $LCTL set_param debug=+trace
13939
13940         local nr=600
13941         createmany -o $DIR/$tdir/f $nr &
13942         local create_pid=$!
13943
13944         echo "Sleep $TIMEOUT seconds ..."
13945         sleep $TIMEOUT
13946         if ! ps -p $create_pid  > /dev/null 2>&1; then
13947                 do_facet mds1 $LCTL set_param fail_loc=0
13948                 do_facet mds1 $LCTL set_param fail_val=0
13949                 do_facet mds1 $LCTL set_param \
13950                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13951                 error "createmany finished incorrectly!"
13952         fi
13953         do_facet mds1 $LCTL set_param fail_loc=0
13954         do_facet mds1 $LCTL set_param fail_val=0
13955         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13956         wait $create_pid || return 1
13957
13958         unlinkmany $DIR/$tdir/f $nr
13959 }
13960 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13961
13962 test_135() {
13963         remote_mds_nodsh && skip "remote MDS with nodsh"
13964         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13965                 skip "Need MDS version at least 2.13.50"
13966         local fname
13967
13968         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13969
13970 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13971         #set only one record at plain llog
13972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13973
13974         #fill already existed plain llog each 64767
13975         #wrapping whole catalog
13976         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13977
13978         createmany -o $DIR/$tdir/$tfile_ 64700
13979         for (( i = 0; i < 64700; i = i + 2 ))
13980         do
13981                 rm $DIR/$tdir/$tfile_$i &
13982                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13983                 local pid=$!
13984                 wait $pid
13985         done
13986
13987         #waiting osp synchronization
13988         wait_delete_completed
13989 }
13990 run_test 135 "Race catalog processing"
13991
13992 test_136() {
13993         remote_mds_nodsh && skip "remote MDS with nodsh"
13994         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13995                 skip "Need MDS version at least 2.13.50"
13996         local fname
13997
13998         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13999         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14000         #set only one record at plain llog
14001 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14002         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14003
14004         #fill already existed 2 plain llogs each 64767
14005         #wrapping whole catalog
14006         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14007         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14008         wait_delete_completed
14009
14010         createmany -o $DIR/$tdir/$tfile_ 10
14011         sleep 25
14012
14013         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14014         for (( i = 0; i < 10; i = i + 3 ))
14015         do
14016                 rm $DIR/$tdir/$tfile_$i &
14017                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14018                 local pid=$!
14019                 wait $pid
14020                 sleep 7
14021                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14022         done
14023
14024         #waiting osp synchronization
14025         wait_delete_completed
14026 }
14027 run_test 136 "Race catalog processing 2"
14028
14029 test_140() { #bug-17379
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         test_mkdir $DIR/$tdir
14033         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14034         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14035
14036         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14037         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14038         local i=0
14039         while i=$((i + 1)); do
14040                 test_mkdir $i
14041                 cd $i || error "Changing to $i"
14042                 ln -s ../stat stat || error "Creating stat symlink"
14043                 # Read the symlink until ELOOP present,
14044                 # not LBUGing the system is considered success,
14045                 # we didn't overrun the stack.
14046                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14047                 if [ $ret -ne 0 ]; then
14048                         if [ $ret -eq 40 ]; then
14049                                 break  # -ELOOP
14050                         else
14051                                 error "Open stat symlink"
14052                                         return
14053                         fi
14054                 fi
14055         done
14056         i=$((i - 1))
14057         echo "The symlink depth = $i"
14058         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14059                 error "Invalid symlink depth"
14060
14061         # Test recursive symlink
14062         ln -s symlink_self symlink_self
14063         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14064         echo "open symlink_self returns $ret"
14065         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14066 }
14067 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14068
14069 test_150a() {
14070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14071
14072         local TF="$TMP/$tfile"
14073
14074         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14075         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14076         cp $TF $DIR/$tfile
14077         cancel_lru_locks $OSC
14078         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14079         remount_client $MOUNT
14080         df -P $MOUNT
14081         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14082
14083         $TRUNCATE $TF 6000
14084         $TRUNCATE $DIR/$tfile 6000
14085         cancel_lru_locks $OSC
14086         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14087
14088         echo "12345" >>$TF
14089         echo "12345" >>$DIR/$tfile
14090         cancel_lru_locks $OSC
14091         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14092
14093         echo "12345" >>$TF
14094         echo "12345" >>$DIR/$tfile
14095         cancel_lru_locks $OSC
14096         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14097 }
14098 run_test 150a "truncate/append tests"
14099
14100 test_150b() {
14101         check_set_fallocate_or_skip
14102
14103         touch $DIR/$tfile
14104         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14105         check_fallocate $DIR/$tfile || error "fallocate failed"
14106 }
14107 run_test 150b "Verify fallocate (prealloc) functionality"
14108
14109 test_150bb() {
14110         check_set_fallocate_or_skip
14111
14112         touch $DIR/$tfile
14113         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14114         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14115         > $DIR/$tfile
14116         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14117         # precomputed md5sum for 20MB of zeroes
14118         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14119         local sum=($(md5sum $DIR/$tfile))
14120
14121         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14122
14123         check_set_fallocate 1
14124
14125         > $DIR/$tfile
14126         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14127         sum=($(md5sum $DIR/$tfile))
14128
14129         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14130 }
14131 run_test 150bb "Verify fallocate modes both zero space"
14132
14133 test_150c() {
14134         check_set_fallocate_or_skip
14135
14136         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14137         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14138         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14139         sync; sync_all_data
14140         cancel_lru_locks $OSC
14141         sleep 5
14142         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14143         want=$((OSTCOUNT * 1048576))
14144
14145         # Must allocate all requested space, not more than 5% extra
14146         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14147                 error "bytes $bytes is not $want"
14148
14149         rm -f $DIR/$tfile
14150         # verify fallocate on PFL file
14151         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14152                 error "Create $DIR/$tfile failed"
14153         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14154                         error "fallocate failed"
14155         sync; sync_all_data
14156         cancel_lru_locks $OSC
14157         sleep 5
14158         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14159         local want=$((1024 * 1048576))
14160
14161         # Must allocate all requested space, not more than 5% extra
14162         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14163                 error "bytes $bytes is not $want"
14164 }
14165 run_test 150c "Verify fallocate Size and Blocks"
14166
14167 test_150d() {
14168         check_set_fallocate_or_skip
14169
14170         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14171         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14172         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14173         sync; sync_all_data
14174         cancel_lru_locks $OSC
14175         sleep 5
14176         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14177         local want=$((OSTCOUNT * 1048576))
14178
14179         # Must allocate all requested space, not more than 5% extra
14180         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14181                 error "bytes $bytes is not $want"
14182 }
14183 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14184
14185 test_150e() {
14186         check_set_fallocate_or_skip
14187
14188         echo "df before:"
14189         $LFS df
14190         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14191         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14192                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14193
14194         # Find OST with Minimum Size
14195         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14196                        sort -un | head -1)
14197
14198         # Get 100MB per OST of the available space to reduce run time
14199         # else 60% of the available space if we are running SLOW tests
14200         if [ $SLOW == "no" ]; then
14201                 local space=$((1024 * 100 * OSTCOUNT))
14202         else
14203                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14204         fi
14205
14206         fallocate -l${space}k $DIR/$tfile ||
14207                 error "fallocate ${space}k $DIR/$tfile failed"
14208         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14209
14210         # get size immediately after fallocate. This should be correctly
14211         # updated
14212         local size=$(stat -c '%s' $DIR/$tfile)
14213         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14214
14215         # Sleep for a while for statfs to get updated. And not pull from cache.
14216         sleep 2
14217
14218         echo "df after fallocate:"
14219         $LFS df
14220
14221         (( size / 1024 == space )) || error "size $size != requested $space"
14222         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14223                 error "used $used < space $space"
14224
14225         rm $DIR/$tfile || error "rm failed"
14226         sync
14227         wait_delete_completed
14228
14229         echo "df after unlink:"
14230         $LFS df
14231 }
14232 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14233
14234 test_150f() {
14235         local size
14236         local blocks
14237         local want_size_before=20480 # in bytes
14238         local want_blocks_before=40 # 512 sized blocks
14239         local want_blocks_after=24  # 512 sized blocks
14240         local length=$(((want_blocks_before - want_blocks_after) * 512))
14241
14242         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14243                 skip "need at least 2.14.0 for fallocate punch"
14244
14245         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14246                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14247         fi
14248
14249         check_set_fallocate_or_skip
14250         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14251
14252         echo "Verify fallocate punch: Range within the file range"
14253         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14254                 error "dd failed for bs 4096 and count 5"
14255
14256         # Call fallocate with punch range which is within the file range
14257         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14258                 error "fallocate failed: offset 4096 and length $length"
14259         # client must see changes immediately after fallocate
14260         size=$(stat -c '%s' $DIR/$tfile)
14261         blocks=$(stat -c '%b' $DIR/$tfile)
14262
14263         # Verify punch worked.
14264         (( blocks == want_blocks_after )) ||
14265                 error "punch failed: blocks $blocks != $want_blocks_after"
14266
14267         (( size == want_size_before )) ||
14268                 error "punch failed: size $size != $want_size_before"
14269
14270         # Verify there is hole in file
14271         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14272         # precomputed md5sum
14273         local expect="4a9a834a2db02452929c0a348273b4aa"
14274
14275         cksum=($(md5sum $DIR/$tfile))
14276         [[ "${cksum[0]}" == "$expect" ]] ||
14277                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14278
14279         # Start second sub-case for fallocate punch.
14280         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14281         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14282                 error "dd failed for bs 4096 and count 5"
14283
14284         # Punch range less than block size will have no change in block count
14285         want_blocks_after=40  # 512 sized blocks
14286
14287         # Punch overlaps two blocks and less than blocksize
14288         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14289                 error "fallocate failed: offset 4000 length 3000"
14290         size=$(stat -c '%s' $DIR/$tfile)
14291         blocks=$(stat -c '%b' $DIR/$tfile)
14292
14293         # Verify punch worked.
14294         (( blocks == want_blocks_after )) ||
14295                 error "punch failed: blocks $blocks != $want_blocks_after"
14296
14297         (( size == want_size_before )) ||
14298                 error "punch failed: size $size != $want_size_before"
14299
14300         # Verify if range is really zero'ed out. We expect Zeros.
14301         # precomputed md5sum
14302         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14303         cksum=($(md5sum $DIR/$tfile))
14304         [[ "${cksum[0]}" == "$expect" ]] ||
14305                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14306 }
14307 run_test 150f "Verify fallocate punch functionality"
14308
14309 test_150g() {
14310         local space
14311         local size
14312         local blocks
14313         local blocks_after
14314         local size_after
14315         local BS=4096 # Block size in bytes
14316
14317         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14318                 skip "need at least 2.14.0 for fallocate punch"
14319
14320         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14321                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14322         fi
14323
14324         check_set_fallocate_or_skip
14325         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14326
14327         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14328                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14329
14330         # Get 100MB per OST of the available space to reduce run time
14331         # else 60% of the available space if we are running SLOW tests
14332         if [ $SLOW == "no" ]; then
14333                 space=$((1024 * 100 * OSTCOUNT))
14334         else
14335                 # Find OST with Minimum Size
14336                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14337                         sort -un | head -1)
14338                 echo "min size OST: $space"
14339                 space=$(((space * 60)/100 * OSTCOUNT))
14340         fi
14341         # space in 1k units, round to 4k blocks
14342         local blkcount=$((space * 1024 / $BS))
14343
14344         echo "Verify fallocate punch: Very large Range"
14345         fallocate -l${space}k $DIR/$tfile ||
14346                 error "fallocate ${space}k $DIR/$tfile failed"
14347         # write 1M at the end, start and in the middle
14348         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14349                 error "dd failed: bs $BS count 256"
14350         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14351                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14352         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14353                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14354
14355         # Gather stats.
14356         size=$(stat -c '%s' $DIR/$tfile)
14357
14358         # gather punch length.
14359         local punch_size=$((size - (BS * 2)))
14360
14361         echo "punch_size = $punch_size"
14362         echo "size - punch_size: $((size - punch_size))"
14363         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14364
14365         # Call fallocate to punch all except 2 blocks. We leave the
14366         # first and the last block
14367         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14368         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14369                 error "fallocate failed: offset $BS length $punch_size"
14370
14371         size_after=$(stat -c '%s' $DIR/$tfile)
14372         blocks_after=$(stat -c '%b' $DIR/$tfile)
14373
14374         # Verify punch worked.
14375         # Size should be kept
14376         (( size == size_after )) ||
14377                 error "punch failed: size $size != $size_after"
14378
14379         # two 4k data blocks to remain plus possible 1 extra extent block
14380         (( blocks_after <= ((BS / 512) * 3) )) ||
14381                 error "too many blocks remains: $blocks_after"
14382
14383         # Verify that file has hole between the first and the last blocks
14384         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14385         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14386
14387         echo "Hole at [$hole_start, $hole_end)"
14388         (( hole_start == BS )) ||
14389                 error "no hole at offset $BS after punch"
14390
14391         (( hole_end == BS + punch_size )) ||
14392                 error "data at offset $hole_end < $((BS + punch_size))"
14393 }
14394 run_test 150g "Verify fallocate punch on large range"
14395
14396 #LU-2902 roc_hit was not able to read all values from lproc
14397 function roc_hit_init() {
14398         local list=$(comma_list $(osts_nodes))
14399         local dir=$DIR/$tdir-check
14400         local file=$dir/$tfile
14401         local BEFORE
14402         local AFTER
14403         local idx
14404
14405         test_mkdir $dir
14406         #use setstripe to do a write to every ost
14407         for i in $(seq 0 $((OSTCOUNT-1))); do
14408                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14409                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14410                 idx=$(printf %04x $i)
14411                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14412                         awk '$1 == "cache_access" {sum += $7}
14413                                 END { printf("%0.0f", sum) }')
14414
14415                 cancel_lru_locks osc
14416                 cat $file >/dev/null
14417
14418                 AFTER=$(get_osd_param $list *OST*$idx stats |
14419                         awk '$1 == "cache_access" {sum += $7}
14420                                 END { printf("%0.0f", sum) }')
14421
14422                 echo BEFORE:$BEFORE AFTER:$AFTER
14423                 if ! let "AFTER - BEFORE == 4"; then
14424                         rm -rf $dir
14425                         error "roc_hit is not safe to use"
14426                 fi
14427                 rm $file
14428         done
14429
14430         rm -rf $dir
14431 }
14432
14433 function roc_hit() {
14434         local list=$(comma_list $(osts_nodes))
14435         echo $(get_osd_param $list '' stats |
14436                 awk '$1 == "cache_hit" {sum += $7}
14437                         END { printf("%0.0f", sum) }')
14438 }
14439
14440 function set_cache() {
14441         local on=1
14442
14443         if [ "$2" == "off" ]; then
14444                 on=0;
14445         fi
14446         local list=$(comma_list $(osts_nodes))
14447         set_osd_param $list '' $1_cache_enable $on
14448
14449         cancel_lru_locks osc
14450 }
14451
14452 test_151() {
14453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14454         remote_ost_nodsh && skip "remote OST with nodsh"
14455
14456         local CPAGES=3
14457         local list=$(comma_list $(osts_nodes))
14458
14459         # check whether obdfilter is cache capable at all
14460         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14461                 skip "not cache-capable obdfilter"
14462         fi
14463
14464         # check cache is enabled on all obdfilters
14465         if get_osd_param $list '' read_cache_enable | grep 0; then
14466                 skip "oss cache is disabled"
14467         fi
14468
14469         set_osd_param $list '' writethrough_cache_enable 1
14470
14471         # check write cache is enabled on all obdfilters
14472         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14473                 skip "oss write cache is NOT enabled"
14474         fi
14475
14476         roc_hit_init
14477
14478         #define OBD_FAIL_OBD_NO_LRU  0x609
14479         do_nodes $list $LCTL set_param fail_loc=0x609
14480
14481         # pages should be in the case right after write
14482         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14483                 error "dd failed"
14484
14485         local BEFORE=$(roc_hit)
14486         cancel_lru_locks osc
14487         cat $DIR/$tfile >/dev/null
14488         local AFTER=$(roc_hit)
14489
14490         do_nodes $list $LCTL set_param fail_loc=0
14491
14492         if ! let "AFTER - BEFORE == CPAGES"; then
14493                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14494         fi
14495
14496         cancel_lru_locks osc
14497         # invalidates OST cache
14498         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14499         set_osd_param $list '' read_cache_enable 0
14500         cat $DIR/$tfile >/dev/null
14501
14502         # now data shouldn't be found in the cache
14503         BEFORE=$(roc_hit)
14504         cancel_lru_locks osc
14505         cat $DIR/$tfile >/dev/null
14506         AFTER=$(roc_hit)
14507         if let "AFTER - BEFORE != 0"; then
14508                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14509         fi
14510
14511         set_osd_param $list '' read_cache_enable 1
14512         rm -f $DIR/$tfile
14513 }
14514 run_test 151 "test cache on oss and controls ==============================="
14515
14516 test_152() {
14517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14518
14519         local TF="$TMP/$tfile"
14520
14521         # simulate ENOMEM during write
14522 #define OBD_FAIL_OST_NOMEM      0x226
14523         lctl set_param fail_loc=0x80000226
14524         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14525         cp $TF $DIR/$tfile
14526         sync || error "sync failed"
14527         lctl set_param fail_loc=0
14528
14529         # discard client's cache
14530         cancel_lru_locks osc
14531
14532         # simulate ENOMEM during read
14533         lctl set_param fail_loc=0x80000226
14534         cmp $TF $DIR/$tfile || error "cmp failed"
14535         lctl set_param fail_loc=0
14536
14537         rm -f $TF
14538 }
14539 run_test 152 "test read/write with enomem ============================"
14540
14541 test_153() {
14542         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14543 }
14544 run_test 153 "test if fdatasync does not crash ======================="
14545
14546 dot_lustre_fid_permission_check() {
14547         local fid=$1
14548         local ffid=$MOUNT/.lustre/fid/$fid
14549         local test_dir=$2
14550
14551         echo "stat fid $fid"
14552         stat $ffid > /dev/null || error "stat $ffid failed."
14553         echo "touch fid $fid"
14554         touch $ffid || error "touch $ffid failed."
14555         echo "write to fid $fid"
14556         cat /etc/hosts > $ffid || error "write $ffid failed."
14557         echo "read fid $fid"
14558         diff /etc/hosts $ffid || error "read $ffid failed."
14559         echo "append write to fid $fid"
14560         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14561         echo "rename fid $fid"
14562         mv $ffid $test_dir/$tfile.1 &&
14563                 error "rename $ffid to $tfile.1 should fail."
14564         touch $test_dir/$tfile.1
14565         mv $test_dir/$tfile.1 $ffid &&
14566                 error "rename $tfile.1 to $ffid should fail."
14567         rm -f $test_dir/$tfile.1
14568         echo "truncate fid $fid"
14569         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14570         echo "link fid $fid"
14571         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14572         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14573                 echo "setfacl fid $fid"
14574                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14575                 echo "getfacl fid $fid"
14576                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14577         fi
14578         echo "unlink fid $fid"
14579         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14580         echo "mknod fid $fid"
14581         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14582
14583         fid=[0xf00000400:0x1:0x0]
14584         ffid=$MOUNT/.lustre/fid/$fid
14585
14586         echo "stat non-exist fid $fid"
14587         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14588         echo "write to non-exist fid $fid"
14589         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14590         echo "link new fid $fid"
14591         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14592
14593         mkdir -p $test_dir/$tdir
14594         touch $test_dir/$tdir/$tfile
14595         fid=$($LFS path2fid $test_dir/$tdir)
14596         rc=$?
14597         [ $rc -ne 0 ] &&
14598                 error "error: could not get fid for $test_dir/$dir/$tfile."
14599
14600         ffid=$MOUNT/.lustre/fid/$fid
14601
14602         echo "ls $fid"
14603         ls $ffid > /dev/null || error "ls $ffid failed."
14604         echo "touch $fid/$tfile.1"
14605         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14606
14607         echo "touch $MOUNT/.lustre/fid/$tfile"
14608         touch $MOUNT/.lustre/fid/$tfile && \
14609                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14610
14611         echo "setxattr to $MOUNT/.lustre/fid"
14612         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14613
14614         echo "listxattr for $MOUNT/.lustre/fid"
14615         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14616
14617         echo "delxattr from $MOUNT/.lustre/fid"
14618         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14619
14620         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14621         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14622                 error "touch invalid fid should fail."
14623
14624         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14625         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14626                 error "touch non-normal fid should fail."
14627
14628         echo "rename $tdir to $MOUNT/.lustre/fid"
14629         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14630                 error "rename to $MOUNT/.lustre/fid should fail."
14631
14632         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14633         then            # LU-3547
14634                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14635                 local new_obf_mode=777
14636
14637                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14638                 chmod $new_obf_mode $DIR/.lustre/fid ||
14639                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14640
14641                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14642                 [ $obf_mode -eq $new_obf_mode ] ||
14643                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14644
14645                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14646                 chmod $old_obf_mode $DIR/.lustre/fid ||
14647                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14648         fi
14649
14650         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14651         fid=$($LFS path2fid $test_dir/$tfile-2)
14652
14653         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14654         then # LU-5424
14655                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14656                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14657                         error "create lov data thru .lustre failed"
14658         fi
14659         echo "cp /etc/passwd $test_dir/$tfile-2"
14660         cp /etc/passwd $test_dir/$tfile-2 ||
14661                 error "copy to $test_dir/$tfile-2 failed."
14662         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14663         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14664                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14665
14666         rm -rf $test_dir/tfile.lnk
14667         rm -rf $test_dir/$tfile-2
14668 }
14669
14670 test_154A() {
14671         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14672                 skip "Need MDS version at least 2.4.1"
14673
14674         local tf=$DIR/$tfile
14675         touch $tf
14676
14677         local fid=$($LFS path2fid $tf)
14678         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14679
14680         # check that we get the same pathname back
14681         local rootpath
14682         local found
14683         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14684                 echo "$rootpath $fid"
14685                 found=$($LFS fid2path $rootpath "$fid")
14686                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14687                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14688         done
14689
14690         # check wrong root path format
14691         rootpath=$MOUNT"_wrong"
14692         found=$($LFS fid2path $rootpath "$fid")
14693         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14694 }
14695 run_test 154A "lfs path2fid and fid2path basic checks"
14696
14697 test_154B() {
14698         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14699                 skip "Need MDS version at least 2.4.1"
14700
14701         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14702         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14703         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14704         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14705
14706         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14707         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14708
14709         # check that we get the same pathname
14710         echo "PFID: $PFID, name: $name"
14711         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14712         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14713         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14714                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14715
14716         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14717 }
14718 run_test 154B "verify the ll_decode_linkea tool"
14719
14720 test_154a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14723         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14724                 skip "Need MDS version at least 2.2.51"
14725         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14726
14727         cp /etc/hosts $DIR/$tfile
14728
14729         fid=$($LFS path2fid $DIR/$tfile)
14730         rc=$?
14731         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14732
14733         dot_lustre_fid_permission_check "$fid" $DIR ||
14734                 error "dot lustre permission check $fid failed"
14735
14736         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14737
14738         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14739
14740         touch $MOUNT/.lustre/file &&
14741                 error "creation is not allowed under .lustre"
14742
14743         mkdir $MOUNT/.lustre/dir &&
14744                 error "mkdir is not allowed under .lustre"
14745
14746         rm -rf $DIR/$tfile
14747 }
14748 run_test 154a "Open-by-FID"
14749
14750 test_154b() {
14751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14752         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14754         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14755                 skip "Need MDS version at least 2.2.51"
14756
14757         local remote_dir=$DIR/$tdir/remote_dir
14758         local MDTIDX=1
14759         local rc=0
14760
14761         mkdir -p $DIR/$tdir
14762         $LFS mkdir -i $MDTIDX $remote_dir ||
14763                 error "create remote directory failed"
14764
14765         cp /etc/hosts $remote_dir/$tfile
14766
14767         fid=$($LFS path2fid $remote_dir/$tfile)
14768         rc=$?
14769         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14770
14771         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14772                 error "dot lustre permission check $fid failed"
14773         rm -rf $DIR/$tdir
14774 }
14775 run_test 154b "Open-by-FID for remote directory"
14776
14777 test_154c() {
14778         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14779                 skip "Need MDS version at least 2.4.1"
14780
14781         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14782         local FID1=$($LFS path2fid $DIR/$tfile.1)
14783         local FID2=$($LFS path2fid $DIR/$tfile.2)
14784         local FID3=$($LFS path2fid $DIR/$tfile.3)
14785
14786         local N=1
14787         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14788                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14789                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14790                 local want=FID$N
14791                 [ "$FID" = "${!want}" ] ||
14792                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14793                 N=$((N + 1))
14794         done
14795
14796         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14797         do
14798                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14799                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14800                 N=$((N + 1))
14801         done
14802 }
14803 run_test 154c "lfs path2fid and fid2path multiple arguments"
14804
14805 test_154d() {
14806         remote_mds_nodsh && skip "remote MDS with nodsh"
14807         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14808                 skip "Need MDS version at least 2.5.53"
14809
14810         if remote_mds; then
14811                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14812         else
14813                 nid="0@lo"
14814         fi
14815         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14816         local fd
14817         local cmd
14818
14819         rm -f $DIR/$tfile
14820         touch $DIR/$tfile
14821
14822         local fid=$($LFS path2fid $DIR/$tfile)
14823         # Open the file
14824         fd=$(free_fd)
14825         cmd="exec $fd<$DIR/$tfile"
14826         eval $cmd
14827         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14828         echo "$fid_list" | grep "$fid"
14829         rc=$?
14830
14831         cmd="exec $fd>/dev/null"
14832         eval $cmd
14833         if [ $rc -ne 0 ]; then
14834                 error "FID $fid not found in open files list $fid_list"
14835         fi
14836 }
14837 run_test 154d "Verify open file fid"
14838
14839 test_154e()
14840 {
14841         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14842                 skip "Need MDS version at least 2.6.50"
14843
14844         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14845                 error ".lustre returned by readdir"
14846         fi
14847 }
14848 run_test 154e ".lustre is not returned by readdir"
14849
14850 test_154f() {
14851         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14852
14853         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14854         test_mkdir -p -c1 $DIR/$tdir/d
14855         # test dirs inherit from its stripe
14856         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14857         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14858         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14859         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14860         touch $DIR/f
14861
14862         # get fid of parents
14863         local FID0=$($LFS path2fid $DIR/$tdir/d)
14864         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14865         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14866         local FID3=$($LFS path2fid $DIR)
14867
14868         # check that path2fid --parents returns expected <parent_fid>/name
14869         # 1) test for a directory (single parent)
14870         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14871         [ "$parent" == "$FID0/foo1" ] ||
14872                 error "expected parent: $FID0/foo1, got: $parent"
14873
14874         # 2) test for a file with nlink > 1 (multiple parents)
14875         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14876         echo "$parent" | grep -F "$FID1/$tfile" ||
14877                 error "$FID1/$tfile not returned in parent list"
14878         echo "$parent" | grep -F "$FID2/link" ||
14879                 error "$FID2/link not returned in parent list"
14880
14881         # 3) get parent by fid
14882         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14883         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14884         echo "$parent" | grep -F "$FID1/$tfile" ||
14885                 error "$FID1/$tfile not returned in parent list (by fid)"
14886         echo "$parent" | grep -F "$FID2/link" ||
14887                 error "$FID2/link not returned in parent list (by fid)"
14888
14889         # 4) test for entry in root directory
14890         parent=$($LFS path2fid --parents $DIR/f)
14891         echo "$parent" | grep -F "$FID3/f" ||
14892                 error "$FID3/f not returned in parent list"
14893
14894         # 5) test it on root directory
14895         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14896                 error "$MOUNT should not have parents"
14897
14898         # enable xattr caching and check that linkea is correctly updated
14899         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14900         save_lustre_params client "llite.*.xattr_cache" > $save
14901         lctl set_param llite.*.xattr_cache 1
14902
14903         # 6.1) linkea update on rename
14904         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14905
14906         # get parents by fid
14907         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14908         # foo1 should no longer be returned in parent list
14909         echo "$parent" | grep -F "$FID1" &&
14910                 error "$FID1 should no longer be in parent list"
14911         # the new path should appear
14912         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14913                 error "$FID2/$tfile.moved is not in parent list"
14914
14915         # 6.2) linkea update on unlink
14916         rm -f $DIR/$tdir/d/foo2/link
14917         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14918         # foo2/link should no longer be returned in parent list
14919         echo "$parent" | grep -F "$FID2/link" &&
14920                 error "$FID2/link should no longer be in parent list"
14921         true
14922
14923         rm -f $DIR/f
14924         restore_lustre_params < $save
14925         rm -f $save
14926 }
14927 run_test 154f "get parent fids by reading link ea"
14928
14929 test_154g()
14930 {
14931         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14932         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14933            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14934                 skip "Need MDS version at least 2.6.92"
14935
14936         mkdir -p $DIR/$tdir
14937         llapi_fid_test -d $DIR/$tdir
14938 }
14939 run_test 154g "various llapi FID tests"
14940
14941 test_155_small_load() {
14942     local temp=$TMP/$tfile
14943     local file=$DIR/$tfile
14944
14945     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14946         error "dd of=$temp bs=6096 count=1 failed"
14947     cp $temp $file
14948     cancel_lru_locks $OSC
14949     cmp $temp $file || error "$temp $file differ"
14950
14951     $TRUNCATE $temp 6000
14952     $TRUNCATE $file 6000
14953     cmp $temp $file || error "$temp $file differ (truncate1)"
14954
14955     echo "12345" >>$temp
14956     echo "12345" >>$file
14957     cmp $temp $file || error "$temp $file differ (append1)"
14958
14959     echo "12345" >>$temp
14960     echo "12345" >>$file
14961     cmp $temp $file || error "$temp $file differ (append2)"
14962
14963     rm -f $temp $file
14964     true
14965 }
14966
14967 test_155_big_load() {
14968         remote_ost_nodsh && skip "remote OST with nodsh"
14969
14970         local temp=$TMP/$tfile
14971         local file=$DIR/$tfile
14972
14973         free_min_max
14974         local cache_size=$(do_facet ost$((MAXI+1)) \
14975                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14976         local large_file_size=$((cache_size * 2))
14977
14978         echo "OSS cache size: $cache_size KB"
14979         echo "Large file size: $large_file_size KB"
14980
14981         [ $MAXV -le $large_file_size ] &&
14982                 skip_env "max available OST size needs > $large_file_size KB"
14983
14984         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14985
14986         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14987                 error "dd of=$temp bs=$large_file_size count=1k failed"
14988         cp $temp $file
14989         ls -lh $temp $file
14990         cancel_lru_locks osc
14991         cmp $temp $file || error "$temp $file differ"
14992
14993         rm -f $temp $file
14994         true
14995 }
14996
14997 save_writethrough() {
14998         local facets=$(get_facets OST)
14999
15000         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15001 }
15002
15003 test_155a() {
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005
15006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15007
15008         save_writethrough $p
15009
15010         set_cache read on
15011         set_cache writethrough on
15012         test_155_small_load
15013         restore_lustre_params < $p
15014         rm -f $p
15015 }
15016 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15017
15018 test_155b() {
15019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15020
15021         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15022
15023         save_writethrough $p
15024
15025         set_cache read on
15026         set_cache writethrough off
15027         test_155_small_load
15028         restore_lustre_params < $p
15029         rm -f $p
15030 }
15031 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15032
15033 test_155c() {
15034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15035
15036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15037
15038         save_writethrough $p
15039
15040         set_cache read off
15041         set_cache writethrough on
15042         test_155_small_load
15043         restore_lustre_params < $p
15044         rm -f $p
15045 }
15046 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15047
15048 test_155d() {
15049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15050
15051         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15052
15053         save_writethrough $p
15054
15055         set_cache read off
15056         set_cache writethrough off
15057         test_155_small_load
15058         restore_lustre_params < $p
15059         rm -f $p
15060 }
15061 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15062
15063 test_155e() {
15064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15065
15066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15067
15068         save_writethrough $p
15069
15070         set_cache read on
15071         set_cache writethrough on
15072         test_155_big_load
15073         restore_lustre_params < $p
15074         rm -f $p
15075 }
15076 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15077
15078 test_155f() {
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080
15081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15082
15083         save_writethrough $p
15084
15085         set_cache read on
15086         set_cache writethrough off
15087         test_155_big_load
15088         restore_lustre_params < $p
15089         rm -f $p
15090 }
15091 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15092
15093 test_155g() {
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095
15096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15097
15098         save_writethrough $p
15099
15100         set_cache read off
15101         set_cache writethrough on
15102         test_155_big_load
15103         restore_lustre_params < $p
15104         rm -f $p
15105 }
15106 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15107
15108 test_155h() {
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110
15111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15112
15113         save_writethrough $p
15114
15115         set_cache read off
15116         set_cache writethrough off
15117         test_155_big_load
15118         restore_lustre_params < $p
15119         rm -f $p
15120 }
15121 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15122
15123 test_156() {
15124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15125         remote_ost_nodsh && skip "remote OST with nodsh"
15126         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15127                 skip "stats not implemented on old servers"
15128         [ "$ost1_FSTYPE" = "zfs" ] &&
15129                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15130
15131         local CPAGES=3
15132         local BEFORE
15133         local AFTER
15134         local file="$DIR/$tfile"
15135         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15136
15137         save_writethrough $p
15138         roc_hit_init
15139
15140         log "Turn on read and write cache"
15141         set_cache read on
15142         set_cache writethrough on
15143
15144         log "Write data and read it back."
15145         log "Read should be satisfied from the cache."
15146         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15147         BEFORE=$(roc_hit)
15148         cancel_lru_locks osc
15149         cat $file >/dev/null
15150         AFTER=$(roc_hit)
15151         if ! let "AFTER - BEFORE == CPAGES"; then
15152                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15153         else
15154                 log "cache hits: before: $BEFORE, after: $AFTER"
15155         fi
15156
15157         log "Read again; it should be satisfied from the cache."
15158         BEFORE=$AFTER
15159         cancel_lru_locks osc
15160         cat $file >/dev/null
15161         AFTER=$(roc_hit)
15162         if ! let "AFTER - BEFORE == CPAGES"; then
15163                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15164         else
15165                 log "cache hits:: before: $BEFORE, after: $AFTER"
15166         fi
15167
15168         log "Turn off the read cache and turn on the write cache"
15169         set_cache read off
15170         set_cache writethrough on
15171
15172         log "Read again; it should be satisfied from the cache."
15173         BEFORE=$(roc_hit)
15174         cancel_lru_locks osc
15175         cat $file >/dev/null
15176         AFTER=$(roc_hit)
15177         if ! let "AFTER - BEFORE == CPAGES"; then
15178                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15179         else
15180                 log "cache hits:: before: $BEFORE, after: $AFTER"
15181         fi
15182
15183         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15184                 # > 2.12.56 uses pagecache if cached
15185                 log "Read again; it should not be satisfied from the cache."
15186                 BEFORE=$AFTER
15187                 cancel_lru_locks osc
15188                 cat $file >/dev/null
15189                 AFTER=$(roc_hit)
15190                 if ! let "AFTER - BEFORE == 0"; then
15191                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15192                 else
15193                         log "cache hits:: before: $BEFORE, after: $AFTER"
15194                 fi
15195         fi
15196
15197         log "Write data and read it back."
15198         log "Read should be satisfied from the cache."
15199         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15200         BEFORE=$(roc_hit)
15201         cancel_lru_locks osc
15202         cat $file >/dev/null
15203         AFTER=$(roc_hit)
15204         if ! let "AFTER - BEFORE == CPAGES"; then
15205                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15206         else
15207                 log "cache hits:: before: $BEFORE, after: $AFTER"
15208         fi
15209
15210         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15211                 # > 2.12.56 uses pagecache if cached
15212                 log "Read again; it should not be satisfied from the cache."
15213                 BEFORE=$AFTER
15214                 cancel_lru_locks osc
15215                 cat $file >/dev/null
15216                 AFTER=$(roc_hit)
15217                 if ! let "AFTER - BEFORE == 0"; then
15218                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15219                 else
15220                         log "cache hits:: before: $BEFORE, after: $AFTER"
15221                 fi
15222         fi
15223
15224         log "Turn off read and write cache"
15225         set_cache read off
15226         set_cache writethrough off
15227
15228         log "Write data and read it back"
15229         log "It should not be satisfied from the cache."
15230         rm -f $file
15231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15232         cancel_lru_locks osc
15233         BEFORE=$(roc_hit)
15234         cat $file >/dev/null
15235         AFTER=$(roc_hit)
15236         if ! let "AFTER - BEFORE == 0"; then
15237                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15238         else
15239                 log "cache hits:: before: $BEFORE, after: $AFTER"
15240         fi
15241
15242         log "Turn on the read cache and turn off the write cache"
15243         set_cache read on
15244         set_cache writethrough off
15245
15246         log "Write data and read it back"
15247         log "It should not be satisfied from the cache."
15248         rm -f $file
15249         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15250         BEFORE=$(roc_hit)
15251         cancel_lru_locks osc
15252         cat $file >/dev/null
15253         AFTER=$(roc_hit)
15254         if ! let "AFTER - BEFORE == 0"; then
15255                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15256         else
15257                 log "cache hits:: before: $BEFORE, after: $AFTER"
15258         fi
15259
15260         log "Read again; it should be satisfied from the cache."
15261         BEFORE=$(roc_hit)
15262         cancel_lru_locks osc
15263         cat $file >/dev/null
15264         AFTER=$(roc_hit)
15265         if ! let "AFTER - BEFORE == CPAGES"; then
15266                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15267         else
15268                 log "cache hits:: before: $BEFORE, after: $AFTER"
15269         fi
15270
15271         restore_lustre_params < $p
15272         rm -f $p $file
15273 }
15274 run_test 156 "Verification of tunables"
15275
15276 test_160a() {
15277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15278         remote_mds_nodsh && skip "remote MDS with nodsh"
15279         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15280                 skip "Need MDS version at least 2.2.0"
15281
15282         changelog_register || error "changelog_register failed"
15283         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15284         changelog_users $SINGLEMDS | grep -q $cl_user ||
15285                 error "User $cl_user not found in changelog_users"
15286
15287         mkdir_on_mdt0 $DIR/$tdir
15288
15289         # change something
15290         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15291         changelog_clear 0 || error "changelog_clear failed"
15292         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15293         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15294         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15295         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15296         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15297         rm $DIR/$tdir/pics/desktop.jpg
15298
15299         changelog_dump | tail -10
15300
15301         echo "verifying changelog mask"
15302         changelog_chmask "-MKDIR"
15303         changelog_chmask "-CLOSE"
15304
15305         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15306         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15307
15308         changelog_chmask "+MKDIR"
15309         changelog_chmask "+CLOSE"
15310
15311         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15312         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15313
15314         changelog_dump | tail -10
15315         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15316         CLOSES=$(changelog_dump | grep -c "CLOSE")
15317         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15318         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15319
15320         # verify contents
15321         echo "verifying target fid"
15322         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15323         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15324         [ "$fidc" == "$fidf" ] ||
15325                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15326         echo "verifying parent fid"
15327         # The FID returned from the Changelog may be the directory shard on
15328         # a different MDT, and not the FID returned by path2fid on the parent.
15329         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15330         # since this is what will matter when recreating this file in the tree.
15331         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15332         local pathp=$($LFS fid2path $MOUNT "$fidp")
15333         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15334                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15335
15336         echo "getting records for $cl_user"
15337         changelog_users $SINGLEMDS
15338         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15339         local nclr=3
15340         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15341                 error "changelog_clear failed"
15342         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15343         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15344         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15345                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15346
15347         local min0_rec=$(changelog_users $SINGLEMDS |
15348                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15349         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15350                           awk '{ print $1; exit; }')
15351
15352         changelog_dump | tail -n 5
15353         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15354         [ $first_rec == $((min0_rec + 1)) ] ||
15355                 error "first index should be $min0_rec + 1 not $first_rec"
15356
15357         # LU-3446 changelog index reset on MDT restart
15358         local cur_rec1=$(changelog_users $SINGLEMDS |
15359                          awk '/^current.index:/ { print $NF }')
15360         changelog_clear 0 ||
15361                 error "clear all changelog records for $cl_user failed"
15362         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15363         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15364                 error "Fail to start $SINGLEMDS"
15365         local cur_rec2=$(changelog_users $SINGLEMDS |
15366                          awk '/^current.index:/ { print $NF }')
15367         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15368         [ $cur_rec1 == $cur_rec2 ] ||
15369                 error "current index should be $cur_rec1 not $cur_rec2"
15370
15371         echo "verifying users from this test are deregistered"
15372         changelog_deregister || error "changelog_deregister failed"
15373         changelog_users $SINGLEMDS | grep -q $cl_user &&
15374                 error "User '$cl_user' still in changelog_users"
15375
15376         # lctl get_param -n mdd.*.changelog_users
15377         # current index: 144
15378         # ID    index (idle seconds)
15379         # cl3   144 (2)
15380         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15381                 # this is the normal case where all users were deregistered
15382                 # make sure no new records are added when no users are present
15383                 local last_rec1=$(changelog_users $SINGLEMDS |
15384                                   awk '/^current.index:/ { print $NF }')
15385                 touch $DIR/$tdir/chloe
15386                 local last_rec2=$(changelog_users $SINGLEMDS |
15387                                   awk '/^current.index:/ { print $NF }')
15388                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15389                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15390         else
15391                 # any changelog users must be leftovers from a previous test
15392                 changelog_users $SINGLEMDS
15393                 echo "other changelog users; can't verify off"
15394         fi
15395 }
15396 run_test 160a "changelog sanity"
15397
15398 test_160b() { # LU-3587
15399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15400         remote_mds_nodsh && skip "remote MDS with nodsh"
15401         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15402                 skip "Need MDS version at least 2.2.0"
15403
15404         changelog_register || error "changelog_register failed"
15405         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15406         changelog_users $SINGLEMDS | grep -q $cl_user ||
15407                 error "User '$cl_user' not found in changelog_users"
15408
15409         local longname1=$(str_repeat a 255)
15410         local longname2=$(str_repeat b 255)
15411
15412         cd $DIR
15413         echo "creating very long named file"
15414         touch $longname1 || error "create of '$longname1' failed"
15415         echo "renaming very long named file"
15416         mv $longname1 $longname2
15417
15418         changelog_dump | grep RENME | tail -n 5
15419         rm -f $longname2
15420 }
15421 run_test 160b "Verify that very long rename doesn't crash in changelog"
15422
15423 test_160c() {
15424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15425         remote_mds_nodsh && skip "remote MDS with nodsh"
15426
15427         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15428                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15429                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15430                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15431
15432         local rc=0
15433
15434         # Registration step
15435         changelog_register || error "changelog_register failed"
15436
15437         rm -rf $DIR/$tdir
15438         mkdir -p $DIR/$tdir
15439         $MCREATE $DIR/$tdir/foo_160c
15440         changelog_chmask "-TRUNC"
15441         $TRUNCATE $DIR/$tdir/foo_160c 200
15442         changelog_chmask "+TRUNC"
15443         $TRUNCATE $DIR/$tdir/foo_160c 199
15444         changelog_dump | tail -n 5
15445         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15446         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15447 }
15448 run_test 160c "verify that changelog log catch the truncate event"
15449
15450 test_160d() {
15451         remote_mds_nodsh && skip "remote MDS with nodsh"
15452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15454         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15455                 skip "Need MDS version at least 2.7.60"
15456
15457         # Registration step
15458         changelog_register || error "changelog_register failed"
15459
15460         mkdir -p $DIR/$tdir/migrate_dir
15461         changelog_clear 0 || error "changelog_clear failed"
15462
15463         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15464         changelog_dump | tail -n 5
15465         local migrates=$(changelog_dump | grep -c "MIGRT")
15466         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15467 }
15468 run_test 160d "verify that changelog log catch the migrate event"
15469
15470 test_160e() {
15471         remote_mds_nodsh && skip "remote MDS with nodsh"
15472
15473         # Create a user
15474         changelog_register || error "changelog_register failed"
15475
15476         # Delete a future user (expect fail)
15477         local MDT0=$(facet_svc $SINGLEMDS)
15478         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15479         local rc=$?
15480
15481         if [ $rc -eq 0 ]; then
15482                 error "Deleted non-existant user cl77"
15483         elif [ $rc -ne 2 ]; then
15484                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15485         fi
15486
15487         # Clear to a bad index (1 billion should be safe)
15488         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15489         rc=$?
15490
15491         if [ $rc -eq 0 ]; then
15492                 error "Successfully cleared to invalid CL index"
15493         elif [ $rc -ne 22 ]; then
15494                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15495         fi
15496 }
15497 run_test 160e "changelog negative testing (should return errors)"
15498
15499 test_160f() {
15500         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15501         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15502                 skip "Need MDS version at least 2.10.56"
15503
15504         local mdts=$(comma_list $(mdts_nodes))
15505
15506         # Create a user
15507         changelog_register || error "first changelog_register failed"
15508         changelog_register || error "second changelog_register failed"
15509         local cl_users
15510         declare -A cl_user1
15511         declare -A cl_user2
15512         local user_rec1
15513         local user_rec2
15514         local i
15515
15516         # generate some changelog records to accumulate on each MDT
15517         # use all_char because created files should be evenly distributed
15518         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15519                 error "test_mkdir $tdir failed"
15520         log "$(date +%s): creating first files"
15521         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15522                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15523                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15524         done
15525
15526         # check changelogs have been generated
15527         local start=$SECONDS
15528         local idle_time=$((MDSCOUNT * 5 + 5))
15529         local nbcl=$(changelog_dump | wc -l)
15530         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15531
15532         for param in "changelog_max_idle_time=$idle_time" \
15533                      "changelog_gc=1" \
15534                      "changelog_min_gc_interval=2" \
15535                      "changelog_min_free_cat_entries=3"; do
15536                 local MDT0=$(facet_svc $SINGLEMDS)
15537                 local var="${param%=*}"
15538                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15539
15540                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15541                 do_nodes $mdts $LCTL set_param mdd.*.$param
15542         done
15543
15544         # force cl_user2 to be idle (1st part), but also cancel the
15545         # cl_user1 records so that it is not evicted later in the test.
15546         local sleep1=$((idle_time / 2))
15547         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15548         sleep $sleep1
15549
15550         # simulate changelog catalog almost full
15551         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15552         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15553
15554         for i in $(seq $MDSCOUNT); do
15555                 cl_users=(${CL_USERS[mds$i]})
15556                 cl_user1[mds$i]="${cl_users[0]}"
15557                 cl_user2[mds$i]="${cl_users[1]}"
15558
15559                 [ -n "${cl_user1[mds$i]}" ] ||
15560                         error "mds$i: no user registered"
15561                 [ -n "${cl_user2[mds$i]}" ] ||
15562                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15563
15564                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15565                 [ -n "$user_rec1" ] ||
15566                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15567                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15568                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15569                 [ -n "$user_rec2" ] ||
15570                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15571                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15572                      "$user_rec1 + 2 == $user_rec2"
15573                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15574                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15575                               "$user_rec1 + 2, but is $user_rec2"
15576                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15577                 [ -n "$user_rec2" ] ||
15578                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15579                 [ $user_rec1 == $user_rec2 ] ||
15580                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15581                               "$user_rec1, but is $user_rec2"
15582         done
15583
15584         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15585         local sleep2=$((idle_time - (SECONDS - start) + 1))
15586         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15587         sleep $sleep2
15588
15589         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15590         # cl_user1 should be OK because it recently processed records.
15591         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15592         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15593                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15594                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15595         done
15596
15597         # ensure gc thread is done
15598         for i in $(mdts_nodes); do
15599                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15600                         error "$i: GC-thread not done"
15601         done
15602
15603         local first_rec
15604         for (( i = 1; i <= MDSCOUNT; i++ )); do
15605                 # check cl_user1 still registered
15606                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15607                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15608                 # check cl_user2 unregistered
15609                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15610                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15611
15612                 # check changelogs are present and starting at $user_rec1 + 1
15613                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15614                 [ -n "$user_rec1" ] ||
15615                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15616                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15617                             awk '{ print $1; exit; }')
15618
15619                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15620                 [ $((user_rec1 + 1)) == $first_rec ] ||
15621                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15622         done
15623 }
15624 run_test 160f "changelog garbage collect (timestamped users)"
15625
15626 test_160g() {
15627         remote_mds_nodsh && skip "remote MDS with nodsh"
15628         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15629                 skip "Need MDS version at least 2.10.56"
15630
15631         local mdts=$(comma_list $(mdts_nodes))
15632
15633         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15634         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15635
15636         # Create a user
15637         changelog_register || error "first changelog_register failed"
15638         changelog_register || error "second changelog_register failed"
15639         local cl_users
15640         declare -A cl_user1
15641         declare -A cl_user2
15642         local user_rec1
15643         local user_rec2
15644         local i
15645
15646         # generate some changelog records to accumulate on each MDT
15647         # use all_char because created files should be evenly distributed
15648         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15649                 error "test_mkdir $tdir failed"
15650         for ((i = 0; i < MDSCOUNT; i++)); do
15651                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15652                         error "create $DIR/$tdir/d$i.1 failed"
15653         done
15654
15655         # check changelogs have been generated
15656         local nbcl=$(changelog_dump | wc -l)
15657         (( $nbcl > 0 )) || error "no changelogs found"
15658
15659         # reduce the max_idle_indexes value to make sure we exceed it
15660         for param in "changelog_max_idle_indexes=1" \
15661                      "changelog_gc=1" \
15662                      "changelog_min_gc_interval=2" \
15663                      "changelog_min_free_cat_entries=3"; do
15664                 local MDT0=$(facet_svc $SINGLEMDS)
15665                 local var="${param%=*}"
15666                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15667
15668                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15669                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15670                         error "unable to set mdd.*.$param"
15671         done
15672
15673         # simulate changelog catalog almost full
15674         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15675         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15676
15677         local start=$SECONDS
15678         for i in $(seq $MDSCOUNT); do
15679                 cl_users=(${CL_USERS[mds$i]})
15680                 cl_user1[mds$i]="${cl_users[0]}"
15681                 cl_user2[mds$i]="${cl_users[1]}"
15682
15683                 [ -n "${cl_user1[mds$i]}" ] ||
15684                         error "mds$i: no user registered"
15685                 [ -n "${cl_user2[mds$i]}" ] ||
15686                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15687
15688                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15689                 [ -n "$user_rec1" ] ||
15690                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15691                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15692                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15693                 [ -n "$user_rec2" ] ||
15694                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15695                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15696                      "$user_rec1 + 2 == $user_rec2"
15697                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15698                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15699                               "$user_rec1 + 2, but is $user_rec2"
15700                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15701                 [ -n "$user_rec2" ] ||
15702                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15703                 [ $user_rec1 == $user_rec2 ] ||
15704                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15705                               "$user_rec1, but is $user_rec2"
15706         done
15707
15708         # ensure we are past the previous changelog_min_gc_interval set above
15709         local sleep2=$((start + 2 - SECONDS))
15710         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15711
15712         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15713         # cl_user1 should be OK because it recently processed records.
15714         for ((i = 0; i < MDSCOUNT; i++)); do
15715                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15716                         error "create $DIR/$tdir/d$i.3 failed"
15717         done
15718
15719         # ensure gc thread is done
15720         for i in $(mdts_nodes); do
15721                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15722                         error "$i: GC-thread not done"
15723         done
15724
15725         local first_rec
15726         for (( i = 1; i <= MDSCOUNT; i++ )); do
15727                 # check cl_user1 still registered
15728                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15729                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15730                 # check cl_user2 unregistered
15731                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15732                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15733
15734                 # check changelogs are present and starting at $user_rec1 + 1
15735                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15736                 [ -n "$user_rec1" ] ||
15737                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15738                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15739                             awk '{ print $1; exit; }')
15740
15741                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15742                 [ $((user_rec1 + 1)) == $first_rec ] ||
15743                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15744         done
15745 }
15746 run_test 160g "changelog garbage collect (old users)"
15747
15748 test_160h() {
15749         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15750         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15751                 skip "Need MDS version at least 2.10.56"
15752
15753         local mdts=$(comma_list $(mdts_nodes))
15754
15755         # Create a user
15756         changelog_register || error "first changelog_register failed"
15757         changelog_register || error "second changelog_register failed"
15758         local cl_users
15759         declare -A cl_user1
15760         declare -A cl_user2
15761         local user_rec1
15762         local user_rec2
15763         local i
15764
15765         # generate some changelog records to accumulate on each MDT
15766         # use all_char because created files should be evenly distributed
15767         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15768                 error "test_mkdir $tdir failed"
15769         for ((i = 0; i < MDSCOUNT; i++)); do
15770                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15771                         error "create $DIR/$tdir/d$i.1 failed"
15772         done
15773
15774         # check changelogs have been generated
15775         local nbcl=$(changelog_dump | wc -l)
15776         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15777
15778         for param in "changelog_max_idle_time=10" \
15779                      "changelog_gc=1" \
15780                      "changelog_min_gc_interval=2"; do
15781                 local MDT0=$(facet_svc $SINGLEMDS)
15782                 local var="${param%=*}"
15783                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15784
15785                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15786                 do_nodes $mdts $LCTL set_param mdd.*.$param
15787         done
15788
15789         # force cl_user2 to be idle (1st part)
15790         sleep 9
15791
15792         for i in $(seq $MDSCOUNT); do
15793                 cl_users=(${CL_USERS[mds$i]})
15794                 cl_user1[mds$i]="${cl_users[0]}"
15795                 cl_user2[mds$i]="${cl_users[1]}"
15796
15797                 [ -n "${cl_user1[mds$i]}" ] ||
15798                         error "mds$i: no user registered"
15799                 [ -n "${cl_user2[mds$i]}" ] ||
15800                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15801
15802                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15803                 [ -n "$user_rec1" ] ||
15804                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15805                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15806                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15807                 [ -n "$user_rec2" ] ||
15808                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15809                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15810                      "$user_rec1 + 2 == $user_rec2"
15811                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15812                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15813                               "$user_rec1 + 2, but is $user_rec2"
15814                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15815                 [ -n "$user_rec2" ] ||
15816                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15817                 [ $user_rec1 == $user_rec2 ] ||
15818                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15819                               "$user_rec1, but is $user_rec2"
15820         done
15821
15822         # force cl_user2 to be idle (2nd part) and to reach
15823         # changelog_max_idle_time
15824         sleep 2
15825
15826         # force each GC-thread start and block then
15827         # one per MDT/MDD, set fail_val accordingly
15828         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15829         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15830
15831         # generate more changelogs to trigger fail_loc
15832         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15833                 error "create $DIR/$tdir/${tfile}bis failed"
15834
15835         # stop MDT to stop GC-thread, should be done in back-ground as it will
15836         # block waiting for the thread to be released and exit
15837         declare -A stop_pids
15838         for i in $(seq $MDSCOUNT); do
15839                 stop mds$i &
15840                 stop_pids[mds$i]=$!
15841         done
15842
15843         for i in $(mdts_nodes); do
15844                 local facet
15845                 local nb=0
15846                 local facets=$(facets_up_on_host $i)
15847
15848                 for facet in ${facets//,/ }; do
15849                         if [[ $facet == mds* ]]; then
15850                                 nb=$((nb + 1))
15851                         fi
15852                 done
15853                 # ensure each MDS's gc threads are still present and all in "R"
15854                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15855                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15856                         error "$i: expected $nb GC-thread"
15857                 wait_update $i \
15858                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15859                         "R" 20 ||
15860                         error "$i: GC-thread not found in R-state"
15861                 # check umounts of each MDT on MDS have reached kthread_stop()
15862                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15863                         error "$i: expected $nb umount"
15864                 wait_update $i \
15865                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15866                         error "$i: umount not found in D-state"
15867         done
15868
15869         # release all GC-threads
15870         do_nodes $mdts $LCTL set_param fail_loc=0
15871
15872         # wait for MDT stop to complete
15873         for i in $(seq $MDSCOUNT); do
15874                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15875         done
15876
15877         # XXX
15878         # may try to check if any orphan changelog records are present
15879         # via ldiskfs/zfs and llog_reader...
15880
15881         # re-start/mount MDTs
15882         for i in $(seq $MDSCOUNT); do
15883                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15884                         error "Fail to start mds$i"
15885         done
15886
15887         local first_rec
15888         for i in $(seq $MDSCOUNT); do
15889                 # check cl_user1 still registered
15890                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15891                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15892                 # check cl_user2 unregistered
15893                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15894                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15895
15896                 # check changelogs are present and starting at $user_rec1 + 1
15897                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15898                 [ -n "$user_rec1" ] ||
15899                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15900                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15901                             awk '{ print $1; exit; }')
15902
15903                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15904                 [ $((user_rec1 + 1)) == $first_rec ] ||
15905                         error "mds$i: first index should be $user_rec1 + 1, " \
15906                               "but is $first_rec"
15907         done
15908 }
15909 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15910               "during mount"
15911
15912 test_160i() {
15913
15914         local mdts=$(comma_list $(mdts_nodes))
15915
15916         changelog_register || error "first changelog_register failed"
15917
15918         # generate some changelog records to accumulate on each MDT
15919         # use all_char because created files should be evenly distributed
15920         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15921                 error "test_mkdir $tdir failed"
15922         for ((i = 0; i < MDSCOUNT; i++)); do
15923                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15924                         error "create $DIR/$tdir/d$i.1 failed"
15925         done
15926
15927         # check changelogs have been generated
15928         local nbcl=$(changelog_dump | wc -l)
15929         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15930
15931         # simulate race between register and unregister
15932         # XXX as fail_loc is set per-MDS, with DNE configs the race
15933         # simulation will only occur for one MDT per MDS and for the
15934         # others the normal race scenario will take place
15935         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15936         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15937         do_nodes $mdts $LCTL set_param fail_val=1
15938
15939         # unregister 1st user
15940         changelog_deregister &
15941         local pid1=$!
15942         # wait some time for deregister work to reach race rdv
15943         sleep 2
15944         # register 2nd user
15945         changelog_register || error "2nd user register failed"
15946
15947         wait $pid1 || error "1st user deregister failed"
15948
15949         local i
15950         local last_rec
15951         declare -A LAST_REC
15952         for i in $(seq $MDSCOUNT); do
15953                 if changelog_users mds$i | grep "^cl"; then
15954                         # make sure new records are added with one user present
15955                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15956                                           awk '/^current.index:/ { print $NF }')
15957                 else
15958                         error "mds$i has no user registered"
15959                 fi
15960         done
15961
15962         # generate more changelog records to accumulate on each MDT
15963         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15964                 error "create $DIR/$tdir/${tfile}bis failed"
15965
15966         for i in $(seq $MDSCOUNT); do
15967                 last_rec=$(changelog_users $SINGLEMDS |
15968                            awk '/^current.index:/ { print $NF }')
15969                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15970                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15971                         error "changelogs are off on mds$i"
15972         done
15973 }
15974 run_test 160i "changelog user register/unregister race"
15975
15976 test_160j() {
15977         remote_mds_nodsh && skip "remote MDS with nodsh"
15978         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15979                 skip "Need MDS version at least 2.12.56"
15980
15981         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15982         stack_trap "umount $MOUNT2" EXIT
15983
15984         changelog_register || error "first changelog_register failed"
15985         stack_trap "changelog_deregister" EXIT
15986
15987         # generate some changelog
15988         # use all_char because created files should be evenly distributed
15989         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15990                 error "mkdir $tdir failed"
15991         for ((i = 0; i < MDSCOUNT; i++)); do
15992                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15993                         error "create $DIR/$tdir/d$i.1 failed"
15994         done
15995
15996         # open the changelog device
15997         exec 3>/dev/changelog-$FSNAME-MDT0000
15998         stack_trap "exec 3>&-" EXIT
15999         exec 4</dev/changelog-$FSNAME-MDT0000
16000         stack_trap "exec 4<&-" EXIT
16001
16002         # umount the first lustre mount
16003         umount $MOUNT
16004         stack_trap "mount_client $MOUNT" EXIT
16005
16006         # read changelog, which may or may not fail, but should not crash
16007         cat <&4 >/dev/null
16008
16009         # clear changelog
16010         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16011         changelog_users $SINGLEMDS | grep -q $cl_user ||
16012                 error "User $cl_user not found in changelog_users"
16013
16014         printf 'clear:'$cl_user':0' >&3
16015 }
16016 run_test 160j "client can be umounted while its chanangelog is being used"
16017
16018 test_160k() {
16019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16020         remote_mds_nodsh && skip "remote MDS with nodsh"
16021
16022         mkdir -p $DIR/$tdir/1/1
16023
16024         changelog_register || error "changelog_register failed"
16025         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16026
16027         changelog_users $SINGLEMDS | grep -q $cl_user ||
16028                 error "User '$cl_user' not found in changelog_users"
16029 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16030         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16031         rmdir $DIR/$tdir/1/1 & sleep 1
16032         mkdir $DIR/$tdir/2
16033         touch $DIR/$tdir/2/2
16034         rm -rf $DIR/$tdir/2
16035
16036         wait
16037         sleep 4
16038
16039         changelog_dump | grep rmdir || error "rmdir not recorded"
16040 }
16041 run_test 160k "Verify that changelog records are not lost"
16042
16043 # Verifies that a file passed as a parameter has recently had an operation
16044 # performed on it that has generated an MTIME changelog which contains the
16045 # correct parent FID. As files might reside on a different MDT from the
16046 # parent directory in DNE configurations, the FIDs are translated to paths
16047 # before being compared, which should be identical
16048 compare_mtime_changelog() {
16049         local file="${1}"
16050         local mdtidx
16051         local mtime
16052         local cl_fid
16053         local pdir
16054         local dir
16055
16056         mdtidx=$($LFS getstripe --mdt-index $file)
16057         mdtidx=$(printf "%04x" $mdtidx)
16058
16059         # Obtain the parent FID from the MTIME changelog
16060         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16061         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16062
16063         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16064         [ -z "$cl_fid" ] && error "parent FID not present"
16065
16066         # Verify that the path for the parent FID is the same as the path for
16067         # the test directory
16068         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16069
16070         dir=$(dirname $1)
16071
16072         [[ "${pdir%/}" == "$dir" ]] ||
16073                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16074 }
16075
16076 test_160l() {
16077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16078
16079         remote_mds_nodsh && skip "remote MDS with nodsh"
16080         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16081                 skip "Need MDS version at least 2.13.55"
16082
16083         local cl_user
16084
16085         changelog_register || error "changelog_register failed"
16086         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16087
16088         changelog_users $SINGLEMDS | grep -q $cl_user ||
16089                 error "User '$cl_user' not found in changelog_users"
16090
16091         # Clear some types so that MTIME changelogs are generated
16092         changelog_chmask "-CREAT"
16093         changelog_chmask "-CLOSE"
16094
16095         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16096
16097         # Test CL_MTIME during setattr
16098         touch $DIR/$tdir/$tfile
16099         compare_mtime_changelog $DIR/$tdir/$tfile
16100
16101         # Test CL_MTIME during close
16102         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16103         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16104 }
16105 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16106
16107 test_160m() {
16108         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16109         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16110                 skip "Need MDS version at least 2.14.51"
16111         local cl_users
16112         local cl_user1
16113         local cl_user2
16114         local pid1
16115
16116         # Create a user
16117         changelog_register || error "first changelog_register failed"
16118         changelog_register || error "second changelog_register failed"
16119
16120         cl_users=(${CL_USERS[mds1]})
16121         cl_user1="${cl_users[0]}"
16122         cl_user2="${cl_users[1]}"
16123         # generate some changelog records to accumulate on MDT0
16124         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16125         createmany -m $DIR/$tdir/$tfile 50 ||
16126                 error "create $DIR/$tdir/$tfile failed"
16127         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16128         rm -f $DIR/$tdir
16129
16130         # check changelogs have been generated
16131         local nbcl=$(changelog_dump | wc -l)
16132         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16133
16134 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16135         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16136
16137         __changelog_clear mds1 $cl_user1 +10
16138         __changelog_clear mds1 $cl_user2 0 &
16139         pid1=$!
16140         sleep 2
16141         __changelog_clear mds1 $cl_user1 0 ||
16142                 error "fail to cancel record for $cl_user1"
16143         wait $pid1
16144         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16145 }
16146 run_test 160m "Changelog clear race"
16147
16148 test_160n() {
16149         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16150         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16151                 skip "Need MDS version at least 2.14.51"
16152         local cl_users
16153         local cl_user1
16154         local cl_user2
16155         local pid1
16156         local first_rec
16157         local last_rec=0
16158
16159         # Create a user
16160         changelog_register || error "first changelog_register failed"
16161
16162         cl_users=(${CL_USERS[mds1]})
16163         cl_user1="${cl_users[0]}"
16164
16165         # generate some changelog records to accumulate on MDT0
16166         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16167         first_rec=$(changelog_users $SINGLEMDS |
16168                         awk '/^current.index:/ { print $NF }')
16169         while (( last_rec < (( first_rec + 65000)) )); do
16170                 createmany -m $DIR/$tdir/$tfile 10000 ||
16171                         error "create $DIR/$tdir/$tfile failed"
16172
16173                 for i in $(seq 0 10000); do
16174                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16175                                 > /dev/null
16176                 done
16177
16178                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16179                         error "unlinkmany failed unlink"
16180                 last_rec=$(changelog_users $SINGLEMDS |
16181                         awk '/^current.index:/ { print $NF }')
16182                 echo last record $last_rec
16183                 (( last_rec == 0 )) && error "no changelog found"
16184         done
16185
16186 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16187         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16188
16189         __changelog_clear mds1 $cl_user1 0 &
16190         pid1=$!
16191         sleep 2
16192         __changelog_clear mds1 $cl_user1 0 ||
16193                 error "fail to cancel record for $cl_user1"
16194         wait $pid1
16195         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16196 }
16197 run_test 160n "Changelog destroy race"
16198
16199 test_160p() {
16200         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16201         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16202                 skip "Need MDS version at least 2.14.51"
16203         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16204         local cl_users
16205         local cl_user1
16206         local entry_count
16207
16208         # Create a user
16209         changelog_register || error "first changelog_register failed"
16210
16211         cl_users=(${CL_USERS[mds1]})
16212         cl_user1="${cl_users[0]}"
16213
16214         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16215         createmany -m $DIR/$tdir/$tfile 50 ||
16216                 error "create $DIR/$tdir/$tfile failed"
16217         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16218         rm -rf $DIR/$tdir
16219
16220         # check changelogs have been generated
16221         entry_count=$(changelog_dump | wc -l)
16222         ((entry_count != 0)) || error "no changelog entries found"
16223
16224         # remove changelog_users and check that orphan entries are removed
16225         stop mds1
16226         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16227         start mds1 || error "cannot start mdt"
16228         entry_count=$(changelog_dump | wc -l)
16229         ((entry_count == 0)) ||
16230                 error "found $entry_count changelog entries, expected none"
16231 }
16232 run_test 160p "Changelog orphan cleanup with no users"
16233
16234 test_161a() {
16235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16236
16237         test_mkdir -c1 $DIR/$tdir
16238         cp /etc/hosts $DIR/$tdir/$tfile
16239         test_mkdir -c1 $DIR/$tdir/foo1
16240         test_mkdir -c1 $DIR/$tdir/foo2
16241         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16242         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16243         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16244         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16245         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16246         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16247                 $LFS fid2path $DIR $FID
16248                 error "bad link ea"
16249         fi
16250         # middle
16251         rm $DIR/$tdir/foo2/zachary
16252         # last
16253         rm $DIR/$tdir/foo2/thor
16254         # first
16255         rm $DIR/$tdir/$tfile
16256         # rename
16257         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16258         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16259                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16260         rm $DIR/$tdir/foo2/maggie
16261
16262         # overflow the EA
16263         local longname=$tfile.avg_len_is_thirty_two_
16264         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16265                 error_noexit 'failed to unlink many hardlinks'" EXIT
16266         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16267                 error "failed to hardlink many files"
16268         links=$($LFS fid2path $DIR $FID | wc -l)
16269         echo -n "${links}/1000 links in link EA"
16270         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16271 }
16272 run_test 161a "link ea sanity"
16273
16274 test_161b() {
16275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16276         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16277
16278         local MDTIDX=1
16279         local remote_dir=$DIR/$tdir/remote_dir
16280
16281         mkdir -p $DIR/$tdir
16282         $LFS mkdir -i $MDTIDX $remote_dir ||
16283                 error "create remote directory failed"
16284
16285         cp /etc/hosts $remote_dir/$tfile
16286         mkdir -p $remote_dir/foo1
16287         mkdir -p $remote_dir/foo2
16288         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16289         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16290         ln $remote_dir/$tfile $remote_dir/foo1/luna
16291         ln $remote_dir/$tfile $remote_dir/foo2/thor
16292
16293         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16294                      tr -d ']')
16295         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16296                 $LFS fid2path $DIR $FID
16297                 error "bad link ea"
16298         fi
16299         # middle
16300         rm $remote_dir/foo2/zachary
16301         # last
16302         rm $remote_dir/foo2/thor
16303         # first
16304         rm $remote_dir/$tfile
16305         # rename
16306         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16307         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16308         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16309                 $LFS fid2path $DIR $FID
16310                 error "bad link rename"
16311         fi
16312         rm $remote_dir/foo2/maggie
16313
16314         # overflow the EA
16315         local longname=filename_avg_len_is_thirty_two_
16316         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16317                 error "failed to hardlink many files"
16318         links=$($LFS fid2path $DIR $FID | wc -l)
16319         echo -n "${links}/1000 links in link EA"
16320         [[ ${links} -gt 60 ]] ||
16321                 error "expected at least 60 links in link EA"
16322         unlinkmany $remote_dir/foo2/$longname 1000 ||
16323         error "failed to unlink many hardlinks"
16324 }
16325 run_test 161b "link ea sanity under remote directory"
16326
16327 test_161c() {
16328         remote_mds_nodsh && skip "remote MDS with nodsh"
16329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16330         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16331                 skip "Need MDS version at least 2.1.5"
16332
16333         # define CLF_RENAME_LAST 0x0001
16334         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16335         changelog_register || error "changelog_register failed"
16336
16337         rm -rf $DIR/$tdir
16338         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16339         touch $DIR/$tdir/foo_161c
16340         touch $DIR/$tdir/bar_161c
16341         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16342         changelog_dump | grep RENME | tail -n 5
16343         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16344         changelog_clear 0 || error "changelog_clear failed"
16345         if [ x$flags != "x0x1" ]; then
16346                 error "flag $flags is not 0x1"
16347         fi
16348
16349         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16350         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16351         touch $DIR/$tdir/foo_161c
16352         touch $DIR/$tdir/bar_161c
16353         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16354         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16355         changelog_dump | grep RENME | tail -n 5
16356         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16357         changelog_clear 0 || error "changelog_clear failed"
16358         if [ x$flags != "x0x0" ]; then
16359                 error "flag $flags is not 0x0"
16360         fi
16361         echo "rename overwrite a target having nlink > 1," \
16362                 "changelog record has flags of $flags"
16363
16364         # rename doesn't overwrite a target (changelog flag 0x0)
16365         touch $DIR/$tdir/foo_161c
16366         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16367         changelog_dump | grep RENME | tail -n 5
16368         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16369         changelog_clear 0 || error "changelog_clear failed"
16370         if [ x$flags != "x0x0" ]; then
16371                 error "flag $flags is not 0x0"
16372         fi
16373         echo "rename doesn't overwrite a target," \
16374                 "changelog record has flags of $flags"
16375
16376         # define CLF_UNLINK_LAST 0x0001
16377         # unlink a file having nlink = 1 (changelog flag 0x1)
16378         rm -f $DIR/$tdir/foo2_161c
16379         changelog_dump | grep UNLNK | tail -n 5
16380         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16381         changelog_clear 0 || error "changelog_clear failed"
16382         if [ x$flags != "x0x1" ]; then
16383                 error "flag $flags is not 0x1"
16384         fi
16385         echo "unlink a file having nlink = 1," \
16386                 "changelog record has flags of $flags"
16387
16388         # unlink a file having nlink > 1 (changelog flag 0x0)
16389         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16390         rm -f $DIR/$tdir/foobar_161c
16391         changelog_dump | grep UNLNK | tail -n 5
16392         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16393         changelog_clear 0 || error "changelog_clear failed"
16394         if [ x$flags != "x0x0" ]; then
16395                 error "flag $flags is not 0x0"
16396         fi
16397         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16398 }
16399 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16400
16401 test_161d() {
16402         remote_mds_nodsh && skip "remote MDS with nodsh"
16403         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16404
16405         local pid
16406         local fid
16407
16408         changelog_register || error "changelog_register failed"
16409
16410         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16411         # interfer with $MOUNT/.lustre/fid/ access
16412         mkdir $DIR/$tdir
16413         [[ $? -eq 0 ]] || error "mkdir failed"
16414
16415         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16416         $LCTL set_param fail_loc=0x8000140c
16417         # 5s pause
16418         $LCTL set_param fail_val=5
16419
16420         # create file
16421         echo foofoo > $DIR/$tdir/$tfile &
16422         pid=$!
16423
16424         # wait for create to be delayed
16425         sleep 2
16426
16427         ps -p $pid
16428         [[ $? -eq 0 ]] || error "create should be blocked"
16429
16430         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16431         stack_trap "rm -f $tempfile"
16432         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16433         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16434         # some delay may occur during ChangeLog publishing and file read just
16435         # above, that could allow file write to happen finally
16436         [[ -s $tempfile ]] && echo "file should be empty"
16437
16438         $LCTL set_param fail_loc=0
16439
16440         wait $pid
16441         [[ $? -eq 0 ]] || error "create failed"
16442 }
16443 run_test 161d "create with concurrent .lustre/fid access"
16444
16445 check_path() {
16446         local expected="$1"
16447         shift
16448         local fid="$2"
16449
16450         local path
16451         path=$($LFS fid2path "$@")
16452         local rc=$?
16453
16454         if [ $rc -ne 0 ]; then
16455                 error "path looked up of '$expected' failed: rc=$rc"
16456         elif [ "$path" != "$expected" ]; then
16457                 error "path looked up '$path' instead of '$expected'"
16458         else
16459                 echo "FID '$fid' resolves to path '$path' as expected"
16460         fi
16461 }
16462
16463 test_162a() { # was test_162
16464         test_mkdir -p -c1 $DIR/$tdir/d2
16465         touch $DIR/$tdir/d2/$tfile
16466         touch $DIR/$tdir/d2/x1
16467         touch $DIR/$tdir/d2/x2
16468         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16469         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16470         # regular file
16471         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16472         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16473
16474         # softlink
16475         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16476         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16477         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16478
16479         # softlink to wrong file
16480         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16481         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16482         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16483
16484         # hardlink
16485         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16486         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16487         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16488         # fid2path dir/fsname should both work
16489         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16490         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16491
16492         # hardlink count: check that there are 2 links
16493         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16494         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16495
16496         # hardlink indexing: remove the first link
16497         rm $DIR/$tdir/d2/p/q/r/hlink
16498         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16499 }
16500 run_test 162a "path lookup sanity"
16501
16502 test_162b() {
16503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16505
16506         mkdir $DIR/$tdir
16507         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16508                                 error "create striped dir failed"
16509
16510         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16511                                         tail -n 1 | awk '{print $2}')
16512         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16513
16514         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16515         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16516
16517         # regular file
16518         for ((i=0;i<5;i++)); do
16519                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16520                         error "get fid for f$i failed"
16521                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16522
16523                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16524                         error "get fid for d$i failed"
16525                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16526         done
16527
16528         return 0
16529 }
16530 run_test 162b "striped directory path lookup sanity"
16531
16532 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16533 test_162c() {
16534         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16535                 skip "Need MDS version at least 2.7.51"
16536
16537         local lpath=$tdir.local
16538         local rpath=$tdir.remote
16539
16540         test_mkdir $DIR/$lpath
16541         test_mkdir $DIR/$rpath
16542
16543         for ((i = 0; i <= 101; i++)); do
16544                 lpath="$lpath/$i"
16545                 mkdir $DIR/$lpath
16546                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16547                         error "get fid for local directory $DIR/$lpath failed"
16548                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16549
16550                 rpath="$rpath/$i"
16551                 test_mkdir $DIR/$rpath
16552                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16553                         error "get fid for remote directory $DIR/$rpath failed"
16554                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16555         done
16556
16557         return 0
16558 }
16559 run_test 162c "fid2path works with paths 100 or more directories deep"
16560
16561 oalr_event_count() {
16562         local event="${1}"
16563         local trace="${2}"
16564
16565         awk -v name="${FSNAME}-OST0000" \
16566             -v event="${event}" \
16567             '$1 == "TRACE" && $2 == event && $3 == name' \
16568             "${trace}" |
16569         wc -l
16570 }
16571
16572 oalr_expect_event_count() {
16573         local event="${1}"
16574         local trace="${2}"
16575         local expect="${3}"
16576         local count
16577
16578         count=$(oalr_event_count "${event}" "${trace}")
16579         if ((count == expect)); then
16580                 return 0
16581         fi
16582
16583         error_noexit "${event} event count was '${count}', expected ${expect}"
16584         cat "${trace}" >&2
16585         exit 1
16586 }
16587
16588 cleanup_165() {
16589         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16590         stop ost1
16591         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16592 }
16593
16594 setup_165() {
16595         sync # Flush previous IOs so we can count log entries.
16596         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16597         stack_trap cleanup_165 EXIT
16598 }
16599
16600 test_165a() {
16601         local trace="/tmp/${tfile}.trace"
16602         local rc
16603         local count
16604
16605         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16606                 skip "OFD access log unsupported"
16607
16608         setup_165
16609         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16610         sleep 5
16611
16612         do_facet ost1 ofd_access_log_reader --list
16613         stop ost1
16614
16615         do_facet ost1 killall -TERM ofd_access_log_reader
16616         wait
16617         rc=$?
16618
16619         if ((rc != 0)); then
16620                 error "ofd_access_log_reader exited with rc = '${rc}'"
16621         fi
16622
16623         # Parse trace file for discovery events:
16624         oalr_expect_event_count alr_log_add "${trace}" 1
16625         oalr_expect_event_count alr_log_eof "${trace}" 1
16626         oalr_expect_event_count alr_log_free "${trace}" 1
16627 }
16628 run_test 165a "ofd access log discovery"
16629
16630 test_165b() {
16631         local trace="/tmp/${tfile}.trace"
16632         local file="${DIR}/${tfile}"
16633         local pfid1
16634         local pfid2
16635         local -a entry
16636         local rc
16637         local count
16638         local size
16639         local flags
16640
16641         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16642                 skip "OFD access log unsupported"
16643
16644         setup_165
16645         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16646         sleep 5
16647
16648         do_facet ost1 ofd_access_log_reader --list
16649
16650         lfs setstripe -c 1 -i 0 "${file}"
16651         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16652                 error "cannot create '${file}'"
16653
16654         sleep 5
16655         do_facet ost1 killall -TERM ofd_access_log_reader
16656         wait
16657         rc=$?
16658
16659         if ((rc != 0)); then
16660                 error "ofd_access_log_reader exited with rc = '${rc}'"
16661         fi
16662
16663         oalr_expect_event_count alr_log_entry "${trace}" 1
16664
16665         pfid1=$($LFS path2fid "${file}")
16666
16667         # 1     2             3   4    5     6   7    8    9     10
16668         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16669         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16670
16671         echo "entry = '${entry[*]}'" >&2
16672
16673         pfid2=${entry[4]}
16674         if [[ "${pfid1}" != "${pfid2}" ]]; then
16675                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16676         fi
16677
16678         size=${entry[8]}
16679         if ((size != 1048576)); then
16680                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16681         fi
16682
16683         flags=${entry[10]}
16684         if [[ "${flags}" != "w" ]]; then
16685                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16686         fi
16687
16688         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16689         sleep 5
16690
16691         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16692                 error "cannot read '${file}'"
16693         sleep 5
16694
16695         do_facet ost1 killall -TERM ofd_access_log_reader
16696         wait
16697         rc=$?
16698
16699         if ((rc != 0)); then
16700                 error "ofd_access_log_reader exited with rc = '${rc}'"
16701         fi
16702
16703         oalr_expect_event_count alr_log_entry "${trace}" 1
16704
16705         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16706         echo "entry = '${entry[*]}'" >&2
16707
16708         pfid2=${entry[4]}
16709         if [[ "${pfid1}" != "${pfid2}" ]]; then
16710                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16711         fi
16712
16713         size=${entry[8]}
16714         if ((size != 524288)); then
16715                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16716         fi
16717
16718         flags=${entry[10]}
16719         if [[ "${flags}" != "r" ]]; then
16720                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16721         fi
16722 }
16723 run_test 165b "ofd access log entries are produced and consumed"
16724
16725 test_165c() {
16726         local trace="/tmp/${tfile}.trace"
16727         local file="${DIR}/${tdir}/${tfile}"
16728
16729         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16730                 skip "OFD access log unsupported"
16731
16732         test_mkdir "${DIR}/${tdir}"
16733
16734         setup_165
16735         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16736         sleep 5
16737
16738         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16739
16740         # 4096 / 64 = 64. Create twice as many entries.
16741         for ((i = 0; i < 128; i++)); do
16742                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16743                         error "cannot create file"
16744         done
16745
16746         sync
16747
16748         do_facet ost1 killall -TERM ofd_access_log_reader
16749         wait
16750         rc=$?
16751         if ((rc != 0)); then
16752                 error "ofd_access_log_reader exited with rc = '${rc}'"
16753         fi
16754
16755         unlinkmany  "${file}-%d" 128
16756 }
16757 run_test 165c "full ofd access logs do not block IOs"
16758
16759 oal_get_read_count() {
16760         local stats="$1"
16761
16762         # STATS lustre-OST0001 alr_read_count 1
16763
16764         do_facet ost1 cat "${stats}" |
16765         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16766              END { print count; }'
16767 }
16768
16769 oal_expect_read_count() {
16770         local stats="$1"
16771         local count
16772         local expect="$2"
16773
16774         # Ask ofd_access_log_reader to write stats.
16775         do_facet ost1 killall -USR1 ofd_access_log_reader
16776
16777         # Allow some time for things to happen.
16778         sleep 1
16779
16780         count=$(oal_get_read_count "${stats}")
16781         if ((count == expect)); then
16782                 return 0
16783         fi
16784
16785         error_noexit "bad read count, got ${count}, expected ${expect}"
16786         do_facet ost1 cat "${stats}" >&2
16787         exit 1
16788 }
16789
16790 test_165d() {
16791         local stats="/tmp/${tfile}.stats"
16792         local file="${DIR}/${tdir}/${tfile}"
16793         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16794
16795         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16796                 skip "OFD access log unsupported"
16797
16798         test_mkdir "${DIR}/${tdir}"
16799
16800         setup_165
16801         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16802         sleep 5
16803
16804         lfs setstripe -c 1 -i 0 "${file}"
16805
16806         do_facet ost1 lctl set_param "${param}=rw"
16807         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16808                 error "cannot create '${file}'"
16809         oal_expect_read_count "${stats}" 1
16810
16811         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16812                 error "cannot read '${file}'"
16813         oal_expect_read_count "${stats}" 2
16814
16815         do_facet ost1 lctl set_param "${param}=r"
16816         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16817                 error "cannot create '${file}'"
16818         oal_expect_read_count "${stats}" 2
16819
16820         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16821                 error "cannot read '${file}'"
16822         oal_expect_read_count "${stats}" 3
16823
16824         do_facet ost1 lctl set_param "${param}=w"
16825         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16826                 error "cannot create '${file}'"
16827         oal_expect_read_count "${stats}" 4
16828
16829         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16830                 error "cannot read '${file}'"
16831         oal_expect_read_count "${stats}" 4
16832
16833         do_facet ost1 lctl set_param "${param}=0"
16834         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16835                 error "cannot create '${file}'"
16836         oal_expect_read_count "${stats}" 4
16837
16838         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16839                 error "cannot read '${file}'"
16840         oal_expect_read_count "${stats}" 4
16841
16842         do_facet ost1 killall -TERM ofd_access_log_reader
16843         wait
16844         rc=$?
16845         if ((rc != 0)); then
16846                 error "ofd_access_log_reader exited with rc = '${rc}'"
16847         fi
16848 }
16849 run_test 165d "ofd_access_log mask works"
16850
16851 test_165e() {
16852         local stats="/tmp/${tfile}.stats"
16853         local file0="${DIR}/${tdir}-0/${tfile}"
16854         local file1="${DIR}/${tdir}-1/${tfile}"
16855
16856         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16857                 skip "OFD access log unsupported"
16858
16859         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16860
16861         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16862         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16863
16864         lfs setstripe -c 1 -i 0 "${file0}"
16865         lfs setstripe -c 1 -i 0 "${file1}"
16866
16867         setup_165
16868         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16869         sleep 5
16870
16871         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16872                 error "cannot create '${file0}'"
16873         sync
16874         oal_expect_read_count "${stats}" 0
16875
16876         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16877                 error "cannot create '${file1}'"
16878         sync
16879         oal_expect_read_count "${stats}" 1
16880
16881         do_facet ost1 killall -TERM ofd_access_log_reader
16882         wait
16883         rc=$?
16884         if ((rc != 0)); then
16885                 error "ofd_access_log_reader exited with rc = '${rc}'"
16886         fi
16887 }
16888 run_test 165e "ofd_access_log MDT index filter works"
16889
16890 test_165f() {
16891         local trace="/tmp/${tfile}.trace"
16892         local rc
16893         local count
16894
16895         setup_165
16896         do_facet ost1 timeout 60 ofd_access_log_reader \
16897                 --exit-on-close --debug=- --trace=- > "${trace}" &
16898         sleep 5
16899         stop ost1
16900
16901         wait
16902         rc=$?
16903
16904         if ((rc != 0)); then
16905                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16906                 cat "${trace}"
16907                 exit 1
16908         fi
16909 }
16910 run_test 165f "ofd_access_log_reader --exit-on-close works"
16911
16912 test_169() {
16913         # do directio so as not to populate the page cache
16914         log "creating a 10 Mb file"
16915         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16916                 error "multiop failed while creating a file"
16917         log "starting reads"
16918         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16919         log "truncating the file"
16920         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16921                 error "multiop failed while truncating the file"
16922         log "killing dd"
16923         kill %+ || true # reads might have finished
16924         echo "wait until dd is finished"
16925         wait
16926         log "removing the temporary file"
16927         rm -rf $DIR/$tfile || error "tmp file removal failed"
16928 }
16929 run_test 169 "parallel read and truncate should not deadlock"
16930
16931 test_170() {
16932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16933
16934         $LCTL clear     # bug 18514
16935         $LCTL debug_daemon start $TMP/${tfile}_log_good
16936         touch $DIR/$tfile
16937         $LCTL debug_daemon stop
16938         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16939                 error "sed failed to read log_good"
16940
16941         $LCTL debug_daemon start $TMP/${tfile}_log_good
16942         rm -rf $DIR/$tfile
16943         $LCTL debug_daemon stop
16944
16945         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16946                error "lctl df log_bad failed"
16947
16948         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16949         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16950
16951         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16952         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16953
16954         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16955                 error "bad_line good_line1 good_line2 are empty"
16956
16957         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16958         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16959         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16960
16961         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16962         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16963         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16964
16965         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16966                 error "bad_line_new good_line_new are empty"
16967
16968         local expected_good=$((good_line1 + good_line2*2))
16969
16970         rm -f $TMP/${tfile}*
16971         # LU-231, short malformed line may not be counted into bad lines
16972         if [ $bad_line -ne $bad_line_new ] &&
16973                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16974                 error "expected $bad_line bad lines, but got $bad_line_new"
16975                 return 1
16976         fi
16977
16978         if [ $expected_good -ne $good_line_new ]; then
16979                 error "expected $expected_good good lines, but got $good_line_new"
16980                 return 2
16981         fi
16982         true
16983 }
16984 run_test 170 "test lctl df to handle corrupted log ====================="
16985
16986 test_171() { # bug20592
16987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16988
16989         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16990         $LCTL set_param fail_loc=0x50e
16991         $LCTL set_param fail_val=3000
16992         multiop_bg_pause $DIR/$tfile O_s || true
16993         local MULTIPID=$!
16994         kill -USR1 $MULTIPID
16995         # cause log dump
16996         sleep 3
16997         wait $MULTIPID
16998         if dmesg | grep "recursive fault"; then
16999                 error "caught a recursive fault"
17000         fi
17001         $LCTL set_param fail_loc=0
17002         true
17003 }
17004 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17005
17006 # it would be good to share it with obdfilter-survey/iokit-libecho code
17007 setup_obdecho_osc () {
17008         local rc=0
17009         local ost_nid=$1
17010         local obdfilter_name=$2
17011         echo "Creating new osc for $obdfilter_name on $ost_nid"
17012         # make sure we can find loopback nid
17013         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17014
17015         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17016                            ${obdfilter_name}_osc_UUID || rc=2; }
17017         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17018                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17019         return $rc
17020 }
17021
17022 cleanup_obdecho_osc () {
17023         local obdfilter_name=$1
17024         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17025         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17026         return 0
17027 }
17028
17029 obdecho_test() {
17030         local OBD=$1
17031         local node=$2
17032         local pages=${3:-64}
17033         local rc=0
17034         local id
17035
17036         local count=10
17037         local obd_size=$(get_obd_size $node $OBD)
17038         local page_size=$(get_page_size $node)
17039         if [[ -n "$obd_size" ]]; then
17040                 local new_count=$((obd_size / (pages * page_size / 1024)))
17041                 [[ $new_count -ge $count ]] || count=$new_count
17042         fi
17043
17044         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17045         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17046                            rc=2; }
17047         if [ $rc -eq 0 ]; then
17048             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17049             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17050         fi
17051         echo "New object id is $id"
17052         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17053                            rc=4; }
17054         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17055                            "test_brw $count w v $pages $id" || rc=4; }
17056         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17057                            rc=4; }
17058         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17059                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17060         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17061                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17062         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17063         return $rc
17064 }
17065
17066 test_180a() {
17067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17068
17069         if ! [ -d /sys/fs/lustre/echo_client ] &&
17070            ! module_loaded obdecho; then
17071                 load_module obdecho/obdecho &&
17072                         stack_trap "rmmod obdecho" EXIT ||
17073                         error "unable to load obdecho on client"
17074         fi
17075
17076         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17077         local host=$($LCTL get_param -n osc.$osc.import |
17078                      awk '/current_connection:/ { print $2 }' )
17079         local target=$($LCTL get_param -n osc.$osc.import |
17080                        awk '/target:/ { print $2 }' )
17081         target=${target%_UUID}
17082
17083         if [ -n "$target" ]; then
17084                 setup_obdecho_osc $host $target &&
17085                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17086                         { error "obdecho setup failed with $?"; return; }
17087
17088                 obdecho_test ${target}_osc client ||
17089                         error "obdecho_test failed on ${target}_osc"
17090         else
17091                 $LCTL get_param osc.$osc.import
17092                 error "there is no osc.$osc.import target"
17093         fi
17094 }
17095 run_test 180a "test obdecho on osc"
17096
17097 test_180b() {
17098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17099         remote_ost_nodsh && skip "remote OST with nodsh"
17100
17101         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17102                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17103                 error "failed to load module obdecho"
17104
17105         local target=$(do_facet ost1 $LCTL dl |
17106                        awk '/obdfilter/ { print $4; exit; }')
17107
17108         if [ -n "$target" ]; then
17109                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17110         else
17111                 do_facet ost1 $LCTL dl
17112                 error "there is no obdfilter target on ost1"
17113         fi
17114 }
17115 run_test 180b "test obdecho directly on obdfilter"
17116
17117 test_180c() { # LU-2598
17118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17119         remote_ost_nodsh && skip "remote OST with nodsh"
17120         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17121                 skip "Need MDS version at least 2.4.0"
17122
17123         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17124                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17125                 error "failed to load module obdecho"
17126
17127         local target=$(do_facet ost1 $LCTL dl |
17128                        awk '/obdfilter/ { print $4; exit; }')
17129
17130         if [ -n "$target" ]; then
17131                 local pages=16384 # 64MB bulk I/O RPC size
17132
17133                 obdecho_test "$target" ost1 "$pages" ||
17134                         error "obdecho_test with pages=$pages failed with $?"
17135         else
17136                 do_facet ost1 $LCTL dl
17137                 error "there is no obdfilter target on ost1"
17138         fi
17139 }
17140 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17141
17142 test_181() { # bug 22177
17143         test_mkdir $DIR/$tdir
17144         # create enough files to index the directory
17145         createmany -o $DIR/$tdir/foobar 4000
17146         # print attributes for debug purpose
17147         lsattr -d .
17148         # open dir
17149         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17150         MULTIPID=$!
17151         # remove the files & current working dir
17152         unlinkmany $DIR/$tdir/foobar 4000
17153         rmdir $DIR/$tdir
17154         kill -USR1 $MULTIPID
17155         wait $MULTIPID
17156         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17157         return 0
17158 }
17159 run_test 181 "Test open-unlinked dir ========================"
17160
17161 test_182() {
17162         local fcount=1000
17163         local tcount=10
17164
17165         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17166
17167         $LCTL set_param mdc.*.rpc_stats=clear
17168
17169         for (( i = 0; i < $tcount; i++ )) ; do
17170                 mkdir $DIR/$tdir/$i
17171         done
17172
17173         for (( i = 0; i < $tcount; i++ )) ; do
17174                 createmany -o $DIR/$tdir/$i/f- $fcount &
17175         done
17176         wait
17177
17178         for (( i = 0; i < $tcount; i++ )) ; do
17179                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17180         done
17181         wait
17182
17183         $LCTL get_param mdc.*.rpc_stats
17184
17185         rm -rf $DIR/$tdir
17186 }
17187 run_test 182 "Test parallel modify metadata operations ================"
17188
17189 test_183() { # LU-2275
17190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17191         remote_mds_nodsh && skip "remote MDS with nodsh"
17192         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17193                 skip "Need MDS version at least 2.3.56"
17194
17195         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17196         echo aaa > $DIR/$tdir/$tfile
17197
17198 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17199         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17200
17201         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17202         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17203
17204         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17205
17206         # Flush negative dentry cache
17207         touch $DIR/$tdir/$tfile
17208
17209         # We are not checking for any leaked references here, they'll
17210         # become evident next time we do cleanup with module unload.
17211         rm -rf $DIR/$tdir
17212 }
17213 run_test 183 "No crash or request leak in case of strange dispositions ========"
17214
17215 # test suite 184 is for LU-2016, LU-2017
17216 test_184a() {
17217         check_swap_layouts_support
17218
17219         dir0=$DIR/$tdir/$testnum
17220         test_mkdir -p -c1 $dir0
17221         ref1=/etc/passwd
17222         ref2=/etc/group
17223         file1=$dir0/f1
17224         file2=$dir0/f2
17225         $LFS setstripe -c1 $file1
17226         cp $ref1 $file1
17227         $LFS setstripe -c2 $file2
17228         cp $ref2 $file2
17229         gen1=$($LFS getstripe -g $file1)
17230         gen2=$($LFS getstripe -g $file2)
17231
17232         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17233         gen=$($LFS getstripe -g $file1)
17234         [[ $gen1 != $gen ]] ||
17235                 "Layout generation on $file1 does not change"
17236         gen=$($LFS getstripe -g $file2)
17237         [[ $gen2 != $gen ]] ||
17238                 "Layout generation on $file2 does not change"
17239
17240         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17241         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17242
17243         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17244 }
17245 run_test 184a "Basic layout swap"
17246
17247 test_184b() {
17248         check_swap_layouts_support
17249
17250         dir0=$DIR/$tdir/$testnum
17251         mkdir -p $dir0 || error "creating dir $dir0"
17252         file1=$dir0/f1
17253         file2=$dir0/f2
17254         file3=$dir0/f3
17255         dir1=$dir0/d1
17256         dir2=$dir0/d2
17257         mkdir $dir1 $dir2
17258         $LFS setstripe -c1 $file1
17259         $LFS setstripe -c2 $file2
17260         $LFS setstripe -c1 $file3
17261         chown $RUNAS_ID $file3
17262         gen1=$($LFS getstripe -g $file1)
17263         gen2=$($LFS getstripe -g $file2)
17264
17265         $LFS swap_layouts $dir1 $dir2 &&
17266                 error "swap of directories layouts should fail"
17267         $LFS swap_layouts $dir1 $file1 &&
17268                 error "swap of directory and file layouts should fail"
17269         $RUNAS $LFS swap_layouts $file1 $file2 &&
17270                 error "swap of file we cannot write should fail"
17271         $LFS swap_layouts $file1 $file3 &&
17272                 error "swap of file with different owner should fail"
17273         /bin/true # to clear error code
17274 }
17275 run_test 184b "Forbidden layout swap (will generate errors)"
17276
17277 test_184c() {
17278         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17279         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17280         check_swap_layouts_support
17281         check_swap_layout_no_dom $DIR
17282
17283         local dir0=$DIR/$tdir/$testnum
17284         mkdir -p $dir0 || error "creating dir $dir0"
17285
17286         local ref1=$dir0/ref1
17287         local ref2=$dir0/ref2
17288         local file1=$dir0/file1
17289         local file2=$dir0/file2
17290         # create a file large enough for the concurrent test
17291         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17292         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17293         echo "ref file size: ref1($(stat -c %s $ref1))," \
17294              "ref2($(stat -c %s $ref2))"
17295
17296         cp $ref2 $file2
17297         dd if=$ref1 of=$file1 bs=16k &
17298         local DD_PID=$!
17299
17300         # Make sure dd starts to copy file, but wait at most 5 seconds
17301         local loops=0
17302         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17303
17304         $LFS swap_layouts $file1 $file2
17305         local rc=$?
17306         wait $DD_PID
17307         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17308         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17309
17310         # how many bytes copied before swapping layout
17311         local copied=$(stat -c %s $file2)
17312         local remaining=$(stat -c %s $ref1)
17313         remaining=$((remaining - copied))
17314         echo "Copied $copied bytes before swapping layout..."
17315
17316         cmp -n $copied $file1 $ref2 | grep differ &&
17317                 error "Content mismatch [0, $copied) of ref2 and file1"
17318         cmp -n $copied $file2 $ref1 ||
17319                 error "Content mismatch [0, $copied) of ref1 and file2"
17320         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17321                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17322
17323         # clean up
17324         rm -f $ref1 $ref2 $file1 $file2
17325 }
17326 run_test 184c "Concurrent write and layout swap"
17327
17328 test_184d() {
17329         check_swap_layouts_support
17330         check_swap_layout_no_dom $DIR
17331         [ -z "$(which getfattr 2>/dev/null)" ] &&
17332                 skip_env "no getfattr command"
17333
17334         local file1=$DIR/$tdir/$tfile-1
17335         local file2=$DIR/$tdir/$tfile-2
17336         local file3=$DIR/$tdir/$tfile-3
17337         local lovea1
17338         local lovea2
17339
17340         mkdir -p $DIR/$tdir
17341         touch $file1 || error "create $file1 failed"
17342         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17343                 error "create $file2 failed"
17344         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17345                 error "create $file3 failed"
17346         lovea1=$(get_layout_param $file1)
17347
17348         $LFS swap_layouts $file2 $file3 ||
17349                 error "swap $file2 $file3 layouts failed"
17350         $LFS swap_layouts $file1 $file2 ||
17351                 error "swap $file1 $file2 layouts failed"
17352
17353         lovea2=$(get_layout_param $file2)
17354         echo "$lovea1"
17355         echo "$lovea2"
17356         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17357
17358         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17359         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17360 }
17361 run_test 184d "allow stripeless layouts swap"
17362
17363 test_184e() {
17364         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17365                 skip "Need MDS version at least 2.6.94"
17366         check_swap_layouts_support
17367         check_swap_layout_no_dom $DIR
17368         [ -z "$(which getfattr 2>/dev/null)" ] &&
17369                 skip_env "no getfattr command"
17370
17371         local file1=$DIR/$tdir/$tfile-1
17372         local file2=$DIR/$tdir/$tfile-2
17373         local file3=$DIR/$tdir/$tfile-3
17374         local lovea
17375
17376         mkdir -p $DIR/$tdir
17377         touch $file1 || error "create $file1 failed"
17378         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17379                 error "create $file2 failed"
17380         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17381                 error "create $file3 failed"
17382
17383         $LFS swap_layouts $file1 $file2 ||
17384                 error "swap $file1 $file2 layouts failed"
17385
17386         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17387         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17388
17389         echo 123 > $file1 || error "Should be able to write into $file1"
17390
17391         $LFS swap_layouts $file1 $file3 ||
17392                 error "swap $file1 $file3 layouts failed"
17393
17394         echo 123 > $file1 || error "Should be able to write into $file1"
17395
17396         rm -rf $file1 $file2 $file3
17397 }
17398 run_test 184e "Recreate layout after stripeless layout swaps"
17399
17400 test_184f() {
17401         # Create a file with name longer than sizeof(struct stat) ==
17402         # 144 to see if we can get chars from the file name to appear
17403         # in the returned striping. Note that 'f' == 0x66.
17404         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17405
17406         mkdir -p $DIR/$tdir
17407         mcreate $DIR/$tdir/$file
17408         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17409                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17410         fi
17411 }
17412 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17413
17414 test_185() { # LU-2441
17415         # LU-3553 - no volatile file support in old servers
17416         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17417                 skip "Need MDS version at least 2.3.60"
17418
17419         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17420         touch $DIR/$tdir/spoo
17421         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17422         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17423                 error "cannot create/write a volatile file"
17424         [ "$FILESET" == "" ] &&
17425         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17426                 error "FID is still valid after close"
17427
17428         multiop_bg_pause $DIR/$tdir vVw4096_c
17429         local multi_pid=$!
17430
17431         local OLD_IFS=$IFS
17432         IFS=":"
17433         local fidv=($fid)
17434         IFS=$OLD_IFS
17435         # assume that the next FID for this client is sequential, since stdout
17436         # is unfortunately eaten by multiop_bg_pause
17437         local n=$((${fidv[1]} + 1))
17438         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17439         if [ "$FILESET" == "" ]; then
17440                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17441                         error "FID is missing before close"
17442         fi
17443         kill -USR1 $multi_pid
17444         # 1 second delay, so if mtime change we will see it
17445         sleep 1
17446         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17447         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17448 }
17449 run_test 185 "Volatile file support"
17450
17451 function create_check_volatile() {
17452         local idx=$1
17453         local tgt
17454
17455         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17456         local PID=$!
17457         sleep 1
17458         local FID=$(cat /tmp/${tfile}.fid)
17459         [ "$FID" == "" ] && error "can't get FID for volatile"
17460         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17461         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17462         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17463         kill -USR1 $PID
17464         wait
17465         sleep 1
17466         cancel_lru_locks mdc # flush opencache
17467         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17468         return 0
17469 }
17470
17471 test_185a(){
17472         # LU-12516 - volatile creation via .lustre
17473         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17474                 skip "Need MDS version at least 2.3.55"
17475
17476         create_check_volatile 0
17477         [ $MDSCOUNT -lt 2 ] && return 0
17478
17479         # DNE case
17480         create_check_volatile 1
17481
17482         return 0
17483 }
17484 run_test 185a "Volatile file creation in .lustre/fid/"
17485
17486 test_187a() {
17487         remote_mds_nodsh && skip "remote MDS with nodsh"
17488         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17489                 skip "Need MDS version at least 2.3.0"
17490
17491         local dir0=$DIR/$tdir/$testnum
17492         mkdir -p $dir0 || error "creating dir $dir0"
17493
17494         local file=$dir0/file1
17495         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17496         local dv1=$($LFS data_version $file)
17497         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17498         local dv2=$($LFS data_version $file)
17499         [[ $dv1 != $dv2 ]] ||
17500                 error "data version did not change on write $dv1 == $dv2"
17501
17502         # clean up
17503         rm -f $file1
17504 }
17505 run_test 187a "Test data version change"
17506
17507 test_187b() {
17508         remote_mds_nodsh && skip "remote MDS with nodsh"
17509         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17510                 skip "Need MDS version at least 2.3.0"
17511
17512         local dir0=$DIR/$tdir/$testnum
17513         mkdir -p $dir0 || error "creating dir $dir0"
17514
17515         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17516         [[ ${DV[0]} != ${DV[1]} ]] ||
17517                 error "data version did not change on write"\
17518                       " ${DV[0]} == ${DV[1]}"
17519
17520         # clean up
17521         rm -f $file1
17522 }
17523 run_test 187b "Test data version change on volatile file"
17524
17525 test_200() {
17526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17527         remote_mgs_nodsh && skip "remote MGS with nodsh"
17528         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17529
17530         local POOL=${POOL:-cea1}
17531         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17532         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17533         # Pool OST targets
17534         local first_ost=0
17535         local last_ost=$(($OSTCOUNT - 1))
17536         local ost_step=2
17537         local ost_list=$(seq $first_ost $ost_step $last_ost)
17538         local ost_range="$first_ost $last_ost $ost_step"
17539         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17540         local file_dir=$POOL_ROOT/file_tst
17541         local subdir=$test_path/subdir
17542         local rc=0
17543
17544         while : ; do
17545                 # former test_200a test_200b
17546                 pool_add $POOL                          || { rc=$? ; break; }
17547                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17548                 # former test_200c test_200d
17549                 mkdir -p $test_path
17550                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17551                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17552                 mkdir -p $subdir
17553                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17554                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17555                                                         || { rc=$? ; break; }
17556                 # former test_200e test_200f
17557                 local files=$((OSTCOUNT*3))
17558                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17559                                                         || { rc=$? ; break; }
17560                 pool_create_files $POOL $file_dir $files "$ost_list" \
17561                                                         || { rc=$? ; break; }
17562                 # former test_200g test_200h
17563                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17564                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17565
17566                 # former test_201a test_201b test_201c
17567                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17568
17569                 local f=$test_path/$tfile
17570                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17571                 pool_remove $POOL $f                    || { rc=$? ; break; }
17572                 break
17573         done
17574
17575         destroy_test_pools
17576
17577         return $rc
17578 }
17579 run_test 200 "OST pools"
17580
17581 # usage: default_attr <count | size | offset>
17582 default_attr() {
17583         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17584 }
17585
17586 # usage: check_default_stripe_attr
17587 check_default_stripe_attr() {
17588         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17589         case $1 in
17590         --stripe-count|-c)
17591                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17592         --stripe-size|-S)
17593                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17594         --stripe-index|-i)
17595                 EXPECTED=-1;;
17596         *)
17597                 error "unknown getstripe attr '$1'"
17598         esac
17599
17600         [ $ACTUAL == $EXPECTED ] ||
17601                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17602 }
17603
17604 test_204a() {
17605         test_mkdir $DIR/$tdir
17606         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17607
17608         check_default_stripe_attr --stripe-count
17609         check_default_stripe_attr --stripe-size
17610         check_default_stripe_attr --stripe-index
17611 }
17612 run_test 204a "Print default stripe attributes"
17613
17614 test_204b() {
17615         test_mkdir $DIR/$tdir
17616         $LFS setstripe --stripe-count 1 $DIR/$tdir
17617
17618         check_default_stripe_attr --stripe-size
17619         check_default_stripe_attr --stripe-index
17620 }
17621 run_test 204b "Print default stripe size and offset"
17622
17623 test_204c() {
17624         test_mkdir $DIR/$tdir
17625         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17626
17627         check_default_stripe_attr --stripe-count
17628         check_default_stripe_attr --stripe-index
17629 }
17630 run_test 204c "Print default stripe count and offset"
17631
17632 test_204d() {
17633         test_mkdir $DIR/$tdir
17634         $LFS setstripe --stripe-index 0 $DIR/$tdir
17635
17636         check_default_stripe_attr --stripe-count
17637         check_default_stripe_attr --stripe-size
17638 }
17639 run_test 204d "Print default stripe count and size"
17640
17641 test_204e() {
17642         test_mkdir $DIR/$tdir
17643         $LFS setstripe -d $DIR/$tdir
17644
17645         check_default_stripe_attr --stripe-count --raw
17646         check_default_stripe_attr --stripe-size --raw
17647         check_default_stripe_attr --stripe-index --raw
17648 }
17649 run_test 204e "Print raw stripe attributes"
17650
17651 test_204f() {
17652         test_mkdir $DIR/$tdir
17653         $LFS setstripe --stripe-count 1 $DIR/$tdir
17654
17655         check_default_stripe_attr --stripe-size --raw
17656         check_default_stripe_attr --stripe-index --raw
17657 }
17658 run_test 204f "Print raw stripe size and offset"
17659
17660 test_204g() {
17661         test_mkdir $DIR/$tdir
17662         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17663
17664         check_default_stripe_attr --stripe-count --raw
17665         check_default_stripe_attr --stripe-index --raw
17666 }
17667 run_test 204g "Print raw stripe count and offset"
17668
17669 test_204h() {
17670         test_mkdir $DIR/$tdir
17671         $LFS setstripe --stripe-index 0 $DIR/$tdir
17672
17673         check_default_stripe_attr --stripe-count --raw
17674         check_default_stripe_attr --stripe-size --raw
17675 }
17676 run_test 204h "Print raw stripe count and size"
17677
17678 # Figure out which job scheduler is being used, if any,
17679 # or use a fake one
17680 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17681         JOBENV=SLURM_JOB_ID
17682 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17683         JOBENV=LSB_JOBID
17684 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17685         JOBENV=PBS_JOBID
17686 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17687         JOBENV=LOADL_STEP_ID
17688 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17689         JOBENV=JOB_ID
17690 else
17691         $LCTL list_param jobid_name > /dev/null 2>&1
17692         if [ $? -eq 0 ]; then
17693                 JOBENV=nodelocal
17694         else
17695                 JOBENV=FAKE_JOBID
17696         fi
17697 fi
17698 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17699
17700 verify_jobstats() {
17701         local cmd=($1)
17702         shift
17703         local facets="$@"
17704
17705 # we don't really need to clear the stats for this test to work, since each
17706 # command has a unique jobid, but it makes debugging easier if needed.
17707 #       for facet in $facets; do
17708 #               local dev=$(convert_facet2label $facet)
17709 #               # clear old jobstats
17710 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17711 #       done
17712
17713         # use a new JobID for each test, or we might see an old one
17714         [ "$JOBENV" = "FAKE_JOBID" ] &&
17715                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17716
17717         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17718
17719         [ "$JOBENV" = "nodelocal" ] && {
17720                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17721                 $LCTL set_param jobid_name=$FAKE_JOBID
17722                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17723         }
17724
17725         log "Test: ${cmd[*]}"
17726         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17727
17728         if [ $JOBENV = "FAKE_JOBID" ]; then
17729                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17730         else
17731                 ${cmd[*]}
17732         fi
17733
17734         # all files are created on OST0000
17735         for facet in $facets; do
17736                 local stats="*.$(convert_facet2label $facet).job_stats"
17737
17738                 # strip out libtool wrappers for in-tree executables
17739                 if [ $(do_facet $facet lctl get_param $stats |
17740                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17741                         do_facet $facet lctl get_param $stats
17742                         error "No jobstats for $JOBVAL found on $facet::$stats"
17743                 fi
17744         done
17745 }
17746
17747 jobstats_set() {
17748         local new_jobenv=$1
17749
17750         set_persistent_param_and_check client "jobid_var" \
17751                 "$FSNAME.sys.jobid_var" $new_jobenv
17752 }
17753
17754 test_205a() { # Job stats
17755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17756         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17757                 skip "Need MDS version with at least 2.7.1"
17758         remote_mgs_nodsh && skip "remote MGS with nodsh"
17759         remote_mds_nodsh && skip "remote MDS with nodsh"
17760         remote_ost_nodsh && skip "remote OST with nodsh"
17761         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17762                 skip "Server doesn't support jobstats"
17763         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17764
17765         local old_jobenv=$($LCTL get_param -n jobid_var)
17766         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17767
17768         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17769                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17770         else
17771                 stack_trap "do_facet mgs $PERM_CMD \
17772                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17773         fi
17774         changelog_register
17775
17776         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17777                                 mdt.*.job_cleanup_interval | head -n 1)
17778         local new_interval=5
17779         do_facet $SINGLEMDS \
17780                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17781         stack_trap "do_facet $SINGLEMDS \
17782                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17783         local start=$SECONDS
17784
17785         local cmd
17786         # mkdir
17787         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17788         verify_jobstats "$cmd" "$SINGLEMDS"
17789         # rmdir
17790         cmd="rmdir $DIR/$tdir"
17791         verify_jobstats "$cmd" "$SINGLEMDS"
17792         # mkdir on secondary MDT
17793         if [ $MDSCOUNT -gt 1 ]; then
17794                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17795                 verify_jobstats "$cmd" "mds2"
17796         fi
17797         # mknod
17798         cmd="mknod $DIR/$tfile c 1 3"
17799         verify_jobstats "$cmd" "$SINGLEMDS"
17800         # unlink
17801         cmd="rm -f $DIR/$tfile"
17802         verify_jobstats "$cmd" "$SINGLEMDS"
17803         # create all files on OST0000 so verify_jobstats can find OST stats
17804         # open & close
17805         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17806         verify_jobstats "$cmd" "$SINGLEMDS"
17807         # setattr
17808         cmd="touch $DIR/$tfile"
17809         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17810         # write
17811         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17812         verify_jobstats "$cmd" "ost1"
17813         # read
17814         cancel_lru_locks osc
17815         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17816         verify_jobstats "$cmd" "ost1"
17817         # truncate
17818         cmd="$TRUNCATE $DIR/$tfile 0"
17819         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17820         # rename
17821         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17822         verify_jobstats "$cmd" "$SINGLEMDS"
17823         # jobstats expiry - sleep until old stats should be expired
17824         local left=$((new_interval + 5 - (SECONDS - start)))
17825         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17826                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17827                         "0" $left
17828         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17829         verify_jobstats "$cmd" "$SINGLEMDS"
17830         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17831             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17832
17833         # Ensure that jobid are present in changelog (if supported by MDS)
17834         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17835                 changelog_dump | tail -10
17836                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17837                 [ $jobids -eq 9 ] ||
17838                         error "Wrong changelog jobid count $jobids != 9"
17839
17840                 # LU-5862
17841                 JOBENV="disable"
17842                 jobstats_set $JOBENV
17843                 touch $DIR/$tfile
17844                 changelog_dump | grep $tfile
17845                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17846                 [ $jobids -eq 0 ] ||
17847                         error "Unexpected jobids when jobid_var=$JOBENV"
17848         fi
17849
17850         # test '%j' access to environment variable - if supported
17851         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17852                 JOBENV="JOBCOMPLEX"
17853                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17854
17855                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17856         fi
17857
17858         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17859                 JOBENV="JOBCOMPLEX"
17860                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17861
17862                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17863         fi
17864
17865         # test '%j' access to per-session jobid - if supported
17866         if lctl list_param jobid_this_session > /dev/null 2>&1
17867         then
17868                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17869                 lctl set_param jobid_this_session=$USER
17870
17871                 JOBENV="JOBCOMPLEX"
17872                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17873
17874                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17875         fi
17876 }
17877 run_test 205a "Verify job stats"
17878
17879 # LU-13117, LU-13597
17880 test_205b() {
17881         job_stats="mdt.*.job_stats"
17882         $LCTL set_param $job_stats=clear
17883         # Setting jobid_var to USER might not be supported
17884         $LCTL set_param jobid_var=USER || true
17885         $LCTL set_param jobid_name="%e.%u"
17886         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17887         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17888                 grep "job_id:.*foolish" &&
17889                         error "Unexpected jobid found"
17890         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17891                 grep "open:.*min.*max.*sum" ||
17892                         error "wrong job_stats format found"
17893 }
17894 run_test 205b "Verify job stats jobid and output format"
17895
17896 # LU-13733
17897 test_205c() {
17898         $LCTL set_param llite.*.stats=0
17899         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17900         $LCTL get_param llite.*.stats
17901         $LCTL get_param llite.*.stats | grep \
17902                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17903                         error "wrong client stats format found"
17904 }
17905 run_test 205c "Verify client stats format"
17906
17907 # LU-1480, LU-1773 and LU-1657
17908 test_206() {
17909         mkdir -p $DIR/$tdir
17910         $LFS setstripe -c -1 $DIR/$tdir
17911 #define OBD_FAIL_LOV_INIT 0x1403
17912         $LCTL set_param fail_loc=0xa0001403
17913         $LCTL set_param fail_val=1
17914         touch $DIR/$tdir/$tfile || true
17915 }
17916 run_test 206 "fail lov_init_raid0() doesn't lbug"
17917
17918 test_207a() {
17919         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17920         local fsz=`stat -c %s $DIR/$tfile`
17921         cancel_lru_locks mdc
17922
17923         # do not return layout in getattr intent
17924 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17925         $LCTL set_param fail_loc=0x170
17926         local sz=`stat -c %s $DIR/$tfile`
17927
17928         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17929
17930         rm -rf $DIR/$tfile
17931 }
17932 run_test 207a "can refresh layout at glimpse"
17933
17934 test_207b() {
17935         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17936         local cksum=`md5sum $DIR/$tfile`
17937         local fsz=`stat -c %s $DIR/$tfile`
17938         cancel_lru_locks mdc
17939         cancel_lru_locks osc
17940
17941         # do not return layout in getattr intent
17942 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17943         $LCTL set_param fail_loc=0x171
17944
17945         # it will refresh layout after the file is opened but before read issues
17946         echo checksum is "$cksum"
17947         echo "$cksum" |md5sum -c --quiet || error "file differs"
17948
17949         rm -rf $DIR/$tfile
17950 }
17951 run_test 207b "can refresh layout at open"
17952
17953 test_208() {
17954         # FIXME: in this test suite, only RD lease is used. This is okay
17955         # for now as only exclusive open is supported. After generic lease
17956         # is done, this test suite should be revised. - Jinshan
17957
17958         remote_mds_nodsh && skip "remote MDS with nodsh"
17959         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17960                 skip "Need MDS version at least 2.4.52"
17961
17962         echo "==== test 1: verify get lease work"
17963         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17964
17965         echo "==== test 2: verify lease can be broken by upcoming open"
17966         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17967         local PID=$!
17968         sleep 1
17969
17970         $MULTIOP $DIR/$tfile oO_RDONLY:c
17971         kill -USR1 $PID && wait $PID || error "break lease error"
17972
17973         echo "==== test 3: verify lease can't be granted if an open already exists"
17974         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17975         local PID=$!
17976         sleep 1
17977
17978         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17979         kill -USR1 $PID && wait $PID || error "open file error"
17980
17981         echo "==== test 4: lease can sustain over recovery"
17982         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17983         PID=$!
17984         sleep 1
17985
17986         fail mds1
17987
17988         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17989
17990         echo "==== test 5: lease broken can't be regained by replay"
17991         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17992         PID=$!
17993         sleep 1
17994
17995         # open file to break lease and then recovery
17996         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17997         fail mds1
17998
17999         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18000
18001         rm -f $DIR/$tfile
18002 }
18003 run_test 208 "Exclusive open"
18004
18005 test_209() {
18006         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18007                 skip_env "must have disp_stripe"
18008
18009         touch $DIR/$tfile
18010         sync; sleep 5; sync;
18011
18012         echo 3 > /proc/sys/vm/drop_caches
18013         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18014                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18015         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18016
18017         # open/close 500 times
18018         for i in $(seq 500); do
18019                 cat $DIR/$tfile
18020         done
18021
18022         echo 3 > /proc/sys/vm/drop_caches
18023         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18024                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18025         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18026
18027         echo "before: $req_before, after: $req_after"
18028         [ $((req_after - req_before)) -ge 300 ] &&
18029                 error "open/close requests are not freed"
18030         return 0
18031 }
18032 run_test 209 "read-only open/close requests should be freed promptly"
18033
18034 test_210() {
18035         local pid
18036
18037         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18038         pid=$!
18039         sleep 1
18040
18041         $LFS getstripe $DIR/$tfile
18042         kill -USR1 $pid
18043         wait $pid || error "multiop failed"
18044
18045         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18046         pid=$!
18047         sleep 1
18048
18049         $LFS getstripe $DIR/$tfile
18050         kill -USR1 $pid
18051         wait $pid || error "multiop failed"
18052 }
18053 run_test 210 "lfs getstripe does not break leases"
18054
18055 test_212() {
18056         size=`date +%s`
18057         size=$((size % 8192 + 1))
18058         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18059         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18060         rm -f $DIR/f212 $DIR/f212.xyz
18061 }
18062 run_test 212 "Sendfile test ============================================"
18063
18064 test_213() {
18065         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18066         cancel_lru_locks osc
18067         lctl set_param fail_loc=0x8000040f
18068         # generate a read lock
18069         cat $DIR/$tfile > /dev/null
18070         # write to the file, it will try to cancel the above read lock.
18071         cat /etc/hosts >> $DIR/$tfile
18072 }
18073 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18074
18075 test_214() { # for bug 20133
18076         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18077         for (( i=0; i < 340; i++ )) ; do
18078                 touch $DIR/$tdir/d214c/a$i
18079         done
18080
18081         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18082         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18083         ls $DIR/d214c || error "ls $DIR/d214c failed"
18084         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18085         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18086 }
18087 run_test 214 "hash-indexed directory test - bug 20133"
18088
18089 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18090 create_lnet_proc_files() {
18091         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18092 }
18093
18094 # counterpart of create_lnet_proc_files
18095 remove_lnet_proc_files() {
18096         rm -f $TMP/lnet_$1.sys
18097 }
18098
18099 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18100 # 3rd arg as regexp for body
18101 check_lnet_proc_stats() {
18102         local l=$(cat "$TMP/lnet_$1" |wc -l)
18103         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18104
18105         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18106 }
18107
18108 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18109 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18110 # optional and can be regexp for 2nd line (lnet.routes case)
18111 check_lnet_proc_entry() {
18112         local blp=2          # blp stands for 'position of 1st line of body'
18113         [ -z "$5" ] || blp=3 # lnet.routes case
18114
18115         local l=$(cat "$TMP/lnet_$1" |wc -l)
18116         # subtracting one from $blp because the body can be empty
18117         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18118
18119         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18120                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18121
18122         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18123                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18124
18125         # bail out if any unexpected line happened
18126         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18127         [ "$?" != 0 ] || error "$2 misformatted"
18128 }
18129
18130 test_215() { # for bugs 18102, 21079, 21517
18131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18132
18133         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18134         local P='[1-9][0-9]*'           # positive numeric
18135         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18136         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18137         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18138         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18139
18140         local L1 # regexp for 1st line
18141         local L2 # regexp for 2nd line (optional)
18142         local BR # regexp for the rest (body)
18143
18144         # lnet.stats should look as 11 space-separated non-negative numerics
18145         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18146         create_lnet_proc_files "stats"
18147         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18148         remove_lnet_proc_files "stats"
18149
18150         # lnet.routes should look like this:
18151         # Routing disabled/enabled
18152         # net hops priority state router
18153         # where net is a string like tcp0, hops > 0, priority >= 0,
18154         # state is up/down,
18155         # router is a string like 192.168.1.1@tcp2
18156         L1="^Routing (disabled|enabled)$"
18157         L2="^net +hops +priority +state +router$"
18158         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18159         create_lnet_proc_files "routes"
18160         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18161         remove_lnet_proc_files "routes"
18162
18163         # lnet.routers should look like this:
18164         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18165         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18166         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18167         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18168         L1="^ref +rtr_ref +alive +router$"
18169         BR="^$P +$P +(up|down) +$NID$"
18170         create_lnet_proc_files "routers"
18171         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18172         remove_lnet_proc_files "routers"
18173
18174         # lnet.peers should look like this:
18175         # nid refs state last max rtr min tx min queue
18176         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18177         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18178         # numeric (0 or >0 or <0), queue >= 0.
18179         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18180         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18181         create_lnet_proc_files "peers"
18182         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18183         remove_lnet_proc_files "peers"
18184
18185         # lnet.buffers  should look like this:
18186         # pages count credits min
18187         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18188         L1="^pages +count +credits +min$"
18189         BR="^ +$N +$N +$I +$I$"
18190         create_lnet_proc_files "buffers"
18191         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18192         remove_lnet_proc_files "buffers"
18193
18194         # lnet.nis should look like this:
18195         # nid status alive refs peer rtr max tx min
18196         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18197         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18198         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18199         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18200         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18201         create_lnet_proc_files "nis"
18202         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18203         remove_lnet_proc_files "nis"
18204
18205         # can we successfully write to lnet.stats?
18206         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18207 }
18208 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18209
18210 test_216() { # bug 20317
18211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18212         remote_ost_nodsh && skip "remote OST with nodsh"
18213
18214         local node
18215         local facets=$(get_facets OST)
18216         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18217
18218         save_lustre_params client "osc.*.contention_seconds" > $p
18219         save_lustre_params $facets \
18220                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18221         save_lustre_params $facets \
18222                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18223         save_lustre_params $facets \
18224                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18225         clear_stats osc.*.osc_stats
18226
18227         # agressive lockless i/o settings
18228         do_nodes $(comma_list $(osts_nodes)) \
18229                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18230                         ldlm.namespaces.filter-*.contended_locks=0 \
18231                         ldlm.namespaces.filter-*.contention_seconds=60"
18232         lctl set_param -n osc.*.contention_seconds=60
18233
18234         $DIRECTIO write $DIR/$tfile 0 10 4096
18235         $CHECKSTAT -s 40960 $DIR/$tfile
18236
18237         # disable lockless i/o
18238         do_nodes $(comma_list $(osts_nodes)) \
18239                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18240                         ldlm.namespaces.filter-*.contended_locks=32 \
18241                         ldlm.namespaces.filter-*.contention_seconds=0"
18242         lctl set_param -n osc.*.contention_seconds=0
18243         clear_stats osc.*.osc_stats
18244
18245         dd if=/dev/zero of=$DIR/$tfile count=0
18246         $CHECKSTAT -s 0 $DIR/$tfile
18247
18248         restore_lustre_params <$p
18249         rm -f $p
18250         rm $DIR/$tfile
18251 }
18252 run_test 216 "check lockless direct write updates file size and kms correctly"
18253
18254 test_217() { # bug 22430
18255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18256
18257         local node
18258         local nid
18259
18260         for node in $(nodes_list); do
18261                 nid=$(host_nids_address $node $NETTYPE)
18262                 if [[ $nid = *-* ]] ; then
18263                         echo "lctl ping $(h2nettype $nid)"
18264                         lctl ping $(h2nettype $nid)
18265                 else
18266                         echo "skipping $node (no hyphen detected)"
18267                 fi
18268         done
18269 }
18270 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18271
18272 test_218() {
18273        # do directio so as not to populate the page cache
18274        log "creating a 10 Mb file"
18275        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18276        log "starting reads"
18277        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18278        log "truncating the file"
18279        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18280        log "killing dd"
18281        kill %+ || true # reads might have finished
18282        echo "wait until dd is finished"
18283        wait
18284        log "removing the temporary file"
18285        rm -rf $DIR/$tfile || error "tmp file removal failed"
18286 }
18287 run_test 218 "parallel read and truncate should not deadlock"
18288
18289 test_219() {
18290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18291
18292         # write one partial page
18293         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18294         # set no grant so vvp_io_commit_write will do sync write
18295         $LCTL set_param fail_loc=0x411
18296         # write a full page at the end of file
18297         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18298
18299         $LCTL set_param fail_loc=0
18300         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18301         $LCTL set_param fail_loc=0x411
18302         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18303
18304         # LU-4201
18305         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18306         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18307 }
18308 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18309
18310 test_220() { #LU-325
18311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18312         remote_ost_nodsh && skip "remote OST with nodsh"
18313         remote_mds_nodsh && skip "remote MDS with nodsh"
18314         remote_mgs_nodsh && skip "remote MGS with nodsh"
18315
18316         local OSTIDX=0
18317
18318         # create on MDT0000 so the last_id and next_id are correct
18319         mkdir_on_mdt0 $DIR/$tdir
18320         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18321         OST=${OST%_UUID}
18322
18323         # on the mdt's osc
18324         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18325         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18326                         osp.$mdtosc_proc1.prealloc_last_id)
18327         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18328                         osp.$mdtosc_proc1.prealloc_next_id)
18329
18330         $LFS df -i
18331
18332         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18333         #define OBD_FAIL_OST_ENOINO              0x229
18334         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18335         create_pool $FSNAME.$TESTNAME || return 1
18336         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18337
18338         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18339
18340         MDSOBJS=$((last_id - next_id))
18341         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18342
18343         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18344         echo "OST still has $count kbytes free"
18345
18346         echo "create $MDSOBJS files @next_id..."
18347         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18348
18349         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18350                         osp.$mdtosc_proc1.prealloc_last_id)
18351         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18352                         osp.$mdtosc_proc1.prealloc_next_id)
18353
18354         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18355         $LFS df -i
18356
18357         echo "cleanup..."
18358
18359         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18360         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18361
18362         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18363                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18364         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18365                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18366         echo "unlink $MDSOBJS files @$next_id..."
18367         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18368 }
18369 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18370
18371 test_221() {
18372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18373
18374         dd if=`which date` of=$MOUNT/date oflag=sync
18375         chmod +x $MOUNT/date
18376
18377         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18378         $LCTL set_param fail_loc=0x80001401
18379
18380         $MOUNT/date > /dev/null
18381         rm -f $MOUNT/date
18382 }
18383 run_test 221 "make sure fault and truncate race to not cause OOM"
18384
18385 test_222a () {
18386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18387
18388         rm -rf $DIR/$tdir
18389         test_mkdir $DIR/$tdir
18390         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18391         createmany -o $DIR/$tdir/$tfile 10
18392         cancel_lru_locks mdc
18393         cancel_lru_locks osc
18394         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18395         $LCTL set_param fail_loc=0x31a
18396         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18397         $LCTL set_param fail_loc=0
18398         rm -r $DIR/$tdir
18399 }
18400 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18401
18402 test_222b () {
18403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18404
18405         rm -rf $DIR/$tdir
18406         test_mkdir $DIR/$tdir
18407         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18408         createmany -o $DIR/$tdir/$tfile 10
18409         cancel_lru_locks mdc
18410         cancel_lru_locks osc
18411         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18412         $LCTL set_param fail_loc=0x31a
18413         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18414         $LCTL set_param fail_loc=0
18415 }
18416 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18417
18418 test_223 () {
18419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18420
18421         rm -rf $DIR/$tdir
18422         test_mkdir $DIR/$tdir
18423         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18424         createmany -o $DIR/$tdir/$tfile 10
18425         cancel_lru_locks mdc
18426         cancel_lru_locks osc
18427         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18428         $LCTL set_param fail_loc=0x31b
18429         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18430         $LCTL set_param fail_loc=0
18431         rm -r $DIR/$tdir
18432 }
18433 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18434
18435 test_224a() { # LU-1039, MRP-303
18436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18437
18438         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18439         $LCTL set_param fail_loc=0x508
18440         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18441         $LCTL set_param fail_loc=0
18442         df $DIR
18443 }
18444 run_test 224a "Don't panic on bulk IO failure"
18445
18446 test_224b() { # LU-1039, MRP-303
18447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18448
18449         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18450         cancel_lru_locks osc
18451         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18452         $LCTL set_param fail_loc=0x515
18453         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18454         $LCTL set_param fail_loc=0
18455         df $DIR
18456 }
18457 run_test 224b "Don't panic on bulk IO failure"
18458
18459 test_224c() { # LU-6441
18460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18461         remote_mds_nodsh && skip "remote MDS with nodsh"
18462
18463         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18464         save_writethrough $p
18465         set_cache writethrough on
18466
18467         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18468         local at_max=$($LCTL get_param -n at_max)
18469         local timeout=$($LCTL get_param -n timeout)
18470         local test_at="at_max"
18471         local param_at="$FSNAME.sys.at_max"
18472         local test_timeout="timeout"
18473         local param_timeout="$FSNAME.sys.timeout"
18474
18475         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18476
18477         set_persistent_param_and_check client "$test_at" "$param_at" 0
18478         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18479
18480         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18481         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18482         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18483         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18484         sync
18485         do_facet ost1 "$LCTL set_param fail_loc=0"
18486
18487         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18488         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18489                 $timeout
18490
18491         $LCTL set_param -n $pages_per_rpc
18492         restore_lustre_params < $p
18493         rm -f $p
18494 }
18495 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18496
18497 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18498 test_225a () {
18499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18500         if [ -z ${MDSSURVEY} ]; then
18501                 skip_env "mds-survey not found"
18502         fi
18503         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18504                 skip "Need MDS version at least 2.2.51"
18505
18506         local mds=$(facet_host $SINGLEMDS)
18507         local target=$(do_nodes $mds 'lctl dl' |
18508                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18509
18510         local cmd1="file_count=1000 thrhi=4"
18511         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18512         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18513         local cmd="$cmd1 $cmd2 $cmd3"
18514
18515         rm -f ${TMP}/mds_survey*
18516         echo + $cmd
18517         eval $cmd || error "mds-survey with zero-stripe failed"
18518         cat ${TMP}/mds_survey*
18519         rm -f ${TMP}/mds_survey*
18520 }
18521 run_test 225a "Metadata survey sanity with zero-stripe"
18522
18523 test_225b () {
18524         if [ -z ${MDSSURVEY} ]; then
18525                 skip_env "mds-survey not found"
18526         fi
18527         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18528                 skip "Need MDS version at least 2.2.51"
18529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18530         remote_mds_nodsh && skip "remote MDS with nodsh"
18531         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18532                 skip_env "Need to mount OST to test"
18533         fi
18534
18535         local mds=$(facet_host $SINGLEMDS)
18536         local target=$(do_nodes $mds 'lctl dl' |
18537                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18538
18539         local cmd1="file_count=1000 thrhi=4"
18540         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18541         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18542         local cmd="$cmd1 $cmd2 $cmd3"
18543
18544         rm -f ${TMP}/mds_survey*
18545         echo + $cmd
18546         eval $cmd || error "mds-survey with stripe_count failed"
18547         cat ${TMP}/mds_survey*
18548         rm -f ${TMP}/mds_survey*
18549 }
18550 run_test 225b "Metadata survey sanity with stripe_count = 1"
18551
18552 mcreate_path2fid () {
18553         local mode=$1
18554         local major=$2
18555         local minor=$3
18556         local name=$4
18557         local desc=$5
18558         local path=$DIR/$tdir/$name
18559         local fid
18560         local rc
18561         local fid_path
18562
18563         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18564                 error "cannot create $desc"
18565
18566         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18567         rc=$?
18568         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18569
18570         fid_path=$($LFS fid2path $MOUNT $fid)
18571         rc=$?
18572         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18573
18574         [ "$path" == "$fid_path" ] ||
18575                 error "fid2path returned $fid_path, expected $path"
18576
18577         echo "pass with $path and $fid"
18578 }
18579
18580 test_226a () {
18581         rm -rf $DIR/$tdir
18582         mkdir -p $DIR/$tdir
18583
18584         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18585         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18586         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18587         mcreate_path2fid 0040666 0 0 dir "directory"
18588         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18589         mcreate_path2fid 0100666 0 0 file "regular file"
18590         mcreate_path2fid 0120666 0 0 link "symbolic link"
18591         mcreate_path2fid 0140666 0 0 sock "socket"
18592 }
18593 run_test 226a "call path2fid and fid2path on files of all type"
18594
18595 test_226b () {
18596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18597
18598         local MDTIDX=1
18599
18600         rm -rf $DIR/$tdir
18601         mkdir -p $DIR/$tdir
18602         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18603                 error "create remote directory failed"
18604         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18605         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18606                                 "character special file (null)"
18607         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18608                                 "character special file (no device)"
18609         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18610         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18611                                 "block special file (loop)"
18612         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18613         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18614         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18615 }
18616 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18617
18618 test_226c () {
18619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18620         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18621                 skip "Need MDS version at least 2.13.55"
18622
18623         local submnt=/mnt/submnt
18624         local srcfile=/etc/passwd
18625         local dstfile=$submnt/passwd
18626         local path
18627         local fid
18628
18629         rm -rf $DIR/$tdir
18630         rm -rf $submnt
18631         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18632                 error "create remote directory failed"
18633         mkdir -p $submnt || error "create $submnt failed"
18634         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18635                 error "mount $submnt failed"
18636         stack_trap "umount $submnt" EXIT
18637
18638         cp $srcfile $dstfile
18639         fid=$($LFS path2fid $dstfile)
18640         path=$($LFS fid2path $submnt "$fid")
18641         [ "$path" = "$dstfile" ] ||
18642                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18643 }
18644 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18645
18646 # LU-1299 Executing or running ldd on a truncated executable does not
18647 # cause an out-of-memory condition.
18648 test_227() {
18649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18650         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18651
18652         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18653         chmod +x $MOUNT/date
18654
18655         $MOUNT/date > /dev/null
18656         ldd $MOUNT/date > /dev/null
18657         rm -f $MOUNT/date
18658 }
18659 run_test 227 "running truncated executable does not cause OOM"
18660
18661 # LU-1512 try to reuse idle OI blocks
18662 test_228a() {
18663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18664         remote_mds_nodsh && skip "remote MDS with nodsh"
18665         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18666
18667         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18668         local myDIR=$DIR/$tdir
18669
18670         mkdir -p $myDIR
18671         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18672         $LCTL set_param fail_loc=0x80001002
18673         createmany -o $myDIR/t- 10000
18674         $LCTL set_param fail_loc=0
18675         # The guard is current the largest FID holder
18676         touch $myDIR/guard
18677         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18678                     tr -d '[')
18679         local IDX=$(($SEQ % 64))
18680
18681         do_facet $SINGLEMDS sync
18682         # Make sure journal flushed.
18683         sleep 6
18684         local blk1=$(do_facet $SINGLEMDS \
18685                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18686                      grep Blockcount | awk '{print $4}')
18687
18688         # Remove old files, some OI blocks will become idle.
18689         unlinkmany $myDIR/t- 10000
18690         # Create new files, idle OI blocks should be reused.
18691         createmany -o $myDIR/t- 2000
18692         do_facet $SINGLEMDS sync
18693         # Make sure journal flushed.
18694         sleep 6
18695         local blk2=$(do_facet $SINGLEMDS \
18696                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18697                      grep Blockcount | awk '{print $4}')
18698
18699         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18700 }
18701 run_test 228a "try to reuse idle OI blocks"
18702
18703 test_228b() {
18704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18705         remote_mds_nodsh && skip "remote MDS with nodsh"
18706         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18707
18708         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18709         local myDIR=$DIR/$tdir
18710
18711         mkdir -p $myDIR
18712         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18713         $LCTL set_param fail_loc=0x80001002
18714         createmany -o $myDIR/t- 10000
18715         $LCTL set_param fail_loc=0
18716         # The guard is current the largest FID holder
18717         touch $myDIR/guard
18718         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18719                     tr -d '[')
18720         local IDX=$(($SEQ % 64))
18721
18722         do_facet $SINGLEMDS sync
18723         # Make sure journal flushed.
18724         sleep 6
18725         local blk1=$(do_facet $SINGLEMDS \
18726                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18727                      grep Blockcount | awk '{print $4}')
18728
18729         # Remove old files, some OI blocks will become idle.
18730         unlinkmany $myDIR/t- 10000
18731
18732         # stop the MDT
18733         stop $SINGLEMDS || error "Fail to stop MDT."
18734         # remount the MDT
18735         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18736
18737         df $MOUNT || error "Fail to df."
18738         # Create new files, idle OI blocks should be reused.
18739         createmany -o $myDIR/t- 2000
18740         do_facet $SINGLEMDS sync
18741         # Make sure journal flushed.
18742         sleep 6
18743         local blk2=$(do_facet $SINGLEMDS \
18744                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18745                      grep Blockcount | awk '{print $4}')
18746
18747         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18748 }
18749 run_test 228b "idle OI blocks can be reused after MDT restart"
18750
18751 #LU-1881
18752 test_228c() {
18753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18754         remote_mds_nodsh && skip "remote MDS with nodsh"
18755         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18756
18757         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18758         local myDIR=$DIR/$tdir
18759
18760         mkdir -p $myDIR
18761         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18762         $LCTL set_param fail_loc=0x80001002
18763         # 20000 files can guarantee there are index nodes in the OI file
18764         createmany -o $myDIR/t- 20000
18765         $LCTL set_param fail_loc=0
18766         # The guard is current the largest FID holder
18767         touch $myDIR/guard
18768         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18769                     tr -d '[')
18770         local IDX=$(($SEQ % 64))
18771
18772         do_facet $SINGLEMDS sync
18773         # Make sure journal flushed.
18774         sleep 6
18775         local blk1=$(do_facet $SINGLEMDS \
18776                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18777                      grep Blockcount | awk '{print $4}')
18778
18779         # Remove old files, some OI blocks will become idle.
18780         unlinkmany $myDIR/t- 20000
18781         rm -f $myDIR/guard
18782         # The OI file should become empty now
18783
18784         # Create new files, idle OI blocks should be reused.
18785         createmany -o $myDIR/t- 2000
18786         do_facet $SINGLEMDS sync
18787         # Make sure journal flushed.
18788         sleep 6
18789         local blk2=$(do_facet $SINGLEMDS \
18790                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18791                      grep Blockcount | awk '{print $4}')
18792
18793         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18794 }
18795 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18796
18797 test_229() { # LU-2482, LU-3448
18798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18799         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18800         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18801                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18802
18803         rm -f $DIR/$tfile
18804
18805         # Create a file with a released layout and stripe count 2.
18806         $MULTIOP $DIR/$tfile H2c ||
18807                 error "failed to create file with released layout"
18808
18809         $LFS getstripe -v $DIR/$tfile
18810
18811         local pattern=$($LFS getstripe -L $DIR/$tfile)
18812         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18813
18814         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18815                 error "getstripe"
18816         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18817         stat $DIR/$tfile || error "failed to stat released file"
18818
18819         chown $RUNAS_ID $DIR/$tfile ||
18820                 error "chown $RUNAS_ID $DIR/$tfile failed"
18821
18822         chgrp $RUNAS_ID $DIR/$tfile ||
18823                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18824
18825         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18826         rm $DIR/$tfile || error "failed to remove released file"
18827 }
18828 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18829
18830 test_230a() {
18831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18833         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18834                 skip "Need MDS version at least 2.11.52"
18835
18836         local MDTIDX=1
18837
18838         test_mkdir $DIR/$tdir
18839         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18840         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18841         [ $mdt_idx -ne 0 ] &&
18842                 error "create local directory on wrong MDT $mdt_idx"
18843
18844         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18845                         error "create remote directory failed"
18846         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18847         [ $mdt_idx -ne $MDTIDX ] &&
18848                 error "create remote directory on wrong MDT $mdt_idx"
18849
18850         createmany -o $DIR/$tdir/test_230/t- 10 ||
18851                 error "create files on remote directory failed"
18852         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18853         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18854         rm -r $DIR/$tdir || error "unlink remote directory failed"
18855 }
18856 run_test 230a "Create remote directory and files under the remote directory"
18857
18858 test_230b() {
18859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18862                 skip "Need MDS version at least 2.11.52"
18863
18864         local MDTIDX=1
18865         local mdt_index
18866         local i
18867         local file
18868         local pid
18869         local stripe_count
18870         local migrate_dir=$DIR/$tdir/migrate_dir
18871         local other_dir=$DIR/$tdir/other_dir
18872
18873         test_mkdir $DIR/$tdir
18874         test_mkdir -i0 -c1 $migrate_dir
18875         test_mkdir -i0 -c1 $other_dir
18876         for ((i=0; i<10; i++)); do
18877                 mkdir -p $migrate_dir/dir_${i}
18878                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18879                         error "create files under remote dir failed $i"
18880         done
18881
18882         cp /etc/passwd $migrate_dir/$tfile
18883         cp /etc/passwd $other_dir/$tfile
18884         chattr +SAD $migrate_dir
18885         chattr +SAD $migrate_dir/$tfile
18886
18887         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18888         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18889         local old_dir_mode=$(stat -c%f $migrate_dir)
18890         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18891
18892         mkdir -p $migrate_dir/dir_default_stripe2
18893         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18894         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18895
18896         mkdir -p $other_dir
18897         ln $migrate_dir/$tfile $other_dir/luna
18898         ln $migrate_dir/$tfile $migrate_dir/sofia
18899         ln $other_dir/$tfile $migrate_dir/david
18900         ln -s $migrate_dir/$tfile $other_dir/zachary
18901         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18902         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18903
18904         local len
18905         local lnktgt
18906
18907         # inline symlink
18908         for len in 58 59 60; do
18909                 lnktgt=$(str_repeat 'l' $len)
18910                 touch $migrate_dir/$lnktgt
18911                 ln -s $lnktgt $migrate_dir/${len}char_ln
18912         done
18913
18914         # PATH_MAX
18915         for len in 4094 4095; do
18916                 lnktgt=$(str_repeat 'l' $len)
18917                 ln -s $lnktgt $migrate_dir/${len}char_ln
18918         done
18919
18920         # NAME_MAX
18921         for len in 254 255; do
18922                 touch $migrate_dir/$(str_repeat 'l' $len)
18923         done
18924
18925         $LFS migrate -m $MDTIDX $migrate_dir ||
18926                 error "fails on migrating remote dir to MDT1"
18927
18928         echo "migratate to MDT1, then checking.."
18929         for ((i = 0; i < 10; i++)); do
18930                 for file in $(find $migrate_dir/dir_${i}); do
18931                         mdt_index=$($LFS getstripe -m $file)
18932                         # broken symlink getstripe will fail
18933                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18934                                 error "$file is not on MDT${MDTIDX}"
18935                 done
18936         done
18937
18938         # the multiple link file should still in MDT0
18939         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18940         [ $mdt_index == 0 ] ||
18941                 error "$file is not on MDT${MDTIDX}"
18942
18943         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18944         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18945                 error " expect $old_dir_flag get $new_dir_flag"
18946
18947         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18948         [ "$old_file_flag" = "$new_file_flag" ] ||
18949                 error " expect $old_file_flag get $new_file_flag"
18950
18951         local new_dir_mode=$(stat -c%f $migrate_dir)
18952         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18953                 error "expect mode $old_dir_mode get $new_dir_mode"
18954
18955         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18956         [ "$old_file_mode" = "$new_file_mode" ] ||
18957                 error "expect mode $old_file_mode get $new_file_mode"
18958
18959         diff /etc/passwd $migrate_dir/$tfile ||
18960                 error "$tfile different after migration"
18961
18962         diff /etc/passwd $other_dir/luna ||
18963                 error "luna different after migration"
18964
18965         diff /etc/passwd $migrate_dir/sofia ||
18966                 error "sofia different after migration"
18967
18968         diff /etc/passwd $migrate_dir/david ||
18969                 error "david different after migration"
18970
18971         diff /etc/passwd $other_dir/zachary ||
18972                 error "zachary different after migration"
18973
18974         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18975                 error "${tfile}_ln different after migration"
18976
18977         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18978                 error "${tfile}_ln_other different after migration"
18979
18980         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18981         [ $stripe_count = 2 ] ||
18982                 error "dir strpe_count $d != 2 after migration."
18983
18984         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18985         [ $stripe_count = 2 ] ||
18986                 error "file strpe_count $d != 2 after migration."
18987
18988         #migrate back to MDT0
18989         MDTIDX=0
18990
18991         $LFS migrate -m $MDTIDX $migrate_dir ||
18992                 error "fails on migrating remote dir to MDT0"
18993
18994         echo "migrate back to MDT0, checking.."
18995         for file in $(find $migrate_dir); do
18996                 mdt_index=$($LFS getstripe -m $file)
18997                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18998                         error "$file is not on MDT${MDTIDX}"
18999         done
19000
19001         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19002         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19003                 error " expect $old_dir_flag get $new_dir_flag"
19004
19005         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19006         [ "$old_file_flag" = "$new_file_flag" ] ||
19007                 error " expect $old_file_flag get $new_file_flag"
19008
19009         local new_dir_mode=$(stat -c%f $migrate_dir)
19010         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19011                 error "expect mode $old_dir_mode get $new_dir_mode"
19012
19013         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19014         [ "$old_file_mode" = "$new_file_mode" ] ||
19015                 error "expect mode $old_file_mode get $new_file_mode"
19016
19017         diff /etc/passwd ${migrate_dir}/$tfile ||
19018                 error "$tfile different after migration"
19019
19020         diff /etc/passwd ${other_dir}/luna ||
19021                 error "luna different after migration"
19022
19023         diff /etc/passwd ${migrate_dir}/sofia ||
19024                 error "sofia different after migration"
19025
19026         diff /etc/passwd ${other_dir}/zachary ||
19027                 error "zachary different after migration"
19028
19029         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19030                 error "${tfile}_ln different after migration"
19031
19032         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19033                 error "${tfile}_ln_other different after migration"
19034
19035         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19036         [ $stripe_count = 2 ] ||
19037                 error "dir strpe_count $d != 2 after migration."
19038
19039         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19040         [ $stripe_count = 2 ] ||
19041                 error "file strpe_count $d != 2 after migration."
19042
19043         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19044 }
19045 run_test 230b "migrate directory"
19046
19047 test_230c() {
19048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19050         remote_mds_nodsh && skip "remote MDS with nodsh"
19051         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19052                 skip "Need MDS version at least 2.11.52"
19053
19054         local MDTIDX=1
19055         local total=3
19056         local mdt_index
19057         local file
19058         local migrate_dir=$DIR/$tdir/migrate_dir
19059
19060         #If migrating directory fails in the middle, all entries of
19061         #the directory is still accessiable.
19062         test_mkdir $DIR/$tdir
19063         test_mkdir -i0 -c1 $migrate_dir
19064         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19065         stat $migrate_dir
19066         createmany -o $migrate_dir/f $total ||
19067                 error "create files under ${migrate_dir} failed"
19068
19069         # fail after migrating top dir, and this will fail only once, so the
19070         # first sub file migration will fail (currently f3), others succeed.
19071         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19072         do_facet mds1 lctl set_param fail_loc=0x1801
19073         local t=$(ls $migrate_dir | wc -l)
19074         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19075                 error "migrate should fail"
19076         local u=$(ls $migrate_dir | wc -l)
19077         [ "$u" == "$t" ] || error "$u != $t during migration"
19078
19079         # add new dir/file should succeed
19080         mkdir $migrate_dir/dir ||
19081                 error "mkdir failed under migrating directory"
19082         touch $migrate_dir/file ||
19083                 error "create file failed under migrating directory"
19084
19085         # add file with existing name should fail
19086         for file in $migrate_dir/f*; do
19087                 stat $file > /dev/null || error "stat $file failed"
19088                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19089                         error "open(O_CREAT|O_EXCL) $file should fail"
19090                 $MULTIOP $file m && error "create $file should fail"
19091                 touch $DIR/$tdir/remote_dir/$tfile ||
19092                         error "touch $tfile failed"
19093                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19094                         error "link $file should fail"
19095                 mdt_index=$($LFS getstripe -m $file)
19096                 if [ $mdt_index == 0 ]; then
19097                         # file failed to migrate is not allowed to rename to
19098                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19099                                 error "rename to $file should fail"
19100                 else
19101                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19102                                 error "rename to $file failed"
19103                 fi
19104                 echo hello >> $file || error "write $file failed"
19105         done
19106
19107         # resume migration with different options should fail
19108         $LFS migrate -m 0 $migrate_dir &&
19109                 error "migrate -m 0 $migrate_dir should fail"
19110
19111         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19112                 error "migrate -c 2 $migrate_dir should fail"
19113
19114         # resume migration should succeed
19115         $LFS migrate -m $MDTIDX $migrate_dir ||
19116                 error "migrate $migrate_dir failed"
19117
19118         echo "Finish migration, then checking.."
19119         for file in $(find $migrate_dir); do
19120                 mdt_index=$($LFS getstripe -m $file)
19121                 [ $mdt_index == $MDTIDX ] ||
19122                         error "$file is not on MDT${MDTIDX}"
19123         done
19124
19125         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19126 }
19127 run_test 230c "check directory accessiblity if migration failed"
19128
19129 test_230d() {
19130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19131         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19132         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19133                 skip "Need MDS version at least 2.11.52"
19134         # LU-11235
19135         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19136
19137         local migrate_dir=$DIR/$tdir/migrate_dir
19138         local old_index
19139         local new_index
19140         local old_count
19141         local new_count
19142         local new_hash
19143         local mdt_index
19144         local i
19145         local j
19146
19147         old_index=$((RANDOM % MDSCOUNT))
19148         old_count=$((MDSCOUNT - old_index))
19149         new_index=$((RANDOM % MDSCOUNT))
19150         new_count=$((MDSCOUNT - new_index))
19151         new_hash=1 # for all_char
19152
19153         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19154         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19155
19156         test_mkdir $DIR/$tdir
19157         test_mkdir -i $old_index -c $old_count $migrate_dir
19158
19159         for ((i=0; i<100; i++)); do
19160                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19161                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19162                         error "create files under remote dir failed $i"
19163         done
19164
19165         echo -n "Migrate from MDT$old_index "
19166         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19167         echo -n "to MDT$new_index"
19168         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19169         echo
19170
19171         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19172         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19173                 error "migrate remote dir error"
19174
19175         echo "Finish migration, then checking.."
19176         for file in $(find $migrate_dir); do
19177                 mdt_index=$($LFS getstripe -m $file)
19178                 if [ $mdt_index -lt $new_index ] ||
19179                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19180                         error "$file is on MDT$mdt_index"
19181                 fi
19182         done
19183
19184         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19185 }
19186 run_test 230d "check migrate big directory"
19187
19188 test_230e() {
19189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19191         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19192                 skip "Need MDS version at least 2.11.52"
19193
19194         local i
19195         local j
19196         local a_fid
19197         local b_fid
19198
19199         mkdir_on_mdt0 $DIR/$tdir
19200         mkdir $DIR/$tdir/migrate_dir
19201         mkdir $DIR/$tdir/other_dir
19202         touch $DIR/$tdir/migrate_dir/a
19203         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19204         ls $DIR/$tdir/other_dir
19205
19206         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19207                 error "migrate dir fails"
19208
19209         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19210         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19211
19212         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19213         [ $mdt_index == 0 ] || error "a is not on MDT0"
19214
19215         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19216                 error "migrate dir fails"
19217
19218         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19219         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19220
19221         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19222         [ $mdt_index == 1 ] || error "a is not on MDT1"
19223
19224         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19225         [ $mdt_index == 1 ] || error "b is not on MDT1"
19226
19227         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19228         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19229
19230         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19231
19232         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19233 }
19234 run_test 230e "migrate mulitple local link files"
19235
19236 test_230f() {
19237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19238         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19239         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19240                 skip "Need MDS version at least 2.11.52"
19241
19242         local a_fid
19243         local ln_fid
19244
19245         mkdir -p $DIR/$tdir
19246         mkdir $DIR/$tdir/migrate_dir
19247         $LFS mkdir -i1 $DIR/$tdir/other_dir
19248         touch $DIR/$tdir/migrate_dir/a
19249         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19250         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19251         ls $DIR/$tdir/other_dir
19252
19253         # a should be migrated to MDT1, since no other links on MDT0
19254         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19255                 error "#1 migrate dir fails"
19256         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19257         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19258         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19259         [ $mdt_index == 1 ] || error "a is not on MDT1"
19260
19261         # a should stay on MDT1, because it is a mulitple link file
19262         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19263                 error "#2 migrate dir fails"
19264         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19265         [ $mdt_index == 1 ] || error "a is not on MDT1"
19266
19267         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19268                 error "#3 migrate dir fails"
19269
19270         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19271         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19272         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19273
19274         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19275         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19276
19277         # a should be migrated to MDT0, since no other links on MDT1
19278         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19279                 error "#4 migrate dir fails"
19280         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19281         [ $mdt_index == 0 ] || error "a is not on MDT0"
19282
19283         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19284 }
19285 run_test 230f "migrate mulitple remote link files"
19286
19287 test_230g() {
19288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19289         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19290         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19291                 skip "Need MDS version at least 2.11.52"
19292
19293         mkdir -p $DIR/$tdir/migrate_dir
19294
19295         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19296                 error "migrating dir to non-exist MDT succeeds"
19297         true
19298 }
19299 run_test 230g "migrate dir to non-exist MDT"
19300
19301 test_230h() {
19302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19303         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19304         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19305                 skip "Need MDS version at least 2.11.52"
19306
19307         local mdt_index
19308
19309         mkdir -p $DIR/$tdir/migrate_dir
19310
19311         $LFS migrate -m1 $DIR &&
19312                 error "migrating mountpoint1 should fail"
19313
19314         $LFS migrate -m1 $DIR/$tdir/.. &&
19315                 error "migrating mountpoint2 should fail"
19316
19317         # same as mv
19318         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19319                 error "migrating $tdir/migrate_dir/.. should fail"
19320
19321         true
19322 }
19323 run_test 230h "migrate .. and root"
19324
19325 test_230i() {
19326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19328         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19329                 skip "Need MDS version at least 2.11.52"
19330
19331         mkdir -p $DIR/$tdir/migrate_dir
19332
19333         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19334                 error "migration fails with a tailing slash"
19335
19336         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19337                 error "migration fails with two tailing slashes"
19338 }
19339 run_test 230i "lfs migrate -m tolerates trailing slashes"
19340
19341 test_230j() {
19342         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19343         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19344                 skip "Need MDS version at least 2.11.52"
19345
19346         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19347         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19348                 error "create $tfile failed"
19349         cat /etc/passwd > $DIR/$tdir/$tfile
19350
19351         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19352
19353         cmp /etc/passwd $DIR/$tdir/$tfile ||
19354                 error "DoM file mismatch after migration"
19355 }
19356 run_test 230j "DoM file data not changed after dir migration"
19357
19358 test_230k() {
19359         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19360         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19361                 skip "Need MDS version at least 2.11.56"
19362
19363         local total=20
19364         local files_on_starting_mdt=0
19365
19366         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19367         $LFS getdirstripe $DIR/$tdir
19368         for i in $(seq $total); do
19369                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19370                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19371                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19372         done
19373
19374         echo "$files_on_starting_mdt files on MDT0"
19375
19376         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19377         $LFS getdirstripe $DIR/$tdir
19378
19379         files_on_starting_mdt=0
19380         for i in $(seq $total); do
19381                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19382                         error "file $tfile.$i mismatch after migration"
19383                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19384                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19385         done
19386
19387         echo "$files_on_starting_mdt files on MDT1 after migration"
19388         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19389
19390         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19391         $LFS getdirstripe $DIR/$tdir
19392
19393         files_on_starting_mdt=0
19394         for i in $(seq $total); do
19395                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19396                         error "file $tfile.$i mismatch after 2nd migration"
19397                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19398                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19399         done
19400
19401         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19402         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19403
19404         true
19405 }
19406 run_test 230k "file data not changed after dir migration"
19407
19408 test_230l() {
19409         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19410         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19411                 skip "Need MDS version at least 2.11.56"
19412
19413         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19414         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19415                 error "create files under remote dir failed $i"
19416         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19417 }
19418 run_test 230l "readdir between MDTs won't crash"
19419
19420 test_230m() {
19421         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19422         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19423                 skip "Need MDS version at least 2.11.56"
19424
19425         local MDTIDX=1
19426         local mig_dir=$DIR/$tdir/migrate_dir
19427         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19428         local shortstr="b"
19429         local val
19430
19431         echo "Creating files and dirs with xattrs"
19432         test_mkdir $DIR/$tdir
19433         test_mkdir -i0 -c1 $mig_dir
19434         mkdir $mig_dir/dir
19435         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19436                 error "cannot set xattr attr1 on dir"
19437         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19438                 error "cannot set xattr attr2 on dir"
19439         touch $mig_dir/dir/f0
19440         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19441                 error "cannot set xattr attr1 on file"
19442         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19443                 error "cannot set xattr attr2 on file"
19444         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19445         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19446         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19447         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19448         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19449         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19450         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19451         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19452         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19453
19454         echo "Migrating to MDT1"
19455         $LFS migrate -m $MDTIDX $mig_dir ||
19456                 error "fails on migrating dir to MDT1"
19457
19458         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19459         echo "Checking xattrs"
19460         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19461         [ "$val" = $longstr ] ||
19462                 error "expecting xattr1 $longstr on dir, found $val"
19463         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19464         [ "$val" = $shortstr ] ||
19465                 error "expecting xattr2 $shortstr on dir, found $val"
19466         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19467         [ "$val" = $longstr ] ||
19468                 error "expecting xattr1 $longstr on file, found $val"
19469         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19470         [ "$val" = $shortstr ] ||
19471                 error "expecting xattr2 $shortstr on file, found $val"
19472 }
19473 run_test 230m "xattrs not changed after dir migration"
19474
19475 test_230n() {
19476         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19477         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19478                 skip "Need MDS version at least 2.13.53"
19479
19480         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19481         cat /etc/hosts > $DIR/$tdir/$tfile
19482         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19483         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19484
19485         cmp /etc/hosts $DIR/$tdir/$tfile ||
19486                 error "File data mismatch after migration"
19487 }
19488 run_test 230n "Dir migration with mirrored file"
19489
19490 test_230o() {
19491         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19492         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19493                 skip "Need MDS version at least 2.13.52"
19494
19495         local mdts=$(comma_list $(mdts_nodes))
19496         local timeout=100
19497         local restripe_status
19498         local delta
19499         local i
19500
19501         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19502
19503         # in case "crush" hash type is not set
19504         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19505
19506         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19507                            mdt.*MDT0000.enable_dir_restripe)
19508         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19509         stack_trap "do_nodes $mdts $LCTL set_param \
19510                     mdt.*.enable_dir_restripe=$restripe_status"
19511
19512         mkdir $DIR/$tdir
19513         createmany -m $DIR/$tdir/f 100 ||
19514                 error "create files under remote dir failed $i"
19515         createmany -d $DIR/$tdir/d 100 ||
19516                 error "create dirs under remote dir failed $i"
19517
19518         for i in $(seq 2 $MDSCOUNT); do
19519                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19520                 $LFS setdirstripe -c $i $DIR/$tdir ||
19521                         error "split -c $i $tdir failed"
19522                 wait_update $HOSTNAME \
19523                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19524                         error "dir split not finished"
19525                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19526                         awk '/migrate/ {sum += $2} END { print sum }')
19527                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19528                 # delta is around total_files/stripe_count
19529                 (( $delta < 200 / (i - 1) + 4 )) ||
19530                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19531         done
19532 }
19533 run_test 230o "dir split"
19534
19535 test_230p() {
19536         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19537         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19538                 skip "Need MDS version at least 2.13.52"
19539
19540         local mdts=$(comma_list $(mdts_nodes))
19541         local timeout=100
19542         local restripe_status
19543         local delta
19544         local i
19545
19546         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19547
19548         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19549
19550         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19551                            mdt.*MDT0000.enable_dir_restripe)
19552         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19553         stack_trap "do_nodes $mdts $LCTL set_param \
19554                     mdt.*.enable_dir_restripe=$restripe_status"
19555
19556         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19557         createmany -m $DIR/$tdir/f 100 ||
19558                 error "create files under remote dir failed $i"
19559         createmany -d $DIR/$tdir/d 100 ||
19560                 error "create dirs under remote dir failed $i"
19561
19562         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19563                 local mdt_hash="crush"
19564
19565                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19566                 $LFS setdirstripe -c $i $DIR/$tdir ||
19567                         error "split -c $i $tdir failed"
19568                 [ $i -eq 1 ] && mdt_hash="none"
19569                 wait_update $HOSTNAME \
19570                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19571                         error "dir merge not finished"
19572                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19573                         awk '/migrate/ {sum += $2} END { print sum }')
19574                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19575                 # delta is around total_files/stripe_count
19576                 (( $delta < 200 / i + 4 )) ||
19577                         error "$delta files migrated >= $((200 / i + 4))"
19578         done
19579 }
19580 run_test 230p "dir merge"
19581
19582 test_230q() {
19583         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19584         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19585                 skip "Need MDS version at least 2.13.52"
19586
19587         local mdts=$(comma_list $(mdts_nodes))
19588         local saved_threshold=$(do_facet mds1 \
19589                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19590         local saved_delta=$(do_facet mds1 \
19591                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19592         local threshold=100
19593         local delta=2
19594         local total=0
19595         local stripe_count=0
19596         local stripe_index
19597         local nr_files
19598         local create
19599
19600         # test with fewer files on ZFS
19601         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19602
19603         stack_trap "do_nodes $mdts $LCTL set_param \
19604                     mdt.*.dir_split_count=$saved_threshold"
19605         stack_trap "do_nodes $mdts $LCTL set_param \
19606                     mdt.*.dir_split_delta=$saved_delta"
19607         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19608         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19609         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19610         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19611         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19612         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19613
19614         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19615         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19616
19617         create=$((threshold * 3 / 2))
19618         while [ $stripe_count -lt $MDSCOUNT ]; do
19619                 createmany -m $DIR/$tdir/f $total $create ||
19620                         error "create sub files failed"
19621                 stat $DIR/$tdir > /dev/null
19622                 total=$((total + create))
19623                 stripe_count=$((stripe_count + delta))
19624                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19625
19626                 wait_update $HOSTNAME \
19627                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19628                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19629
19630                 wait_update $HOSTNAME \
19631                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19632                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19633
19634                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19635                 echo "$nr_files/$total files on MDT$stripe_index after split"
19636                 # allow 10% margin of imbalance with crush hash
19637                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19638                         error "$nr_files files on MDT$stripe_index after split"
19639
19640                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19641                 [ $nr_files -eq $total ] ||
19642                         error "total sub files $nr_files != $total"
19643         done
19644 }
19645 run_test 230q "dir auto split"
19646
19647 test_230r() {
19648         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19649         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19650         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19651                 skip "Need MDS version at least 2.13.54"
19652
19653         # maximum amount of local locks:
19654         # parent striped dir - 2 locks
19655         # new stripe in parent to migrate to - 1 lock
19656         # source and target - 2 locks
19657         # Total 5 locks for regular file
19658         mkdir -p $DIR/$tdir
19659         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19660         touch $DIR/$tdir/dir1/eee
19661
19662         # create 4 hardlink for 4 more locks
19663         # Total: 9 locks > RS_MAX_LOCKS (8)
19664         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19665         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19666         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19667         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19668         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19669         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19670         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19671         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19672
19673         cancel_lru_locks mdc
19674
19675         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19676                 error "migrate dir fails"
19677
19678         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19679 }
19680 run_test 230r "migrate with too many local locks"
19681
19682 test_230s() {
19683         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19684                 skip "Need MDS version at least 2.13.57"
19685
19686         local mdts=$(comma_list $(mdts_nodes))
19687         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19688                                 mdt.*MDT0000.enable_dir_restripe)
19689
19690         stack_trap "do_nodes $mdts $LCTL set_param \
19691                     mdt.*.enable_dir_restripe=$restripe_status"
19692
19693         local st
19694         for st in 0 1; do
19695                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19696                 test_mkdir $DIR/$tdir
19697                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19698                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19699                 rmdir $DIR/$tdir
19700         done
19701 }
19702 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19703
19704 test_230t()
19705 {
19706         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19707         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19708                 skip "Need MDS version at least 2.14.50"
19709
19710         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19711         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19712         $LFS project -p 1 -s $DIR/$tdir ||
19713                 error "set $tdir project id failed"
19714         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19715                 error "set subdir project id failed"
19716         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19717 }
19718 run_test 230t "migrate directory with project ID set"
19719
19720 test_231a()
19721 {
19722         # For simplicity this test assumes that max_pages_per_rpc
19723         # is the same across all OSCs
19724         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19725         local bulk_size=$((max_pages * PAGE_SIZE))
19726         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19727                                        head -n 1)
19728
19729         mkdir -p $DIR/$tdir
19730         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19731                 error "failed to set stripe with -S ${brw_size}M option"
19732
19733         # clear the OSC stats
19734         $LCTL set_param osc.*.stats=0 &>/dev/null
19735         stop_writeback
19736
19737         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19738         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19739                 oflag=direct &>/dev/null || error "dd failed"
19740
19741         sync; sleep 1; sync # just to be safe
19742         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19743         if [ x$nrpcs != "x1" ]; then
19744                 $LCTL get_param osc.*.stats
19745                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19746         fi
19747
19748         start_writeback
19749         # Drop the OSC cache, otherwise we will read from it
19750         cancel_lru_locks osc
19751
19752         # clear the OSC stats
19753         $LCTL set_param osc.*.stats=0 &>/dev/null
19754
19755         # Client reads $bulk_size.
19756         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19757                 iflag=direct &>/dev/null || error "dd failed"
19758
19759         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19760         if [ x$nrpcs != "x1" ]; then
19761                 $LCTL get_param osc.*.stats
19762                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19763         fi
19764 }
19765 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19766
19767 test_231b() {
19768         mkdir -p $DIR/$tdir
19769         local i
19770         for i in {0..1023}; do
19771                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19772                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19773                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19774         done
19775         sync
19776 }
19777 run_test 231b "must not assert on fully utilized OST request buffer"
19778
19779 test_232a() {
19780         mkdir -p $DIR/$tdir
19781         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19782
19783         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19784         do_facet ost1 $LCTL set_param fail_loc=0x31c
19785
19786         # ignore dd failure
19787         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19788
19789         do_facet ost1 $LCTL set_param fail_loc=0
19790         umount_client $MOUNT || error "umount failed"
19791         mount_client $MOUNT || error "mount failed"
19792         stop ost1 || error "cannot stop ost1"
19793         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19794 }
19795 run_test 232a "failed lock should not block umount"
19796
19797 test_232b() {
19798         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19799                 skip "Need MDS version at least 2.10.58"
19800
19801         mkdir -p $DIR/$tdir
19802         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19804         sync
19805         cancel_lru_locks osc
19806
19807         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19808         do_facet ost1 $LCTL set_param fail_loc=0x31c
19809
19810         # ignore failure
19811         $LFS data_version $DIR/$tdir/$tfile || true
19812
19813         do_facet ost1 $LCTL set_param fail_loc=0
19814         umount_client $MOUNT || error "umount failed"
19815         mount_client $MOUNT || error "mount failed"
19816         stop ost1 || error "cannot stop ost1"
19817         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19818 }
19819 run_test 232b "failed data version lock should not block umount"
19820
19821 test_233a() {
19822         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19823                 skip "Need MDS version at least 2.3.64"
19824         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19825
19826         local fid=$($LFS path2fid $MOUNT)
19827
19828         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19829                 error "cannot access $MOUNT using its FID '$fid'"
19830 }
19831 run_test 233a "checking that OBF of the FS root succeeds"
19832
19833 test_233b() {
19834         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19835                 skip "Need MDS version at least 2.5.90"
19836         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19837
19838         local fid=$($LFS path2fid $MOUNT/.lustre)
19839
19840         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19841                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19842
19843         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19844         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19845                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19846 }
19847 run_test 233b "checking that OBF of the FS .lustre succeeds"
19848
19849 test_234() {
19850         local p="$TMP/sanityN-$TESTNAME.parameters"
19851         save_lustre_params client "llite.*.xattr_cache" > $p
19852         lctl set_param llite.*.xattr_cache 1 ||
19853                 skip_env "xattr cache is not supported"
19854
19855         mkdir -p $DIR/$tdir || error "mkdir failed"
19856         touch $DIR/$tdir/$tfile || error "touch failed"
19857         # OBD_FAIL_LLITE_XATTR_ENOMEM
19858         $LCTL set_param fail_loc=0x1405
19859         getfattr -n user.attr $DIR/$tdir/$tfile &&
19860                 error "getfattr should have failed with ENOMEM"
19861         $LCTL set_param fail_loc=0x0
19862         rm -rf $DIR/$tdir
19863
19864         restore_lustre_params < $p
19865         rm -f $p
19866 }
19867 run_test 234 "xattr cache should not crash on ENOMEM"
19868
19869 test_235() {
19870         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19871                 skip "Need MDS version at least 2.4.52"
19872
19873         flock_deadlock $DIR/$tfile
19874         local RC=$?
19875         case $RC in
19876                 0)
19877                 ;;
19878                 124) error "process hangs on a deadlock"
19879                 ;;
19880                 *) error "error executing flock_deadlock $DIR/$tfile"
19881                 ;;
19882         esac
19883 }
19884 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19885
19886 #LU-2935
19887 test_236() {
19888         check_swap_layouts_support
19889
19890         local ref1=/etc/passwd
19891         local ref2=/etc/group
19892         local file1=$DIR/$tdir/f1
19893         local file2=$DIR/$tdir/f2
19894
19895         test_mkdir -c1 $DIR/$tdir
19896         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19897         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19898         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19899         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19900         local fd=$(free_fd)
19901         local cmd="exec $fd<>$file2"
19902         eval $cmd
19903         rm $file2
19904         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19905                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19906         cmd="exec $fd>&-"
19907         eval $cmd
19908         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19909
19910         #cleanup
19911         rm -rf $DIR/$tdir
19912 }
19913 run_test 236 "Layout swap on open unlinked file"
19914
19915 # LU-4659 linkea consistency
19916 test_238() {
19917         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19918                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19919                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19920                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19921
19922         touch $DIR/$tfile
19923         ln $DIR/$tfile $DIR/$tfile.lnk
19924         touch $DIR/$tfile.new
19925         mv $DIR/$tfile.new $DIR/$tfile
19926         local fid1=$($LFS path2fid $DIR/$tfile)
19927         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19928         local path1=$($LFS fid2path $FSNAME "$fid1")
19929         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19930         local path2=$($LFS fid2path $FSNAME "$fid2")
19931         [ $tfile.lnk == $path2 ] ||
19932                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19933         rm -f $DIR/$tfile*
19934 }
19935 run_test 238 "Verify linkea consistency"
19936
19937 test_239A() { # was test_239
19938         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19939                 skip "Need MDS version at least 2.5.60"
19940
19941         local list=$(comma_list $(mdts_nodes))
19942
19943         mkdir -p $DIR/$tdir
19944         createmany -o $DIR/$tdir/f- 5000
19945         unlinkmany $DIR/$tdir/f- 5000
19946         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19947                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19948         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19949                         osp.*MDT*.sync_in_flight" | calc_sum)
19950         [ "$changes" -eq 0 ] || error "$changes not synced"
19951 }
19952 run_test 239A "osp_sync test"
19953
19954 test_239a() { #LU-5297
19955         remote_mds_nodsh && skip "remote MDS with nodsh"
19956
19957         touch $DIR/$tfile
19958         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19959         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19960         chgrp $RUNAS_GID $DIR/$tfile
19961         wait_delete_completed
19962 }
19963 run_test 239a "process invalid osp sync record correctly"
19964
19965 test_239b() { #LU-5297
19966         remote_mds_nodsh && skip "remote MDS with nodsh"
19967
19968         touch $DIR/$tfile1
19969         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19970         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19971         chgrp $RUNAS_GID $DIR/$tfile1
19972         wait_delete_completed
19973         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19974         touch $DIR/$tfile2
19975         chgrp $RUNAS_GID $DIR/$tfile2
19976         wait_delete_completed
19977 }
19978 run_test 239b "process osp sync record with ENOMEM error correctly"
19979
19980 test_240() {
19981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19982         remote_mds_nodsh && skip "remote MDS with nodsh"
19983
19984         mkdir -p $DIR/$tdir
19985
19986         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19987                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19988         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19989                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19990
19991         umount_client $MOUNT || error "umount failed"
19992         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19993         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19994         mount_client $MOUNT || error "failed to mount client"
19995
19996         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19997         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19998 }
19999 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20000
20001 test_241_bio() {
20002         local count=$1
20003         local bsize=$2
20004
20005         for LOOP in $(seq $count); do
20006                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20007                 cancel_lru_locks $OSC || true
20008         done
20009 }
20010
20011 test_241_dio() {
20012         local count=$1
20013         local bsize=$2
20014
20015         for LOOP in $(seq $1); do
20016                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20017                         2>/dev/null
20018         done
20019 }
20020
20021 test_241a() { # was test_241
20022         local bsize=$PAGE_SIZE
20023
20024         (( bsize < 40960 )) && bsize=40960
20025         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20026         ls -la $DIR/$tfile
20027         cancel_lru_locks $OSC
20028         test_241_bio 1000 $bsize &
20029         PID=$!
20030         test_241_dio 1000 $bsize
20031         wait $PID
20032 }
20033 run_test 241a "bio vs dio"
20034
20035 test_241b() {
20036         local bsize=$PAGE_SIZE
20037
20038         (( bsize < 40960 )) && bsize=40960
20039         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20040         ls -la $DIR/$tfile
20041         test_241_dio 1000 $bsize &
20042         PID=$!
20043         test_241_dio 1000 $bsize
20044         wait $PID
20045 }
20046 run_test 241b "dio vs dio"
20047
20048 test_242() {
20049         remote_mds_nodsh && skip "remote MDS with nodsh"
20050
20051         mkdir_on_mdt0 $DIR/$tdir
20052         touch $DIR/$tdir/$tfile
20053
20054         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20055         do_facet mds1 lctl set_param fail_loc=0x105
20056         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20057
20058         do_facet mds1 lctl set_param fail_loc=0
20059         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20060 }
20061 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20062
20063 test_243()
20064 {
20065         test_mkdir $DIR/$tdir
20066         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20067 }
20068 run_test 243 "various group lock tests"
20069
20070 test_244a()
20071 {
20072         test_mkdir $DIR/$tdir
20073         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20074         sendfile_grouplock $DIR/$tdir/$tfile || \
20075                 error "sendfile+grouplock failed"
20076         rm -rf $DIR/$tdir
20077 }
20078 run_test 244a "sendfile with group lock tests"
20079
20080 test_244b()
20081 {
20082         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20083
20084         local threads=50
20085         local size=$((1024*1024))
20086
20087         test_mkdir $DIR/$tdir
20088         for i in $(seq 1 $threads); do
20089                 local file=$DIR/$tdir/file_$((i / 10))
20090                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20091                 local pids[$i]=$!
20092         done
20093         for i in $(seq 1 $threads); do
20094                 wait ${pids[$i]}
20095         done
20096 }
20097 run_test 244b "multi-threaded write with group lock"
20098
20099 test_245() {
20100         local flagname="multi_mod_rpcs"
20101         local connect_data_name="max_mod_rpcs"
20102         local out
20103
20104         # check if multiple modify RPCs flag is set
20105         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20106                 grep "connect_flags:")
20107         echo "$out"
20108
20109         echo "$out" | grep -qw $flagname
20110         if [ $? -ne 0 ]; then
20111                 echo "connect flag $flagname is not set"
20112                 return
20113         fi
20114
20115         # check if multiple modify RPCs data is set
20116         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20117         echo "$out"
20118
20119         echo "$out" | grep -qw $connect_data_name ||
20120                 error "import should have connect data $connect_data_name"
20121 }
20122 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20123
20124 cleanup_247() {
20125         local submount=$1
20126
20127         trap 0
20128         umount_client $submount
20129         rmdir $submount
20130 }
20131
20132 test_247a() {
20133         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20134                 grep -q subtree ||
20135                 skip_env "Fileset feature is not supported"
20136
20137         local submount=${MOUNT}_$tdir
20138
20139         mkdir $MOUNT/$tdir
20140         mkdir -p $submount || error "mkdir $submount failed"
20141         FILESET="$FILESET/$tdir" mount_client $submount ||
20142                 error "mount $submount failed"
20143         trap "cleanup_247 $submount" EXIT
20144         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20145         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20146                 error "read $MOUNT/$tdir/$tfile failed"
20147         cleanup_247 $submount
20148 }
20149 run_test 247a "mount subdir as fileset"
20150
20151 test_247b() {
20152         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20153                 skip_env "Fileset feature is not supported"
20154
20155         local submount=${MOUNT}_$tdir
20156
20157         rm -rf $MOUNT/$tdir
20158         mkdir -p $submount || error "mkdir $submount failed"
20159         SKIP_FILESET=1
20160         FILESET="$FILESET/$tdir" mount_client $submount &&
20161                 error "mount $submount should fail"
20162         rmdir $submount
20163 }
20164 run_test 247b "mount subdir that dose not exist"
20165
20166 test_247c() {
20167         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20168                 skip_env "Fileset feature is not supported"
20169
20170         local submount=${MOUNT}_$tdir
20171
20172         mkdir -p $MOUNT/$tdir/dir1
20173         mkdir -p $submount || error "mkdir $submount failed"
20174         trap "cleanup_247 $submount" EXIT
20175         FILESET="$FILESET/$tdir" mount_client $submount ||
20176                 error "mount $submount failed"
20177         local fid=$($LFS path2fid $MOUNT/)
20178         $LFS fid2path $submount $fid && error "fid2path should fail"
20179         cleanup_247 $submount
20180 }
20181 run_test 247c "running fid2path outside subdirectory root"
20182
20183 test_247d() {
20184         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20185                 skip "Fileset feature is not supported"
20186
20187         local submount=${MOUNT}_$tdir
20188
20189         mkdir -p $MOUNT/$tdir/dir1
20190         mkdir -p $submount || error "mkdir $submount failed"
20191         FILESET="$FILESET/$tdir" mount_client $submount ||
20192                 error "mount $submount failed"
20193         trap "cleanup_247 $submount" EXIT
20194
20195         local td=$submount/dir1
20196         local fid=$($LFS path2fid $td)
20197         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20198
20199         # check that we get the same pathname back
20200         local rootpath
20201         local found
20202         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20203                 echo "$rootpath $fid"
20204                 found=$($LFS fid2path $rootpath "$fid")
20205                 [ -n "found" ] || error "fid2path should succeed"
20206                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20207         done
20208         # check wrong root path format
20209         rootpath=$submount"_wrong"
20210         found=$($LFS fid2path $rootpath "$fid")
20211         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20212
20213         cleanup_247 $submount
20214 }
20215 run_test 247d "running fid2path inside subdirectory root"
20216
20217 # LU-8037
20218 test_247e() {
20219         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20220                 grep -q subtree ||
20221                 skip "Fileset feature is not supported"
20222
20223         local submount=${MOUNT}_$tdir
20224
20225         mkdir $MOUNT/$tdir
20226         mkdir -p $submount || error "mkdir $submount failed"
20227         FILESET="$FILESET/.." mount_client $submount &&
20228                 error "mount $submount should fail"
20229         rmdir $submount
20230 }
20231 run_test 247e "mount .. as fileset"
20232
20233 test_247f() {
20234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20235         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20236                 skip "Need at least version 2.13.52"
20237         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20238                 skip "Need at least version 2.14.50"
20239         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20240                 grep -q subtree ||
20241                 skip "Fileset feature is not supported"
20242
20243         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20244         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20245                 error "mkdir remote failed"
20246         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20247         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20248                 error "mkdir striped failed"
20249         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20250
20251         local submount=${MOUNT}_$tdir
20252
20253         mkdir -p $submount || error "mkdir $submount failed"
20254         stack_trap "rmdir $submount"
20255
20256         local dir
20257         local stat
20258         local fileset=$FILESET
20259         local mdts=$(comma_list $(mdts_nodes))
20260
20261         stat=$(do_facet mds1 $LCTL get_param -n \
20262                 mdt.*MDT0000.enable_remote_subdir_mount)
20263         stack_trap "do_nodes $mdts $LCTL set_param \
20264                 mdt.*.enable_remote_subdir_mount=$stat"
20265
20266         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20267         stack_trap "umount_client $submount"
20268         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20269                 error "mount remote dir $dir should fail"
20270
20271         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20272                 $tdir/striped/. ; do
20273                 FILESET="$fileset/$dir" mount_client $submount ||
20274                         error "mount $dir failed"
20275                 umount_client $submount
20276         done
20277
20278         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20279         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20280                 error "mount $tdir/remote failed"
20281 }
20282 run_test 247f "mount striped or remote directory as fileset"
20283
20284 test_247g() {
20285         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20286         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20287                 skip "Need at least version 2.14.50"
20288
20289         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20290                 error "mkdir $tdir failed"
20291         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20292
20293         local submount=${MOUNT}_$tdir
20294
20295         mkdir -p $submount || error "mkdir $submount failed"
20296         stack_trap "rmdir $submount"
20297
20298         FILESET="$fileset/$tdir" mount_client $submount ||
20299                 error "mount $dir failed"
20300         stack_trap "umount $submount"
20301
20302         local mdts=$(comma_list $(mdts_nodes))
20303
20304         local nrpcs
20305
20306         stat $submount > /dev/null
20307         cancel_lru_locks $MDC
20308         stat $submount > /dev/null
20309         stat $submount/$tfile > /dev/null
20310         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20311         stat $submount/$tfile > /dev/null
20312         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20313                 awk '/getattr/ {sum += $2} END {print sum}')
20314
20315         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20316 }
20317 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20318
20319 test_248a() {
20320         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20321         [ -z "$fast_read_sav" ] && skip "no fast read support"
20322
20323         # create a large file for fast read verification
20324         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20325
20326         # make sure the file is created correctly
20327         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20328                 { rm -f $DIR/$tfile; skip "file creation error"; }
20329
20330         echo "Test 1: verify that fast read is 4 times faster on cache read"
20331
20332         # small read with fast read enabled
20333         $LCTL set_param -n llite.*.fast_read=1
20334         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20335                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20336                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20337         # small read with fast read disabled
20338         $LCTL set_param -n llite.*.fast_read=0
20339         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20340                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20341                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20342
20343         # verify that fast read is 4 times faster for cache read
20344         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20345                 error_not_in_vm "fast read was not 4 times faster: " \
20346                            "$t_fast vs $t_slow"
20347
20348         echo "Test 2: verify the performance between big and small read"
20349         $LCTL set_param -n llite.*.fast_read=1
20350
20351         # 1k non-cache read
20352         cancel_lru_locks osc
20353         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20354                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20355                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20356
20357         # 1M non-cache read
20358         cancel_lru_locks osc
20359         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20360                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20361                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20362
20363         # verify that big IO is not 4 times faster than small IO
20364         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20365                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20366
20367         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20368         rm -f $DIR/$tfile
20369 }
20370 run_test 248a "fast read verification"
20371
20372 test_248b() {
20373         # Default short_io_bytes=16384, try both smaller and larger sizes.
20374         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20375         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20376         echo "bs=53248 count=113 normal buffered write"
20377         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20378                 error "dd of initial data file failed"
20379         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20380
20381         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20382         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20383                 error "dd with sync normal writes failed"
20384         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20385
20386         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20387         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20388                 error "dd with sync small writes failed"
20389         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20390
20391         cancel_lru_locks osc
20392
20393         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20394         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20395         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20396         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20397                 iflag=direct || error "dd with O_DIRECT small read failed"
20398         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20399         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20400                 error "compare $TMP/$tfile.1 failed"
20401
20402         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20403         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20404
20405         # just to see what the maximum tunable value is, and test parsing
20406         echo "test invalid parameter 2MB"
20407         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20408                 error "too-large short_io_bytes allowed"
20409         echo "test maximum parameter 512KB"
20410         # if we can set a larger short_io_bytes, run test regardless of version
20411         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20412                 # older clients may not allow setting it this large, that's OK
20413                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20414                         skip "Need at least client version 2.13.50"
20415                 error "medium short_io_bytes failed"
20416         fi
20417         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20418         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20419
20420         echo "test large parameter 64KB"
20421         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20422         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20423
20424         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20425         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20426                 error "dd with sync large writes failed"
20427         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20428
20429         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20430         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20431         num=$((113 * 4096 / PAGE_SIZE))
20432         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20433         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20434                 error "dd with O_DIRECT large writes failed"
20435         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20436                 error "compare $DIR/$tfile.3 failed"
20437
20438         cancel_lru_locks osc
20439
20440         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20441         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20442                 error "dd with O_DIRECT large read failed"
20443         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20444                 error "compare $TMP/$tfile.2 failed"
20445
20446         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20447         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20448                 error "dd with O_DIRECT large read failed"
20449         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20450                 error "compare $TMP/$tfile.3 failed"
20451 }
20452 run_test 248b "test short_io read and write for both small and large sizes"
20453
20454 test_249() { # LU-7890
20455         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20456                 skip "Need at least version 2.8.54"
20457
20458         rm -f $DIR/$tfile
20459         $LFS setstripe -c 1 $DIR/$tfile
20460         # Offset 2T == 4k * 512M
20461         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20462                 error "dd to 2T offset failed"
20463 }
20464 run_test 249 "Write above 2T file size"
20465
20466 test_250() {
20467         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20468          && skip "no 16TB file size limit on ZFS"
20469
20470         $LFS setstripe -c 1 $DIR/$tfile
20471         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20472         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20473         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20474         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20475                 conv=notrunc,fsync && error "append succeeded"
20476         return 0
20477 }
20478 run_test 250 "Write above 16T limit"
20479
20480 test_251() {
20481         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20482
20483         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20484         #Skip once - writing the first stripe will succeed
20485         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20486         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20487                 error "short write happened"
20488
20489         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20490         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20491                 error "short read happened"
20492
20493         rm -f $DIR/$tfile
20494 }
20495 run_test 251 "Handling short read and write correctly"
20496
20497 test_252() {
20498         remote_mds_nodsh && skip "remote MDS with nodsh"
20499         remote_ost_nodsh && skip "remote OST with nodsh"
20500         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20501                 skip_env "ldiskfs only test"
20502         fi
20503
20504         local tgt
20505         local dev
20506         local out
20507         local uuid
20508         local num
20509         local gen
20510
20511         # check lr_reader on OST0000
20512         tgt=ost1
20513         dev=$(facet_device $tgt)
20514         out=$(do_facet $tgt $LR_READER $dev)
20515         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20516         echo "$out"
20517         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20518         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20519                 error "Invalid uuid returned by $LR_READER on target $tgt"
20520         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20521
20522         # check lr_reader -c on MDT0000
20523         tgt=mds1
20524         dev=$(facet_device $tgt)
20525         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20526                 skip "$LR_READER does not support additional options"
20527         fi
20528         out=$(do_facet $tgt $LR_READER -c $dev)
20529         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20530         echo "$out"
20531         num=$(echo "$out" | grep -c "mdtlov")
20532         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20533                 error "Invalid number of mdtlov clients returned by $LR_READER"
20534         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20535
20536         # check lr_reader -cr on MDT0000
20537         out=$(do_facet $tgt $LR_READER -cr $dev)
20538         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20539         echo "$out"
20540         echo "$out" | grep -q "^reply_data:$" ||
20541                 error "$LR_READER should have returned 'reply_data' section"
20542         num=$(echo "$out" | grep -c "client_generation")
20543         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20544 }
20545 run_test 252 "check lr_reader tool"
20546
20547 test_253() {
20548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20549         remote_mds_nodsh && skip "remote MDS with nodsh"
20550         remote_mgs_nodsh && skip "remote MGS with nodsh"
20551
20552         local ostidx=0
20553         local rc=0
20554         local ost_name=$(ostname_from_index $ostidx)
20555
20556         # on the mdt's osc
20557         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20558         do_facet $SINGLEMDS $LCTL get_param -n \
20559                 osp.$mdtosc_proc1.reserved_mb_high ||
20560                 skip  "remote MDS does not support reserved_mb_high"
20561
20562         rm -rf $DIR/$tdir
20563         wait_mds_ost_sync
20564         wait_delete_completed
20565         mkdir $DIR/$tdir
20566
20567         pool_add $TESTNAME || error "Pool creation failed"
20568         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20569
20570         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20571                 error "Setstripe failed"
20572
20573         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20574
20575         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20576                     grep "watermarks")
20577         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20578
20579         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20580                         osp.$mdtosc_proc1.prealloc_status)
20581         echo "prealloc_status $oa_status"
20582
20583         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20584                 error "File creation should fail"
20585
20586         #object allocation was stopped, but we still able to append files
20587         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20588                 oflag=append || error "Append failed"
20589
20590         rm -f $DIR/$tdir/$tfile.0
20591
20592         # For this test, we want to delete the files we created to go out of
20593         # space but leave the watermark, so we remain nearly out of space
20594         ost_watermarks_enospc_delete_files $tfile $ostidx
20595
20596         wait_delete_completed
20597
20598         sleep_maxage
20599
20600         for i in $(seq 10 12); do
20601                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20602                         2>/dev/null || error "File creation failed after rm"
20603         done
20604
20605         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20606                         osp.$mdtosc_proc1.prealloc_status)
20607         echo "prealloc_status $oa_status"
20608
20609         if (( oa_status != 0 )); then
20610                 error "Object allocation still disable after rm"
20611         fi
20612 }
20613 run_test 253 "Check object allocation limit"
20614
20615 test_254() {
20616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20617         remote_mds_nodsh && skip "remote MDS with nodsh"
20618         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20619                 skip "MDS does not support changelog_size"
20620
20621         local cl_user
20622         local MDT0=$(facet_svc $SINGLEMDS)
20623
20624         changelog_register || error "changelog_register failed"
20625
20626         changelog_clear 0 || error "changelog_clear failed"
20627
20628         local size1=$(do_facet $SINGLEMDS \
20629                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20630         echo "Changelog size $size1"
20631
20632         rm -rf $DIR/$tdir
20633         $LFS mkdir -i 0 $DIR/$tdir
20634         # change something
20635         mkdir -p $DIR/$tdir/pics/2008/zachy
20636         touch $DIR/$tdir/pics/2008/zachy/timestamp
20637         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20638         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20639         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20640         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20641         rm $DIR/$tdir/pics/desktop.jpg
20642
20643         local size2=$(do_facet $SINGLEMDS \
20644                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20645         echo "Changelog size after work $size2"
20646
20647         (( $size2 > $size1 )) ||
20648                 error "new Changelog size=$size2 less than old size=$size1"
20649 }
20650 run_test 254 "Check changelog size"
20651
20652 ladvise_no_type()
20653 {
20654         local type=$1
20655         local file=$2
20656
20657         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20658                 awk -F: '{print $2}' | grep $type > /dev/null
20659         if [ $? -ne 0 ]; then
20660                 return 0
20661         fi
20662         return 1
20663 }
20664
20665 ladvise_no_ioctl()
20666 {
20667         local file=$1
20668
20669         lfs ladvise -a willread $file > /dev/null 2>&1
20670         if [ $? -eq 0 ]; then
20671                 return 1
20672         fi
20673
20674         lfs ladvise -a willread $file 2>&1 |
20675                 grep "Inappropriate ioctl for device" > /dev/null
20676         if [ $? -eq 0 ]; then
20677                 return 0
20678         fi
20679         return 1
20680 }
20681
20682 percent() {
20683         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20684 }
20685
20686 # run a random read IO workload
20687 # usage: random_read_iops <filename> <filesize> <iosize>
20688 random_read_iops() {
20689         local file=$1
20690         local fsize=$2
20691         local iosize=${3:-4096}
20692
20693         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20694                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20695 }
20696
20697 drop_file_oss_cache() {
20698         local file="$1"
20699         local nodes="$2"
20700
20701         $LFS ladvise -a dontneed $file 2>/dev/null ||
20702                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20703 }
20704
20705 ladvise_willread_performance()
20706 {
20707         local repeat=10
20708         local average_origin=0
20709         local average_cache=0
20710         local average_ladvise=0
20711
20712         for ((i = 1; i <= $repeat; i++)); do
20713                 echo "Iter $i/$repeat: reading without willread hint"
20714                 cancel_lru_locks osc
20715                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20716                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20717                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20718                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20719
20720                 cancel_lru_locks osc
20721                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20722                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20723                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20724
20725                 cancel_lru_locks osc
20726                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20727                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20728                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20729                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20730                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20731         done
20732         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20733         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20734         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20735
20736         speedup_cache=$(percent $average_cache $average_origin)
20737         speedup_ladvise=$(percent $average_ladvise $average_origin)
20738
20739         echo "Average uncached read: $average_origin"
20740         echo "Average speedup with OSS cached read: " \
20741                 "$average_cache = +$speedup_cache%"
20742         echo "Average speedup with ladvise willread: " \
20743                 "$average_ladvise = +$speedup_ladvise%"
20744
20745         local lowest_speedup=20
20746         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20747                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20748                         "got $average_cache%. Skipping ladvise willread check."
20749                 return 0
20750         fi
20751
20752         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20753         # it is still good to run until then to exercise 'ladvise willread'
20754         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20755                 [ "$ost1_FSTYPE" = "zfs" ] &&
20756                 echo "osd-zfs does not support dontneed or drop_caches" &&
20757                 return 0
20758
20759         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20760         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20761                 error_not_in_vm "Speedup with willread is less than " \
20762                         "$lowest_speedup%, got $average_ladvise%"
20763 }
20764
20765 test_255a() {
20766         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20767                 skip "lustre < 2.8.54 does not support ladvise "
20768         remote_ost_nodsh && skip "remote OST with nodsh"
20769
20770         stack_trap "rm -f $DIR/$tfile"
20771         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20772
20773         ladvise_no_type willread $DIR/$tfile &&
20774                 skip "willread ladvise is not supported"
20775
20776         ladvise_no_ioctl $DIR/$tfile &&
20777                 skip "ladvise ioctl is not supported"
20778
20779         local size_mb=100
20780         local size=$((size_mb * 1048576))
20781         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20782                 error "dd to $DIR/$tfile failed"
20783
20784         lfs ladvise -a willread $DIR/$tfile ||
20785                 error "Ladvise failed with no range argument"
20786
20787         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20788                 error "Ladvise failed with no -l or -e argument"
20789
20790         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20791                 error "Ladvise failed with only -e argument"
20792
20793         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20794                 error "Ladvise failed with only -l argument"
20795
20796         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20797                 error "End offset should not be smaller than start offset"
20798
20799         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20800                 error "End offset should not be equal to start offset"
20801
20802         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20803                 error "Ladvise failed with overflowing -s argument"
20804
20805         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20806                 error "Ladvise failed with overflowing -e argument"
20807
20808         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20809                 error "Ladvise failed with overflowing -l argument"
20810
20811         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20812                 error "Ladvise succeeded with conflicting -l and -e arguments"
20813
20814         echo "Synchronous ladvise should wait"
20815         local delay=4
20816 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20817         do_nodes $(comma_list $(osts_nodes)) \
20818                 $LCTL set_param fail_val=$delay fail_loc=0x237
20819
20820         local start_ts=$SECONDS
20821         lfs ladvise -a willread $DIR/$tfile ||
20822                 error "Ladvise failed with no range argument"
20823         local end_ts=$SECONDS
20824         local inteval_ts=$((end_ts - start_ts))
20825
20826         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20827                 error "Synchronous advice didn't wait reply"
20828         fi
20829
20830         echo "Asynchronous ladvise shouldn't wait"
20831         local start_ts=$SECONDS
20832         lfs ladvise -a willread -b $DIR/$tfile ||
20833                 error "Ladvise failed with no range argument"
20834         local end_ts=$SECONDS
20835         local inteval_ts=$((end_ts - start_ts))
20836
20837         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20838                 error "Asynchronous advice blocked"
20839         fi
20840
20841         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20842         ladvise_willread_performance
20843 }
20844 run_test 255a "check 'lfs ladvise -a willread'"
20845
20846 facet_meminfo() {
20847         local facet=$1
20848         local info=$2
20849
20850         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20851 }
20852
20853 test_255b() {
20854         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20855                 skip "lustre < 2.8.54 does not support ladvise "
20856         remote_ost_nodsh && skip "remote OST with nodsh"
20857
20858         stack_trap "rm -f $DIR/$tfile"
20859         lfs setstripe -c 1 -i 0 $DIR/$tfile
20860
20861         ladvise_no_type dontneed $DIR/$tfile &&
20862                 skip "dontneed ladvise is not supported"
20863
20864         ladvise_no_ioctl $DIR/$tfile &&
20865                 skip "ladvise ioctl is not supported"
20866
20867         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20868                 [ "$ost1_FSTYPE" = "zfs" ] &&
20869                 skip "zfs-osd does not support 'ladvise dontneed'"
20870
20871         local size_mb=100
20872         local size=$((size_mb * 1048576))
20873         # In order to prevent disturbance of other processes, only check 3/4
20874         # of the memory usage
20875         local kibibytes=$((size_mb * 1024 * 3 / 4))
20876
20877         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20878                 error "dd to $DIR/$tfile failed"
20879
20880         #force write to complete before dropping OST cache & checking memory
20881         sync
20882
20883         local total=$(facet_meminfo ost1 MemTotal)
20884         echo "Total memory: $total KiB"
20885
20886         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20887         local before_read=$(facet_meminfo ost1 Cached)
20888         echo "Cache used before read: $before_read KiB"
20889
20890         lfs ladvise -a willread $DIR/$tfile ||
20891                 error "Ladvise willread failed"
20892         local after_read=$(facet_meminfo ost1 Cached)
20893         echo "Cache used after read: $after_read KiB"
20894
20895         lfs ladvise -a dontneed $DIR/$tfile ||
20896                 error "Ladvise dontneed again failed"
20897         local no_read=$(facet_meminfo ost1 Cached)
20898         echo "Cache used after dontneed ladvise: $no_read KiB"
20899
20900         if [ $total -lt $((before_read + kibibytes)) ]; then
20901                 echo "Memory is too small, abort checking"
20902                 return 0
20903         fi
20904
20905         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20906                 error "Ladvise willread should use more memory" \
20907                         "than $kibibytes KiB"
20908         fi
20909
20910         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20911                 error "Ladvise dontneed should release more memory" \
20912                         "than $kibibytes KiB"
20913         fi
20914 }
20915 run_test 255b "check 'lfs ladvise -a dontneed'"
20916
20917 test_255c() {
20918         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20919                 skip "lustre < 2.10.50 does not support lockahead"
20920
20921         local ost1_imp=$(get_osc_import_name client ost1)
20922         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20923                          cut -d'.' -f2)
20924         local count
20925         local new_count
20926         local difference
20927         local i
20928         local rc
20929
20930         test_mkdir -p $DIR/$tdir
20931         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20932
20933         #test 10 returns only success/failure
20934         i=10
20935         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20936         rc=$?
20937         if [ $rc -eq 255 ]; then
20938                 error "Ladvise test${i} failed, ${rc}"
20939         fi
20940
20941         #test 11 counts lock enqueue requests, all others count new locks
20942         i=11
20943         count=$(do_facet ost1 \
20944                 $LCTL get_param -n ost.OSS.ost.stats)
20945         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20946
20947         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20948         rc=$?
20949         if [ $rc -eq 255 ]; then
20950                 error "Ladvise test${i} failed, ${rc}"
20951         fi
20952
20953         new_count=$(do_facet ost1 \
20954                 $LCTL get_param -n ost.OSS.ost.stats)
20955         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20956                    awk '{ print $2 }')
20957
20958         difference="$((new_count - count))"
20959         if [ $difference -ne $rc ]; then
20960                 error "Ladvise test${i}, bad enqueue count, returned " \
20961                       "${rc}, actual ${difference}"
20962         fi
20963
20964         for i in $(seq 12 21); do
20965                 # If we do not do this, we run the risk of having too many
20966                 # locks and starting lock cancellation while we are checking
20967                 # lock counts.
20968                 cancel_lru_locks osc
20969
20970                 count=$($LCTL get_param -n \
20971                        ldlm.namespaces.$imp_name.lock_unused_count)
20972
20973                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20974                 rc=$?
20975                 if [ $rc -eq 255 ]; then
20976                         error "Ladvise test ${i} failed, ${rc}"
20977                 fi
20978
20979                 new_count=$($LCTL get_param -n \
20980                        ldlm.namespaces.$imp_name.lock_unused_count)
20981                 difference="$((new_count - count))"
20982
20983                 # Test 15 output is divided by 100 to map down to valid return
20984                 if [ $i -eq 15 ]; then
20985                         rc="$((rc * 100))"
20986                 fi
20987
20988                 if [ $difference -ne $rc ]; then
20989                         error "Ladvise test ${i}, bad lock count, returned " \
20990                               "${rc}, actual ${difference}"
20991                 fi
20992         done
20993
20994         #test 22 returns only success/failure
20995         i=22
20996         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20997         rc=$?
20998         if [ $rc -eq 255 ]; then
20999                 error "Ladvise test${i} failed, ${rc}"
21000         fi
21001 }
21002 run_test 255c "suite of ladvise lockahead tests"
21003
21004 test_256() {
21005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21006         remote_mds_nodsh && skip "remote MDS with nodsh"
21007         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21008         changelog_users $SINGLEMDS | grep "^cl" &&
21009                 skip "active changelog user"
21010
21011         local cl_user
21012         local cat_sl
21013         local mdt_dev
21014
21015         mdt_dev=$(mdsdevname 1)
21016         echo $mdt_dev
21017
21018         changelog_register || error "changelog_register failed"
21019
21020         rm -rf $DIR/$tdir
21021         mkdir_on_mdt0 $DIR/$tdir
21022
21023         changelog_clear 0 || error "changelog_clear failed"
21024
21025         # change something
21026         touch $DIR/$tdir/{1..10}
21027
21028         # stop the MDT
21029         stop $SINGLEMDS || error "Fail to stop MDT"
21030
21031         # remount the MDT
21032
21033         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21034
21035         #after mount new plainllog is used
21036         touch $DIR/$tdir/{11..19}
21037         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21038         stack_trap "rm -f $tmpfile"
21039         cat_sl=$(do_facet $SINGLEMDS "sync; \
21040                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21041                  llog_reader $tmpfile | grep -c type=1064553b")
21042         do_facet $SINGLEMDS llog_reader $tmpfile
21043
21044         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21045
21046         changelog_clear 0 || error "changelog_clear failed"
21047
21048         cat_sl=$(do_facet $SINGLEMDS "sync; \
21049                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21050                  llog_reader $tmpfile | grep -c type=1064553b")
21051
21052         if (( cat_sl == 2 )); then
21053                 error "Empty plain llog was not deleted from changelog catalog"
21054         elif (( cat_sl != 1 )); then
21055                 error "Active plain llog shouldn't be deleted from catalog"
21056         fi
21057 }
21058 run_test 256 "Check llog delete for empty and not full state"
21059
21060 test_257() {
21061         remote_mds_nodsh && skip "remote MDS with nodsh"
21062         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21063                 skip "Need MDS version at least 2.8.55"
21064
21065         test_mkdir $DIR/$tdir
21066
21067         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21068                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21069         stat $DIR/$tdir
21070
21071 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21072         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21073         local facet=mds$((mdtidx + 1))
21074         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21075         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21076
21077         stop $facet || error "stop MDS failed"
21078         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21079                 error "start MDS fail"
21080         wait_recovery_complete $facet
21081 }
21082 run_test 257 "xattr locks are not lost"
21083
21084 # Verify we take the i_mutex when security requires it
21085 test_258a() {
21086 #define OBD_FAIL_IMUTEX_SEC 0x141c
21087         $LCTL set_param fail_loc=0x141c
21088         touch $DIR/$tfile
21089         chmod u+s $DIR/$tfile
21090         chmod a+rwx $DIR/$tfile
21091         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21092         RC=$?
21093         if [ $RC -ne 0 ]; then
21094                 error "error, failed to take i_mutex, rc=$?"
21095         fi
21096         rm -f $DIR/$tfile
21097 }
21098 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21099
21100 # Verify we do NOT take the i_mutex in the normal case
21101 test_258b() {
21102 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21103         $LCTL set_param fail_loc=0x141d
21104         touch $DIR/$tfile
21105         chmod a+rwx $DIR
21106         chmod a+rw $DIR/$tfile
21107         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21108         RC=$?
21109         if [ $RC -ne 0 ]; then
21110                 error "error, took i_mutex unnecessarily, rc=$?"
21111         fi
21112         rm -f $DIR/$tfile
21113
21114 }
21115 run_test 258b "verify i_mutex security behavior"
21116
21117 test_259() {
21118         local file=$DIR/$tfile
21119         local before
21120         local after
21121
21122         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21123
21124         stack_trap "rm -f $file" EXIT
21125
21126         wait_delete_completed
21127         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21128         echo "before: $before"
21129
21130         $LFS setstripe -i 0 -c 1 $file
21131         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21132         sync_all_data
21133         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21134         echo "after write: $after"
21135
21136 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21137         do_facet ost1 $LCTL set_param fail_loc=0x2301
21138         $TRUNCATE $file 0
21139         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21140         echo "after truncate: $after"
21141
21142         stop ost1
21143         do_facet ost1 $LCTL set_param fail_loc=0
21144         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21145         sleep 2
21146         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21147         echo "after restart: $after"
21148         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21149                 error "missing truncate?"
21150
21151         return 0
21152 }
21153 run_test 259 "crash at delayed truncate"
21154
21155 test_260() {
21156 #define OBD_FAIL_MDC_CLOSE               0x806
21157         $LCTL set_param fail_loc=0x80000806
21158         touch $DIR/$tfile
21159
21160 }
21161 run_test 260 "Check mdc_close fail"
21162
21163 ### Data-on-MDT sanity tests ###
21164 test_270a() {
21165         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21166                 skip "Need MDS version at least 2.10.55 for DoM"
21167
21168         # create DoM file
21169         local dom=$DIR/$tdir/dom_file
21170         local tmp=$DIR/$tdir/tmp_file
21171
21172         mkdir_on_mdt0 $DIR/$tdir
21173
21174         # basic checks for DoM component creation
21175         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21176                 error "Can set MDT layout to non-first entry"
21177
21178         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21179                 error "Can define multiple entries as MDT layout"
21180
21181         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21182
21183         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21184         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21185         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21186
21187         local mdtidx=$($LFS getstripe -m $dom)
21188         local mdtname=MDT$(printf %04x $mdtidx)
21189         local facet=mds$((mdtidx + 1))
21190         local space_check=1
21191
21192         # Skip free space checks with ZFS
21193         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21194
21195         # write
21196         sync
21197         local size_tmp=$((65536 * 3))
21198         local mdtfree1=$(do_facet $facet \
21199                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21200
21201         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21202         # check also direct IO along write
21203         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21204         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21205         sync
21206         cmp $tmp $dom || error "file data is different"
21207         [ $(stat -c%s $dom) == $size_tmp ] ||
21208                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21209         if [ $space_check == 1 ]; then
21210                 local mdtfree2=$(do_facet $facet \
21211                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21212
21213                 # increase in usage from by $size_tmp
21214                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21215                         error "MDT free space wrong after write: " \
21216                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21217         fi
21218
21219         # truncate
21220         local size_dom=10000
21221
21222         $TRUNCATE $dom $size_dom
21223         [ $(stat -c%s $dom) == $size_dom ] ||
21224                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21225         if [ $space_check == 1 ]; then
21226                 mdtfree1=$(do_facet $facet \
21227                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21228                 # decrease in usage from $size_tmp to new $size_dom
21229                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21230                   $(((size_tmp - size_dom) / 1024)) ] ||
21231                         error "MDT free space is wrong after truncate: " \
21232                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21233         fi
21234
21235         # append
21236         cat $tmp >> $dom
21237         sync
21238         size_dom=$((size_dom + size_tmp))
21239         [ $(stat -c%s $dom) == $size_dom ] ||
21240                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21241         if [ $space_check == 1 ]; then
21242                 mdtfree2=$(do_facet $facet \
21243                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21244                 # increase in usage by $size_tmp from previous
21245                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21246                         error "MDT free space is wrong after append: " \
21247                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21248         fi
21249
21250         # delete
21251         rm $dom
21252         if [ $space_check == 1 ]; then
21253                 mdtfree1=$(do_facet $facet \
21254                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21255                 # decrease in usage by $size_dom from previous
21256                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21257                         error "MDT free space is wrong after removal: " \
21258                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21259         fi
21260
21261         # combined striping
21262         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21263                 error "Can't create DoM + OST striping"
21264
21265         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21266         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21267         # check also direct IO along write
21268         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21269         sync
21270         cmp $tmp $dom || error "file data is different"
21271         [ $(stat -c%s $dom) == $size_tmp ] ||
21272                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21273         rm $dom $tmp
21274
21275         return 0
21276 }
21277 run_test 270a "DoM: basic functionality tests"
21278
21279 test_270b() {
21280         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21281                 skip "Need MDS version at least 2.10.55"
21282
21283         local dom=$DIR/$tdir/dom_file
21284         local max_size=1048576
21285
21286         mkdir -p $DIR/$tdir
21287         $LFS setstripe -E $max_size -L mdt $dom
21288
21289         # truncate over the limit
21290         $TRUNCATE $dom $(($max_size + 1)) &&
21291                 error "successful truncate over the maximum size"
21292         # write over the limit
21293         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21294                 error "successful write over the maximum size"
21295         # append over the limit
21296         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21297         echo "12345" >> $dom && error "successful append over the maximum size"
21298         rm $dom
21299
21300         return 0
21301 }
21302 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21303
21304 test_270c() {
21305         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21306                 skip "Need MDS version at least 2.10.55"
21307
21308         mkdir -p $DIR/$tdir
21309         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21310
21311         # check files inherit DoM EA
21312         touch $DIR/$tdir/first
21313         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21314                 error "bad pattern"
21315         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21316                 error "bad stripe count"
21317         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21318                 error "bad stripe size"
21319
21320         # check directory inherits DoM EA and uses it as default
21321         mkdir $DIR/$tdir/subdir
21322         touch $DIR/$tdir/subdir/second
21323         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21324                 error "bad pattern in sub-directory"
21325         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21326                 error "bad stripe count in sub-directory"
21327         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21328                 error "bad stripe size in sub-directory"
21329         return 0
21330 }
21331 run_test 270c "DoM: DoM EA inheritance tests"
21332
21333 test_270d() {
21334         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21335                 skip "Need MDS version at least 2.10.55"
21336
21337         mkdir -p $DIR/$tdir
21338         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21339
21340         # inherit default DoM striping
21341         mkdir $DIR/$tdir/subdir
21342         touch $DIR/$tdir/subdir/f1
21343
21344         # change default directory striping
21345         $LFS setstripe -c 1 $DIR/$tdir/subdir
21346         touch $DIR/$tdir/subdir/f2
21347         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21348                 error "wrong default striping in file 2"
21349         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21350                 error "bad pattern in file 2"
21351         return 0
21352 }
21353 run_test 270d "DoM: change striping from DoM to RAID0"
21354
21355 test_270e() {
21356         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21357                 skip "Need MDS version at least 2.10.55"
21358
21359         mkdir -p $DIR/$tdir/dom
21360         mkdir -p $DIR/$tdir/norm
21361         DOMFILES=20
21362         NORMFILES=10
21363         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21364         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21365
21366         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21367         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21368
21369         # find DoM files by layout
21370         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21371         [ $NUM -eq  $DOMFILES ] ||
21372                 error "lfs find -L: found $NUM, expected $DOMFILES"
21373         echo "Test 1: lfs find 20 DOM files by layout: OK"
21374
21375         # there should be 1 dir with default DOM striping
21376         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21377         [ $NUM -eq  1 ] ||
21378                 error "lfs find -L: found $NUM, expected 1 dir"
21379         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21380
21381         # find DoM files by stripe size
21382         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21383         [ $NUM -eq  $DOMFILES ] ||
21384                 error "lfs find -S: found $NUM, expected $DOMFILES"
21385         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21386
21387         # find files by stripe offset except DoM files
21388         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21389         [ $NUM -eq  $NORMFILES ] ||
21390                 error "lfs find -i: found $NUM, expected $NORMFILES"
21391         echo "Test 5: lfs find no DOM files by stripe index: OK"
21392         return 0
21393 }
21394 run_test 270e "DoM: lfs find with DoM files test"
21395
21396 test_270f() {
21397         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21398                 skip "Need MDS version at least 2.10.55"
21399
21400         local mdtname=${FSNAME}-MDT0000-mdtlov
21401         local dom=$DIR/$tdir/dom_file
21402         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21403                                                 lod.$mdtname.dom_stripesize)
21404         local dom_limit=131072
21405
21406         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21407         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21408                                                 lod.$mdtname.dom_stripesize)
21409         [ ${dom_limit} -eq ${dom_current} ] ||
21410                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21411
21412         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21413         $LFS setstripe -d $DIR/$tdir
21414         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21415                 error "Can't set directory default striping"
21416
21417         # exceed maximum stripe size
21418         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21419                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21420         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21421                 error "Able to create DoM component size more than LOD limit"
21422
21423         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21424         dom_current=$(do_facet mds1 $LCTL get_param -n \
21425                                                 lod.$mdtname.dom_stripesize)
21426         [ 0 -eq ${dom_current} ] ||
21427                 error "Can't set zero DoM stripe limit"
21428         rm $dom
21429
21430         # attempt to create DoM file on server with disabled DoM should
21431         # remove DoM entry from layout and be succeed
21432         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21433                 error "Can't create DoM file (DoM is disabled)"
21434         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21435                 error "File has DoM component while DoM is disabled"
21436         rm $dom
21437
21438         # attempt to create DoM file with only DoM stripe should return error
21439         $LFS setstripe -E $dom_limit -L mdt $dom &&
21440                 error "Able to create DoM-only file while DoM is disabled"
21441
21442         # too low values to be aligned with smallest stripe size 64K
21443         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21444         dom_current=$(do_facet mds1 $LCTL get_param -n \
21445                                                 lod.$mdtname.dom_stripesize)
21446         [ 30000 -eq ${dom_current} ] &&
21447                 error "Can set too small DoM stripe limit"
21448
21449         # 64K is a minimal stripe size in Lustre, expect limit of that size
21450         [ 65536 -eq ${dom_current} ] ||
21451                 error "Limit is not set to 64K but ${dom_current}"
21452
21453         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21454         dom_current=$(do_facet mds1 $LCTL get_param -n \
21455                                                 lod.$mdtname.dom_stripesize)
21456         echo $dom_current
21457         [ 2147483648 -eq ${dom_current} ] &&
21458                 error "Can set too large DoM stripe limit"
21459
21460         do_facet mds1 $LCTL set_param -n \
21461                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21462         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21463                 error "Can't create DoM component size after limit change"
21464         do_facet mds1 $LCTL set_param -n \
21465                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21466         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21467                 error "Can't create DoM file after limit decrease"
21468         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21469                 error "Can create big DoM component after limit decrease"
21470         touch ${dom}_def ||
21471                 error "Can't create file with old default layout"
21472
21473         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21474         return 0
21475 }
21476 run_test 270f "DoM: maximum DoM stripe size checks"
21477
21478 test_270g() {
21479         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21480                 skip "Need MDS version at least 2.13.52"
21481         local dom=$DIR/$tdir/$tfile
21482
21483         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21484         local lodname=${FSNAME}-MDT0000-mdtlov
21485
21486         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21487         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21488         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21489         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21490
21491         local dom_limit=1024
21492         local dom_threshold="50%"
21493
21494         $LFS setstripe -d $DIR/$tdir
21495         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21496                 error "Can't set directory default striping"
21497
21498         do_facet mds1 $LCTL set_param -n \
21499                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21500         # set 0 threshold and create DOM file to change tunable stripesize
21501         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21502         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21503                 error "Failed to create $dom file"
21504         # now tunable dom_cur_stripesize should reach maximum
21505         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21506                                         lod.${lodname}.dom_stripesize_cur_kb)
21507         [[ $dom_current == $dom_limit ]] ||
21508                 error "Current DOM stripesize is not maximum"
21509         rm $dom
21510
21511         # set threshold for further tests
21512         do_facet mds1 $LCTL set_param -n \
21513                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21514         echo "DOM threshold is $dom_threshold free space"
21515         local dom_def
21516         local dom_set
21517         # Spoof bfree to exceed threshold
21518         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21519         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21520         for spfree in 40 20 0 15 30 55; do
21521                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21522                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21523                         error "Failed to create $dom file"
21524                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21525                                         lod.${lodname}.dom_stripesize_cur_kb)
21526                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21527                 [[ $dom_def != $dom_current ]] ||
21528                         error "Default stripe size was not changed"
21529                 if [[ $spfree > 0 ]] ; then
21530                         dom_set=$($LFS getstripe -S $dom)
21531                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21532                                 error "DOM component size is still old"
21533                 else
21534                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21535                                 error "DoM component is set with no free space"
21536                 fi
21537                 rm $dom
21538                 dom_current=$dom_def
21539         done
21540 }
21541 run_test 270g "DoM: default DoM stripe size depends on free space"
21542
21543 test_270h() {
21544         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21545                 skip "Need MDS version at least 2.13.53"
21546
21547         local mdtname=${FSNAME}-MDT0000-mdtlov
21548         local dom=$DIR/$tdir/$tfile
21549         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21550
21551         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21552         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21553
21554         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21555         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21556                 error "can't create OST file"
21557         # mirrored file with DOM entry in the second mirror
21558         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21559                 error "can't create mirror with DoM component"
21560
21561         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21562
21563         # DOM component in the middle and has other enries in the same mirror,
21564         # should succeed but lost DoM component
21565         $LFS setstripe --copy=${dom}_1 $dom ||
21566                 error "Can't create file from OST|DOM mirror layout"
21567         # check new file has no DoM layout after all
21568         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21569                 error "File has DoM component while DoM is disabled"
21570 }
21571 run_test 270h "DoM: DoM stripe removal when disabled on server"
21572
21573 test_271a() {
21574         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21575                 skip "Need MDS version at least 2.10.55"
21576
21577         local dom=$DIR/$tdir/dom
21578
21579         mkdir -p $DIR/$tdir
21580
21581         $LFS setstripe -E 1024K -L mdt $dom
21582
21583         lctl set_param -n mdc.*.stats=clear
21584         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21585         cat $dom > /dev/null
21586         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21587         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21588         ls $dom
21589         rm -f $dom
21590 }
21591 run_test 271a "DoM: data is cached for read after write"
21592
21593 test_271b() {
21594         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21595                 skip "Need MDS version at least 2.10.55"
21596
21597         local dom=$DIR/$tdir/dom
21598
21599         mkdir -p $DIR/$tdir
21600
21601         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21602
21603         lctl set_param -n mdc.*.stats=clear
21604         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21605         cancel_lru_locks mdc
21606         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21607         # second stat to check size is cached on client
21608         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21609         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21610         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21611         rm -f $dom
21612 }
21613 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21614
21615 test_271ba() {
21616         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21617                 skip "Need MDS version at least 2.10.55"
21618
21619         local dom=$DIR/$tdir/dom
21620
21621         mkdir -p $DIR/$tdir
21622
21623         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21624
21625         lctl set_param -n mdc.*.stats=clear
21626         lctl set_param -n osc.*.stats=clear
21627         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21628         cancel_lru_locks mdc
21629         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21630         # second stat to check size is cached on client
21631         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21632         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21633         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21634         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21635         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21636         rm -f $dom
21637 }
21638 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21639
21640
21641 get_mdc_stats() {
21642         local mdtidx=$1
21643         local param=$2
21644         local mdt=MDT$(printf %04x $mdtidx)
21645
21646         if [ -z $param ]; then
21647                 lctl get_param -n mdc.*$mdt*.stats
21648         else
21649                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21650         fi
21651 }
21652
21653 test_271c() {
21654         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21655                 skip "Need MDS version at least 2.10.55"
21656
21657         local dom=$DIR/$tdir/dom
21658
21659         mkdir -p $DIR/$tdir
21660
21661         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21662
21663         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21664         local facet=mds$((mdtidx + 1))
21665
21666         cancel_lru_locks mdc
21667         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21668         createmany -o $dom 1000
21669         lctl set_param -n mdc.*.stats=clear
21670         smalliomany -w $dom 1000 200
21671         get_mdc_stats $mdtidx
21672         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21673         # Each file has 1 open, 1 IO enqueues, total 2000
21674         # but now we have also +1 getxattr for security.capability, total 3000
21675         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21676         unlinkmany $dom 1000
21677
21678         cancel_lru_locks mdc
21679         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21680         createmany -o $dom 1000
21681         lctl set_param -n mdc.*.stats=clear
21682         smalliomany -w $dom 1000 200
21683         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21684         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21685         # for OPEN and IO lock.
21686         [ $((enq - enq_2)) -ge 1000 ] ||
21687                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21688         unlinkmany $dom 1000
21689         return 0
21690 }
21691 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21692
21693 cleanup_271def_tests() {
21694         trap 0
21695         rm -f $1
21696 }
21697
21698 test_271d() {
21699         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21700                 skip "Need MDS version at least 2.10.57"
21701
21702         local dom=$DIR/$tdir/dom
21703         local tmp=$TMP/$tfile
21704         trap "cleanup_271def_tests $tmp" EXIT
21705
21706         mkdir -p $DIR/$tdir
21707
21708         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21709
21710         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21711
21712         cancel_lru_locks mdc
21713         dd if=/dev/urandom of=$tmp bs=1000 count=1
21714         dd if=$tmp of=$dom bs=1000 count=1
21715         cancel_lru_locks mdc
21716
21717         cat /etc/hosts >> $tmp
21718         lctl set_param -n mdc.*.stats=clear
21719
21720         # append data to the same file it should update local page
21721         echo "Append to the same page"
21722         cat /etc/hosts >> $dom
21723         local num=$(get_mdc_stats $mdtidx ost_read)
21724         local ra=$(get_mdc_stats $mdtidx req_active)
21725         local rw=$(get_mdc_stats $mdtidx req_waittime)
21726
21727         [ -z $num ] || error "$num READ RPC occured"
21728         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21729         echo "... DONE"
21730
21731         # compare content
21732         cmp $tmp $dom || error "file miscompare"
21733
21734         cancel_lru_locks mdc
21735         lctl set_param -n mdc.*.stats=clear
21736
21737         echo "Open and read file"
21738         cat $dom > /dev/null
21739         local num=$(get_mdc_stats $mdtidx ost_read)
21740         local ra=$(get_mdc_stats $mdtidx req_active)
21741         local rw=$(get_mdc_stats $mdtidx req_waittime)
21742
21743         [ -z $num ] || error "$num READ RPC occured"
21744         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21745         echo "... DONE"
21746
21747         # compare content
21748         cmp $tmp $dom || error "file miscompare"
21749
21750         return 0
21751 }
21752 run_test 271d "DoM: read on open (1K file in reply buffer)"
21753
21754 test_271f() {
21755         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21756                 skip "Need MDS version at least 2.10.57"
21757
21758         local dom=$DIR/$tdir/dom
21759         local tmp=$TMP/$tfile
21760         trap "cleanup_271def_tests $tmp" EXIT
21761
21762         mkdir -p $DIR/$tdir
21763
21764         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21765
21766         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21767
21768         cancel_lru_locks mdc
21769         dd if=/dev/urandom of=$tmp bs=265000 count=1
21770         dd if=$tmp of=$dom bs=265000 count=1
21771         cancel_lru_locks mdc
21772         cat /etc/hosts >> $tmp
21773         lctl set_param -n mdc.*.stats=clear
21774
21775         echo "Append to the same page"
21776         cat /etc/hosts >> $dom
21777         local num=$(get_mdc_stats $mdtidx ost_read)
21778         local ra=$(get_mdc_stats $mdtidx req_active)
21779         local rw=$(get_mdc_stats $mdtidx req_waittime)
21780
21781         [ -z $num ] || error "$num READ RPC occured"
21782         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21783         echo "... DONE"
21784
21785         # compare content
21786         cmp $tmp $dom || error "file miscompare"
21787
21788         cancel_lru_locks mdc
21789         lctl set_param -n mdc.*.stats=clear
21790
21791         echo "Open and read file"
21792         cat $dom > /dev/null
21793         local num=$(get_mdc_stats $mdtidx ost_read)
21794         local ra=$(get_mdc_stats $mdtidx req_active)
21795         local rw=$(get_mdc_stats $mdtidx req_waittime)
21796
21797         [ -z $num ] && num=0
21798         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21799         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21800         echo "... DONE"
21801
21802         # compare content
21803         cmp $tmp $dom || error "file miscompare"
21804
21805         return 0
21806 }
21807 run_test 271f "DoM: read on open (200K file and read tail)"
21808
21809 test_271g() {
21810         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21811                 skip "Skipping due to old client or server version"
21812
21813         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21814         # to get layout
21815         $CHECKSTAT -t file $DIR1/$tfile
21816
21817         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21818         MULTIOP_PID=$!
21819         sleep 1
21820         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21821         $LCTL set_param fail_loc=0x80000314
21822         rm $DIR1/$tfile || error "Unlink fails"
21823         RC=$?
21824         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21825         [ $RC -eq 0 ] || error "Failed write to stale object"
21826 }
21827 run_test 271g "Discard DoM data vs client flush race"
21828
21829 test_272a() {
21830         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21831                 skip "Need MDS version at least 2.11.50"
21832
21833         local dom=$DIR/$tdir/dom
21834         mkdir -p $DIR/$tdir
21835
21836         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21837         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21838                 error "failed to write data into $dom"
21839         local old_md5=$(md5sum $dom)
21840
21841         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21842                 error "failed to migrate to the same DoM component"
21843
21844         local new_md5=$(md5sum $dom)
21845
21846         [ "$old_md5" == "$new_md5" ] ||
21847                 error "md5sum differ: $old_md5, $new_md5"
21848
21849         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21850                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21851 }
21852 run_test 272a "DoM migration: new layout with the same DOM component"
21853
21854 test_272b() {
21855         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21856                 skip "Need MDS version at least 2.11.50"
21857
21858         local dom=$DIR/$tdir/dom
21859         mkdir -p $DIR/$tdir
21860         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21861
21862         local mdtidx=$($LFS getstripe -m $dom)
21863         local mdtname=MDT$(printf %04x $mdtidx)
21864         local facet=mds$((mdtidx + 1))
21865
21866         local mdtfree1=$(do_facet $facet \
21867                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21868         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21869                 error "failed to write data into $dom"
21870         local old_md5=$(md5sum $dom)
21871         cancel_lru_locks mdc
21872         local mdtfree1=$(do_facet $facet \
21873                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21874
21875         $LFS migrate -c2 $dom ||
21876                 error "failed to migrate to the new composite layout"
21877         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21878                 error "MDT stripe was not removed"
21879
21880         cancel_lru_locks mdc
21881         local new_md5=$(md5sum $dom)
21882         [ "$old_md5" == "$new_md5" ] ||
21883                 error "$old_md5 != $new_md5"
21884
21885         # Skip free space checks with ZFS
21886         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21887                 local mdtfree2=$(do_facet $facet \
21888                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21889                 [ $mdtfree2 -gt $mdtfree1 ] ||
21890                         error "MDT space is not freed after migration"
21891         fi
21892         return 0
21893 }
21894 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21895
21896 test_272c() {
21897         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21898                 skip "Need MDS version at least 2.11.50"
21899
21900         local dom=$DIR/$tdir/$tfile
21901         mkdir -p $DIR/$tdir
21902         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21903
21904         local mdtidx=$($LFS getstripe -m $dom)
21905         local mdtname=MDT$(printf %04x $mdtidx)
21906         local facet=mds$((mdtidx + 1))
21907
21908         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21909                 error "failed to write data into $dom"
21910         local old_md5=$(md5sum $dom)
21911         cancel_lru_locks mdc
21912         local mdtfree1=$(do_facet $facet \
21913                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21914
21915         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21916                 error "failed to migrate to the new composite layout"
21917         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21918                 error "MDT stripe was not removed"
21919
21920         cancel_lru_locks mdc
21921         local new_md5=$(md5sum $dom)
21922         [ "$old_md5" == "$new_md5" ] ||
21923                 error "$old_md5 != $new_md5"
21924
21925         # Skip free space checks with ZFS
21926         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21927                 local mdtfree2=$(do_facet $facet \
21928                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21929                 [ $mdtfree2 -gt $mdtfree1 ] ||
21930                         error "MDS space is not freed after migration"
21931         fi
21932         return 0
21933 }
21934 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21935
21936 test_272d() {
21937         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21938                 skip "Need MDS version at least 2.12.55"
21939
21940         local dom=$DIR/$tdir/$tfile
21941         mkdir -p $DIR/$tdir
21942         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21943
21944         local mdtidx=$($LFS getstripe -m $dom)
21945         local mdtname=MDT$(printf %04x $mdtidx)
21946         local facet=mds$((mdtidx + 1))
21947
21948         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21949                 error "failed to write data into $dom"
21950         local old_md5=$(md5sum $dom)
21951         cancel_lru_locks mdc
21952         local mdtfree1=$(do_facet $facet \
21953                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21954
21955         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21956                 error "failed mirroring to the new composite layout"
21957         $LFS mirror resync $dom ||
21958                 error "failed mirror resync"
21959         $LFS mirror split --mirror-id 1 -d $dom ||
21960                 error "failed mirror split"
21961
21962         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21963                 error "MDT stripe was not removed"
21964
21965         cancel_lru_locks mdc
21966         local new_md5=$(md5sum $dom)
21967         [ "$old_md5" == "$new_md5" ] ||
21968                 error "$old_md5 != $new_md5"
21969
21970         # Skip free space checks with ZFS
21971         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21972                 local mdtfree2=$(do_facet $facet \
21973                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21974                 [ $mdtfree2 -gt $mdtfree1 ] ||
21975                         error "MDS space is not freed after DOM mirror deletion"
21976         fi
21977         return 0
21978 }
21979 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21980
21981 test_272e() {
21982         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21983                 skip "Need MDS version at least 2.12.55"
21984
21985         local dom=$DIR/$tdir/$tfile
21986         mkdir -p $DIR/$tdir
21987         $LFS setstripe -c 2 $dom
21988
21989         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21990                 error "failed to write data into $dom"
21991         local old_md5=$(md5sum $dom)
21992         cancel_lru_locks mdc
21993
21994         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21995                 error "failed mirroring to the DOM layout"
21996         $LFS mirror resync $dom ||
21997                 error "failed mirror resync"
21998         $LFS mirror split --mirror-id 1 -d $dom ||
21999                 error "failed mirror split"
22000
22001         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22002                 error "MDT stripe was not removed"
22003
22004         cancel_lru_locks mdc
22005         local new_md5=$(md5sum $dom)
22006         [ "$old_md5" == "$new_md5" ] ||
22007                 error "$old_md5 != $new_md5"
22008
22009         return 0
22010 }
22011 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22012
22013 test_272f() {
22014         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22015                 skip "Need MDS version at least 2.12.55"
22016
22017         local dom=$DIR/$tdir/$tfile
22018         mkdir -p $DIR/$tdir
22019         $LFS setstripe -c 2 $dom
22020
22021         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22022                 error "failed to write data into $dom"
22023         local old_md5=$(md5sum $dom)
22024         cancel_lru_locks mdc
22025
22026         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22027                 error "failed migrating to the DOM file"
22028
22029         cancel_lru_locks mdc
22030         local new_md5=$(md5sum $dom)
22031         [ "$old_md5" != "$new_md5" ] &&
22032                 error "$old_md5 != $new_md5"
22033
22034         return 0
22035 }
22036 run_test 272f "DoM migration: OST-striped file to DOM file"
22037
22038 test_273a() {
22039         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22040                 skip "Need MDS version at least 2.11.50"
22041
22042         # Layout swap cannot be done if either file has DOM component,
22043         # this will never be supported, migration should be used instead
22044
22045         local dom=$DIR/$tdir/$tfile
22046         mkdir -p $DIR/$tdir
22047
22048         $LFS setstripe -c2 ${dom}_plain
22049         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22050         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22051                 error "can swap layout with DoM component"
22052         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22053                 error "can swap layout with DoM component"
22054
22055         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22056         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22057                 error "can swap layout with DoM component"
22058         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22059                 error "can swap layout with DoM component"
22060         return 0
22061 }
22062 run_test 273a "DoM: layout swapping should fail with DOM"
22063
22064 test_273b() {
22065         mkdir -p $DIR/$tdir
22066         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22067
22068 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22069         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22070
22071         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22072 }
22073 run_test 273b "DoM: race writeback and object destroy"
22074
22075 test_275() {
22076         remote_ost_nodsh && skip "remote OST with nodsh"
22077         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22078                 skip "Need OST version >= 2.10.57"
22079
22080         local file=$DIR/$tfile
22081         local oss
22082
22083         oss=$(comma_list $(osts_nodes))
22084
22085         dd if=/dev/urandom of=$file bs=1M count=2 ||
22086                 error "failed to create a file"
22087         cancel_lru_locks osc
22088
22089         #lock 1
22090         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22091                 error "failed to read a file"
22092
22093 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22094         $LCTL set_param fail_loc=0x8000031f
22095
22096         cancel_lru_locks osc &
22097         sleep 1
22098
22099 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22100         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22101         #IO takes another lock, but matches the PENDING one
22102         #and places it to the IO RPC
22103         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22104                 error "failed to read a file with PENDING lock"
22105 }
22106 run_test 275 "Read on a canceled duplicate lock"
22107
22108 test_276() {
22109         remote_ost_nodsh && skip "remote OST with nodsh"
22110         local pid
22111
22112         do_facet ost1 "(while true; do \
22113                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22114                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22115         pid=$!
22116
22117         for LOOP in $(seq 20); do
22118                 stop ost1
22119                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22120         done
22121         kill -9 $pid
22122         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22123                 rm $TMP/sanity_276_pid"
22124 }
22125 run_test 276 "Race between mount and obd_statfs"
22126
22127 test_277() {
22128         $LCTL set_param ldlm.namespaces.*.lru_size=0
22129         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22130         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22131                         grep ^used_mb | awk '{print $2}')
22132         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22134                 oflag=direct conv=notrunc
22135         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22136                         grep ^used_mb | awk '{print $2}')
22137         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22138 }
22139 run_test 277 "Direct IO shall drop page cache"
22140
22141 test_278() {
22142         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22143         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22144         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22145                 skip "needs the same host for mdt1 mdt2" && return
22146
22147         local pid1
22148         local pid2
22149
22150 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22151         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22152         stop mds2 &
22153         pid2=$!
22154
22155         stop mds1
22156
22157         echo "Starting MDTs"
22158         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22159         wait $pid2
22160 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22161 #will return NULL
22162         do_facet mds2 $LCTL set_param fail_loc=0
22163
22164         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22165         wait_recovery_complete mds2
22166 }
22167 run_test 278 "Race starting MDS between MDTs stop/start"
22168
22169 test_280() {
22170         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22171                 skip "Need MGS version at least 2.13.52"
22172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22173         combined_mgs_mds || skip "needs combined MGS/MDT"
22174
22175         umount_client $MOUNT
22176 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22177         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22178
22179         mount_client $MOUNT &
22180         sleep 1
22181         stop mgs || error "stop mgs failed"
22182         #for a race mgs would crash
22183         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22184         # make sure we unmount client before remounting
22185         wait
22186         umount_client $MOUNT
22187         mount_client $MOUNT || error "mount client failed"
22188 }
22189 run_test 280 "Race between MGS umount and client llog processing"
22190
22191 cleanup_test_300() {
22192         trap 0
22193         umask $SAVE_UMASK
22194 }
22195 test_striped_dir() {
22196         local mdt_index=$1
22197         local stripe_count
22198         local stripe_index
22199
22200         mkdir -p $DIR/$tdir
22201
22202         SAVE_UMASK=$(umask)
22203         trap cleanup_test_300 RETURN EXIT
22204
22205         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22206                                                 $DIR/$tdir/striped_dir ||
22207                 error "set striped dir error"
22208
22209         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22210         [ "$mode" = "755" ] || error "expect 755 got $mode"
22211
22212         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22213                 error "getdirstripe failed"
22214         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22215         if [ "$stripe_count" != "2" ]; then
22216                 error "1:stripe_count is $stripe_count, expect 2"
22217         fi
22218         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22219         if [ "$stripe_count" != "2" ]; then
22220                 error "2:stripe_count is $stripe_count, expect 2"
22221         fi
22222
22223         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22224         if [ "$stripe_index" != "$mdt_index" ]; then
22225                 error "stripe_index is $stripe_index, expect $mdt_index"
22226         fi
22227
22228         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22229                 error "nlink error after create striped dir"
22230
22231         mkdir $DIR/$tdir/striped_dir/a
22232         mkdir $DIR/$tdir/striped_dir/b
22233
22234         stat $DIR/$tdir/striped_dir/a ||
22235                 error "create dir under striped dir failed"
22236         stat $DIR/$tdir/striped_dir/b ||
22237                 error "create dir under striped dir failed"
22238
22239         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22240                 error "nlink error after mkdir"
22241
22242         rmdir $DIR/$tdir/striped_dir/a
22243         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22244                 error "nlink error after rmdir"
22245
22246         rmdir $DIR/$tdir/striped_dir/b
22247         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22248                 error "nlink error after rmdir"
22249
22250         chattr +i $DIR/$tdir/striped_dir
22251         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22252                 error "immutable flags not working under striped dir!"
22253         chattr -i $DIR/$tdir/striped_dir
22254
22255         rmdir $DIR/$tdir/striped_dir ||
22256                 error "rmdir striped dir error"
22257
22258         cleanup_test_300
22259
22260         true
22261 }
22262
22263 test_300a() {
22264         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22265                 skip "skipped for lustre < 2.7.0"
22266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22268
22269         test_striped_dir 0 || error "failed on striped dir on MDT0"
22270         test_striped_dir 1 || error "failed on striped dir on MDT0"
22271 }
22272 run_test 300a "basic striped dir sanity test"
22273
22274 test_300b() {
22275         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22276                 skip "skipped for lustre < 2.7.0"
22277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22279
22280         local i
22281         local mtime1
22282         local mtime2
22283         local mtime3
22284
22285         test_mkdir $DIR/$tdir || error "mkdir fail"
22286         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22287                 error "set striped dir error"
22288         for i in {0..9}; do
22289                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22290                 sleep 1
22291                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22292                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22293                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22294                 sleep 1
22295                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22296                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22297                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22298         done
22299         true
22300 }
22301 run_test 300b "check ctime/mtime for striped dir"
22302
22303 test_300c() {
22304         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22305                 skip "skipped for lustre < 2.7.0"
22306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22308
22309         local file_count
22310
22311         mkdir_on_mdt0 $DIR/$tdir
22312         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22313                 error "set striped dir error"
22314
22315         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22316                 error "chown striped dir failed"
22317
22318         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22319                 error "create 5k files failed"
22320
22321         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22322
22323         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22324
22325         rm -rf $DIR/$tdir
22326 }
22327 run_test 300c "chown && check ls under striped directory"
22328
22329 test_300d() {
22330         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22331                 skip "skipped for lustre < 2.7.0"
22332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22334
22335         local stripe_count
22336         local file
22337
22338         mkdir -p $DIR/$tdir
22339         $LFS setstripe -c 2 $DIR/$tdir
22340
22341         #local striped directory
22342         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22343                 error "set striped dir error"
22344         #look at the directories for debug purposes
22345         ls -l $DIR/$tdir
22346         $LFS getdirstripe $DIR/$tdir
22347         ls -l $DIR/$tdir/striped_dir
22348         $LFS getdirstripe $DIR/$tdir/striped_dir
22349         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22350                 error "create 10 files failed"
22351
22352         #remote striped directory
22353         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22354                 error "set striped dir error"
22355         #look at the directories for debug purposes
22356         ls -l $DIR/$tdir
22357         $LFS getdirstripe $DIR/$tdir
22358         ls -l $DIR/$tdir/remote_striped_dir
22359         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22360         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22361                 error "create 10 files failed"
22362
22363         for file in $(find $DIR/$tdir); do
22364                 stripe_count=$($LFS getstripe -c $file)
22365                 [ $stripe_count -eq 2 ] ||
22366                         error "wrong stripe $stripe_count for $file"
22367         done
22368
22369         rm -rf $DIR/$tdir
22370 }
22371 run_test 300d "check default stripe under striped directory"
22372
22373 test_300e() {
22374         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22375                 skip "Need MDS version at least 2.7.55"
22376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22377         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22378
22379         local stripe_count
22380         local file
22381
22382         mkdir -p $DIR/$tdir
22383
22384         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22385                 error "set striped dir error"
22386
22387         touch $DIR/$tdir/striped_dir/a
22388         touch $DIR/$tdir/striped_dir/b
22389         touch $DIR/$tdir/striped_dir/c
22390
22391         mkdir $DIR/$tdir/striped_dir/dir_a
22392         mkdir $DIR/$tdir/striped_dir/dir_b
22393         mkdir $DIR/$tdir/striped_dir/dir_c
22394
22395         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22396                 error "set striped adir under striped dir error"
22397
22398         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22399                 error "set striped bdir under striped dir error"
22400
22401         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22402                 error "set striped cdir under striped dir error"
22403
22404         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22405                 error "rename dir under striped dir fails"
22406
22407         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22408                 error "rename dir under different stripes fails"
22409
22410         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22411                 error "rename file under striped dir should succeed"
22412
22413         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22414                 error "rename dir under striped dir should succeed"
22415
22416         rm -rf $DIR/$tdir
22417 }
22418 run_test 300e "check rename under striped directory"
22419
22420 test_300f() {
22421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22423         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22424                 skip "Need MDS version at least 2.7.55"
22425
22426         local stripe_count
22427         local file
22428
22429         rm -rf $DIR/$tdir
22430         mkdir -p $DIR/$tdir
22431
22432         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22433                 error "set striped dir error"
22434
22435         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22436                 error "set striped dir error"
22437
22438         touch $DIR/$tdir/striped_dir/a
22439         mkdir $DIR/$tdir/striped_dir/dir_a
22440         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22441                 error "create striped dir under striped dir fails"
22442
22443         touch $DIR/$tdir/striped_dir1/b
22444         mkdir $DIR/$tdir/striped_dir1/dir_b
22445         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22446                 error "create striped dir under striped dir fails"
22447
22448         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22449                 error "rename dir under different striped dir should fail"
22450
22451         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22452                 error "rename striped dir under diff striped dir should fail"
22453
22454         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22455                 error "rename file under diff striped dirs fails"
22456
22457         rm -rf $DIR/$tdir
22458 }
22459 run_test 300f "check rename cross striped directory"
22460
22461 test_300_check_default_striped_dir()
22462 {
22463         local dirname=$1
22464         local default_count=$2
22465         local default_index=$3
22466         local stripe_count
22467         local stripe_index
22468         local dir_stripe_index
22469         local dir
22470
22471         echo "checking $dirname $default_count $default_index"
22472         $LFS setdirstripe -D -c $default_count -i $default_index \
22473                                 -H all_char $DIR/$tdir/$dirname ||
22474                 error "set default stripe on striped dir error"
22475         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22476         [ $stripe_count -eq $default_count ] ||
22477                 error "expect $default_count get $stripe_count for $dirname"
22478
22479         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22480         [ $stripe_index -eq $default_index ] ||
22481                 error "expect $default_index get $stripe_index for $dirname"
22482
22483         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22484                                                 error "create dirs failed"
22485
22486         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22487         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22488         for dir in $(find $DIR/$tdir/$dirname/*); do
22489                 stripe_count=$($LFS getdirstripe -c $dir)
22490                 (( $stripe_count == $default_count )) ||
22491                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22492                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22493                 error "stripe count $default_count != $stripe_count for $dir"
22494
22495                 stripe_index=$($LFS getdirstripe -i $dir)
22496                 [ $default_index -eq -1 ] ||
22497                         [ $stripe_index -eq $default_index ] ||
22498                         error "$stripe_index != $default_index for $dir"
22499
22500                 #check default stripe
22501                 stripe_count=$($LFS getdirstripe -D -c $dir)
22502                 [ $stripe_count -eq $default_count ] ||
22503                 error "default count $default_count != $stripe_count for $dir"
22504
22505                 stripe_index=$($LFS getdirstripe -D -i $dir)
22506                 [ $stripe_index -eq $default_index ] ||
22507                 error "default index $default_index != $stripe_index for $dir"
22508         done
22509         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22510 }
22511
22512 test_300g() {
22513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22514         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22515                 skip "Need MDS version at least 2.7.55"
22516
22517         local dir
22518         local stripe_count
22519         local stripe_index
22520
22521         mkdir_on_mdt0 $DIR/$tdir
22522         mkdir $DIR/$tdir/normal_dir
22523
22524         #Checking when client cache stripe index
22525         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22526         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22527                 error "create striped_dir failed"
22528
22529         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22530                 error "create dir0 fails"
22531         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22532         [ $stripe_index -eq 0 ] ||
22533                 error "dir0 expect index 0 got $stripe_index"
22534
22535         mkdir $DIR/$tdir/striped_dir/dir1 ||
22536                 error "create dir1 fails"
22537         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22538         [ $stripe_index -eq 1 ] ||
22539                 error "dir1 expect index 1 got $stripe_index"
22540
22541         #check default stripe count/stripe index
22542         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22543         test_300_check_default_striped_dir normal_dir 1 0
22544         test_300_check_default_striped_dir normal_dir -1 1
22545         test_300_check_default_striped_dir normal_dir 2 -1
22546
22547         #delete default stripe information
22548         echo "delete default stripeEA"
22549         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22550                 error "set default stripe on striped dir error"
22551
22552         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22553         for dir in $(find $DIR/$tdir/normal_dir/*); do
22554                 stripe_count=$($LFS getdirstripe -c $dir)
22555                 [ $stripe_count -eq 0 ] ||
22556                         error "expect 1 get $stripe_count for $dir"
22557                 stripe_index=$($LFS getdirstripe -i $dir)
22558                 [ $stripe_index -eq 0 ] ||
22559                         error "expect 0 get $stripe_index for $dir"
22560         done
22561 }
22562 run_test 300g "check default striped directory for normal directory"
22563
22564 test_300h() {
22565         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22566         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22567                 skip "Need MDS version at least 2.7.55"
22568
22569         local dir
22570         local stripe_count
22571
22572         mkdir $DIR/$tdir
22573         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22574                 error "set striped dir error"
22575
22576         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22577         test_300_check_default_striped_dir striped_dir 1 0
22578         test_300_check_default_striped_dir striped_dir -1 1
22579         test_300_check_default_striped_dir striped_dir 2 -1
22580
22581         #delete default stripe information
22582         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22583                 error "set default stripe on striped dir error"
22584
22585         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22586         for dir in $(find $DIR/$tdir/striped_dir/*); do
22587                 stripe_count=$($LFS getdirstripe -c $dir)
22588                 [ $stripe_count -eq 0 ] ||
22589                         error "expect 1 get $stripe_count for $dir"
22590         done
22591 }
22592 run_test 300h "check default striped directory for striped directory"
22593
22594 test_300i() {
22595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22597         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22598                 skip "Need MDS version at least 2.7.55"
22599
22600         local stripe_count
22601         local file
22602
22603         mkdir $DIR/$tdir
22604
22605         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22606                 error "set striped dir error"
22607
22608         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22609                 error "create files under striped dir failed"
22610
22611         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22612                 error "set striped hashdir error"
22613
22614         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22615                 error "create dir0 under hash dir failed"
22616         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22617                 error "create dir1 under hash dir failed"
22618         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22619                 error "create dir2 under hash dir failed"
22620
22621         # unfortunately, we need to umount to clear dir layout cache for now
22622         # once we fully implement dir layout, we can drop this
22623         umount_client $MOUNT || error "umount failed"
22624         mount_client $MOUNT || error "mount failed"
22625
22626         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22627         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22628         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22629
22630         #set the stripe to be unknown hash type
22631         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22632         $LCTL set_param fail_loc=0x1901
22633         for ((i = 0; i < 10; i++)); do
22634                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22635                         error "stat f-$i failed"
22636                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22637         done
22638
22639         touch $DIR/$tdir/striped_dir/f0 &&
22640                 error "create under striped dir with unknown hash should fail"
22641
22642         $LCTL set_param fail_loc=0
22643
22644         umount_client $MOUNT || error "umount failed"
22645         mount_client $MOUNT || error "mount failed"
22646
22647         return 0
22648 }
22649 run_test 300i "client handle unknown hash type striped directory"
22650
22651 test_300j() {
22652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22654         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22655                 skip "Need MDS version at least 2.7.55"
22656
22657         local stripe_count
22658         local file
22659
22660         mkdir $DIR/$tdir
22661
22662         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22663         $LCTL set_param fail_loc=0x1702
22664         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22665                 error "set striped dir error"
22666
22667         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22668                 error "create files under striped dir failed"
22669
22670         $LCTL set_param fail_loc=0
22671
22672         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22673
22674         return 0
22675 }
22676 run_test 300j "test large update record"
22677
22678 test_300k() {
22679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22680         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22681         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22682                 skip "Need MDS version at least 2.7.55"
22683
22684         # this test needs a huge transaction
22685         local kb
22686         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22687              osd*.$FSNAME-MDT0000.kbytestotal")
22688         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22689
22690         local stripe_count
22691         local file
22692
22693         mkdir $DIR/$tdir
22694
22695         #define OBD_FAIL_LARGE_STRIPE   0x1703
22696         $LCTL set_param fail_loc=0x1703
22697         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22698                 error "set striped dir error"
22699         $LCTL set_param fail_loc=0
22700
22701         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22702                 error "getstripeddir fails"
22703         rm -rf $DIR/$tdir/striped_dir ||
22704                 error "unlink striped dir fails"
22705
22706         return 0
22707 }
22708 run_test 300k "test large striped directory"
22709
22710 test_300l() {
22711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22713         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22714                 skip "Need MDS version at least 2.7.55"
22715
22716         local stripe_index
22717
22718         test_mkdir -p $DIR/$tdir/striped_dir
22719         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22720                         error "chown $RUNAS_ID failed"
22721         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22722                 error "set default striped dir failed"
22723
22724         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22725         $LCTL set_param fail_loc=0x80000158
22726         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22727
22728         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22729         [ $stripe_index -eq 1 ] ||
22730                 error "expect 1 get $stripe_index for $dir"
22731 }
22732 run_test 300l "non-root user to create dir under striped dir with stale layout"
22733
22734 test_300m() {
22735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22736         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22737         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22738                 skip "Need MDS version at least 2.7.55"
22739
22740         mkdir -p $DIR/$tdir/striped_dir
22741         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22742                 error "set default stripes dir error"
22743
22744         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22745
22746         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22747         [ $stripe_count -eq 0 ] ||
22748                         error "expect 0 get $stripe_count for a"
22749
22750         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22751                 error "set default stripes dir error"
22752
22753         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22754
22755         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22756         [ $stripe_count -eq 0 ] ||
22757                         error "expect 0 get $stripe_count for b"
22758
22759         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22760                 error "set default stripes dir error"
22761
22762         mkdir $DIR/$tdir/striped_dir/c &&
22763                 error "default stripe_index is invalid, mkdir c should fails"
22764
22765         rm -rf $DIR/$tdir || error "rmdir fails"
22766 }
22767 run_test 300m "setstriped directory on single MDT FS"
22768
22769 cleanup_300n() {
22770         local list=$(comma_list $(mdts_nodes))
22771
22772         trap 0
22773         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22774 }
22775
22776 test_300n() {
22777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22779         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22780                 skip "Need MDS version at least 2.7.55"
22781         remote_mds_nodsh && skip "remote MDS with nodsh"
22782
22783         local stripe_index
22784         local list=$(comma_list $(mdts_nodes))
22785
22786         trap cleanup_300n RETURN EXIT
22787         mkdir -p $DIR/$tdir
22788         chmod 777 $DIR/$tdir
22789         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22790                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22791                 error "create striped dir succeeds with gid=0"
22792
22793         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22794         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22795                 error "create striped dir fails with gid=-1"
22796
22797         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22798         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22799                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22800                 error "set default striped dir succeeds with gid=0"
22801
22802
22803         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22804         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22805                 error "set default striped dir fails with gid=-1"
22806
22807
22808         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22809         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22810                                         error "create test_dir fails"
22811         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22812                                         error "create test_dir1 fails"
22813         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22814                                         error "create test_dir2 fails"
22815         cleanup_300n
22816 }
22817 run_test 300n "non-root user to create dir under striped dir with default EA"
22818
22819 test_300o() {
22820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22822         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22823                 skip "Need MDS version at least 2.7.55"
22824
22825         local numfree1
22826         local numfree2
22827
22828         mkdir -p $DIR/$tdir
22829
22830         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22831         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22832         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22833                 skip "not enough free inodes $numfree1 $numfree2"
22834         fi
22835
22836         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22837         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22838         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22839                 skip "not enough free space $numfree1 $numfree2"
22840         fi
22841
22842         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22843                 error "setdirstripe fails"
22844
22845         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22846                 error "create dirs fails"
22847
22848         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22849         ls $DIR/$tdir/striped_dir > /dev/null ||
22850                 error "ls striped dir fails"
22851         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22852                 error "unlink big striped dir fails"
22853 }
22854 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22855
22856 test_300p() {
22857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22859         remote_mds_nodsh && skip "remote MDS with nodsh"
22860
22861         mkdir_on_mdt0 $DIR/$tdir
22862
22863         #define OBD_FAIL_OUT_ENOSPC     0x1704
22864         do_facet mds2 lctl set_param fail_loc=0x80001704
22865         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22866                  && error "create striped directory should fail"
22867
22868         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22869
22870         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22871         true
22872 }
22873 run_test 300p "create striped directory without space"
22874
22875 test_300q() {
22876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22878
22879         local fd=$(free_fd)
22880         local cmd="exec $fd<$tdir"
22881         cd $DIR
22882         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22883         eval $cmd
22884         cmd="exec $fd<&-"
22885         trap "eval $cmd" EXIT
22886         cd $tdir || error "cd $tdir fails"
22887         rmdir  ../$tdir || error "rmdir $tdir fails"
22888         mkdir local_dir && error "create dir succeeds"
22889         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22890         eval $cmd
22891         return 0
22892 }
22893 run_test 300q "create remote directory under orphan directory"
22894
22895 test_300r() {
22896         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22897                 skip "Need MDS version at least 2.7.55" && return
22898         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22899
22900         mkdir $DIR/$tdir
22901
22902         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22903                 error "set striped dir error"
22904
22905         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22906                 error "getstripeddir fails"
22907
22908         local stripe_count
22909         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22910                       awk '/lmv_stripe_count:/ { print $2 }')
22911
22912         [ $MDSCOUNT -ne $stripe_count ] &&
22913                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22914
22915         rm -rf $DIR/$tdir/striped_dir ||
22916                 error "unlink striped dir fails"
22917 }
22918 run_test 300r "test -1 striped directory"
22919
22920 test_300s_helper() {
22921         local count=$1
22922
22923         local stripe_dir=$DIR/$tdir/striped_dir.$count
22924
22925         $LFS mkdir -c $count $stripe_dir ||
22926                 error "lfs mkdir -c error"
22927
22928         $LFS getdirstripe $stripe_dir ||
22929                 error "lfs getdirstripe fails"
22930
22931         local stripe_count
22932         stripe_count=$($LFS getdirstripe $stripe_dir |
22933                       awk '/lmv_stripe_count:/ { print $2 }')
22934
22935         [ $count -ne $stripe_count ] &&
22936                 error_noexit "bad stripe count $stripe_count expected $count"
22937
22938         local dupe_stripes
22939         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22940                 awk '/0x/ {count[$1] += 1}; END {
22941                         for (idx in count) {
22942                                 if (count[idx]>1) {
22943                                         print "index " idx " count " count[idx]
22944                                 }
22945                         }
22946                 }')
22947
22948         if [[ -n "$dupe_stripes" ]] ; then
22949                 lfs getdirstripe $stripe_dir
22950                 error_noexit "Dupe MDT above: $dupe_stripes "
22951         fi
22952
22953         rm -rf $stripe_dir ||
22954                 error_noexit "unlink $stripe_dir fails"
22955 }
22956
22957 test_300s() {
22958         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22959                 skip "Need MDS version at least 2.7.55" && return
22960         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22961
22962         mkdir $DIR/$tdir
22963         for count in $(seq 2 $MDSCOUNT); do
22964                 test_300s_helper $count
22965         done
22966 }
22967 run_test 300s "test lfs mkdir -c without -i"
22968
22969
22970 prepare_remote_file() {
22971         mkdir $DIR/$tdir/src_dir ||
22972                 error "create remote source failed"
22973
22974         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22975                  error "cp to remote source failed"
22976         touch $DIR/$tdir/src_dir/a
22977
22978         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22979                 error "create remote target dir failed"
22980
22981         touch $DIR/$tdir/tgt_dir/b
22982
22983         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22984                 error "rename dir cross MDT failed!"
22985
22986         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22987                 error "src_child still exists after rename"
22988
22989         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22990                 error "missing file(a) after rename"
22991
22992         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22993                 error "diff after rename"
22994 }
22995
22996 test_310a() {
22997         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22999
23000         local remote_file=$DIR/$tdir/tgt_dir/b
23001
23002         mkdir -p $DIR/$tdir
23003
23004         prepare_remote_file || error "prepare remote file failed"
23005
23006         #open-unlink file
23007         $OPENUNLINK $remote_file $remote_file ||
23008                 error "openunlink $remote_file failed"
23009         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23010 }
23011 run_test 310a "open unlink remote file"
23012
23013 test_310b() {
23014         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23016
23017         local remote_file=$DIR/$tdir/tgt_dir/b
23018
23019         mkdir -p $DIR/$tdir
23020
23021         prepare_remote_file || error "prepare remote file failed"
23022
23023         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23024         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23025         $CHECKSTAT -t file $remote_file || error "check file failed"
23026 }
23027 run_test 310b "unlink remote file with multiple links while open"
23028
23029 test_310c() {
23030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23031         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23032
23033         local remote_file=$DIR/$tdir/tgt_dir/b
23034
23035         mkdir -p $DIR/$tdir
23036
23037         prepare_remote_file || error "prepare remote file failed"
23038
23039         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23040         multiop_bg_pause $remote_file O_uc ||
23041                         error "mulitop failed for remote file"
23042         MULTIPID=$!
23043         $MULTIOP $DIR/$tfile Ouc
23044         kill -USR1 $MULTIPID
23045         wait $MULTIPID
23046 }
23047 run_test 310c "open-unlink remote file with multiple links"
23048
23049 #LU-4825
23050 test_311() {
23051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23052         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23053         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23054                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23055         remote_mds_nodsh && skip "remote MDS with nodsh"
23056
23057         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23058         local mdts=$(comma_list $(mdts_nodes))
23059
23060         mkdir -p $DIR/$tdir
23061         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23062         createmany -o $DIR/$tdir/$tfile. 1000
23063
23064         # statfs data is not real time, let's just calculate it
23065         old_iused=$((old_iused + 1000))
23066
23067         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23068                         osp.*OST0000*MDT0000.create_count")
23069         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23070                                 osp.*OST0000*MDT0000.max_create_count")
23071         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23072
23073         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23074         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23075         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23076
23077         unlinkmany $DIR/$tdir/$tfile. 1000
23078
23079         do_nodes $mdts "$LCTL set_param -n \
23080                         osp.*OST0000*.max_create_count=$max_count"
23081         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23082                 do_nodes $mdts "$LCTL set_param -n \
23083                                 osp.*OST0000*.create_count=$count"
23084         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23085                         grep "=0" && error "create_count is zero"
23086
23087         local new_iused
23088         for i in $(seq 120); do
23089                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23090                 # system may be too busy to destroy all objs in time, use
23091                 # a somewhat small value to not fail autotest
23092                 [ $((old_iused - new_iused)) -gt 400 ] && break
23093                 sleep 1
23094         done
23095
23096         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23097         [ $((old_iused - new_iused)) -gt 400 ] ||
23098                 error "objs not destroyed after unlink"
23099 }
23100 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23101
23102 zfs_oid_to_objid()
23103 {
23104         local ost=$1
23105         local objid=$2
23106
23107         local vdevdir=$(dirname $(facet_vdevice $ost))
23108         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23109         local zfs_zapid=$(do_facet $ost $cmd |
23110                           grep -w "/O/0/d$((objid%32))" -C 5 |
23111                           awk '/Object/{getline; print $1}')
23112         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23113                           awk "/$objid = /"'{printf $3}')
23114
23115         echo $zfs_objid
23116 }
23117
23118 zfs_object_blksz() {
23119         local ost=$1
23120         local objid=$2
23121
23122         local vdevdir=$(dirname $(facet_vdevice $ost))
23123         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23124         local blksz=$(do_facet $ost $cmd $objid |
23125                       awk '/dblk/{getline; printf $4}')
23126
23127         case "${blksz: -1}" in
23128                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23129                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23130                 *) ;;
23131         esac
23132
23133         echo $blksz
23134 }
23135
23136 test_312() { # LU-4856
23137         remote_ost_nodsh && skip "remote OST with nodsh"
23138         [ "$ost1_FSTYPE" = "zfs" ] ||
23139                 skip_env "the test only applies to zfs"
23140
23141         local max_blksz=$(do_facet ost1 \
23142                           $ZFS get -p recordsize $(facet_device ost1) |
23143                           awk '!/VALUE/{print $3}')
23144
23145         # to make life a little bit easier
23146         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23147         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23148
23149         local tf=$DIR/$tdir/$tfile
23150         touch $tf
23151         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23152
23153         # Get ZFS object id
23154         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23155         # block size change by sequential overwrite
23156         local bs
23157
23158         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23159                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23160
23161                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23162                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23163         done
23164         rm -f $tf
23165
23166         # block size change by sequential append write
23167         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23168         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23169         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23170         local count
23171
23172         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23173                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23174                         oflag=sync conv=notrunc
23175
23176                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23177                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23178                         error "blksz error, actual $blksz, " \
23179                                 "expected: 2 * $count * $PAGE_SIZE"
23180         done
23181         rm -f $tf
23182
23183         # random write
23184         touch $tf
23185         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23186         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23187
23188         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23189         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23190         [ $blksz -eq $PAGE_SIZE ] ||
23191                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23192
23193         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23194         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23195         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23196
23197         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23198         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23199         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23200 }
23201 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23202
23203 test_313() {
23204         remote_ost_nodsh && skip "remote OST with nodsh"
23205
23206         local file=$DIR/$tfile
23207
23208         rm -f $file
23209         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23210
23211         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23212         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23213         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23214                 error "write should failed"
23215         do_facet ost1 "$LCTL set_param fail_loc=0"
23216         rm -f $file
23217 }
23218 run_test 313 "io should fail after last_rcvd update fail"
23219
23220 test_314() {
23221         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23222
23223         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23224         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23225         rm -f $DIR/$tfile
23226         wait_delete_completed
23227         do_facet ost1 "$LCTL set_param fail_loc=0"
23228 }
23229 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23230
23231 test_315() { # LU-618
23232         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23233
23234         local file=$DIR/$tfile
23235         rm -f $file
23236
23237         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23238                 error "multiop file write failed"
23239         $MULTIOP $file oO_RDONLY:r4063232_c &
23240         PID=$!
23241
23242         sleep 2
23243
23244         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23245         kill -USR1 $PID
23246
23247         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23248         rm -f $file
23249 }
23250 run_test 315 "read should be accounted"
23251
23252 test_316() {
23253         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23254         large_xattr_enabled || skip_env "ea_inode feature disabled"
23255
23256         rm -rf $DIR/$tdir/d
23257         mkdir -p $DIR/$tdir/d
23258         chown nobody $DIR/$tdir/d
23259         touch $DIR/$tdir/d/file
23260
23261         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23262 }
23263 run_test 316 "lfs mv"
23264
23265 test_317() {
23266         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23267                 skip "Need MDS version at least 2.11.53"
23268         if [ "$ost1_FSTYPE" == "zfs" ]; then
23269                 skip "LU-10370: no implementation for ZFS"
23270         fi
23271
23272         local trunc_sz
23273         local grant_blk_size
23274
23275         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23276                         awk '/grant_block_size:/ { print $2; exit; }')
23277         #
23278         # Create File of size 5M. Truncate it to below size's and verify
23279         # blocks count.
23280         #
23281         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23282                 error "Create file $DIR/$tfile failed"
23283         stack_trap "rm -f $DIR/$tfile" EXIT
23284
23285         for trunc_sz in 2097152 4097 4000 509 0; do
23286                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23287                         error "truncate $tfile to $trunc_sz failed"
23288                 local sz=$(stat --format=%s $DIR/$tfile)
23289                 local blk=$(stat --format=%b $DIR/$tfile)
23290                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23291                                      grant_blk_size) * 8))
23292
23293                 if [[ $blk -ne $trunc_blk ]]; then
23294                         $(which stat) $DIR/$tfile
23295                         error "Expected Block $trunc_blk got $blk for $tfile"
23296                 fi
23297
23298                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23299                         error "Expected Size $trunc_sz got $sz for $tfile"
23300         done
23301
23302         #
23303         # sparse file test
23304         # Create file with a hole and write actual two blocks. Block count
23305         # must be 16.
23306         #
23307         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23308                 conv=fsync || error "Create file : $DIR/$tfile"
23309
23310         # Calculate the final truncate size.
23311         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23312
23313         #
23314         # truncate to size $trunc_sz bytes. Strip the last block
23315         # The block count must drop to 8
23316         #
23317         $TRUNCATE $DIR/$tfile $trunc_sz ||
23318                 error "truncate $tfile to $trunc_sz failed"
23319
23320         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23321         sz=$(stat --format=%s $DIR/$tfile)
23322         blk=$(stat --format=%b $DIR/$tfile)
23323
23324         if [[ $blk -ne $trunc_bsz ]]; then
23325                 $(which stat) $DIR/$tfile
23326                 error "Expected Block $trunc_bsz got $blk for $tfile"
23327         fi
23328
23329         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23330                 error "Expected Size $trunc_sz got $sz for $tfile"
23331 }
23332 run_test 317 "Verify blocks get correctly update after truncate"
23333
23334 test_318() {
23335         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23336         local old_max_active=$($LCTL get_param -n \
23337                             ${llite_name}.max_read_ahead_async_active \
23338                             2>/dev/null)
23339
23340         $LCTL set_param llite.*.max_read_ahead_async_active=256
23341         local max_active=$($LCTL get_param -n \
23342                            ${llite_name}.max_read_ahead_async_active \
23343                            2>/dev/null)
23344         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23345
23346         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23347                 error "set max_read_ahead_async_active should succeed"
23348
23349         $LCTL set_param llite.*.max_read_ahead_async_active=512
23350         max_active=$($LCTL get_param -n \
23351                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23352         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23353
23354         # restore @max_active
23355         [ $old_max_active -ne 0 ] && $LCTL set_param \
23356                 llite.*.max_read_ahead_async_active=$old_max_active
23357
23358         local old_threshold=$($LCTL get_param -n \
23359                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23360         local max_per_file_mb=$($LCTL get_param -n \
23361                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23362
23363         local invalid=$(($max_per_file_mb + 1))
23364         $LCTL set_param \
23365                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23366                         && error "set $invalid should fail"
23367
23368         local valid=$(($invalid - 1))
23369         $LCTL set_param \
23370                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23371                         error "set $valid should succeed"
23372         local threshold=$($LCTL get_param -n \
23373                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23374         [ $threshold -eq $valid ] || error \
23375                 "expect threshold $valid got $threshold"
23376         $LCTL set_param \
23377                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23378 }
23379 run_test 318 "Verify async readahead tunables"
23380
23381 test_319() {
23382         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23383
23384         local before=$(date +%s)
23385         local evict
23386         local mdir=$DIR/$tdir
23387         local file=$mdir/xxx
23388
23389         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23390         touch $file
23391
23392 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23393         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23394         $LFS mv -m1 $file &
23395
23396         sleep 1
23397         dd if=$file of=/dev/null
23398         wait
23399         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23400           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23401
23402         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23403 }
23404 run_test 319 "lost lease lock on migrate error"
23405
23406 test_398a() { # LU-4198
23407         local ost1_imp=$(get_osc_import_name client ost1)
23408         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23409                          cut -d'.' -f2)
23410
23411         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23412         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23413
23414         # request a new lock on client
23415         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23416
23417         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23418         local lock_count=$($LCTL get_param -n \
23419                            ldlm.namespaces.$imp_name.lru_size)
23420         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23421
23422         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23423
23424         # no lock cached, should use lockless IO and not enqueue new lock
23425         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23426         lock_count=$($LCTL get_param -n \
23427                      ldlm.namespaces.$imp_name.lru_size)
23428         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23429 }
23430 run_test 398a "direct IO should cancel lock otherwise lockless"
23431
23432 test_398b() { # LU-4198
23433         which fio || skip_env "no fio installed"
23434         $LFS setstripe -c -1 $DIR/$tfile
23435
23436         local size=12
23437         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23438
23439         local njobs=4
23440         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23441         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23442                 --numjobs=$njobs --fallocate=none \
23443                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23444                 --filename=$DIR/$tfile &
23445         bg_pid=$!
23446
23447         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23448         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23449                 --numjobs=$njobs --fallocate=none \
23450                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23451                 --filename=$DIR/$tfile || true
23452         wait $bg_pid
23453
23454         rm -f $DIR/$tfile
23455 }
23456 run_test 398b "DIO and buffer IO race"
23457
23458 test_398c() { # LU-4198
23459         local ost1_imp=$(get_osc_import_name client ost1)
23460         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23461                          cut -d'.' -f2)
23462
23463         which fio || skip_env "no fio installed"
23464
23465         saved_debug=$($LCTL get_param -n debug)
23466         $LCTL set_param debug=0
23467
23468         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23469         ((size /= 1024)) # by megabytes
23470         ((size /= 2)) # write half of the OST at most
23471         [ $size -gt 40 ] && size=40 #reduce test time anyway
23472
23473         $LFS setstripe -c 1 $DIR/$tfile
23474
23475         # it seems like ldiskfs reserves more space than necessary if the
23476         # writing blocks are not mapped, so it extends the file firstly
23477         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23478         cancel_lru_locks osc
23479
23480         # clear and verify rpc_stats later
23481         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23482
23483         local njobs=4
23484         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23485         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23486                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23487                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23488                 --filename=$DIR/$tfile
23489         [ $? -eq 0 ] || error "fio write error"
23490
23491         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23492                 error "Locks were requested while doing AIO"
23493
23494         # get the percentage of 1-page I/O
23495         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23496                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23497                 awk '{print $7}')
23498         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23499
23500         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23501         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23502                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23503                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23504                 --filename=$DIR/$tfile
23505         [ $? -eq 0 ] || error "fio mixed read write error"
23506
23507         echo "AIO with large block size ${size}M"
23508         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23509                 --numjobs=1 --fallocate=none --ioengine=libaio \
23510                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23511                 --filename=$DIR/$tfile
23512         [ $? -eq 0 ] || error "fio large block size failed"
23513
23514         rm -f $DIR/$tfile
23515         $LCTL set_param debug="$saved_debug"
23516 }
23517 run_test 398c "run fio to test AIO"
23518
23519 test_398d() { #  LU-13846
23520         which aiocp || skip_env "no aiocp installed"
23521         local aio_file=$DIR/$tfile.aio
23522
23523         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23524
23525         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23526         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23527         stack_trap "rm -f $DIR/$tfile $aio_file"
23528
23529         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23530
23531         # make sure we don't crash and fail properly
23532         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23533                 error "aio not aligned with PAGE SIZE should fail"
23534
23535         rm -f $DIR/$tfile $aio_file
23536 }
23537 run_test 398d "run aiocp to verify block size > stripe size"
23538
23539 test_398e() {
23540         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23541         touch $DIR/$tfile.new
23542         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23543 }
23544 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23545
23546 test_398f() { #  LU-14687
23547         which aiocp || skip_env "no aiocp installed"
23548         local aio_file=$DIR/$tfile.aio
23549
23550         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23551
23552         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23553         stack_trap "rm -f $DIR/$tfile $aio_file"
23554
23555         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23556         $LCTL set_param fail_loc=0x1418
23557         # make sure we don't crash and fail properly
23558         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23559                 error "aio with page allocation failure succeeded"
23560         $LCTL set_param fail_loc=0
23561         diff $DIR/$tfile $aio_file
23562         [[ $? != 0 ]] || error "no diff after failed aiocp"
23563 }
23564 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23565
23566 test_fake_rw() {
23567         local read_write=$1
23568         if [ "$read_write" = "write" ]; then
23569                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23570         elif [ "$read_write" = "read" ]; then
23571                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23572         else
23573                 error "argument error"
23574         fi
23575
23576         # turn off debug for performance testing
23577         local saved_debug=$($LCTL get_param -n debug)
23578         $LCTL set_param debug=0
23579
23580         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23581
23582         # get ost1 size - $FSNAME-OST0000
23583         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23584         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23585         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23586
23587         if [ "$read_write" = "read" ]; then
23588                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23589         fi
23590
23591         local start_time=$(date +%s.%N)
23592         $dd_cmd bs=1M count=$blocks oflag=sync ||
23593                 error "real dd $read_write error"
23594         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23595
23596         if [ "$read_write" = "write" ]; then
23597                 rm -f $DIR/$tfile
23598         fi
23599
23600         # define OBD_FAIL_OST_FAKE_RW           0x238
23601         do_facet ost1 $LCTL set_param fail_loc=0x238
23602
23603         local start_time=$(date +%s.%N)
23604         $dd_cmd bs=1M count=$blocks oflag=sync ||
23605                 error "fake dd $read_write error"
23606         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23607
23608         if [ "$read_write" = "write" ]; then
23609                 # verify file size
23610                 cancel_lru_locks osc
23611                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23612                         error "$tfile size not $blocks MB"
23613         fi
23614         do_facet ost1 $LCTL set_param fail_loc=0
23615
23616         echo "fake $read_write $duration_fake vs. normal $read_write" \
23617                 "$duration in seconds"
23618         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23619                 error_not_in_vm "fake write is slower"
23620
23621         $LCTL set_param -n debug="$saved_debug"
23622         rm -f $DIR/$tfile
23623 }
23624 test_399a() { # LU-7655 for OST fake write
23625         remote_ost_nodsh && skip "remote OST with nodsh"
23626
23627         test_fake_rw write
23628 }
23629 run_test 399a "fake write should not be slower than normal write"
23630
23631 test_399b() { # LU-8726 for OST fake read
23632         remote_ost_nodsh && skip "remote OST with nodsh"
23633         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23634                 skip_env "ldiskfs only test"
23635         fi
23636
23637         test_fake_rw read
23638 }
23639 run_test 399b "fake read should not be slower than normal read"
23640
23641 test_400a() { # LU-1606, was conf-sanity test_74
23642         if ! which $CC > /dev/null 2>&1; then
23643                 skip_env "$CC is not installed"
23644         fi
23645
23646         local extra_flags=''
23647         local out=$TMP/$tfile
23648         local prefix=/usr/include/lustre
23649         local prog
23650
23651         # Oleg removes c files in his test rig so test if any c files exist
23652         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23653                 skip_env "Needed c test files are missing"
23654
23655         if ! [[ -d $prefix ]]; then
23656                 # Assume we're running in tree and fixup the include path.
23657                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23658                 extra_flags+=" -L$LUSTRE/utils/.lib"
23659         fi
23660
23661         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23662                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23663                         error "client api broken"
23664         done
23665         rm -f $out
23666 }
23667 run_test 400a "Lustre client api program can compile and link"
23668
23669 test_400b() { # LU-1606, LU-5011
23670         local header
23671         local out=$TMP/$tfile
23672         local prefix=/usr/include/linux/lustre
23673
23674         # We use a hard coded prefix so that this test will not fail
23675         # when run in tree. There are headers in lustre/include/lustre/
23676         # that are not packaged (like lustre_idl.h) and have more
23677         # complicated include dependencies (like config.h and lnet/types.h).
23678         # Since this test about correct packaging we just skip them when
23679         # they don't exist (see below) rather than try to fixup cppflags.
23680
23681         if ! which $CC > /dev/null 2>&1; then
23682                 skip_env "$CC is not installed"
23683         fi
23684
23685         for header in $prefix/*.h; do
23686                 if ! [[ -f "$header" ]]; then
23687                         continue
23688                 fi
23689
23690                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23691                         continue # lustre_ioctl.h is internal header
23692                 fi
23693
23694                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23695                         error "cannot compile '$header'"
23696         done
23697         rm -f $out
23698 }
23699 run_test 400b "packaged headers can be compiled"
23700
23701 test_401a() { #LU-7437
23702         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23703         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23704
23705         #count the number of parameters by "list_param -R"
23706         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23707         #count the number of parameters by listing proc files
23708         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23709         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23710         echo "proc_dirs='$proc_dirs'"
23711         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23712         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23713                       sort -u | wc -l)
23714
23715         [ $params -eq $procs ] ||
23716                 error "found $params parameters vs. $procs proc files"
23717
23718         # test the list_param -D option only returns directories
23719         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23720         #count the number of parameters by listing proc directories
23721         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23722                 sort -u | wc -l)
23723
23724         [ $params -eq $procs ] ||
23725                 error "found $params parameters vs. $procs proc files"
23726 }
23727 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23728
23729 test_401b() {
23730         # jobid_var may not allow arbitrary values, so use jobid_name
23731         # if available
23732         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23733                 local testname=jobid_name tmp='testing%p'
23734         else
23735                 local testname=jobid_var tmp=testing
23736         fi
23737
23738         local save=$($LCTL get_param -n $testname)
23739
23740         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23741                 error "no error returned when setting bad parameters"
23742
23743         local jobid_new=$($LCTL get_param -n foe $testname baz)
23744         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23745
23746         $LCTL set_param -n fog=bam $testname=$save bat=fog
23747         local jobid_old=$($LCTL get_param -n foe $testname bag)
23748         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23749 }
23750 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23751
23752 test_401c() {
23753         # jobid_var may not allow arbitrary values, so use jobid_name
23754         # if available
23755         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23756                 local testname=jobid_name
23757         else
23758                 local testname=jobid_var
23759         fi
23760
23761         local jobid_var_old=$($LCTL get_param -n $testname)
23762         local jobid_var_new
23763
23764         $LCTL set_param $testname= &&
23765                 error "no error returned for 'set_param a='"
23766
23767         jobid_var_new=$($LCTL get_param -n $testname)
23768         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23769                 error "$testname was changed by setting without value"
23770
23771         $LCTL set_param $testname &&
23772                 error "no error returned for 'set_param a'"
23773
23774         jobid_var_new=$($LCTL get_param -n $testname)
23775         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23776                 error "$testname was changed by setting without value"
23777 }
23778 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23779
23780 test_401d() {
23781         # jobid_var may not allow arbitrary values, so use jobid_name
23782         # if available
23783         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23784                 local testname=jobid_name new_value='foo=bar%p'
23785         else
23786                 local testname=jobid_var new_valuie=foo=bar
23787         fi
23788
23789         local jobid_var_old=$($LCTL get_param -n $testname)
23790         local jobid_var_new
23791
23792         $LCTL set_param $testname=$new_value ||
23793                 error "'set_param a=b' did not accept a value containing '='"
23794
23795         jobid_var_new=$($LCTL get_param -n $testname)
23796         [[ "$jobid_var_new" == "$new_value" ]] ||
23797                 error "'set_param a=b' failed on a value containing '='"
23798
23799         # Reset the $testname to test the other format
23800         $LCTL set_param $testname=$jobid_var_old
23801         jobid_var_new=$($LCTL get_param -n $testname)
23802         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23803                 error "failed to reset $testname"
23804
23805         $LCTL set_param $testname $new_value ||
23806                 error "'set_param a b' did not accept a value containing '='"
23807
23808         jobid_var_new=$($LCTL get_param -n $testname)
23809         [[ "$jobid_var_new" == "$new_value" ]] ||
23810                 error "'set_param a b' failed on a value containing '='"
23811
23812         $LCTL set_param $testname $jobid_var_old
23813         jobid_var_new=$($LCTL get_param -n $testname)
23814         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23815                 error "failed to reset $testname"
23816 }
23817 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23818
23819 test_402() {
23820         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23821         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23822                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23823         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23824                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23825                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23826         remote_mds_nodsh && skip "remote MDS with nodsh"
23827
23828         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23829 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23830         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23831         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23832                 echo "Touch failed - OK"
23833 }
23834 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23835
23836 test_403() {
23837         local file1=$DIR/$tfile.1
23838         local file2=$DIR/$tfile.2
23839         local tfile=$TMP/$tfile
23840
23841         rm -f $file1 $file2 $tfile
23842
23843         touch $file1
23844         ln $file1 $file2
23845
23846         # 30 sec OBD_TIMEOUT in ll_getattr()
23847         # right before populating st_nlink
23848         $LCTL set_param fail_loc=0x80001409
23849         stat -c %h $file1 > $tfile &
23850
23851         # create an alias, drop all locks and reclaim the dentry
23852         < $file2
23853         cancel_lru_locks mdc
23854         cancel_lru_locks osc
23855         sysctl -w vm.drop_caches=2
23856
23857         wait
23858
23859         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23860
23861         rm -f $tfile $file1 $file2
23862 }
23863 run_test 403 "i_nlink should not drop to zero due to aliasing"
23864
23865 test_404() { # LU-6601
23866         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23867                 skip "Need server version newer than 2.8.52"
23868         remote_mds_nodsh && skip "remote MDS with nodsh"
23869
23870         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23871                 awk '/osp .*-osc-MDT/ { print $4}')
23872
23873         local osp
23874         for osp in $mosps; do
23875                 echo "Deactivate: " $osp
23876                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23877                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23878                         awk -vp=$osp '$4 == p { print $2 }')
23879                 [ $stat = IN ] || {
23880                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23881                         error "deactivate error"
23882                 }
23883                 echo "Activate: " $osp
23884                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23885                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23886                         awk -vp=$osp '$4 == p { print $2 }')
23887                 [ $stat = UP ] || {
23888                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23889                         error "activate error"
23890                 }
23891         done
23892 }
23893 run_test 404 "validate manual {de}activated works properly for OSPs"
23894
23895 test_405() {
23896         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23897         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23898                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23899                         skip "Layout swap lock is not supported"
23900
23901         check_swap_layouts_support
23902         check_swap_layout_no_dom $DIR
23903
23904         test_mkdir $DIR/$tdir
23905         swap_lock_test -d $DIR/$tdir ||
23906                 error "One layout swap locked test failed"
23907 }
23908 run_test 405 "Various layout swap lock tests"
23909
23910 test_406() {
23911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23912         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23913         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23915         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23916                 skip "Need MDS version at least 2.8.50"
23917
23918         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23919         local test_pool=$TESTNAME
23920
23921         pool_add $test_pool || error "pool_add failed"
23922         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23923                 error "pool_add_targets failed"
23924
23925         save_layout_restore_at_exit $MOUNT
23926
23927         # parent set default stripe count only, child will stripe from both
23928         # parent and fs default
23929         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23930                 error "setstripe $MOUNT failed"
23931         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23932         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23933         for i in $(seq 10); do
23934                 local f=$DIR/$tdir/$tfile.$i
23935                 touch $f || error "touch failed"
23936                 local count=$($LFS getstripe -c $f)
23937                 [ $count -eq $OSTCOUNT ] ||
23938                         error "$f stripe count $count != $OSTCOUNT"
23939                 local offset=$($LFS getstripe -i $f)
23940                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23941                 local size=$($LFS getstripe -S $f)
23942                 [ $size -eq $((def_stripe_size * 2)) ] ||
23943                         error "$f stripe size $size != $((def_stripe_size * 2))"
23944                 local pool=$($LFS getstripe -p $f)
23945                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23946         done
23947
23948         # change fs default striping, delete parent default striping, now child
23949         # will stripe from new fs default striping only
23950         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23951                 error "change $MOUNT default stripe failed"
23952         $LFS setstripe -c 0 $DIR/$tdir ||
23953                 error "delete $tdir default stripe failed"
23954         for i in $(seq 11 20); do
23955                 local f=$DIR/$tdir/$tfile.$i
23956                 touch $f || error "touch $f failed"
23957                 local count=$($LFS getstripe -c $f)
23958                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23959                 local offset=$($LFS getstripe -i $f)
23960                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23961                 local size=$($LFS getstripe -S $f)
23962                 [ $size -eq $def_stripe_size ] ||
23963                         error "$f stripe size $size != $def_stripe_size"
23964                 local pool=$($LFS getstripe -p $f)
23965                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23966         done
23967
23968         unlinkmany $DIR/$tdir/$tfile. 1 20
23969
23970         local f=$DIR/$tdir/$tfile
23971         pool_remove_all_targets $test_pool $f
23972         pool_remove $test_pool $f
23973 }
23974 run_test 406 "DNE support fs default striping"
23975
23976 test_407() {
23977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23978         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23979                 skip "Need MDS version at least 2.8.55"
23980         remote_mds_nodsh && skip "remote MDS with nodsh"
23981
23982         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23983                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23984         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23985                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23986         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23987
23988         #define OBD_FAIL_DT_TXN_STOP    0x2019
23989         for idx in $(seq $MDSCOUNT); do
23990                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23991         done
23992         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23993         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23994                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23995         true
23996 }
23997 run_test 407 "transaction fail should cause operation fail"
23998
23999 test_408() {
24000         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24001
24002         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24003         lctl set_param fail_loc=0x8000040a
24004         # let ll_prepare_partial_page() fail
24005         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24006
24007         rm -f $DIR/$tfile
24008
24009         # create at least 100 unused inodes so that
24010         # shrink_icache_memory(0) should not return 0
24011         touch $DIR/$tfile-{0..100}
24012         rm -f $DIR/$tfile-{0..100}
24013         sync
24014
24015         echo 2 > /proc/sys/vm/drop_caches
24016 }
24017 run_test 408 "drop_caches should not hang due to page leaks"
24018
24019 test_409()
24020 {
24021         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24022
24023         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24024         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24025         touch $DIR/$tdir/guard || error "(2) Fail to create"
24026
24027         local PREFIX=$(str_repeat 'A' 128)
24028         echo "Create 1K hard links start at $(date)"
24029         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24030                 error "(3) Fail to hard link"
24031
24032         echo "Links count should be right although linkEA overflow"
24033         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24034         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24035         [ $linkcount -eq 1001 ] ||
24036                 error "(5) Unexpected hard links count: $linkcount"
24037
24038         echo "List all links start at $(date)"
24039         ls -l $DIR/$tdir/foo > /dev/null ||
24040                 error "(6) Fail to list $DIR/$tdir/foo"
24041
24042         echo "Unlink hard links start at $(date)"
24043         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24044                 error "(7) Fail to unlink"
24045         echo "Unlink hard links finished at $(date)"
24046 }
24047 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24048
24049 test_410()
24050 {
24051         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24052                 skip "Need client version at least 2.9.59"
24053         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24054                 skip "Need MODULES build"
24055
24056         # Create a file, and stat it from the kernel
24057         local testfile=$DIR/$tfile
24058         touch $testfile
24059
24060         local run_id=$RANDOM
24061         local my_ino=$(stat --format "%i" $testfile)
24062
24063         # Try to insert the module. This will always fail as the
24064         # module is designed to not be inserted.
24065         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24066             &> /dev/null
24067
24068         # Anything but success is a test failure
24069         dmesg | grep -q \
24070             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24071             error "no inode match"
24072 }
24073 run_test 410 "Test inode number returned from kernel thread"
24074
24075 cleanup_test411_cgroup() {
24076         trap 0
24077         rmdir "$1"
24078 }
24079
24080 test_411() {
24081         local cg_basedir=/sys/fs/cgroup/memory
24082         # LU-9966
24083         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24084                 skip "no setup for cgroup"
24085
24086         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24087                 error "test file creation failed"
24088         cancel_lru_locks osc
24089
24090         # Create a very small memory cgroup to force a slab allocation error
24091         local cgdir=$cg_basedir/osc_slab_alloc
24092         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24093         trap "cleanup_test411_cgroup $cgdir" EXIT
24094         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24095         echo 1M > $cgdir/memory.limit_in_bytes
24096
24097         # Should not LBUG, just be killed by oom-killer
24098         # dd will return 0 even allocation failure in some environment.
24099         # So don't check return value
24100         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24101         cleanup_test411_cgroup $cgdir
24102
24103         return 0
24104 }
24105 run_test 411 "Slab allocation error with cgroup does not LBUG"
24106
24107 test_412() {
24108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24109         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24110                 skip "Need server version at least 2.10.55"
24111         fi
24112
24113         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24114                 error "mkdir failed"
24115         $LFS getdirstripe $DIR/$tdir
24116         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24117         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24118                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24119         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24120         [ $stripe_count -eq 2 ] ||
24121                 error "expect 2 get $stripe_count"
24122 }
24123 run_test 412 "mkdir on specific MDTs"
24124
24125 test_qos_mkdir() {
24126         local mkdir_cmd=$1
24127         local stripe_count=$2
24128         local mdts=$(comma_list $(mdts_nodes))
24129
24130         local testdir
24131         local lmv_qos_prio_free
24132         local lmv_qos_threshold_rr
24133         local lmv_qos_maxage
24134         local lod_qos_prio_free
24135         local lod_qos_threshold_rr
24136         local lod_qos_maxage
24137         local count
24138         local i
24139
24140         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24141         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24142         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24143                 head -n1)
24144         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24145         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24146         stack_trap "$LCTL set_param \
24147                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24148         stack_trap "$LCTL set_param \
24149                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24150         stack_trap "$LCTL set_param \
24151                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24152
24153         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24154                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24155         lod_qos_prio_free=${lod_qos_prio_free%%%}
24156         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24157                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24158         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24159         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24160                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24161         stack_trap "do_nodes $mdts $LCTL set_param \
24162                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24163         stack_trap "do_nodes $mdts $LCTL set_param \
24164                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24165                 EXIT
24166         stack_trap "do_nodes $mdts $LCTL set_param \
24167                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24168
24169         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24170         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24171
24172         testdir=$DIR/$tdir-s$stripe_count/rr
24173
24174         local stripe_index=$($LFS getstripe -m $testdir)
24175         local test_mkdir_rr=true
24176
24177         getfattr -d -m dmv $testdir | grep dmv
24178         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24179                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24180
24181                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24182         fi
24183
24184         echo
24185         $test_mkdir_rr &&
24186                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24187                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24188
24189         for i in $(seq $((100 * MDSCOUNT))); do
24190                 eval $mkdir_cmd $testdir/subdir$i ||
24191                         error "$mkdir_cmd subdir$i failed"
24192         done
24193
24194         for i in $(seq $MDSCOUNT); do
24195                 count=$($LFS getdirstripe -i $testdir/* |
24196                                 grep ^$((i - 1))$ | wc -l)
24197                 echo "$count directories created on MDT$((i - 1))"
24198                 if $test_mkdir_rr; then
24199                         (( $count == 100 )) ||
24200                                 error "subdirs are not evenly distributed"
24201                 elif [ $((i - 1)) -eq $stripe_index ]; then
24202                         (( $count == 100 * MDSCOUNT )) ||
24203                                 error "$count subdirs created on MDT$((i - 1))"
24204                 else
24205                         (( $count == 0 )) ||
24206                                 error "$count subdirs created on MDT$((i - 1))"
24207                 fi
24208
24209                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24210                         count=$($LFS getdirstripe $testdir/* |
24211                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24212                         echo "$count stripes created on MDT$((i - 1))"
24213                         # deviation should < 5% of average
24214                         (( $count < 95 * stripe_count )) ||
24215                         (( $count > 105 * stripe_count)) &&
24216                                 error "stripes are not evenly distributed"
24217                 fi
24218         done
24219
24220         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24221         do_nodes $mdts $LCTL set_param \
24222                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24223
24224         echo
24225         echo "Check for uneven MDTs: "
24226
24227         local ffree
24228         local bavail
24229         local max
24230         local min
24231         local max_index
24232         local min_index
24233         local tmp
24234
24235         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24236         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24237         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24238
24239         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24240         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24241         max_index=0
24242         min_index=0
24243         for ((i = 1; i < ${#ffree[@]}; i++)); do
24244                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24245                 if [ $tmp -gt $max ]; then
24246                         max=$tmp
24247                         max_index=$i
24248                 fi
24249                 if [ $tmp -lt $min ]; then
24250                         min=$tmp
24251                         min_index=$i
24252                 fi
24253         done
24254
24255         (( ${ffree[min_index]} == 0 )) &&
24256                 skip "no free files in MDT$min_index"
24257         (( ${ffree[min_index]} > 100000000 )) &&
24258                 skip "too many free files in MDT$min_index"
24259
24260         # Check if we need to generate uneven MDTs
24261         local threshold=50
24262         local diff=$(((max - min) * 100 / min))
24263         local value="$(generate_string 1024)"
24264
24265         while [ $diff -lt $threshold ]; do
24266                 # generate uneven MDTs, create till $threshold% diff
24267                 echo -n "weight diff=$diff% must be > $threshold% ..."
24268                 count=$((${ffree[min_index]} / 10))
24269                 # 50 sec per 10000 files in vm
24270                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24271                         skip "$count files to create"
24272                 echo "Fill MDT$min_index with $count files"
24273                 [ -d $DIR/$tdir-MDT$min_index ] ||
24274                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24275                         error "mkdir $tdir-MDT$min_index failed"
24276                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24277                         error "create d$count failed"
24278
24279                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24280                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24281                 max=$(((${ffree[max_index]} >> 8) * \
24282                         (${bavail[max_index]} * bsize >> 16)))
24283                 min=$(((${ffree[min_index]} >> 8) * \
24284                         (${bavail[min_index]} * bsize >> 16)))
24285                 diff=$(((max - min) * 100 / min))
24286         done
24287
24288         echo "MDT filesfree available: ${ffree[@]}"
24289         echo "MDT blocks available: ${bavail[@]}"
24290         echo "weight diff=$diff%"
24291
24292         echo
24293         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24294
24295         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24296         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24297         # decrease statfs age, so that it can be updated in time
24298         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24299         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24300
24301         sleep 1
24302
24303         testdir=$DIR/$tdir-s$stripe_count/qos
24304
24305         for i in $(seq $((100 * MDSCOUNT))); do
24306                 eval $mkdir_cmd $testdir/subdir$i ||
24307                         error "$mkdir_cmd subdir$i failed"
24308         done
24309
24310         for i in $(seq $MDSCOUNT); do
24311                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24312                         wc -l)
24313                 echo "$count directories created on MDT$((i - 1))"
24314
24315                 if [ $stripe_count -gt 1 ]; then
24316                         count=$($LFS getdirstripe $testdir/* |
24317                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24318                         echo "$count stripes created on MDT$((i - 1))"
24319                 fi
24320         done
24321
24322         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24323         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24324
24325         # D-value should > 10% of averge
24326         (( $max - $min < 10 )) &&
24327                 error "subdirs shouldn't be evenly distributed"
24328
24329         # ditto
24330         if [ $stripe_count -gt 1 ]; then
24331                 max=$($LFS getdirstripe $testdir/* |
24332                         grep -P "^\s+$max_index\t" | wc -l)
24333                 min=$($LFS getdirstripe $testdir/* |
24334                         grep -P "^\s+$min_index\t" | wc -l)
24335                 (( $max - $min < 10 * $stripe_count )) &&
24336                         error "stripes shouldn't be evenly distributed"|| true
24337         fi
24338 }
24339
24340 test_413a() {
24341         [ $MDSCOUNT -lt 2 ] &&
24342                 skip "We need at least 2 MDTs for this test"
24343
24344         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24345                 skip "Need server version at least 2.12.52"
24346
24347         local stripe_count
24348
24349         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24350                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24351                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24352                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24353                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24354         done
24355 }
24356 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24357
24358 test_413b() {
24359         [ $MDSCOUNT -lt 2 ] &&
24360                 skip "We need at least 2 MDTs for this test"
24361
24362         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24363                 skip "Need server version at least 2.12.52"
24364
24365         local testdir
24366         local stripe_count
24367
24368         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24369                 testdir=$DIR/$tdir-s$stripe_count
24370                 mkdir $testdir || error "mkdir $testdir failed"
24371                 mkdir $testdir/rr || error "mkdir rr failed"
24372                 mkdir $testdir/qos || error "mkdir qos failed"
24373                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24374                         $testdir/rr || error "setdirstripe rr failed"
24375                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24376                         error "setdirstripe failed"
24377                 test_qos_mkdir "mkdir" $stripe_count
24378         done
24379 }
24380 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24381
24382 test_413c() {
24383         [ $MDSCOUNT -ge 2 ] ||
24384                 skip "We need at least 2 MDTs for this test"
24385
24386         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24387                 skip "Need server version at least 2.14.50"
24388
24389         local testdir
24390         local inherit
24391         local inherit_rr
24392
24393         testdir=$DIR/${tdir}-s1
24394         mkdir $testdir || error "mkdir $testdir failed"
24395         mkdir $testdir/rr || error "mkdir rr failed"
24396         mkdir $testdir/qos || error "mkdir qos failed"
24397         # default max_inherit is -1, default max_inherit_rr is 0
24398         $LFS setdirstripe -D -c 1 $testdir/rr ||
24399                 error "setdirstripe rr failed"
24400         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24401                 error "setdirstripe qos failed"
24402         test_qos_mkdir "mkdir" 1
24403
24404         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24405         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24406         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24407         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24408         (( $inherit_rr == 0 )) ||
24409                 error "rr/level1 inherit-rr $inherit_rr != 0"
24410
24411         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24412         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24413         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24414         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24415         (( $inherit_rr == 0 )) ||
24416                 error "qos/level1 inherit-rr $inherit_rr !=0"
24417         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24418         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24419                 error "level2 shouldn't have default LMV" || true
24420 }
24421 run_test 413c "mkdir with default LMV max inherit rr"
24422
24423 test_414() {
24424 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24425         $LCTL set_param fail_loc=0x80000521
24426         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24427         rm -f $DIR/$tfile
24428 }
24429 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24430
24431 test_415() {
24432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24433         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24434                 skip "Need server version at least 2.11.52"
24435
24436         # LU-11102
24437         local total
24438         local setattr_pid
24439         local start_time
24440         local end_time
24441         local duration
24442
24443         total=500
24444         # this test may be slow on ZFS
24445         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24446
24447         # though this test is designed for striped directory, let's test normal
24448         # directory too since lock is always saved as CoS lock.
24449         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24450         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24451
24452         (
24453                 while true; do
24454                         touch $DIR/$tdir
24455                 done
24456         ) &
24457         setattr_pid=$!
24458
24459         start_time=$(date +%s)
24460         for i in $(seq $total); do
24461                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24462                         > /dev/null
24463         done
24464         end_time=$(date +%s)
24465         duration=$((end_time - start_time))
24466
24467         kill -9 $setattr_pid
24468
24469         echo "rename $total files took $duration sec"
24470         [ $duration -lt 100 ] || error "rename took $duration sec"
24471 }
24472 run_test 415 "lock revoke is not missing"
24473
24474 test_416() {
24475         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24476                 skip "Need server version at least 2.11.55"
24477
24478         # define OBD_FAIL_OSD_TXN_START    0x19a
24479         do_facet mds1 lctl set_param fail_loc=0x19a
24480
24481         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24482
24483         true
24484 }
24485 run_test 416 "transaction start failure won't cause system hung"
24486
24487 cleanup_417() {
24488         trap 0
24489         do_nodes $(comma_list $(mdts_nodes)) \
24490                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24491         do_nodes $(comma_list $(mdts_nodes)) \
24492                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24493         do_nodes $(comma_list $(mdts_nodes)) \
24494                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24495 }
24496
24497 test_417() {
24498         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24499         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24500                 skip "Need MDS version at least 2.11.56"
24501
24502         trap cleanup_417 RETURN EXIT
24503
24504         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24505         do_nodes $(comma_list $(mdts_nodes)) \
24506                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24507         $LFS migrate -m 0 $DIR/$tdir.1 &&
24508                 error "migrate dir $tdir.1 should fail"
24509
24510         do_nodes $(comma_list $(mdts_nodes)) \
24511                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24512         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24513                 error "create remote dir $tdir.2 should fail"
24514
24515         do_nodes $(comma_list $(mdts_nodes)) \
24516                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24517         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24518                 error "create striped dir $tdir.3 should fail"
24519         true
24520 }
24521 run_test 417 "disable remote dir, striped dir and dir migration"
24522
24523 # Checks that the outputs of df [-i] and lfs df [-i] match
24524 #
24525 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24526 check_lfs_df() {
24527         local dir=$2
24528         local inodes
24529         local df_out
24530         local lfs_df_out
24531         local count
24532         local passed=false
24533
24534         # blocks or inodes
24535         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24536
24537         for count in {1..100}; do
24538                 cancel_lru_locks
24539                 sync; sleep 0.2
24540
24541                 # read the lines of interest
24542                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24543                         error "df $inodes $dir | tail -n +2 failed"
24544                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24545                         error "lfs df $inodes $dir | grep summary: failed"
24546
24547                 # skip first substrings of each output as they are different
24548                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24549                 # compare the two outputs
24550                 passed=true
24551                 for i in {1..5}; do
24552                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24553                 done
24554                 $passed && break
24555         done
24556
24557         if ! $passed; then
24558                 df -P $inodes $dir
24559                 echo
24560                 lfs df $inodes $dir
24561                 error "df and lfs df $1 output mismatch: "      \
24562                       "df ${inodes}: ${df_out[*]}, "            \
24563                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24564         fi
24565 }
24566
24567 test_418() {
24568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24569
24570         local dir=$DIR/$tdir
24571         local numfiles=$((RANDOM % 4096 + 2))
24572         local numblocks=$((RANDOM % 256 + 1))
24573
24574         wait_delete_completed
24575         test_mkdir $dir
24576
24577         # check block output
24578         check_lfs_df blocks $dir
24579         # check inode output
24580         check_lfs_df inodes $dir
24581
24582         # create a single file and retest
24583         echo "Creating a single file and testing"
24584         createmany -o $dir/$tfile- 1 &>/dev/null ||
24585                 error "creating 1 file in $dir failed"
24586         check_lfs_df blocks $dir
24587         check_lfs_df inodes $dir
24588
24589         # create a random number of files
24590         echo "Creating $((numfiles - 1)) files and testing"
24591         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24592                 error "creating $((numfiles - 1)) files in $dir failed"
24593
24594         # write a random number of blocks to the first test file
24595         echo "Writing $numblocks 4K blocks and testing"
24596         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24597                 count=$numblocks &>/dev/null ||
24598                 error "dd to $dir/${tfile}-0 failed"
24599
24600         # retest
24601         check_lfs_df blocks $dir
24602         check_lfs_df inodes $dir
24603
24604         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24605                 error "unlinking $numfiles files in $dir failed"
24606 }
24607 run_test 418 "df and lfs df outputs match"
24608
24609 test_419()
24610 {
24611         local dir=$DIR/$tdir
24612
24613         mkdir -p $dir
24614         touch $dir/file
24615
24616         cancel_lru_locks mdc
24617
24618         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24619         $LCTL set_param fail_loc=0x1410
24620         cat $dir/file
24621         $LCTL set_param fail_loc=0
24622         rm -rf $dir
24623 }
24624 run_test 419 "Verify open file by name doesn't crash kernel"
24625
24626 test_420()
24627 {
24628         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24629                 skip "Need MDS version at least 2.12.53"
24630
24631         local SAVE_UMASK=$(umask)
24632         local dir=$DIR/$tdir
24633         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24634
24635         mkdir -p $dir
24636         umask 0000
24637         mkdir -m03777 $dir/testdir
24638         ls -dn $dir/testdir
24639         # Need to remove trailing '.' when SELinux is enabled
24640         local dirperms=$(ls -dn $dir/testdir |
24641                          awk '{ sub(/\.$/, "", $1); print $1}')
24642         [ $dirperms == "drwxrwsrwt" ] ||
24643                 error "incorrect perms on $dir/testdir"
24644
24645         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24646                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24647         ls -n $dir/testdir/testfile
24648         local fileperms=$(ls -n $dir/testdir/testfile |
24649                           awk '{ sub(/\.$/, "", $1); print $1}')
24650         [ $fileperms == "-rwxr-xr-x" ] ||
24651                 error "incorrect perms on $dir/testdir/testfile"
24652
24653         umask $SAVE_UMASK
24654 }
24655 run_test 420 "clear SGID bit on non-directories for non-members"
24656
24657 test_421a() {
24658         local cnt
24659         local fid1
24660         local fid2
24661
24662         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24663                 skip "Need MDS version at least 2.12.54"
24664
24665         test_mkdir $DIR/$tdir
24666         createmany -o $DIR/$tdir/f 3
24667         cnt=$(ls -1 $DIR/$tdir | wc -l)
24668         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24669
24670         fid1=$(lfs path2fid $DIR/$tdir/f1)
24671         fid2=$(lfs path2fid $DIR/$tdir/f2)
24672         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24673
24674         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24675         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24676
24677         cnt=$(ls -1 $DIR/$tdir | wc -l)
24678         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24679
24680         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24681         createmany -o $DIR/$tdir/f 3
24682         cnt=$(ls -1 $DIR/$tdir | wc -l)
24683         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24684
24685         fid1=$(lfs path2fid $DIR/$tdir/f1)
24686         fid2=$(lfs path2fid $DIR/$tdir/f2)
24687         echo "remove using fsname $FSNAME"
24688         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24689
24690         cnt=$(ls -1 $DIR/$tdir | wc -l)
24691         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24692 }
24693 run_test 421a "simple rm by fid"
24694
24695 test_421b() {
24696         local cnt
24697         local FID1
24698         local FID2
24699
24700         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24701                 skip "Need MDS version at least 2.12.54"
24702
24703         test_mkdir $DIR/$tdir
24704         createmany -o $DIR/$tdir/f 3
24705         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24706         MULTIPID=$!
24707
24708         FID1=$(lfs path2fid $DIR/$tdir/f1)
24709         FID2=$(lfs path2fid $DIR/$tdir/f2)
24710         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24711
24712         kill -USR1 $MULTIPID
24713         wait
24714
24715         cnt=$(ls $DIR/$tdir | wc -l)
24716         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24717 }
24718 run_test 421b "rm by fid on open file"
24719
24720 test_421c() {
24721         local cnt
24722         local FIDS
24723
24724         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24725                 skip "Need MDS version at least 2.12.54"
24726
24727         test_mkdir $DIR/$tdir
24728         createmany -o $DIR/$tdir/f 3
24729         touch $DIR/$tdir/$tfile
24730         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24731         cnt=$(ls -1 $DIR/$tdir | wc -l)
24732         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24733
24734         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24735         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24736
24737         cnt=$(ls $DIR/$tdir | wc -l)
24738         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24739 }
24740 run_test 421c "rm by fid against hardlinked files"
24741
24742 test_421d() {
24743         local cnt
24744         local FIDS
24745
24746         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24747                 skip "Need MDS version at least 2.12.54"
24748
24749         test_mkdir $DIR/$tdir
24750         createmany -o $DIR/$tdir/f 4097
24751         cnt=$(ls -1 $DIR/$tdir | wc -l)
24752         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24753
24754         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24755         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24756
24757         cnt=$(ls $DIR/$tdir | wc -l)
24758         rm -rf $DIR/$tdir
24759         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24760 }
24761 run_test 421d "rmfid en masse"
24762
24763 test_421e() {
24764         local cnt
24765         local FID
24766
24767         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24768         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24769                 skip "Need MDS version at least 2.12.54"
24770
24771         mkdir -p $DIR/$tdir
24772         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24773         createmany -o $DIR/$tdir/striped_dir/f 512
24774         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24775         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24776
24777         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24778                 sed "s/[/][^:]*://g")
24779         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24780
24781         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24782         rm -rf $DIR/$tdir
24783         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24784 }
24785 run_test 421e "rmfid in DNE"
24786
24787 test_421f() {
24788         local cnt
24789         local FID
24790
24791         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24792                 skip "Need MDS version at least 2.12.54"
24793
24794         test_mkdir $DIR/$tdir
24795         touch $DIR/$tdir/f
24796         cnt=$(ls -1 $DIR/$tdir | wc -l)
24797         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24798
24799         FID=$(lfs path2fid $DIR/$tdir/f)
24800         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24801         # rmfid should fail
24802         cnt=$(ls -1 $DIR/$tdir | wc -l)
24803         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24804
24805         chmod a+rw $DIR/$tdir
24806         ls -la $DIR/$tdir
24807         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24808         # rmfid should fail
24809         cnt=$(ls -1 $DIR/$tdir | wc -l)
24810         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24811
24812         rm -f $DIR/$tdir/f
24813         $RUNAS touch $DIR/$tdir/f
24814         FID=$(lfs path2fid $DIR/$tdir/f)
24815         echo "rmfid as root"
24816         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24817         cnt=$(ls -1 $DIR/$tdir | wc -l)
24818         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24819
24820         rm -f $DIR/$tdir/f
24821         $RUNAS touch $DIR/$tdir/f
24822         cnt=$(ls -1 $DIR/$tdir | wc -l)
24823         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24824         FID=$(lfs path2fid $DIR/$tdir/f)
24825         # rmfid w/o user_fid2path mount option should fail
24826         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24827         cnt=$(ls -1 $DIR/$tdir | wc -l)
24828         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24829
24830         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24831         stack_trap "rmdir $tmpdir"
24832         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24833                 error "failed to mount client'"
24834         stack_trap "umount_client $tmpdir"
24835
24836         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24837         # rmfid should succeed
24838         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24839         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24840
24841         # rmfid shouldn't allow to remove files due to dir's permission
24842         chmod a+rwx $tmpdir/$tdir
24843         touch $tmpdir/$tdir/f
24844         ls -la $tmpdir/$tdir
24845         FID=$(lfs path2fid $tmpdir/$tdir/f)
24846         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24847         return 0
24848 }
24849 run_test 421f "rmfid checks permissions"
24850
24851 test_421g() {
24852         local cnt
24853         local FIDS
24854
24855         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24856         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24857                 skip "Need MDS version at least 2.12.54"
24858
24859         mkdir -p $DIR/$tdir
24860         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24861         createmany -o $DIR/$tdir/striped_dir/f 512
24862         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24863         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24864
24865         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24866                 sed "s/[/][^:]*://g")
24867
24868         rm -f $DIR/$tdir/striped_dir/f1*
24869         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24870         removed=$((512 - cnt))
24871
24872         # few files have been just removed, so we expect
24873         # rmfid to fail on their fids
24874         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24875         [ $removed != $errors ] && error "$errors != $removed"
24876
24877         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24878         rm -rf $DIR/$tdir
24879         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24880 }
24881 run_test 421g "rmfid to return errors properly"
24882
24883 test_422() {
24884         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24885         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24886         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24887         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24888         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24889
24890         local amc=$(at_max_get client)
24891         local amo=$(at_max_get mds1)
24892         local timeout=`lctl get_param -n timeout`
24893
24894         at_max_set 0 client
24895         at_max_set 0 mds1
24896
24897 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24898         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24899                         fail_val=$(((2*timeout + 10)*1000))
24900         touch $DIR/$tdir/d3/file &
24901         sleep 2
24902 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24903         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24904                         fail_val=$((2*timeout + 5))
24905         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24906         local pid=$!
24907         sleep 1
24908         kill -9 $pid
24909         sleep $((2 * timeout))
24910         echo kill $pid
24911         kill -9 $pid
24912         lctl mark touch
24913         touch $DIR/$tdir/d2/file3
24914         touch $DIR/$tdir/d2/file4
24915         touch $DIR/$tdir/d2/file5
24916
24917         wait
24918         at_max_set $amc client
24919         at_max_set $amo mds1
24920
24921         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24922         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24923                 error "Watchdog is always throttled"
24924 }
24925 run_test 422 "kill a process with RPC in progress"
24926
24927 stat_test() {
24928     df -h $MOUNT &
24929     df -h $MOUNT &
24930     df -h $MOUNT &
24931     df -h $MOUNT &
24932     df -h $MOUNT &
24933     df -h $MOUNT &
24934 }
24935
24936 test_423() {
24937     local _stats
24938     # ensure statfs cache is expired
24939     sleep 2;
24940
24941     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24942     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24943
24944     return 0
24945 }
24946 run_test 423 "statfs should return a right data"
24947
24948 test_424() {
24949 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24950         $LCTL set_param fail_loc=0x80000522
24951         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24952         rm -f $DIR/$tfile
24953 }
24954 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24955
24956 test_425() {
24957         test_mkdir -c -1 $DIR/$tdir
24958         $LFS setstripe -c -1 $DIR/$tdir
24959
24960         lru_resize_disable "" 100
24961         stack_trap "lru_resize_enable" EXIT
24962
24963         sleep 5
24964
24965         for i in $(seq $((MDSCOUNT * 125))); do
24966                 local t=$DIR/$tdir/$tfile_$i
24967
24968                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24969                         error_noexit "Create file $t"
24970         done
24971         stack_trap "rm -rf $DIR/$tdir" EXIT
24972
24973         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24974                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24975                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24976
24977                 [ $lock_count -le $lru_size ] ||
24978                         error "osc lock count $lock_count > lru size $lru_size"
24979         done
24980
24981         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24982                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24983                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24984
24985                 [ $lock_count -le $lru_size ] ||
24986                         error "mdc lock count $lock_count > lru size $lru_size"
24987         done
24988 }
24989 run_test 425 "lock count should not exceed lru size"
24990
24991 test_426() {
24992         splice-test -r $DIR/$tfile
24993         splice-test -rd $DIR/$tfile
24994         splice-test $DIR/$tfile
24995         splice-test -d $DIR/$tfile
24996 }
24997 run_test 426 "splice test on Lustre"
24998
24999 test_427() {
25000         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25001         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25002                 skip "Need MDS version at least 2.12.4"
25003         local log
25004
25005         mkdir $DIR/$tdir
25006         mkdir $DIR/$tdir/1
25007         mkdir $DIR/$tdir/2
25008         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25009         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25010
25011         $LFS getdirstripe $DIR/$tdir/1/dir
25012
25013         #first setfattr for creating updatelog
25014         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25015
25016 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25017         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25018         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25019         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25020
25021         sleep 2
25022         fail mds2
25023         wait_recovery_complete mds2 $((2*TIMEOUT))
25024
25025         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25026         echo $log | grep "get update log failed" &&
25027                 error "update log corruption is detected" || true
25028 }
25029 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25030
25031 test_428() {
25032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25033         local cache_limit=$CACHE_MAX
25034
25035         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25036         $LCTL set_param -n llite.*.max_cached_mb=64
25037
25038         mkdir $DIR/$tdir
25039         $LFS setstripe -c 1 $DIR/$tdir
25040         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25041         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25042         #test write
25043         for f in $(seq 4); do
25044                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25045         done
25046         wait
25047
25048         cancel_lru_locks osc
25049         # Test read
25050         for f in $(seq 4); do
25051                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25052         done
25053         wait
25054 }
25055 run_test 428 "large block size IO should not hang"
25056
25057 test_429() { # LU-7915 / LU-10948
25058         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25059         local testfile=$DIR/$tfile
25060         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25061         local new_flag=1
25062         local first_rpc
25063         local second_rpc
25064         local third_rpc
25065
25066         $LCTL get_param $ll_opencache_threshold_count ||
25067                 skip "client does not have opencache parameter"
25068
25069         set_opencache $new_flag
25070         stack_trap "restore_opencache"
25071         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25072                 error "enable opencache failed"
25073         touch $testfile
25074         # drop MDC DLM locks
25075         cancel_lru_locks mdc
25076         # clear MDC RPC stats counters
25077         $LCTL set_param $mdc_rpcstats=clear
25078
25079         # According to the current implementation, we need to run 3 times
25080         # open & close file to verify if opencache is enabled correctly.
25081         # 1st, RPCs are sent for lookup/open and open handle is released on
25082         #      close finally.
25083         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25084         #      so open handle won't be released thereafter.
25085         # 3rd, No RPC is sent out.
25086         $MULTIOP $testfile oc || error "multiop failed"
25087         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25088         echo "1st: $first_rpc RPCs in flight"
25089
25090         $MULTIOP $testfile oc || error "multiop failed"
25091         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25092         echo "2nd: $second_rpc RPCs in flight"
25093
25094         $MULTIOP $testfile oc || error "multiop failed"
25095         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25096         echo "3rd: $third_rpc RPCs in flight"
25097
25098         #verify no MDC RPC is sent
25099         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25100 }
25101 run_test 429 "verify if opencache flag on client side does work"
25102
25103 lseek_test_430() {
25104         local offset
25105         local file=$1
25106
25107         # data at [200K, 400K)
25108         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25109                 error "256K->512K dd fails"
25110         # data at [2M, 3M)
25111         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25112                 error "2M->3M dd fails"
25113         # data at [4M, 5M)
25114         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25115                 error "4M->5M dd fails"
25116         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25117         # start at first component hole #1
25118         printf "Seeking hole from 1000 ... "
25119         offset=$(lseek_test -l 1000 $file)
25120         echo $offset
25121         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25122         printf "Seeking data from 1000 ... "
25123         offset=$(lseek_test -d 1000 $file)
25124         echo $offset
25125         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25126
25127         # start at first component data block
25128         printf "Seeking hole from 300000 ... "
25129         offset=$(lseek_test -l 300000 $file)
25130         echo $offset
25131         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25132         printf "Seeking data from 300000 ... "
25133         offset=$(lseek_test -d 300000 $file)
25134         echo $offset
25135         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25136
25137         # start at the first component but beyond end of object size
25138         printf "Seeking hole from 1000000 ... "
25139         offset=$(lseek_test -l 1000000 $file)
25140         echo $offset
25141         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25142         printf "Seeking data from 1000000 ... "
25143         offset=$(lseek_test -d 1000000 $file)
25144         echo $offset
25145         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25146
25147         # start at second component stripe 2 (empty file)
25148         printf "Seeking hole from 1500000 ... "
25149         offset=$(lseek_test -l 1500000 $file)
25150         echo $offset
25151         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25152         printf "Seeking data from 1500000 ... "
25153         offset=$(lseek_test -d 1500000 $file)
25154         echo $offset
25155         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25156
25157         # start at second component stripe 1 (all data)
25158         printf "Seeking hole from 3000000 ... "
25159         offset=$(lseek_test -l 3000000 $file)
25160         echo $offset
25161         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25162         printf "Seeking data from 3000000 ... "
25163         offset=$(lseek_test -d 3000000 $file)
25164         echo $offset
25165         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25166
25167         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25168                 error "2nd dd fails"
25169         echo "Add data block at 640K...1280K"
25170
25171         # start at before new data block, in hole
25172         printf "Seeking hole from 600000 ... "
25173         offset=$(lseek_test -l 600000 $file)
25174         echo $offset
25175         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25176         printf "Seeking data from 600000 ... "
25177         offset=$(lseek_test -d 600000 $file)
25178         echo $offset
25179         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25180
25181         # start at the first component new data block
25182         printf "Seeking hole from 1000000 ... "
25183         offset=$(lseek_test -l 1000000 $file)
25184         echo $offset
25185         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25186         printf "Seeking data from 1000000 ... "
25187         offset=$(lseek_test -d 1000000 $file)
25188         echo $offset
25189         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25190
25191         # start at second component stripe 2, new data
25192         printf "Seeking hole from 1200000 ... "
25193         offset=$(lseek_test -l 1200000 $file)
25194         echo $offset
25195         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25196         printf "Seeking data from 1200000 ... "
25197         offset=$(lseek_test -d 1200000 $file)
25198         echo $offset
25199         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25200
25201         # start beyond file end
25202         printf "Using offset > filesize ... "
25203         lseek_test -l 4000000 $file && error "lseek should fail"
25204         printf "Using offset > filesize ... "
25205         lseek_test -d 4000000 $file && error "lseek should fail"
25206
25207         printf "Done\n\n"
25208 }
25209
25210 test_430a() {
25211         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25212                 skip "MDT does not support SEEK_HOLE"
25213
25214         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25215                 skip "OST does not support SEEK_HOLE"
25216
25217         local file=$DIR/$tdir/$tfile
25218
25219         mkdir -p $DIR/$tdir
25220
25221         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25222         # OST stripe #1 will have continuous data at [1M, 3M)
25223         # OST stripe #2 is empty
25224         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25225         lseek_test_430 $file
25226         rm $file
25227         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25228         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25229         lseek_test_430 $file
25230         rm $file
25231         $LFS setstripe -c2 -S 512K $file
25232         echo "Two stripes, stripe size 512K"
25233         lseek_test_430 $file
25234         rm $file
25235         # FLR with stale mirror
25236         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25237                        -N -c2 -S 1M $file
25238         echo "Mirrored file:"
25239         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25240         echo "Plain 2 stripes 1M"
25241         lseek_test_430 $file
25242         rm $file
25243 }
25244 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25245
25246 test_430b() {
25247         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25248                 skip "OST does not support SEEK_HOLE"
25249
25250         local offset
25251         local file=$DIR/$tdir/$tfile
25252
25253         mkdir -p $DIR/$tdir
25254         # Empty layout lseek should fail
25255         $MCREATE $file
25256         # seek from 0
25257         printf "Seeking hole from 0 ... "
25258         lseek_test -l 0 $file && error "lseek should fail"
25259         printf "Seeking data from 0 ... "
25260         lseek_test -d 0 $file && error "lseek should fail"
25261         rm $file
25262
25263         # 1M-hole file
25264         $LFS setstripe -E 1M -c2 -E eof $file
25265         $TRUNCATE $file 1048576
25266         printf "Seeking hole from 1000000 ... "
25267         offset=$(lseek_test -l 1000000 $file)
25268         echo $offset
25269         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25270         printf "Seeking data from 1000000 ... "
25271         lseek_test -d 1000000 $file && error "lseek should fail"
25272         rm $file
25273
25274         # full component followed by non-inited one
25275         $LFS setstripe -E 1M -c2 -E eof $file
25276         dd if=/dev/urandom of=$file bs=1M count=1
25277         printf "Seeking hole from 1000000 ... "
25278         offset=$(lseek_test -l 1000000 $file)
25279         echo $offset
25280         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25281         printf "Seeking hole from 1048576 ... "
25282         lseek_test -l 1048576 $file && error "lseek should fail"
25283         # init second component and truncate back
25284         echo "123" >> $file
25285         $TRUNCATE $file 1048576
25286         printf "Seeking hole from 1000000 ... "
25287         offset=$(lseek_test -l 1000000 $file)
25288         echo $offset
25289         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25290         printf "Seeking hole from 1048576 ... "
25291         lseek_test -l 1048576 $file && error "lseek should fail"
25292         # boundary checks for big values
25293         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25294         offset=$(lseek_test -d 0 $file.10g)
25295         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25296         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25297         offset=$(lseek_test -d 0 $file.100g)
25298         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25299         return 0
25300 }
25301 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25302
25303 test_430c() {
25304         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25305                 skip "OST does not support SEEK_HOLE"
25306
25307         local file=$DIR/$tdir/$tfile
25308         local start
25309
25310         mkdir -p $DIR/$tdir
25311         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25312
25313         # cp version 8.33+ prefers lseek over fiemap
25314         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25315                 start=$SECONDS
25316                 time cp $file /dev/null
25317                 (( SECONDS - start < 5 )) ||
25318                         error "cp: too long runtime $((SECONDS - start))"
25319
25320         fi
25321         # tar version 1.29+ supports SEEK_HOLE/DATA
25322         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25323                 start=$SECONDS
25324                 time tar cS $file - | cat > /dev/null
25325                 (( SECONDS - start < 5 )) ||
25326                         error "tar: too long runtime $((SECONDS - start))"
25327         fi
25328 }
25329 run_test 430c "lseek: external tools check"
25330
25331 test_431() { # LU-14187
25332         local file=$DIR/$tdir/$tfile
25333
25334         mkdir -p $DIR/$tdir
25335         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25336         dd if=/dev/urandom of=$file bs=4k count=1
25337         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25338         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25339         #define OBD_FAIL_OST_RESTART_IO 0x251
25340         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25341         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25342         cp $file $file.0
25343         cancel_lru_locks
25344         sync_all_data
25345         echo 3 > /proc/sys/vm/drop_caches
25346         diff  $file $file.0 || error "data diff"
25347 }
25348 run_test 431 "Restart transaction for IO"
25349
25350 prep_801() {
25351         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25352         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25353                 skip "Need server version at least 2.9.55"
25354
25355         start_full_debug_logging
25356 }
25357
25358 post_801() {
25359         stop_full_debug_logging
25360 }
25361
25362 barrier_stat() {
25363         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25364                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25365                            awk '/The barrier for/ { print $7 }')
25366                 echo $st
25367         else
25368                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25369                 echo \'$st\'
25370         fi
25371 }
25372
25373 barrier_expired() {
25374         local expired
25375
25376         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25377                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25378                           awk '/will be expired/ { print $7 }')
25379         else
25380                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25381         fi
25382
25383         echo $expired
25384 }
25385
25386 test_801a() {
25387         prep_801
25388
25389         echo "Start barrier_freeze at: $(date)"
25390         #define OBD_FAIL_BARRIER_DELAY          0x2202
25391         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25392         # Do not reduce barrier time - See LU-11873
25393         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25394
25395         sleep 2
25396         local b_status=$(barrier_stat)
25397         echo "Got barrier status at: $(date)"
25398         [ "$b_status" = "'freezing_p1'" ] ||
25399                 error "(1) unexpected barrier status $b_status"
25400
25401         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25402         wait
25403         b_status=$(barrier_stat)
25404         [ "$b_status" = "'frozen'" ] ||
25405                 error "(2) unexpected barrier status $b_status"
25406
25407         local expired=$(barrier_expired)
25408         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25409         sleep $((expired + 3))
25410
25411         b_status=$(barrier_stat)
25412         [ "$b_status" = "'expired'" ] ||
25413                 error "(3) unexpected barrier status $b_status"
25414
25415         # Do not reduce barrier time - See LU-11873
25416         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25417                 error "(4) fail to freeze barrier"
25418
25419         b_status=$(barrier_stat)
25420         [ "$b_status" = "'frozen'" ] ||
25421                 error "(5) unexpected barrier status $b_status"
25422
25423         echo "Start barrier_thaw at: $(date)"
25424         #define OBD_FAIL_BARRIER_DELAY          0x2202
25425         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25426         do_facet mgs $LCTL barrier_thaw $FSNAME &
25427
25428         sleep 2
25429         b_status=$(barrier_stat)
25430         echo "Got barrier status at: $(date)"
25431         [ "$b_status" = "'thawing'" ] ||
25432                 error "(6) unexpected barrier status $b_status"
25433
25434         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25435         wait
25436         b_status=$(barrier_stat)
25437         [ "$b_status" = "'thawed'" ] ||
25438                 error "(7) unexpected barrier status $b_status"
25439
25440         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25441         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25442         do_facet mgs $LCTL barrier_freeze $FSNAME
25443
25444         b_status=$(barrier_stat)
25445         [ "$b_status" = "'failed'" ] ||
25446                 error "(8) unexpected barrier status $b_status"
25447
25448         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25449         do_facet mgs $LCTL barrier_thaw $FSNAME
25450
25451         post_801
25452 }
25453 run_test 801a "write barrier user interfaces and stat machine"
25454
25455 test_801b() {
25456         prep_801
25457
25458         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25459         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25460         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25461         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25462         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25463
25464         cancel_lru_locks mdc
25465
25466         # 180 seconds should be long enough
25467         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25468
25469         local b_status=$(barrier_stat)
25470         [ "$b_status" = "'frozen'" ] ||
25471                 error "(6) unexpected barrier status $b_status"
25472
25473         mkdir $DIR/$tdir/d0/d10 &
25474         mkdir_pid=$!
25475
25476         touch $DIR/$tdir/d1/f13 &
25477         touch_pid=$!
25478
25479         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25480         ln_pid=$!
25481
25482         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25483         mv_pid=$!
25484
25485         rm -f $DIR/$tdir/d4/f12 &
25486         rm_pid=$!
25487
25488         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25489
25490         # To guarantee taht the 'stat' is not blocked
25491         b_status=$(barrier_stat)
25492         [ "$b_status" = "'frozen'" ] ||
25493                 error "(8) unexpected barrier status $b_status"
25494
25495         # let above commands to run at background
25496         sleep 5
25497
25498         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25499         ps -p $touch_pid || error "(10) touch should be blocked"
25500         ps -p $ln_pid || error "(11) link should be blocked"
25501         ps -p $mv_pid || error "(12) rename should be blocked"
25502         ps -p $rm_pid || error "(13) unlink should be blocked"
25503
25504         b_status=$(barrier_stat)
25505         [ "$b_status" = "'frozen'" ] ||
25506                 error "(14) unexpected barrier status $b_status"
25507
25508         do_facet mgs $LCTL barrier_thaw $FSNAME
25509         b_status=$(barrier_stat)
25510         [ "$b_status" = "'thawed'" ] ||
25511                 error "(15) unexpected barrier status $b_status"
25512
25513         wait $mkdir_pid || error "(16) mkdir should succeed"
25514         wait $touch_pid || error "(17) touch should succeed"
25515         wait $ln_pid || error "(18) link should succeed"
25516         wait $mv_pid || error "(19) rename should succeed"
25517         wait $rm_pid || error "(20) unlink should succeed"
25518
25519         post_801
25520 }
25521 run_test 801b "modification will be blocked by write barrier"
25522
25523 test_801c() {
25524         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25525
25526         prep_801
25527
25528         stop mds2 || error "(1) Fail to stop mds2"
25529
25530         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25531
25532         local b_status=$(barrier_stat)
25533         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25534                 do_facet mgs $LCTL barrier_thaw $FSNAME
25535                 error "(2) unexpected barrier status $b_status"
25536         }
25537
25538         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25539                 error "(3) Fail to rescan barrier bitmap"
25540
25541         # Do not reduce barrier time - See LU-11873
25542         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25543
25544         b_status=$(barrier_stat)
25545         [ "$b_status" = "'frozen'" ] ||
25546                 error "(4) unexpected barrier status $b_status"
25547
25548         do_facet mgs $LCTL barrier_thaw $FSNAME
25549         b_status=$(barrier_stat)
25550         [ "$b_status" = "'thawed'" ] ||
25551                 error "(5) unexpected barrier status $b_status"
25552
25553         local devname=$(mdsdevname 2)
25554
25555         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25556
25557         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25558                 error "(7) Fail to rescan barrier bitmap"
25559
25560         post_801
25561 }
25562 run_test 801c "rescan barrier bitmap"
25563
25564 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25565 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25566 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25567 saved_MOUNT_OPTS=$MOUNT_OPTS
25568
25569 cleanup_802a() {
25570         trap 0
25571
25572         stopall
25573         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25574         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25575         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25576         MOUNT_OPTS=$saved_MOUNT_OPTS
25577         setupall
25578 }
25579
25580 test_802a() {
25581         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25582         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25583         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25584                 skip "Need server version at least 2.9.55"
25585
25586         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25587
25588         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25589
25590         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25591                 error "(2) Fail to copy"
25592
25593         trap cleanup_802a EXIT
25594
25595         # sync by force before remount as readonly
25596         sync; sync_all_data; sleep 3; sync_all_data
25597
25598         stopall
25599
25600         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25601         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25602         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25603
25604         echo "Mount the server as read only"
25605         setupall server_only || error "(3) Fail to start servers"
25606
25607         echo "Mount client without ro should fail"
25608         mount_client $MOUNT &&
25609                 error "(4) Mount client without 'ro' should fail"
25610
25611         echo "Mount client with ro should succeed"
25612         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25613         mount_client $MOUNT ||
25614                 error "(5) Mount client with 'ro' should succeed"
25615
25616         echo "Modify should be refused"
25617         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25618
25619         echo "Read should be allowed"
25620         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25621                 error "(7) Read should succeed under ro mode"
25622
25623         cleanup_802a
25624 }
25625 run_test 802a "simulate readonly device"
25626
25627 test_802b() {
25628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25629         remote_mds_nodsh && skip "remote MDS with nodsh"
25630
25631         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25632                 skip "readonly option not available"
25633
25634         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25635
25636         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25637                 error "(2) Fail to copy"
25638
25639         # write back all cached data before setting MDT to readonly
25640         cancel_lru_locks
25641         sync_all_data
25642
25643         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25644         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25645
25646         echo "Modify should be refused"
25647         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25648
25649         echo "Read should be allowed"
25650         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25651                 error "(7) Read should succeed under ro mode"
25652
25653         # disable readonly
25654         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25655 }
25656 run_test 802b "be able to set MDTs to readonly"
25657
25658 test_803a() {
25659         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25660         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25661                 skip "MDS needs to be newer than 2.10.54"
25662
25663         mkdir_on_mdt0 $DIR/$tdir
25664         # Create some objects on all MDTs to trigger related logs objects
25665         for idx in $(seq $MDSCOUNT); do
25666                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25667                         $DIR/$tdir/dir${idx} ||
25668                         error "Fail to create $DIR/$tdir/dir${idx}"
25669         done
25670
25671         sync; sleep 3
25672         wait_delete_completed # ensure old test cleanups are finished
25673         echo "before create:"
25674         $LFS df -i $MOUNT
25675         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25676
25677         for i in {1..10}; do
25678                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25679                         error "Fail to create $DIR/$tdir/foo$i"
25680         done
25681
25682         sync; sleep 3
25683         echo "after create:"
25684         $LFS df -i $MOUNT
25685         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25686
25687         # allow for an llog to be cleaned up during the test
25688         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25689                 error "before ($before_used) + 10 > after ($after_used)"
25690
25691         for i in {1..10}; do
25692                 rm -rf $DIR/$tdir/foo$i ||
25693                         error "Fail to remove $DIR/$tdir/foo$i"
25694         done
25695
25696         sleep 3 # avoid MDT return cached statfs
25697         wait_delete_completed
25698         echo "after unlink:"
25699         $LFS df -i $MOUNT
25700         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25701
25702         # allow for an llog to be created during the test
25703         [ $after_used -le $((before_used + 1)) ] ||
25704                 error "after ($after_used) > before ($before_used) + 1"
25705 }
25706 run_test 803a "verify agent object for remote object"
25707
25708 test_803b() {
25709         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25710         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25711                 skip "MDS needs to be newer than 2.13.56"
25712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25713
25714         for i in $(seq 0 $((MDSCOUNT - 1))); do
25715                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25716         done
25717
25718         local before=0
25719         local after=0
25720
25721         local tmp
25722
25723         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25724         for i in $(seq 0 $((MDSCOUNT - 1))); do
25725                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25726                         awk '/getattr/ { print $2 }')
25727                 before=$((before + tmp))
25728         done
25729         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25730         for i in $(seq 0 $((MDSCOUNT - 1))); do
25731                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25732                         awk '/getattr/ { print $2 }')
25733                 after=$((after + tmp))
25734         done
25735
25736         [ $before -eq $after ] || error "getattr count $before != $after"
25737 }
25738 run_test 803b "remote object can getattr from cache"
25739
25740 test_804() {
25741         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25742         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25743                 skip "MDS needs to be newer than 2.10.54"
25744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25745
25746         mkdir -p $DIR/$tdir
25747         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25748                 error "Fail to create $DIR/$tdir/dir0"
25749
25750         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25751         local dev=$(mdsdevname 2)
25752
25753         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25754                 grep ${fid} || error "NOT found agent entry for dir0"
25755
25756         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25757                 error "Fail to create $DIR/$tdir/dir1"
25758
25759         touch $DIR/$tdir/dir1/foo0 ||
25760                 error "Fail to create $DIR/$tdir/dir1/foo0"
25761         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25762         local rc=0
25763
25764         for idx in $(seq $MDSCOUNT); do
25765                 dev=$(mdsdevname $idx)
25766                 do_facet mds${idx} \
25767                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25768                         grep ${fid} && rc=$idx
25769         done
25770
25771         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25772                 error "Fail to rename foo0 to foo1"
25773         if [ $rc -eq 0 ]; then
25774                 for idx in $(seq $MDSCOUNT); do
25775                         dev=$(mdsdevname $idx)
25776                         do_facet mds${idx} \
25777                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25778                         grep ${fid} && rc=$idx
25779                 done
25780         fi
25781
25782         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25783                 error "Fail to rename foo1 to foo2"
25784         if [ $rc -eq 0 ]; then
25785                 for idx in $(seq $MDSCOUNT); do
25786                         dev=$(mdsdevname $idx)
25787                         do_facet mds${idx} \
25788                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25789                         grep ${fid} && rc=$idx
25790                 done
25791         fi
25792
25793         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25794
25795         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25796                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25797         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25798                 error "Fail to rename foo2 to foo0"
25799         unlink $DIR/$tdir/dir1/foo0 ||
25800                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25801         rm -rf $DIR/$tdir/dir0 ||
25802                 error "Fail to rm $DIR/$tdir/dir0"
25803
25804         for idx in $(seq $MDSCOUNT); do
25805                 dev=$(mdsdevname $idx)
25806                 rc=0
25807
25808                 stop mds${idx}
25809                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25810                         rc=$?
25811                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25812                         error "mount mds$idx failed"
25813                 df $MOUNT > /dev/null 2>&1
25814
25815                 # e2fsck should not return error
25816                 [ $rc -eq 0 ] ||
25817                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25818         done
25819 }
25820 run_test 804 "verify agent entry for remote entry"
25821
25822 cleanup_805() {
25823         do_facet $SINGLEMDS zfs set quota=$old $fsset
25824         unlinkmany $DIR/$tdir/f- 1000000
25825         trap 0
25826 }
25827
25828 test_805() {
25829         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25830         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25831         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25832                 skip "netfree not implemented before 0.7"
25833         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25834                 skip "Need MDS version at least 2.10.57"
25835
25836         local fsset
25837         local freekb
25838         local usedkb
25839         local old
25840         local quota
25841         local pref="osd-zfs.$FSNAME-MDT0000."
25842
25843         # limit available space on MDS dataset to meet nospace issue
25844         # quickly. then ZFS 0.7.2 can use reserved space if asked
25845         # properly (using netfree flag in osd_declare_destroy()
25846         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25847         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25848                 gawk '{print $3}')
25849         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25850         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25851         let "usedkb=usedkb-freekb"
25852         let "freekb=freekb/2"
25853         if let "freekb > 5000"; then
25854                 let "freekb=5000"
25855         fi
25856         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25857         trap cleanup_805 EXIT
25858         mkdir_on_mdt0 $DIR/$tdir
25859         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25860                 error "Can't set PFL layout"
25861         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25862         rm -rf $DIR/$tdir || error "not able to remove"
25863         do_facet $SINGLEMDS zfs set quota=$old $fsset
25864         trap 0
25865 }
25866 run_test 805 "ZFS can remove from full fs"
25867
25868 # Size-on-MDS test
25869 check_lsom_data()
25870 {
25871         local file=$1
25872         local expect=$(stat -c %s $file)
25873
25874         check_lsom_size $1 $expect
25875
25876         local blocks=$($LFS getsom -b $file)
25877         expect=$(stat -c %b $file)
25878         [[ $blocks == $expect ]] ||
25879                 error "$file expected blocks: $expect, got: $blocks"
25880 }
25881
25882 check_lsom_size()
25883 {
25884         local size
25885         local expect=$2
25886
25887         cancel_lru_locks mdc
25888
25889         size=$($LFS getsom -s $1)
25890         [[ $size == $expect ]] ||
25891                 error "$file expected size: $expect, got: $size"
25892 }
25893
25894 test_806() {
25895         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25896                 skip "Need MDS version at least 2.11.52"
25897
25898         local bs=1048576
25899
25900         touch $DIR/$tfile || error "touch $tfile failed"
25901
25902         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25903         save_lustre_params client "llite.*.xattr_cache" > $save
25904         lctl set_param llite.*.xattr_cache=0
25905         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25906
25907         # single-threaded write
25908         echo "Test SOM for single-threaded write"
25909         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25910                 error "write $tfile failed"
25911         check_lsom_size $DIR/$tfile $bs
25912
25913         local num=32
25914         local size=$(($num * $bs))
25915         local offset=0
25916         local i
25917
25918         echo "Test SOM for single client multi-threaded($num) write"
25919         $TRUNCATE $DIR/$tfile 0
25920         for ((i = 0; i < $num; i++)); do
25921                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25922                 local pids[$i]=$!
25923                 offset=$((offset + $bs))
25924         done
25925         for (( i=0; i < $num; i++ )); do
25926                 wait ${pids[$i]}
25927         done
25928         check_lsom_size $DIR/$tfile $size
25929
25930         $TRUNCATE $DIR/$tfile 0
25931         for ((i = 0; i < $num; i++)); do
25932                 offset=$((offset - $bs))
25933                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25934                 local pids[$i]=$!
25935         done
25936         for (( i=0; i < $num; i++ )); do
25937                 wait ${pids[$i]}
25938         done
25939         check_lsom_size $DIR/$tfile $size
25940
25941         # multi-client writes
25942         num=$(get_node_count ${CLIENTS//,/ })
25943         size=$(($num * $bs))
25944         offset=0
25945         i=0
25946
25947         echo "Test SOM for multi-client ($num) writes"
25948         $TRUNCATE $DIR/$tfile 0
25949         for client in ${CLIENTS//,/ }; do
25950                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25951                 local pids[$i]=$!
25952                 i=$((i + 1))
25953                 offset=$((offset + $bs))
25954         done
25955         for (( i=0; i < $num; i++ )); do
25956                 wait ${pids[$i]}
25957         done
25958         check_lsom_size $DIR/$tfile $offset
25959
25960         i=0
25961         $TRUNCATE $DIR/$tfile 0
25962         for client in ${CLIENTS//,/ }; do
25963                 offset=$((offset - $bs))
25964                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25965                 local pids[$i]=$!
25966                 i=$((i + 1))
25967         done
25968         for (( i=0; i < $num; i++ )); do
25969                 wait ${pids[$i]}
25970         done
25971         check_lsom_size $DIR/$tfile $size
25972
25973         # verify truncate
25974         echo "Test SOM for truncate"
25975         $TRUNCATE $DIR/$tfile 1048576
25976         check_lsom_size $DIR/$tfile 1048576
25977         $TRUNCATE $DIR/$tfile 1234
25978         check_lsom_size $DIR/$tfile 1234
25979
25980         # verify SOM blocks count
25981         echo "Verify SOM block count"
25982         $TRUNCATE $DIR/$tfile 0
25983         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25984                 error "failed to write file $tfile"
25985         check_lsom_data $DIR/$tfile
25986 }
25987 run_test 806 "Verify Lazy Size on MDS"
25988
25989 test_807() {
25990         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25991         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25992                 skip "Need MDS version at least 2.11.52"
25993
25994         # Registration step
25995         changelog_register || error "changelog_register failed"
25996         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25997         changelog_users $SINGLEMDS | grep -q $cl_user ||
25998                 error "User $cl_user not found in changelog_users"
25999
26000         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26001         save_lustre_params client "llite.*.xattr_cache" > $save
26002         lctl set_param llite.*.xattr_cache=0
26003         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26004
26005         rm -rf $DIR/$tdir || error "rm $tdir failed"
26006         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26007         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26008         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26009         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26010                 error "truncate $tdir/trunc failed"
26011
26012         local bs=1048576
26013         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26014                 error "write $tfile failed"
26015
26016         # multi-client wirtes
26017         local num=$(get_node_count ${CLIENTS//,/ })
26018         local offset=0
26019         local i=0
26020
26021         echo "Test SOM for multi-client ($num) writes"
26022         touch $DIR/$tfile || error "touch $tfile failed"
26023         $TRUNCATE $DIR/$tfile 0
26024         for client in ${CLIENTS//,/ }; do
26025                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26026                 local pids[$i]=$!
26027                 i=$((i + 1))
26028                 offset=$((offset + $bs))
26029         done
26030         for (( i=0; i < $num; i++ )); do
26031                 wait ${pids[$i]}
26032         done
26033
26034         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26035         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26036         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26037         check_lsom_data $DIR/$tdir/trunc
26038         check_lsom_data $DIR/$tdir/single_dd
26039         check_lsom_data $DIR/$tfile
26040
26041         rm -rf $DIR/$tdir
26042         # Deregistration step
26043         changelog_deregister || error "changelog_deregister failed"
26044 }
26045 run_test 807 "verify LSOM syncing tool"
26046
26047 check_som_nologged()
26048 {
26049         local lines=$($LFS changelog $FSNAME-MDT0000 |
26050                 grep 'x=trusted.som' | wc -l)
26051         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26052 }
26053
26054 test_808() {
26055         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26056                 skip "Need MDS version at least 2.11.55"
26057
26058         # Registration step
26059         changelog_register || error "changelog_register failed"
26060
26061         touch $DIR/$tfile || error "touch $tfile failed"
26062         check_som_nologged
26063
26064         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26065                 error "write $tfile failed"
26066         check_som_nologged
26067
26068         $TRUNCATE $DIR/$tfile 1234
26069         check_som_nologged
26070
26071         $TRUNCATE $DIR/$tfile 1048576
26072         check_som_nologged
26073
26074         # Deregistration step
26075         changelog_deregister || error "changelog_deregister failed"
26076 }
26077 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26078
26079 check_som_nodata()
26080 {
26081         $LFS getsom $1
26082         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26083 }
26084
26085 test_809() {
26086         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26087                 skip "Need MDS version at least 2.11.56"
26088
26089         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26090                 error "failed to create DoM-only file $DIR/$tfile"
26091         touch $DIR/$tfile || error "touch $tfile failed"
26092         check_som_nodata $DIR/$tfile
26093
26094         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26095                 error "write $tfile failed"
26096         check_som_nodata $DIR/$tfile
26097
26098         $TRUNCATE $DIR/$tfile 1234
26099         check_som_nodata $DIR/$tfile
26100
26101         $TRUNCATE $DIR/$tfile 4097
26102         check_som_nodata $DIR/$file
26103 }
26104 run_test 809 "Verify no SOM xattr store for DoM-only files"
26105
26106 test_810() {
26107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26108         $GSS && skip_env "could not run with gss"
26109         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26110                 skip "OST < 2.12.58 doesn't align checksum"
26111
26112         set_checksums 1
26113         stack_trap "set_checksums $ORIG_CSUM" EXIT
26114         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26115
26116         local csum
26117         local before
26118         local after
26119         for csum in $CKSUM_TYPES; do
26120                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26121                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26122                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26123                         eval set -- $i
26124                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26125                         before=$(md5sum $DIR/$tfile)
26126                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26127                         after=$(md5sum $DIR/$tfile)
26128                         [ "$before" == "$after" ] ||
26129                                 error "$csum: $before != $after bs=$1 seek=$2"
26130                 done
26131         done
26132 }
26133 run_test 810 "partial page writes on ZFS (LU-11663)"
26134
26135 test_812a() {
26136         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26137                 skip "OST < 2.12.51 doesn't support this fail_loc"
26138
26139         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26140         # ensure ost1 is connected
26141         stat $DIR/$tfile >/dev/null || error "can't stat"
26142         wait_osc_import_state client ost1 FULL
26143         # no locks, no reqs to let the connection idle
26144         cancel_lru_locks osc
26145
26146         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26147 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26148         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26149         wait_osc_import_state client ost1 CONNECTING
26150         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26151
26152         stat $DIR/$tfile >/dev/null || error "can't stat file"
26153 }
26154 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26155
26156 test_812b() { # LU-12378
26157         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26158                 skip "OST < 2.12.51 doesn't support this fail_loc"
26159
26160         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26161         # ensure ost1 is connected
26162         stat $DIR/$tfile >/dev/null || error "can't stat"
26163         wait_osc_import_state client ost1 FULL
26164         # no locks, no reqs to let the connection idle
26165         cancel_lru_locks osc
26166
26167         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26168 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26169         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26170         wait_osc_import_state client ost1 CONNECTING
26171         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26172
26173         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26174         wait_osc_import_state client ost1 IDLE
26175 }
26176 run_test 812b "do not drop no resend request for idle connect"
26177
26178 test_812c() {
26179         local old
26180
26181         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26182
26183         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26184         $LFS getstripe $DIR/$tfile
26185         $LCTL set_param osc.*.idle_timeout=10
26186         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26187         # ensure ost1 is connected
26188         stat $DIR/$tfile >/dev/null || error "can't stat"
26189         wait_osc_import_state client ost1 FULL
26190         # no locks, no reqs to let the connection idle
26191         cancel_lru_locks osc
26192
26193 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26194         $LCTL set_param fail_loc=0x80000533
26195         sleep 15
26196         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26197 }
26198 run_test 812c "idle import vs lock enqueue race"
26199
26200 test_813() {
26201         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26202         [ -z "$file_heat_sav" ] && skip "no file heat support"
26203
26204         local readsample
26205         local writesample
26206         local readbyte
26207         local writebyte
26208         local readsample1
26209         local writesample1
26210         local readbyte1
26211         local writebyte1
26212
26213         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26214         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26215
26216         $LCTL set_param -n llite.*.file_heat=1
26217         echo "Turn on file heat"
26218         echo "Period second: $period_second, Decay percentage: $decay_pct"
26219
26220         echo "QQQQ" > $DIR/$tfile
26221         echo "QQQQ" > $DIR/$tfile
26222         echo "QQQQ" > $DIR/$tfile
26223         cat $DIR/$tfile > /dev/null
26224         cat $DIR/$tfile > /dev/null
26225         cat $DIR/$tfile > /dev/null
26226         cat $DIR/$tfile > /dev/null
26227
26228         local out=$($LFS heat_get $DIR/$tfile)
26229
26230         $LFS heat_get $DIR/$tfile
26231         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26232         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26233         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26234         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26235
26236         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26237         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26238         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26239         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26240
26241         sleep $((period_second + 3))
26242         echo "Sleep $((period_second + 3)) seconds..."
26243         # The recursion formula to calculate the heat of the file f is as
26244         # follow:
26245         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26246         # Where Hi is the heat value in the period between time points i*I and
26247         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26248         # to the weight of Ci.
26249         out=$($LFS heat_get $DIR/$tfile)
26250         $LFS heat_get $DIR/$tfile
26251         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26252         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26253         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26254         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26255
26256         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26257                 error "read sample ($readsample) is wrong"
26258         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26259                 error "write sample ($writesample) is wrong"
26260         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26261                 error "read bytes ($readbyte) is wrong"
26262         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26263                 error "write bytes ($writebyte) is wrong"
26264
26265         echo "QQQQ" > $DIR/$tfile
26266         echo "QQQQ" > $DIR/$tfile
26267         echo "QQQQ" > $DIR/$tfile
26268         cat $DIR/$tfile > /dev/null
26269         cat $DIR/$tfile > /dev/null
26270         cat $DIR/$tfile > /dev/null
26271         cat $DIR/$tfile > /dev/null
26272
26273         sleep $((period_second + 3))
26274         echo "Sleep $((period_second + 3)) seconds..."
26275
26276         out=$($LFS heat_get $DIR/$tfile)
26277         $LFS heat_get $DIR/$tfile
26278         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26279         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26280         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26281         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26282
26283         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26284                 4 * $decay_pct) / 100") -eq 1 ] ||
26285                 error "read sample ($readsample1) is wrong"
26286         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26287                 3 * $decay_pct) / 100") -eq 1 ] ||
26288                 error "write sample ($writesample1) is wrong"
26289         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26290                 20 * $decay_pct) / 100") -eq 1 ] ||
26291                 error "read bytes ($readbyte1) is wrong"
26292         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26293                 15 * $decay_pct) / 100") -eq 1 ] ||
26294                 error "write bytes ($writebyte1) is wrong"
26295
26296         echo "Turn off file heat for the file $DIR/$tfile"
26297         $LFS heat_set -o $DIR/$tfile
26298
26299         echo "QQQQ" > $DIR/$tfile
26300         echo "QQQQ" > $DIR/$tfile
26301         echo "QQQQ" > $DIR/$tfile
26302         cat $DIR/$tfile > /dev/null
26303         cat $DIR/$tfile > /dev/null
26304         cat $DIR/$tfile > /dev/null
26305         cat $DIR/$tfile > /dev/null
26306
26307         out=$($LFS heat_get $DIR/$tfile)
26308         $LFS heat_get $DIR/$tfile
26309         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26310         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26311         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26312         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26313
26314         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26315         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26316         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26317         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26318
26319         echo "Trun on file heat for the file $DIR/$tfile"
26320         $LFS heat_set -O $DIR/$tfile
26321
26322         echo "QQQQ" > $DIR/$tfile
26323         echo "QQQQ" > $DIR/$tfile
26324         echo "QQQQ" > $DIR/$tfile
26325         cat $DIR/$tfile > /dev/null
26326         cat $DIR/$tfile > /dev/null
26327         cat $DIR/$tfile > /dev/null
26328         cat $DIR/$tfile > /dev/null
26329
26330         out=$($LFS heat_get $DIR/$tfile)
26331         $LFS heat_get $DIR/$tfile
26332         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26333         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26334         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26335         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26336
26337         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26338         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26339         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26340         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26341
26342         $LFS heat_set -c $DIR/$tfile
26343         $LCTL set_param -n llite.*.file_heat=0
26344         echo "Turn off file heat support for the Lustre filesystem"
26345
26346         echo "QQQQ" > $DIR/$tfile
26347         echo "QQQQ" > $DIR/$tfile
26348         echo "QQQQ" > $DIR/$tfile
26349         cat $DIR/$tfile > /dev/null
26350         cat $DIR/$tfile > /dev/null
26351         cat $DIR/$tfile > /dev/null
26352         cat $DIR/$tfile > /dev/null
26353
26354         out=$($LFS heat_get $DIR/$tfile)
26355         $LFS heat_get $DIR/$tfile
26356         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26357         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26358         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26359         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26360
26361         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26362         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26363         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26364         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26365
26366         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26367         rm -f $DIR/$tfile
26368 }
26369 run_test 813 "File heat verfication"
26370
26371 test_814()
26372 {
26373         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26374         echo -n y >> $DIR/$tfile
26375         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26376         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26377 }
26378 run_test 814 "sparse cp works as expected (LU-12361)"
26379
26380 test_815()
26381 {
26382         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26383         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26384 }
26385 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26386
26387 test_816() {
26388         local ost1_imp=$(get_osc_import_name client ost1)
26389         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26390                          cut -d'.' -f2)
26391
26392         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26393         # ensure ost1 is connected
26394
26395         stat $DIR/$tfile >/dev/null || error "can't stat"
26396         wait_osc_import_state client ost1 FULL
26397         # no locks, no reqs to let the connection idle
26398         cancel_lru_locks osc
26399         lru_resize_disable osc
26400         local before
26401         local now
26402         before=$($LCTL get_param -n \
26403                  ldlm.namespaces.$imp_name.lru_size)
26404
26405         wait_osc_import_state client ost1 IDLE
26406         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26407         now=$($LCTL get_param -n \
26408               ldlm.namespaces.$imp_name.lru_size)
26409         [ $before == $now ] || error "lru_size changed $before != $now"
26410 }
26411 run_test 816 "do not reset lru_resize on idle reconnect"
26412
26413 cleanup_817() {
26414         umount $tmpdir
26415         exportfs -u localhost:$DIR/nfsexp
26416         rm -rf $DIR/nfsexp
26417 }
26418
26419 test_817() {
26420         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26421
26422         mkdir -p $DIR/nfsexp
26423         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26424                 error "failed to export nfs"
26425
26426         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26427         stack_trap cleanup_817 EXIT
26428
26429         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26430                 error "failed to mount nfs to $tmpdir"
26431
26432         cp /bin/true $tmpdir
26433         $DIR/nfsexp/true || error "failed to execute 'true' command"
26434 }
26435 run_test 817 "nfsd won't cache write lock for exec file"
26436
26437 test_818() {
26438         mkdir $DIR/$tdir
26439         $LFS setstripe -c1 -i0 $DIR/$tfile
26440         $LFS setstripe -c1 -i1 $DIR/$tfile
26441         stop $SINGLEMDS
26442         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26443         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26444         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26445                 error "start $SINGLEMDS failed"
26446         rm -rf $DIR/$tdir
26447 }
26448 run_test 818 "unlink with failed llog"
26449
26450 test_819a() {
26451         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26452         cancel_lru_locks osc
26453         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26454         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26455         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26456         rm -f $TDIR/$tfile
26457 }
26458 run_test 819a "too big niobuf in read"
26459
26460 test_819b() {
26461         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26462         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26463         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26464         cancel_lru_locks osc
26465         sleep 1
26466         rm -f $TDIR/$tfile
26467 }
26468 run_test 819b "too big niobuf in write"
26469
26470
26471 function test_820_start_ost() {
26472         sleep 5
26473
26474         for num in $(seq $OSTCOUNT); do
26475                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26476         done
26477 }
26478
26479 test_820() {
26480         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26481
26482         mkdir $DIR/$tdir
26483         umount_client $MOUNT || error "umount failed"
26484         for num in $(seq $OSTCOUNT); do
26485                 stop ost$num
26486         done
26487
26488         # mount client with no active OSTs
26489         # so that the client can't initialize max LOV EA size
26490         # from OSC notifications
26491         mount_client $MOUNT || error "mount failed"
26492         # delay OST starting to keep this 0 max EA size for a while
26493         test_820_start_ost &
26494
26495         # create a directory on MDS2
26496         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26497                 error "Failed to create directory"
26498         # open intent should update default EA size
26499         # see mdc_update_max_ea_from_body()
26500         # notice this is the very first RPC to MDS2
26501         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26502         ret=$?
26503         echo $out
26504         # With SSK, this situation can lead to -EPERM being returned.
26505         # In that case, simply retry.
26506         if [ $ret -ne 0 ] && $SHARED_KEY; then
26507                 if echo "$out" | grep -q "not permitted"; then
26508                         cp /etc/services $DIR/$tdir/mds2
26509                         ret=$?
26510                 fi
26511         fi
26512         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26513 }
26514 run_test 820 "update max EA from open intent"
26515
26516 test_822() {
26517         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26518
26519         save_lustre_params mds1 \
26520                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26521         do_facet $SINGLEMDS "$LCTL set_param -n \
26522                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26523         do_facet $SINGLEMDS "$LCTL set_param -n \
26524                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26525
26526         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26527         local maxage=$(do_facet mds1 $LCTL get_param -n \
26528                        osp.$FSNAME-OST0000*MDT0000.maxage)
26529         sleep $((maxage + 1))
26530
26531         #define OBD_FAIL_NET_ERROR_RPC          0x532
26532         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26533
26534         stack_trap "restore_lustre_params < $p; rm $p"
26535
26536         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26537                       osp.$FSNAME-OST0000*MDT0000.create_count")
26538         for i in $(seq 1 $count); do
26539                 touch $DIR/$tfile.${i} || error "touch failed"
26540         done
26541 }
26542 run_test 822 "test precreate failure"
26543
26544 #
26545 # tests that do cleanup/setup should be run at the end
26546 #
26547
26548 test_900() {
26549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26550         local ls
26551
26552         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26553         $LCTL set_param fail_loc=0x903
26554
26555         cancel_lru_locks MGC
26556
26557         FAIL_ON_ERROR=true cleanup
26558         FAIL_ON_ERROR=true setup
26559 }
26560 run_test 900 "umount should not race with any mgc requeue thread"
26561
26562 # LUS-6253/LU-11185
26563 test_901() {
26564         local oldc
26565         local newc
26566         local olds
26567         local news
26568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26569
26570         # some get_param have a bug to handle dot in param name
26571         cancel_lru_locks MGC
26572         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26573         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26574         umount_client $MOUNT || error "umount failed"
26575         mount_client $MOUNT || error "mount failed"
26576         cancel_lru_locks MGC
26577         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26578         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26579
26580         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26581         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26582
26583         return 0
26584 }
26585 run_test 901 "don't leak a mgc lock on client umount"
26586
26587 # LU-13377
26588 test_902() {
26589         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26590                 skip "client does not have LU-13377 fix"
26591         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26592         $LCTL set_param fail_loc=0x1415
26593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26594         cancel_lru_locks osc
26595         rm -f $DIR/$tfile
26596 }
26597 run_test 902 "test short write doesn't hang lustre"
26598
26599 complete $SECONDS
26600 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26601 check_and_cleanup_lustre
26602 if [ "$I_MOUNTED" != "yes" ]; then
26603         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26604 fi
26605 exit_status