Whamcloud - gitweb
f1732e581b5e8116e7b49564c06080a8ba6349e5
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         test_mkdir $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 test_27Q() {
3323         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3324
3325         test_mkdir $DIR/$tdir-1
3326         test_mkdir $DIR/$tdir-2
3327
3328         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3329         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3330
3331         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3332         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3333
3334         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3335         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3336
3337         # Create some bad symlinks and ensure that we don't loop
3338         # forever or something. These should return ELOOP (40) and
3339         # ENOENT (2) but I don't want to test for that because there's
3340         # always some weirdo architecture that needs to ruin
3341         # everything by defining these error numbers differently.
3342
3343         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3344         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3345
3346         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3347         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3348
3349         return 0
3350 }
3351 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3352
3353 # createtest also checks that device nodes are created and
3354 # then visible correctly (#2091)
3355 test_28() { # bug 2091
3356         test_mkdir $DIR/d28
3357         $CREATETEST $DIR/d28/ct || error "createtest failed"
3358 }
3359 run_test 28 "create/mknod/mkdir with bad file types ============"
3360
3361 test_29() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         sync; sleep 1; sync # flush out any dirty pages from previous tests
3365         cancel_lru_locks
3366         test_mkdir $DIR/d29
3367         touch $DIR/d29/foo
3368         log 'first d29'
3369         ls -l $DIR/d29
3370
3371         declare -i LOCKCOUNTORIG=0
3372         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3373                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3374         done
3375         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3376
3377         declare -i LOCKUNUSEDCOUNTORIG=0
3378         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3379                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3380         done
3381
3382         log 'second d29'
3383         ls -l $DIR/d29
3384         log 'done'
3385
3386         declare -i LOCKCOUNTCURRENT=0
3387         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3388                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3389         done
3390
3391         declare -i LOCKUNUSEDCOUNTCURRENT=0
3392         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3393                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3394         done
3395
3396         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3397                 $LCTL set_param -n ldlm.dump_namespaces ""
3398                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3399                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3400                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3401                 return 2
3402         fi
3403         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3404                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3405                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3406                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3407                 return 3
3408         fi
3409 }
3410 run_test 29 "IT_GETATTR regression  ============================"
3411
3412 test_30a() { # was test_30
3413         cp $(which ls) $DIR || cp /bin/ls $DIR
3414         $DIR/ls / || error "Can't execute binary from lustre"
3415         rm $DIR/ls
3416 }
3417 run_test 30a "execute binary from Lustre (execve) =============="
3418
3419 test_30b() {
3420         cp `which ls` $DIR || cp /bin/ls $DIR
3421         chmod go+rx $DIR/ls
3422         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3423         rm $DIR/ls
3424 }
3425 run_test 30b "execute binary from Lustre as non-root ==========="
3426
3427 test_30c() { # b=22376
3428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3429
3430         cp $(which ls) $DIR || cp /bin/ls $DIR
3431         chmod a-rw $DIR/ls
3432         cancel_lru_locks mdc
3433         cancel_lru_locks osc
3434         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3435         rm -f $DIR/ls
3436 }
3437 run_test 30c "execute binary from Lustre without read perms ===="
3438
3439 test_30d() {
3440         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3441
3442         for i in {1..10}; do
3443                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3444                 local PID=$!
3445                 sleep 1
3446                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3447                 wait $PID || error "executing dd from Lustre failed"
3448                 rm -f $DIR/$tfile
3449         done
3450
3451         rm -f $DIR/dd
3452 }
3453 run_test 30d "execute binary from Lustre while clear locks"
3454
3455 test_31a() {
3456         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3457         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3458 }
3459 run_test 31a "open-unlink file =================================="
3460
3461 test_31b() {
3462         touch $DIR/f31 || error "touch $DIR/f31 failed"
3463         ln $DIR/f31 $DIR/f31b || error "ln failed"
3464         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3465         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3466 }
3467 run_test 31b "unlink file with multiple links while open ======="
3468
3469 test_31c() {
3470         touch $DIR/f31 || error "touch $DIR/f31 failed"
3471         ln $DIR/f31 $DIR/f31c || error "ln failed"
3472         multiop_bg_pause $DIR/f31 O_uc ||
3473                 error "multiop_bg_pause for $DIR/f31 failed"
3474         MULTIPID=$!
3475         $MULTIOP $DIR/f31c Ouc
3476         kill -USR1 $MULTIPID
3477         wait $MULTIPID
3478 }
3479 run_test 31c "open-unlink file with multiple links ============="
3480
3481 test_31d() {
3482         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3483         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3484 }
3485 run_test 31d "remove of open directory ========================="
3486
3487 test_31e() { # bug 2904
3488         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3489 }
3490 run_test 31e "remove of open non-empty directory ==============="
3491
3492 test_31f() { # bug 4554
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         set -vx
3496         test_mkdir $DIR/d31f
3497         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3498         cp /etc/hosts $DIR/d31f
3499         ls -l $DIR/d31f
3500         $LFS getstripe $DIR/d31f/hosts
3501         multiop_bg_pause $DIR/d31f D_c || return 1
3502         MULTIPID=$!
3503
3504         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3505         test_mkdir $DIR/d31f
3506         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3507         cp /etc/hosts $DIR/d31f
3508         ls -l $DIR/d31f
3509         $LFS getstripe $DIR/d31f/hosts
3510         multiop_bg_pause $DIR/d31f D_c || return 1
3511         MULTIPID2=$!
3512
3513         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3514         wait $MULTIPID || error "first opendir $MULTIPID failed"
3515
3516         sleep 6
3517
3518         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3519         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3520         set +vx
3521 }
3522 run_test 31f "remove of open directory with open-unlink file ==="
3523
3524 test_31g() {
3525         echo "-- cross directory link --"
3526         test_mkdir -c1 $DIR/${tdir}ga
3527         test_mkdir -c1 $DIR/${tdir}gb
3528         touch $DIR/${tdir}ga/f
3529         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3530         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3531         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3532         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3533         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3534 }
3535 run_test 31g "cross directory link==============="
3536
3537 test_31h() {
3538         echo "-- cross directory link --"
3539         test_mkdir -c1 $DIR/${tdir}
3540         test_mkdir -c1 $DIR/${tdir}/dir
3541         touch $DIR/${tdir}/f
3542         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3543         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3544         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3545         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3546         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3547 }
3548 run_test 31h "cross directory link under child==============="
3549
3550 test_31i() {
3551         echo "-- cross directory link --"
3552         test_mkdir -c1 $DIR/$tdir
3553         test_mkdir -c1 $DIR/$tdir/dir
3554         touch $DIR/$tdir/dir/f
3555         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3556         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3557         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3558         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3559         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3560 }
3561 run_test 31i "cross directory link under parent==============="
3562
3563 test_31j() {
3564         test_mkdir -c1 -p $DIR/$tdir
3565         test_mkdir -c1 -p $DIR/$tdir/dir1
3566         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3567         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3568         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3569         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3570         return 0
3571 }
3572 run_test 31j "link for directory==============="
3573
3574 test_31k() {
3575         test_mkdir -c1 -p $DIR/$tdir
3576         touch $DIR/$tdir/s
3577         touch $DIR/$tdir/exist
3578         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3579         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3580         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3581         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3582         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3583         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3584         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3585         return 0
3586 }
3587 run_test 31k "link to file: the same, non-existing, dir==============="
3588
3589 test_31m() {
3590         mkdir $DIR/d31m
3591         touch $DIR/d31m/s
3592         mkdir $DIR/d31m2
3593         touch $DIR/d31m2/exist
3594         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3595         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3596         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3597         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3598         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3599         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3600         return 0
3601 }
3602 run_test 31m "link to file: the same, non-existing, dir==============="
3603
3604 test_31n() {
3605         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3606         nlink=$(stat --format=%h $DIR/$tfile)
3607         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3608         local fd=$(free_fd)
3609         local cmd="exec $fd<$DIR/$tfile"
3610         eval $cmd
3611         cmd="exec $fd<&-"
3612         trap "eval $cmd" EXIT
3613         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3614         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3615         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3616         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3617         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3618         eval $cmd
3619 }
3620 run_test 31n "check link count of unlinked file"
3621
3622 link_one() {
3623         local tempfile=$(mktemp $1_XXXXXX)
3624         mlink $tempfile $1 2> /dev/null &&
3625                 echo "$BASHPID: link $tempfile to $1 succeeded"
3626         munlink $tempfile
3627 }
3628
3629 test_31o() { # LU-2901
3630         test_mkdir $DIR/$tdir
3631         for LOOP in $(seq 100); do
3632                 rm -f $DIR/$tdir/$tfile*
3633                 for THREAD in $(seq 8); do
3634                         link_one $DIR/$tdir/$tfile.$LOOP &
3635                 done
3636                 wait
3637                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3638                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3639                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3640                         break || true
3641         done
3642 }
3643 run_test 31o "duplicate hard links with same filename"
3644
3645 test_31p() {
3646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3647
3648         test_mkdir $DIR/$tdir
3649         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3650         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3651
3652         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3653                 error "open unlink test1 failed"
3654         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3655                 error "open unlink test2 failed"
3656
3657         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3658                 error "test1 still exists"
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3660                 error "test2 still exists"
3661 }
3662 run_test 31p "remove of open striped directory"
3663
3664 test_31q() {
3665         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3666
3667         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3668         index=$($LFS getdirstripe -i $DIR/$tdir)
3669         [ $index -eq 3 ] || error "first stripe index $index != 3"
3670         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3671         [ $index -eq 1 ] || error "second stripe index $index != 1"
3672
3673         # when "-c <stripe_count>" is set, the number of MDTs specified after
3674         # "-i" should equal to the stripe count
3675         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3676 }
3677 run_test 31q "create striped directory on specific MDTs"
3678
3679 cleanup_test32_mount() {
3680         local rc=0
3681         trap 0
3682         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3683         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3684         losetup -d $loopdev || true
3685         rm -rf $DIR/$tdir
3686         return $rc
3687 }
3688
3689 test_32a() {
3690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3691
3692         echo "== more mountpoints and symlinks ================="
3693         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3694         trap cleanup_test32_mount EXIT
3695         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3696         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3697                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3698         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3699                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3700         cleanup_test32_mount
3701 }
3702 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3703
3704 test_32b() {
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3708         trap cleanup_test32_mount EXIT
3709         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3710         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3711                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3712         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3713                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3714         cleanup_test32_mount
3715 }
3716 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3717
3718 test_32c() {
3719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3720
3721         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3722         trap cleanup_test32_mount EXIT
3723         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3724         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3725                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3726         test_mkdir -p $DIR/$tdir/d2/test_dir
3727         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3728                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3729         cleanup_test32_mount
3730 }
3731 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3732
3733 test_32d() {
3734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3735
3736         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3737         trap cleanup_test32_mount EXIT
3738         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3739         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3740                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3741         test_mkdir -p $DIR/$tdir/d2/test_dir
3742         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3743                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3744         cleanup_test32_mount
3745 }
3746 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3747
3748 test_32e() {
3749         rm -fr $DIR/$tdir
3750         test_mkdir -p $DIR/$tdir/tmp
3751         local tmp_dir=$DIR/$tdir/tmp
3752         ln -s $DIR/$tdir $tmp_dir/symlink11
3753         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3754         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3755         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3756 }
3757 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3758
3759 test_32f() {
3760         rm -fr $DIR/$tdir
3761         test_mkdir -p $DIR/$tdir/tmp
3762         local tmp_dir=$DIR/$tdir/tmp
3763         ln -s $DIR/$tdir $tmp_dir/symlink11
3764         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3765         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3766         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3767 }
3768 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3769
3770 test_32g() {
3771         local tmp_dir=$DIR/$tdir/tmp
3772         test_mkdir -p $tmp_dir
3773         test_mkdir $DIR/${tdir}2
3774         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3775         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3776         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3777         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3778         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3779         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3780 }
3781 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3782
3783 test_32h() {
3784         rm -fr $DIR/$tdir $DIR/${tdir}2
3785         tmp_dir=$DIR/$tdir/tmp
3786         test_mkdir -p $tmp_dir
3787         test_mkdir $DIR/${tdir}2
3788         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3789         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3790         ls $tmp_dir/symlink12 || error "listing symlink12"
3791         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3792 }
3793 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3794
3795 test_32i() {
3796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3797
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         touch $DIR/$tdir/test_file
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3809
3810 test_32j() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         touch $DIR/$tdir/test_file
3819         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3820                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3821         cleanup_test32_mount
3822 }
3823 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3824
3825 test_32k() {
3826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3827
3828         rm -fr $DIR/$tdir
3829         trap cleanup_test32_mount EXIT
3830         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3831         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3832                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3833         test_mkdir -p $DIR/$tdir/d2
3834         touch $DIR/$tdir/d2/test_file || error "touch failed"
3835         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3836                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3837         cleanup_test32_mount
3838 }
3839 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3840
3841 test_32l() {
3842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3843
3844         rm -fr $DIR/$tdir
3845         trap cleanup_test32_mount EXIT
3846         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3847         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3848                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3849         test_mkdir -p $DIR/$tdir/d2
3850         touch $DIR/$tdir/d2/test_file || error "touch failed"
3851         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3852                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3853         cleanup_test32_mount
3854 }
3855 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3856
3857 test_32m() {
3858         rm -fr $DIR/d32m
3859         test_mkdir -p $DIR/d32m/tmp
3860         TMP_DIR=$DIR/d32m/tmp
3861         ln -s $DIR $TMP_DIR/symlink11
3862         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3863         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3864                 error "symlink11 not a link"
3865         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3866                 error "symlink01 not a link"
3867 }
3868 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3869
3870 test_32n() {
3871         rm -fr $DIR/d32n
3872         test_mkdir -p $DIR/d32n/tmp
3873         TMP_DIR=$DIR/d32n/tmp
3874         ln -s $DIR $TMP_DIR/symlink11
3875         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3876         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3877         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3878 }
3879 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3880
3881 test_32o() {
3882         touch $DIR/$tfile
3883         test_mkdir -p $DIR/d32o/tmp
3884         TMP_DIR=$DIR/d32o/tmp
3885         ln -s $DIR/$tfile $TMP_DIR/symlink12
3886         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3887         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3888                 error "symlink12 not a link"
3889         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3890         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3891                 error "$DIR/d32o/tmp/symlink12 not file type"
3892         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3893                 error "$DIR/d32o/symlink02 not file type"
3894 }
3895 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3896
3897 test_32p() {
3898         log 32p_1
3899         rm -fr $DIR/d32p
3900         log 32p_2
3901         rm -f $DIR/$tfile
3902         log 32p_3
3903         touch $DIR/$tfile
3904         log 32p_4
3905         test_mkdir -p $DIR/d32p/tmp
3906         log 32p_5
3907         TMP_DIR=$DIR/d32p/tmp
3908         log 32p_6
3909         ln -s $DIR/$tfile $TMP_DIR/symlink12
3910         log 32p_7
3911         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3912         log 32p_8
3913         cat $DIR/d32p/tmp/symlink12 ||
3914                 error "Can't open $DIR/d32p/tmp/symlink12"
3915         log 32p_9
3916         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3917         log 32p_10
3918 }
3919 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3920
3921 test_32q() {
3922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3923
3924         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3925         trap cleanup_test32_mount EXIT
3926         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3927         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3928         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3929                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3930         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3931         cleanup_test32_mount
3932 }
3933 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3934
3935 test_32r() {
3936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3937
3938         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3939         trap cleanup_test32_mount EXIT
3940         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3941         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3942         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3943                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3944         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3945         cleanup_test32_mount
3946 }
3947 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3948
3949 test_33aa() {
3950         rm -f $DIR/$tfile
3951         touch $DIR/$tfile
3952         chmod 444 $DIR/$tfile
3953         chown $RUNAS_ID $DIR/$tfile
3954         log 33_1
3955         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3956         log 33_2
3957 }
3958 run_test 33aa "write file with mode 444 (should return error)"
3959
3960 test_33a() {
3961         rm -fr $DIR/$tdir
3962         test_mkdir $DIR/$tdir
3963         chown $RUNAS_ID $DIR/$tdir
3964         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3965                 error "$RUNAS create $tdir/$tfile failed"
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3967                 error "open RDWR" || true
3968 }
3969 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3970
3971 test_33b() {
3972         rm -fr $DIR/$tdir
3973         test_mkdir $DIR/$tdir
3974         chown $RUNAS_ID $DIR/$tdir
3975         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3976 }
3977 run_test 33b "test open file with malformed flags (No panic)"
3978
3979 test_33c() {
3980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3981         remote_ost_nodsh && skip "remote OST with nodsh"
3982
3983         local ostnum
3984         local ostname
3985         local write_bytes
3986         local all_zeros
3987
3988         all_zeros=true
3989         test_mkdir $DIR/$tdir
3990         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3991
3992         sync
3993         for ostnum in $(seq $OSTCOUNT); do
3994                 # test-framework's OST numbering is one-based, while Lustre's
3995                 # is zero-based
3996                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3997                 # check if at least some write_bytes stats are counted
3998                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3999                               obdfilter.$ostname.stats |
4000                               awk '/^write_bytes/ {print $7}' )
4001                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4002                 if (( ${write_bytes:-0} > 0 )); then
4003                         all_zeros=false
4004                         break
4005                 fi
4006         done
4007
4008         $all_zeros || return 0
4009
4010         # Write four bytes
4011         echo foo > $DIR/$tdir/bar
4012         # Really write them
4013         sync
4014
4015         # Total up write_bytes after writing.  We'd better find non-zeros.
4016         for ostnum in $(seq $OSTCOUNT); do
4017                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4018                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4019                               obdfilter/$ostname/stats |
4020                               awk '/^write_bytes/ {print $7}' )
4021                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4022                 if (( ${write_bytes:-0} > 0 )); then
4023                         all_zeros=false
4024                         break
4025                 fi
4026         done
4027
4028         if $all_zeros; then
4029                 for ostnum in $(seq $OSTCOUNT); do
4030                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4031                         echo "Check write_bytes is in obdfilter.*.stats:"
4032                         do_facet ost$ostnum lctl get_param -n \
4033                                 obdfilter.$ostname.stats
4034                 done
4035                 error "OST not keeping write_bytes stats (b=22312)"
4036         fi
4037 }
4038 run_test 33c "test write_bytes stats"
4039
4040 test_33d() {
4041         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4043
4044         local MDTIDX=1
4045         local remote_dir=$DIR/$tdir/remote_dir
4046
4047         test_mkdir $DIR/$tdir
4048         $LFS mkdir -i $MDTIDX $remote_dir ||
4049                 error "create remote directory failed"
4050
4051         touch $remote_dir/$tfile
4052         chmod 444 $remote_dir/$tfile
4053         chown $RUNAS_ID $remote_dir/$tfile
4054
4055         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4056
4057         chown $RUNAS_ID $remote_dir
4058         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4059                                         error "create" || true
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4061                                     error "open RDWR" || true
4062         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4063 }
4064 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4065
4066 test_33e() {
4067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4068
4069         mkdir $DIR/$tdir
4070
4071         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4072         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4073         mkdir $DIR/$tdir/local_dir
4074
4075         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4076         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4077         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4078
4079         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4080                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4081
4082         rmdir $DIR/$tdir/* || error "rmdir failed"
4083
4084         umask 777
4085         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4086         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4087         mkdir $DIR/$tdir/local_dir
4088
4089         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4090         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4091         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4092
4093         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4094                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4095
4096         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4097
4098         umask 000
4099         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4100         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4101         mkdir $DIR/$tdir/local_dir
4102
4103         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4104         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4105         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4106
4107         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4108                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4109 }
4110 run_test 33e "mkdir and striped directory should have same mode"
4111
4112 cleanup_33f() {
4113         trap 0
4114         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4115 }
4116
4117 test_33f() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119         remote_mds_nodsh && skip "remote MDS with nodsh"
4120
4121         mkdir $DIR/$tdir
4122         chmod go+rwx $DIR/$tdir
4123         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4124         trap cleanup_33f EXIT
4125
4126         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4127                 error "cannot create striped directory"
4128
4129         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4130                 error "cannot create files in striped directory"
4131
4132         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4133                 error "cannot remove files in striped directory"
4134
4135         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4136                 error "cannot remove striped directory"
4137
4138         cleanup_33f
4139 }
4140 run_test 33f "nonroot user can create, access, and remove a striped directory"
4141
4142 test_33g() {
4143         mkdir -p $DIR/$tdir/dir2
4144
4145         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4146         echo $err
4147         [[ $err =~ "exists" ]] || error "Not exists error"
4148 }
4149 run_test 33g "nonroot user create already existing root created file"
4150
4151 test_33h() {
4152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4153         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4154                 skip "Need MDS version at least 2.13.50"
4155
4156         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4157                 error "mkdir $tdir failed"
4158         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4159
4160         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4161         local index2
4162
4163         for fname in $DIR/$tdir/$tfile.bak \
4164                      $DIR/$tdir/$tfile.SAV \
4165                      $DIR/$tdir/$tfile.orig \
4166                      $DIR/$tdir/$tfile~; do
4167                 touch $fname  || error "touch $fname failed"
4168                 index2=$($LFS getstripe -m $fname)
4169                 [ $index -eq $index2 ] ||
4170                         error "$fname MDT index mismatch $index != $index2"
4171         done
4172
4173         local failed=0
4174         for i in {1..250}; do
4175                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4176                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4177                         touch $fname  || error "touch $fname failed"
4178                         index2=$($LFS getstripe -m $fname)
4179                         if [[ $index != $index2 ]]; then
4180                                 failed=$((failed + 1))
4181                                 echo "$fname MDT index mismatch $index != $index2"
4182                         fi
4183                 done
4184         done
4185         echo "$failed MDT index mismatches"
4186         (( failed < 20 )) || error "MDT index mismatch $failed times"
4187
4188 }
4189 run_test 33h "temp file is located on the same MDT as target"
4190
4191 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4192 test_34a() {
4193         rm -f $DIR/f34
4194         $MCREATE $DIR/f34 || error "mcreate failed"
4195         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4196                 error "getstripe failed"
4197         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4198         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4199                 error "getstripe failed"
4200         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4201                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4202 }
4203 run_test 34a "truncate file that has not been opened ==========="
4204
4205 test_34b() {
4206         [ ! -f $DIR/f34 ] && test_34a
4207         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4208                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4209         $OPENFILE -f O_RDONLY $DIR/f34
4210         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4211                 error "getstripe failed"
4212         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4213                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4214 }
4215 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4216
4217 test_34c() {
4218         [ ! -f $DIR/f34 ] && test_34a
4219         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4220                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4221         $OPENFILE -f O_RDWR $DIR/f34
4222         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4223                 error "$LFS getstripe failed"
4224         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4225                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4226 }
4227 run_test 34c "O_RDWR opening file-with-size works =============="
4228
4229 test_34d() {
4230         [ ! -f $DIR/f34 ] && test_34a
4231         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4232                 error "dd failed"
4233         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4234                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4235         rm $DIR/f34
4236 }
4237 run_test 34d "write to sparse file ============================="
4238
4239 test_34e() {
4240         rm -f $DIR/f34e
4241         $MCREATE $DIR/f34e || error "mcreate failed"
4242         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4243         $CHECKSTAT -s 1000 $DIR/f34e ||
4244                 error "Size of $DIR/f34e not equal to 1000 bytes"
4245         $OPENFILE -f O_RDWR $DIR/f34e
4246         $CHECKSTAT -s 1000 $DIR/f34e ||
4247                 error "Size of $DIR/f34e not equal to 1000 bytes"
4248 }
4249 run_test 34e "create objects, some with size and some without =="
4250
4251 test_34f() { # bug 6242, 6243
4252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4253
4254         SIZE34F=48000
4255         rm -f $DIR/f34f
4256         $MCREATE $DIR/f34f || error "mcreate failed"
4257         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4258         dd if=$DIR/f34f of=$TMP/f34f
4259         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4260         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4261         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4262         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4263         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4264 }
4265 run_test 34f "read from a file with no objects until EOF ======="
4266
4267 test_34g() {
4268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4269
4270         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4271                 error "dd failed"
4272         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4273         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4274                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4275         cancel_lru_locks osc
4276         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4277                 error "wrong size after lock cancel"
4278
4279         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4280         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4281                 error "expanding truncate failed"
4282         cancel_lru_locks osc
4283         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4284                 error "wrong expanded size after lock cancel"
4285 }
4286 run_test 34g "truncate long file ==============================="
4287
4288 test_34h() {
4289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4290
4291         local gid=10
4292         local sz=1000
4293
4294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4295         sync # Flush the cache so that multiop below does not block on cache
4296              # flush when getting the group lock
4297         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4298         MULTIPID=$!
4299
4300         # Since just timed wait is not good enough, let's do a sync write
4301         # that way we are sure enough time for a roundtrip + processing
4302         # passed + 2 seconds of extra margin.
4303         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4304         rm $DIR/${tfile}-1
4305         sleep 2
4306
4307         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4308                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4309                 kill -9 $MULTIPID
4310         fi
4311         wait $MULTIPID
4312         local nsz=`stat -c %s $DIR/$tfile`
4313         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4314 }
4315 run_test 34h "ftruncate file under grouplock should not block"
4316
4317 test_35a() {
4318         cp /bin/sh $DIR/f35a
4319         chmod 444 $DIR/f35a
4320         chown $RUNAS_ID $DIR/f35a
4321         $RUNAS $DIR/f35a && error || true
4322         rm $DIR/f35a
4323 }
4324 run_test 35a "exec file with mode 444 (should return and not leak)"
4325
4326 test_36a() {
4327         rm -f $DIR/f36
4328         utime $DIR/f36 || error "utime failed for MDS"
4329 }
4330 run_test 36a "MDS utime check (mknod, utime)"
4331
4332 test_36b() {
4333         echo "" > $DIR/f36
4334         utime $DIR/f36 || error "utime failed for OST"
4335 }
4336 run_test 36b "OST utime check (open, utime)"
4337
4338 test_36c() {
4339         rm -f $DIR/d36/f36
4340         test_mkdir $DIR/d36
4341         chown $RUNAS_ID $DIR/d36
4342         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4343 }
4344 run_test 36c "non-root MDS utime check (mknod, utime)"
4345
4346 test_36d() {
4347         [ ! -d $DIR/d36 ] && test_36c
4348         echo "" > $DIR/d36/f36
4349         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4350 }
4351 run_test 36d "non-root OST utime check (open, utime)"
4352
4353 test_36e() {
4354         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4355
4356         test_mkdir $DIR/$tdir
4357         touch $DIR/$tdir/$tfile
4358         $RUNAS utime $DIR/$tdir/$tfile &&
4359                 error "utime worked, expected failure" || true
4360 }
4361 run_test 36e "utime on non-owned file (should return error)"
4362
4363 subr_36fh() {
4364         local fl="$1"
4365         local LANG_SAVE=$LANG
4366         local LC_LANG_SAVE=$LC_LANG
4367         export LANG=C LC_LANG=C # for date language
4368
4369         DATESTR="Dec 20  2000"
4370         test_mkdir $DIR/$tdir
4371         lctl set_param fail_loc=$fl
4372         date; date +%s
4373         cp /etc/hosts $DIR/$tdir/$tfile
4374         sync & # write RPC generated with "current" inode timestamp, but delayed
4375         sleep 1
4376         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4377         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4378         cancel_lru_locks $OSC
4379         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4380         date; date +%s
4381         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4382                 echo "BEFORE: $LS_BEFORE" && \
4383                 echo "AFTER : $LS_AFTER" && \
4384                 echo "WANT  : $DATESTR" && \
4385                 error "$DIR/$tdir/$tfile timestamps changed" || true
4386
4387         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4388 }
4389
4390 test_36f() {
4391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4392
4393         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4394         subr_36fh "0x80000214"
4395 }
4396 run_test 36f "utime on file racing with OST BRW write =========="
4397
4398 test_36g() {
4399         remote_ost_nodsh && skip "remote OST with nodsh"
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4402                 skip "Need MDS version at least 2.12.51"
4403
4404         local fmd_max_age
4405         local fmd
4406         local facet="ost1"
4407         local tgt="obdfilter"
4408
4409         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4410
4411         test_mkdir $DIR/$tdir
4412         fmd_max_age=$(do_facet $facet \
4413                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4414                 head -n 1")
4415
4416         echo "FMD max age: ${fmd_max_age}s"
4417         touch $DIR/$tdir/$tfile
4418         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4419                 gawk '{cnt=cnt+$1}  END{print cnt}')
4420         echo "FMD before: $fmd"
4421         [[ $fmd == 0 ]] &&
4422                 error "FMD wasn't create by touch"
4423         sleep $((fmd_max_age + 12))
4424         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4425                 gawk '{cnt=cnt+$1}  END{print cnt}')
4426         echo "FMD after: $fmd"
4427         [[ $fmd == 0 ]] ||
4428                 error "FMD wasn't expired by ping"
4429 }
4430 run_test 36g "FMD cache expiry ====================="
4431
4432 test_36h() {
4433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4434
4435         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4436         subr_36fh "0x80000227"
4437 }
4438 run_test 36h "utime on file racing with OST BRW write =========="
4439
4440 test_36i() {
4441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4442
4443         test_mkdir $DIR/$tdir
4444         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4445
4446         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4447         local new_mtime=$((mtime + 200))
4448
4449         #change Modify time of striped dir
4450         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4451                         error "change mtime failed"
4452
4453         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4454
4455         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4456 }
4457 run_test 36i "change mtime on striped directory"
4458
4459 # test_37 - duplicate with tests 32q 32r
4460
4461 test_38() {
4462         local file=$DIR/$tfile
4463         touch $file
4464         openfile -f O_DIRECTORY $file
4465         local RC=$?
4466         local ENOTDIR=20
4467         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4468         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4469 }
4470 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4471
4472 test_39a() { # was test_39
4473         touch $DIR/$tfile
4474         touch $DIR/${tfile}2
4475 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4476 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4477 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4478         sleep 2
4479         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4480         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4481                 echo "mtime"
4482                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4483                 echo "atime"
4484                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "ctime"
4486                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4487                 error "O_TRUNC didn't change timestamps"
4488         fi
4489 }
4490 run_test 39a "mtime changed on create"
4491
4492 test_39b() {
4493         test_mkdir -c1 $DIR/$tdir
4494         cp -p /etc/passwd $DIR/$tdir/fopen
4495         cp -p /etc/passwd $DIR/$tdir/flink
4496         cp -p /etc/passwd $DIR/$tdir/funlink
4497         cp -p /etc/passwd $DIR/$tdir/frename
4498         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4499
4500         sleep 1
4501         echo "aaaaaa" >> $DIR/$tdir/fopen
4502         echo "aaaaaa" >> $DIR/$tdir/flink
4503         echo "aaaaaa" >> $DIR/$tdir/funlink
4504         echo "aaaaaa" >> $DIR/$tdir/frename
4505
4506         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4507         local link_new=`stat -c %Y $DIR/$tdir/flink`
4508         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4509         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4510
4511         cat $DIR/$tdir/fopen > /dev/null
4512         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4513         rm -f $DIR/$tdir/funlink2
4514         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4515
4516         for (( i=0; i < 2; i++ )) ; do
4517                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4518                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4519                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4520                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4521
4522                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4523                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4524                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4525                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4526
4527                 cancel_lru_locks $OSC
4528                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4529         done
4530 }
4531 run_test 39b "mtime change on open, link, unlink, rename  ======"
4532
4533 # this should be set to past
4534 TEST_39_MTIME=`date -d "1 year ago" +%s`
4535
4536 # bug 11063
4537 test_39c() {
4538         touch $DIR1/$tfile
4539         sleep 2
4540         local mtime0=`stat -c %Y $DIR1/$tfile`
4541
4542         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4543         local mtime1=`stat -c %Y $DIR1/$tfile`
4544         [ "$mtime1" = $TEST_39_MTIME ] || \
4545                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4546
4547         local d1=`date +%s`
4548         echo hello >> $DIR1/$tfile
4549         local d2=`date +%s`
4550         local mtime2=`stat -c %Y $DIR1/$tfile`
4551         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4552                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4553
4554         mv $DIR1/$tfile $DIR1/$tfile-1
4555
4556         for (( i=0; i < 2; i++ )) ; do
4557                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4558                 [ "$mtime2" = "$mtime3" ] || \
4559                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4560
4561                 cancel_lru_locks $OSC
4562                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4563         done
4564 }
4565 run_test 39c "mtime change on rename ==========================="
4566
4567 # bug 21114
4568 test_39d() {
4569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4570
4571         touch $DIR1/$tfile
4572         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4573
4574         for (( i=0; i < 2; i++ )) ; do
4575                 local mtime=`stat -c %Y $DIR1/$tfile`
4576                 [ $mtime = $TEST_39_MTIME ] || \
4577                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4578
4579                 cancel_lru_locks $OSC
4580                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4581         done
4582 }
4583 run_test 39d "create, utime, stat =============================="
4584
4585 # bug 21114
4586 test_39e() {
4587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4588
4589         touch $DIR1/$tfile
4590         local mtime1=`stat -c %Y $DIR1/$tfile`
4591
4592         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4593
4594         for (( i=0; i < 2; i++ )) ; do
4595                 local mtime2=`stat -c %Y $DIR1/$tfile`
4596                 [ $mtime2 = $TEST_39_MTIME ] || \
4597                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4598
4599                 cancel_lru_locks $OSC
4600                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4601         done
4602 }
4603 run_test 39e "create, stat, utime, stat ========================"
4604
4605 # bug 21114
4606 test_39f() {
4607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4608
4609         touch $DIR1/$tfile
4610         mtime1=`stat -c %Y $DIR1/$tfile`
4611
4612         sleep 2
4613         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4614
4615         for (( i=0; i < 2; i++ )) ; do
4616                 local mtime2=`stat -c %Y $DIR1/$tfile`
4617                 [ $mtime2 = $TEST_39_MTIME ] || \
4618                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4619
4620                 cancel_lru_locks $OSC
4621                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4622         done
4623 }
4624 run_test 39f "create, stat, sleep, utime, stat ================="
4625
4626 # bug 11063
4627 test_39g() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         echo hello >> $DIR1/$tfile
4631         local mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         sleep 2
4634         chmod o+r $DIR1/$tfile
4635
4636         for (( i=0; i < 2; i++ )) ; do
4637                 local mtime2=`stat -c %Y $DIR1/$tfile`
4638                 [ "$mtime1" = "$mtime2" ] || \
4639                         error "lost mtime: $mtime2, should be $mtime1"
4640
4641                 cancel_lru_locks $OSC
4642                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4643         done
4644 }
4645 run_test 39g "write, chmod, stat ==============================="
4646
4647 # bug 11063
4648 test_39h() {
4649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4650
4651         touch $DIR1/$tfile
4652         sleep 1
4653
4654         local d1=`date`
4655         echo hello >> $DIR1/$tfile
4656         local mtime1=`stat -c %Y $DIR1/$tfile`
4657
4658         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4659         local d2=`date`
4660         if [ "$d1" != "$d2" ]; then
4661                 echo "write and touch not within one second"
4662         else
4663                 for (( i=0; i < 2; i++ )) ; do
4664                         local mtime2=`stat -c %Y $DIR1/$tfile`
4665                         [ "$mtime2" = $TEST_39_MTIME ] || \
4666                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4667
4668                         cancel_lru_locks $OSC
4669                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4670                 done
4671         fi
4672 }
4673 run_test 39h "write, utime within one second, stat ============="
4674
4675 test_39i() {
4676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4677
4678         touch $DIR1/$tfile
4679         sleep 1
4680
4681         echo hello >> $DIR1/$tfile
4682         local mtime1=`stat -c %Y $DIR1/$tfile`
4683
4684         mv $DIR1/$tfile $DIR1/$tfile-1
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4688
4689                 [ "$mtime1" = "$mtime2" ] || \
4690                         error "lost mtime: $mtime2, should be $mtime1"
4691
4692                 cancel_lru_locks $OSC
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695 }
4696 run_test 39i "write, rename, stat =============================="
4697
4698 test_39j() {
4699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4700
4701         start_full_debug_logging
4702         touch $DIR1/$tfile
4703         sleep 1
4704
4705         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4706         lctl set_param fail_loc=0x80000412
4707         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4708                 error "multiop failed"
4709         local multipid=$!
4710         local mtime1=`stat -c %Y $DIR1/$tfile`
4711
4712         mv $DIR1/$tfile $DIR1/$tfile-1
4713
4714         kill -USR1 $multipid
4715         wait $multipid || error "multiop close failed"
4716
4717         for (( i=0; i < 2; i++ )) ; do
4718                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4719                 [ "$mtime1" = "$mtime2" ] ||
4720                         error "mtime is lost on close: $mtime2, " \
4721                               "should be $mtime1"
4722
4723                 cancel_lru_locks
4724                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4725         done
4726         lctl set_param fail_loc=0
4727         stop_full_debug_logging
4728 }
4729 run_test 39j "write, rename, close, stat ======================="
4730
4731 test_39k() {
4732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4733
4734         touch $DIR1/$tfile
4735         sleep 1
4736
4737         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4738         local multipid=$!
4739         local mtime1=`stat -c %Y $DIR1/$tfile`
4740
4741         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4742
4743         kill -USR1 $multipid
4744         wait $multipid || error "multiop close failed"
4745
4746         for (( i=0; i < 2; i++ )) ; do
4747                 local mtime2=`stat -c %Y $DIR1/$tfile`
4748
4749                 [ "$mtime2" = $TEST_39_MTIME ] || \
4750                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4751
4752                 cancel_lru_locks
4753                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4754         done
4755 }
4756 run_test 39k "write, utime, close, stat ========================"
4757
4758 # this should be set to future
4759 TEST_39_ATIME=`date -d "1 year" +%s`
4760
4761 test_39l() {
4762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4763         remote_mds_nodsh && skip "remote MDS with nodsh"
4764
4765         local atime_diff=$(do_facet $SINGLEMDS \
4766                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4767         rm -rf $DIR/$tdir
4768         mkdir -p $DIR/$tdir
4769
4770         # test setting directory atime to future
4771         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4772         local atime=$(stat -c %X $DIR/$tdir)
4773         [ "$atime" = $TEST_39_ATIME ] ||
4774                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4775
4776         # test setting directory atime from future to now
4777         local now=$(date +%s)
4778         touch -a -d @$now $DIR/$tdir
4779
4780         atime=$(stat -c %X $DIR/$tdir)
4781         [ "$atime" -eq "$now"  ] ||
4782                 error "atime is not updated from future: $atime, $now"
4783
4784         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4785         sleep 3
4786
4787         # test setting directory atime when now > dir atime + atime_diff
4788         local d1=$(date +%s)
4789         ls $DIR/$tdir
4790         local d2=$(date +%s)
4791         cancel_lru_locks mdc
4792         atime=$(stat -c %X $DIR/$tdir)
4793         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4794                 error "atime is not updated  : $atime, should be $d2"
4795
4796         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4797         sleep 3
4798
4799         # test not setting directory atime when now < dir atime + atime_diff
4800         ls $DIR/$tdir
4801         cancel_lru_locks mdc
4802         atime=$(stat -c %X $DIR/$tdir)
4803         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4804                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4805
4806         do_facet $SINGLEMDS \
4807                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4808 }
4809 run_test 39l "directory atime update ==========================="
4810
4811 test_39m() {
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         touch $DIR1/$tfile
4815         sleep 2
4816         local far_past_mtime=$(date -d "May 29 1953" +%s)
4817         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4818
4819         touch -m -d @$far_past_mtime $DIR1/$tfile
4820         touch -a -d @$far_past_atime $DIR1/$tfile
4821
4822         for (( i=0; i < 2; i++ )) ; do
4823                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4824                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4825                         error "atime or mtime set incorrectly"
4826
4827                 cancel_lru_locks $OSC
4828                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4829         done
4830 }
4831 run_test 39m "test atime and mtime before 1970"
4832
4833 test_39n() { # LU-3832
4834         remote_mds_nodsh && skip "remote MDS with nodsh"
4835
4836         local atime_diff=$(do_facet $SINGLEMDS \
4837                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4838         local atime0
4839         local atime1
4840         local atime2
4841
4842         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4843
4844         rm -rf $DIR/$tfile
4845         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4846         atime0=$(stat -c %X $DIR/$tfile)
4847
4848         sleep 5
4849         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4850         atime1=$(stat -c %X $DIR/$tfile)
4851
4852         sleep 5
4853         cancel_lru_locks mdc
4854         cancel_lru_locks osc
4855         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4856         atime2=$(stat -c %X $DIR/$tfile)
4857
4858         do_facet $SINGLEMDS \
4859                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4860
4861         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4862         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4863 }
4864 run_test 39n "check that O_NOATIME is honored"
4865
4866 test_39o() {
4867         TESTDIR=$DIR/$tdir/$tfile
4868         [ -e $TESTDIR ] && rm -rf $TESTDIR
4869         mkdir -p $TESTDIR
4870         cd $TESTDIR
4871         links1=2
4872         ls
4873         mkdir a b
4874         ls
4875         links2=$(stat -c %h .)
4876         [ $(($links1 + 2)) != $links2 ] &&
4877                 error "wrong links count $(($links1 + 2)) != $links2"
4878         rmdir b
4879         links3=$(stat -c %h .)
4880         [ $(($links1 + 1)) != $links3 ] &&
4881                 error "wrong links count $links1 != $links3"
4882         return 0
4883 }
4884 run_test 39o "directory cached attributes updated after create"
4885
4886 test_39p() {
4887         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4888
4889         local MDTIDX=1
4890         TESTDIR=$DIR/$tdir/$tdir
4891         [ -e $TESTDIR ] && rm -rf $TESTDIR
4892         test_mkdir -p $TESTDIR
4893         cd $TESTDIR
4894         links1=2
4895         ls
4896         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4897         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4898         ls
4899         links2=$(stat -c %h .)
4900         [ $(($links1 + 2)) != $links2 ] &&
4901                 error "wrong links count $(($links1 + 2)) != $links2"
4902         rmdir remote_dir2
4903         links3=$(stat -c %h .)
4904         [ $(($links1 + 1)) != $links3 ] &&
4905                 error "wrong links count $links1 != $links3"
4906         return 0
4907 }
4908 run_test 39p "remote directory cached attributes updated after create ========"
4909
4910 test_39r() {
4911         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4912                 skip "no atime update on old OST"
4913         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4914                 skip_env "ldiskfs only test"
4915         fi
4916
4917         local saved_adiff
4918         saved_adiff=$(do_facet ost1 \
4919                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4920         stack_trap "do_facet ost1 \
4921                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4922
4923         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4924
4925         $LFS setstripe -i 0 $DIR/$tfile
4926         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4927                 error "can't write initial file"
4928         cancel_lru_locks osc
4929
4930         # exceed atime_diff and access file
4931         sleep 6
4932         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4933                 error "can't udpate atime"
4934
4935         local atime_cli=$(stat -c %X $DIR/$tfile)
4936         echo "client atime: $atime_cli"
4937         # allow atime update to be written to device
4938         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4939         sleep 5
4940
4941         local ostdev=$(ostdevname 1)
4942         local fid=($(lfs getstripe -y $DIR/$tfile |
4943                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4944         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4945         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4946
4947         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4948         local atime_ost=$(do_facet ost1 "$cmd" |&
4949                           awk -F'[: ]' '/atime:/ { print $4 }')
4950         (( atime_cli == atime_ost )) ||
4951                 error "atime on client $atime_cli != ost $atime_ost"
4952 }
4953 run_test 39r "lazy atime update on OST"
4954
4955 test_39q() { # LU-8041
4956         local testdir=$DIR/$tdir
4957         mkdir -p $testdir
4958         multiop_bg_pause $testdir D_c || error "multiop failed"
4959         local multipid=$!
4960         cancel_lru_locks mdc
4961         kill -USR1 $multipid
4962         local atime=$(stat -c %X $testdir)
4963         [ "$atime" -ne 0 ] || error "atime is zero"
4964 }
4965 run_test 39q "close won't zero out atime"
4966
4967 test_40() {
4968         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4969         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4970                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4971         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4972                 error "$tfile is not 4096 bytes in size"
4973 }
4974 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4975
4976 test_41() {
4977         # bug 1553
4978         small_write $DIR/f41 18
4979 }
4980 run_test 41 "test small file write + fstat ====================="
4981
4982 count_ost_writes() {
4983         lctl get_param -n ${OSC}.*.stats |
4984                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4985                         END { printf("%0.0f", writes) }'
4986 }
4987
4988 # decent default
4989 WRITEBACK_SAVE=500
4990 DIRTY_RATIO_SAVE=40
4991 MAX_DIRTY_RATIO=50
4992 BG_DIRTY_RATIO_SAVE=10
4993 MAX_BG_DIRTY_RATIO=25
4994
4995 start_writeback() {
4996         trap 0
4997         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4998         # dirty_ratio, dirty_background_ratio
4999         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5000                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5001                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5002                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5003         else
5004                 # if file not here, we are a 2.4 kernel
5005                 kill -CONT `pidof kupdated`
5006         fi
5007 }
5008
5009 stop_writeback() {
5010         # setup the trap first, so someone cannot exit the test at the
5011         # exact wrong time and mess up a machine
5012         trap start_writeback EXIT
5013         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5014         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5015                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5016                 sysctl -w vm.dirty_writeback_centisecs=0
5017                 sysctl -w vm.dirty_writeback_centisecs=0
5018                 # save and increase /proc/sys/vm/dirty_ratio
5019                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5020                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5021                 # save and increase /proc/sys/vm/dirty_background_ratio
5022                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5023                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5024         else
5025                 # if file not here, we are a 2.4 kernel
5026                 kill -STOP `pidof kupdated`
5027         fi
5028 }
5029
5030 # ensure that all stripes have some grant before we test client-side cache
5031 setup_test42() {
5032         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5033                 dd if=/dev/zero of=$i bs=4k count=1
5034                 rm $i
5035         done
5036 }
5037
5038 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5039 # file truncation, and file removal.
5040 test_42a() {
5041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5042
5043         setup_test42
5044         cancel_lru_locks $OSC
5045         stop_writeback
5046         sync; sleep 1; sync # just to be safe
5047         BEFOREWRITES=`count_ost_writes`
5048         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5049         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5050         AFTERWRITES=`count_ost_writes`
5051         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5052                 error "$BEFOREWRITES < $AFTERWRITES"
5053         start_writeback
5054 }
5055 run_test 42a "ensure that we don't flush on close"
5056
5057 test_42b() {
5058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5059
5060         setup_test42
5061         cancel_lru_locks $OSC
5062         stop_writeback
5063         sync
5064         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5065         BEFOREWRITES=$(count_ost_writes)
5066         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5067         AFTERWRITES=$(count_ost_writes)
5068         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5069                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5070         fi
5071         BEFOREWRITES=$(count_ost_writes)
5072         sync || error "sync: $?"
5073         AFTERWRITES=$(count_ost_writes)
5074         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5075                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5076         fi
5077         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5078         start_writeback
5079         return 0
5080 }
5081 run_test 42b "test destroy of file with cached dirty data ======"
5082
5083 # if these tests just want to test the effect of truncation,
5084 # they have to be very careful.  consider:
5085 # - the first open gets a {0,EOF}PR lock
5086 # - the first write conflicts and gets a {0, count-1}PW
5087 # - the rest of the writes are under {count,EOF}PW
5088 # - the open for truncate tries to match a {0,EOF}PR
5089 #   for the filesize and cancels the PWs.
5090 # any number of fixes (don't get {0,EOF} on open, match
5091 # composite locks, do smarter file size management) fix
5092 # this, but for now we want these tests to verify that
5093 # the cancellation with truncate intent works, so we
5094 # start the file with a full-file pw lock to match against
5095 # until the truncate.
5096 trunc_test() {
5097         test=$1
5098         file=$DIR/$test
5099         offset=$2
5100         cancel_lru_locks $OSC
5101         stop_writeback
5102         # prime the file with 0,EOF PW to match
5103         touch $file
5104         $TRUNCATE $file 0
5105         sync; sync
5106         # now the real test..
5107         dd if=/dev/zero of=$file bs=1024 count=100
5108         BEFOREWRITES=`count_ost_writes`
5109         $TRUNCATE $file $offset
5110         cancel_lru_locks $OSC
5111         AFTERWRITES=`count_ost_writes`
5112         start_writeback
5113 }
5114
5115 test_42c() {
5116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5117
5118         trunc_test 42c 1024
5119         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5120                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5121         rm $file
5122 }
5123 run_test 42c "test partial truncate of file with cached dirty data"
5124
5125 test_42d() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         trunc_test 42d 0
5129         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5130                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5131         rm $file
5132 }
5133 run_test 42d "test complete truncate of file with cached dirty data"
5134
5135 test_42e() { # bug22074
5136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5137
5138         local TDIR=$DIR/${tdir}e
5139         local pages=16 # hardcoded 16 pages, don't change it.
5140         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5141         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5142         local max_dirty_mb
5143         local warmup_files
5144
5145         test_mkdir $DIR/${tdir}e
5146         $LFS setstripe -c 1 $TDIR
5147         createmany -o $TDIR/f $files
5148
5149         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5150
5151         # we assume that with $OSTCOUNT files, at least one of them will
5152         # be allocated on OST0.
5153         warmup_files=$((OSTCOUNT * max_dirty_mb))
5154         createmany -o $TDIR/w $warmup_files
5155
5156         # write a large amount of data into one file and sync, to get good
5157         # avail_grant number from OST.
5158         for ((i=0; i<$warmup_files; i++)); do
5159                 idx=$($LFS getstripe -i $TDIR/w$i)
5160                 [ $idx -ne 0 ] && continue
5161                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5162                 break
5163         done
5164         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5165         sync
5166         $LCTL get_param $proc_osc0/cur_dirty_bytes
5167         $LCTL get_param $proc_osc0/cur_grant_bytes
5168
5169         # create as much dirty pages as we can while not to trigger the actual
5170         # RPCs directly. but depends on the env, VFS may trigger flush during this
5171         # period, hopefully we are good.
5172         for ((i=0; i<$warmup_files; i++)); do
5173                 idx=$($LFS getstripe -i $TDIR/w$i)
5174                 [ $idx -ne 0 ] && continue
5175                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5176         done
5177         $LCTL get_param $proc_osc0/cur_dirty_bytes
5178         $LCTL get_param $proc_osc0/cur_grant_bytes
5179
5180         # perform the real test
5181         $LCTL set_param $proc_osc0/rpc_stats 0
5182         for ((;i<$files; i++)); do
5183                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5184                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5185         done
5186         sync
5187         $LCTL get_param $proc_osc0/rpc_stats
5188
5189         local percent=0
5190         local have_ppr=false
5191         $LCTL get_param $proc_osc0/rpc_stats |
5192                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5193                         # skip lines until we are at the RPC histogram data
5194                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5195                         $have_ppr || continue
5196
5197                         # we only want the percent stat for < 16 pages
5198                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5199
5200                         percent=$((percent + WPCT))
5201                         if [[ $percent -gt 15 ]]; then
5202                                 error "less than 16-pages write RPCs" \
5203                                       "$percent% > 15%"
5204                                 break
5205                         fi
5206                 done
5207         rm -rf $TDIR
5208 }
5209 run_test 42e "verify sub-RPC writes are not done synchronously"
5210
5211 test_43A() { # was test_43
5212         test_mkdir $DIR/$tdir
5213         cp -p /bin/ls $DIR/$tdir/$tfile
5214         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5215         pid=$!
5216         # give multiop a chance to open
5217         sleep 1
5218
5219         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5220         kill -USR1 $pid
5221         # Wait for multiop to exit
5222         wait $pid
5223 }
5224 run_test 43A "execution of file opened for write should return -ETXTBSY"
5225
5226 test_43a() {
5227         test_mkdir $DIR/$tdir
5228         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5229         $DIR/$tdir/sleep 60 &
5230         SLEEP_PID=$!
5231         # Make sure exec of $tdir/sleep wins race with truncate
5232         sleep 1
5233         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5234         kill $SLEEP_PID
5235 }
5236 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5237
5238 test_43b() {
5239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5240
5241         test_mkdir $DIR/$tdir
5242         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5243         $DIR/$tdir/sleep 60 &
5244         SLEEP_PID=$!
5245         # Make sure exec of $tdir/sleep wins race with truncate
5246         sleep 1
5247         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5248         kill $SLEEP_PID
5249 }
5250 run_test 43b "truncate of file being executed should return -ETXTBSY"
5251
5252 test_43c() {
5253         local testdir="$DIR/$tdir"
5254         test_mkdir $testdir
5255         cp $SHELL $testdir/
5256         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5257                 ( cd $testdir && md5sum -c )
5258 }
5259 run_test 43c "md5sum of copy into lustre"
5260
5261 test_44A() { # was test_44
5262         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5263
5264         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5265         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5266 }
5267 run_test 44A "zero length read from a sparse stripe"
5268
5269 test_44a() {
5270         local nstripe=$($LFS getstripe -c -d $DIR)
5271         [ -z "$nstripe" ] && skip "can't get stripe info"
5272         [[ $nstripe -gt $OSTCOUNT ]] &&
5273                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5274
5275         local stride=$($LFS getstripe -S -d $DIR)
5276         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5277                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5278         fi
5279
5280         OFFSETS="0 $((stride/2)) $((stride-1))"
5281         for offset in $OFFSETS; do
5282                 for i in $(seq 0 $((nstripe-1))); do
5283                         local GLOBALOFFSETS=""
5284                         # size in Bytes
5285                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5286                         local myfn=$DIR/d44a-$size
5287                         echo "--------writing $myfn at $size"
5288                         ll_sparseness_write $myfn $size ||
5289                                 error "ll_sparseness_write"
5290                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5291                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5292                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5293
5294                         for j in $(seq 0 $((nstripe-1))); do
5295                                 # size in Bytes
5296                                 size=$((((j + $nstripe )*$stride + $offset)))
5297                                 ll_sparseness_write $myfn $size ||
5298                                         error "ll_sparseness_write"
5299                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5300                         done
5301                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5302                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5303                         rm -f $myfn
5304                 done
5305         done
5306 }
5307 run_test 44a "test sparse pwrite ==============================="
5308
5309 dirty_osc_total() {
5310         tot=0
5311         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5312                 tot=$(($tot + $d))
5313         done
5314         echo $tot
5315 }
5316 do_dirty_record() {
5317         before=`dirty_osc_total`
5318         echo executing "\"$*\""
5319         eval $*
5320         after=`dirty_osc_total`
5321         echo before $before, after $after
5322 }
5323 test_45() {
5324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5325
5326         f="$DIR/f45"
5327         # Obtain grants from OST if it supports it
5328         echo blah > ${f}_grant
5329         stop_writeback
5330         sync
5331         do_dirty_record "echo blah > $f"
5332         [[ $before -eq $after ]] && error "write wasn't cached"
5333         do_dirty_record "> $f"
5334         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5335         do_dirty_record "echo blah > $f"
5336         [[ $before -eq $after ]] && error "write wasn't cached"
5337         do_dirty_record "sync"
5338         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5339         do_dirty_record "echo blah > $f"
5340         [[ $before -eq $after ]] && error "write wasn't cached"
5341         do_dirty_record "cancel_lru_locks osc"
5342         [[ $before -gt $after ]] ||
5343                 error "lock cancellation didn't lower dirty count"
5344         start_writeback
5345 }
5346 run_test 45 "osc io page accounting ============================"
5347
5348 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5349 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5350 # objects offset and an assert hit when an rpc was built with 1023's mapped
5351 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5352 test_46() {
5353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5354
5355         f="$DIR/f46"
5356         stop_writeback
5357         sync
5358         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5359         sync
5360         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5361         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5362         sync
5363         start_writeback
5364 }
5365 run_test 46 "dirtying a previously written page ================"
5366
5367 # test_47 is removed "Device nodes check" is moved to test_28
5368
5369 test_48a() { # bug 2399
5370         [ "$mds1_FSTYPE" = "zfs" ] &&
5371         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5372                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5373
5374         test_mkdir $DIR/$tdir
5375         cd $DIR/$tdir
5376         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5377         test_mkdir $DIR/$tdir
5378         touch foo || error "'touch foo' failed after recreating cwd"
5379         test_mkdir bar
5380         touch .foo || error "'touch .foo' failed after recreating cwd"
5381         test_mkdir .bar
5382         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5383         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5384         cd . || error "'cd .' failed after recreating cwd"
5385         mkdir . && error "'mkdir .' worked after recreating cwd"
5386         rmdir . && error "'rmdir .' worked after recreating cwd"
5387         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5388         cd .. || error "'cd ..' failed after recreating cwd"
5389 }
5390 run_test 48a "Access renamed working dir (should return errors)="
5391
5392 test_48b() { # bug 2399
5393         rm -rf $DIR/$tdir
5394         test_mkdir $DIR/$tdir
5395         cd $DIR/$tdir
5396         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5397         touch foo && error "'touch foo' worked after removing cwd"
5398         mkdir foo && error "'mkdir foo' worked after removing cwd"
5399         touch .foo && error "'touch .foo' worked after removing cwd"
5400         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5401         ls . > /dev/null && error "'ls .' worked after removing cwd"
5402         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5403         mkdir . && error "'mkdir .' worked after removing cwd"
5404         rmdir . && error "'rmdir .' worked after removing cwd"
5405         ln -s . foo && error "'ln -s .' worked after removing cwd"
5406         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5407 }
5408 run_test 48b "Access removed working dir (should return errors)="
5409
5410 test_48c() { # bug 2350
5411         #lctl set_param debug=-1
5412         #set -vx
5413         rm -rf $DIR/$tdir
5414         test_mkdir -p $DIR/$tdir/dir
5415         cd $DIR/$tdir/dir
5416         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5417         $TRACE touch foo && error "touch foo worked after removing cwd"
5418         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5419         touch .foo && error "touch .foo worked after removing cwd"
5420         mkdir .foo && error "mkdir .foo worked after removing cwd"
5421         $TRACE ls . && error "'ls .' worked after removing cwd"
5422         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5423         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5424         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5425         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5426         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5427 }
5428 run_test 48c "Access removed working subdir (should return errors)"
5429
5430 test_48d() { # bug 2350
5431         #lctl set_param debug=-1
5432         #set -vx
5433         rm -rf $DIR/$tdir
5434         test_mkdir -p $DIR/$tdir/dir
5435         cd $DIR/$tdir/dir
5436         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5437         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5438         $TRACE touch foo && error "'touch foo' worked after removing parent"
5439         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5440         touch .foo && error "'touch .foo' worked after removing parent"
5441         mkdir .foo && error "mkdir .foo worked after removing parent"
5442         $TRACE ls . && error "'ls .' worked after removing parent"
5443         $TRACE ls .. && error "'ls ..' worked after removing parent"
5444         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5445         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5446         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5447         true
5448 }
5449 run_test 48d "Access removed parent subdir (should return errors)"
5450
5451 test_48e() { # bug 4134
5452         #lctl set_param debug=-1
5453         #set -vx
5454         rm -rf $DIR/$tdir
5455         test_mkdir -p $DIR/$tdir/dir
5456         cd $DIR/$tdir/dir
5457         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5458         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5459         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5460         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5461         # On a buggy kernel addition of "touch foo" after cd .. will
5462         # produce kernel oops in lookup_hash_it
5463         touch ../foo && error "'cd ..' worked after recreate parent"
5464         cd $DIR
5465         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5466 }
5467 run_test 48e "Access to recreated parent subdir (should return errors)"
5468
5469 test_48f() {
5470         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5471                 skip "need MDS >= 2.13.55"
5472         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5473         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5474                 skip "needs different host for mdt1 mdt2"
5475         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5476
5477         $LFS mkdir -i0 $DIR/$tdir
5478         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5479
5480         for d in sub1 sub2 sub3; do
5481                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5482                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5483                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5484         done
5485
5486         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5487 }
5488 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5489
5490 test_49() { # LU-1030
5491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5492         remote_ost_nodsh && skip "remote OST with nodsh"
5493
5494         # get ost1 size - $FSNAME-OST0000
5495         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5496                 awk '{ print $4 }')
5497         # write 800M at maximum
5498         [[ $ost1_size -lt 2 ]] && ost1_size=2
5499         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5500
5501         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5502         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5503         local dd_pid=$!
5504
5505         # change max_pages_per_rpc while writing the file
5506         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5507         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5508         # loop until dd process exits
5509         while ps ax -opid | grep -wq $dd_pid; do
5510                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5511                 sleep $((RANDOM % 5 + 1))
5512         done
5513         # restore original max_pages_per_rpc
5514         $LCTL set_param $osc1_mppc=$orig_mppc
5515         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5516 }
5517 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5518
5519 test_50() {
5520         # bug 1485
5521         test_mkdir $DIR/$tdir
5522         cd $DIR/$tdir
5523         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5524 }
5525 run_test 50 "special situations: /proc symlinks  ==============="
5526
5527 test_51a() {    # was test_51
5528         # bug 1516 - create an empty entry right after ".." then split dir
5529         test_mkdir -c1 $DIR/$tdir
5530         touch $DIR/$tdir/foo
5531         $MCREATE $DIR/$tdir/bar
5532         rm $DIR/$tdir/foo
5533         createmany -m $DIR/$tdir/longfile 201
5534         FNUM=202
5535         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5536                 $MCREATE $DIR/$tdir/longfile$FNUM
5537                 FNUM=$(($FNUM + 1))
5538                 echo -n "+"
5539         done
5540         echo
5541         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5542 }
5543 run_test 51a "special situations: split htree with empty entry =="
5544
5545 cleanup_print_lfs_df () {
5546         trap 0
5547         $LFS df
5548         $LFS df -i
5549 }
5550
5551 test_51b() {
5552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5553
5554         local dir=$DIR/$tdir
5555         local nrdirs=$((65536 + 100))
5556
5557         # cleanup the directory
5558         rm -fr $dir
5559
5560         test_mkdir -c1 $dir
5561
5562         $LFS df
5563         $LFS df -i
5564         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5565         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5566         [[ $numfree -lt $nrdirs ]] &&
5567                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5568
5569         # need to check free space for the directories as well
5570         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5571         numfree=$(( blkfree / $(fs_inode_ksize) ))
5572         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5573
5574         trap cleanup_print_lfs_df EXIT
5575
5576         # create files
5577         createmany -d $dir/d $nrdirs || {
5578                 unlinkmany $dir/d $nrdirs
5579                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5580         }
5581
5582         # really created :
5583         nrdirs=$(ls -U $dir | wc -l)
5584
5585         # unlink all but 100 subdirectories, then check it still works
5586         local left=100
5587         local delete=$((nrdirs - left))
5588
5589         $LFS df
5590         $LFS df -i
5591
5592         # for ldiskfs the nlink count should be 1, but this is OSD specific
5593         # and so this is listed for informational purposes only
5594         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5595         unlinkmany -d $dir/d $delete ||
5596                 error "unlink of first $delete subdirs failed"
5597
5598         echo "nlink between: $(stat -c %h $dir)"
5599         local found=$(ls -U $dir | wc -l)
5600         [ $found -ne $left ] &&
5601                 error "can't find subdirs: found only $found, expected $left"
5602
5603         unlinkmany -d $dir/d $delete $left ||
5604                 error "unlink of second $left subdirs failed"
5605         # regardless of whether the backing filesystem tracks nlink accurately
5606         # or not, the nlink count shouldn't be more than "." and ".." here
5607         local after=$(stat -c %h $dir)
5608         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5609                 echo "nlink after: $after"
5610
5611         cleanup_print_lfs_df
5612 }
5613 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5614
5615 test_51d() {
5616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5617         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5618
5619         test_mkdir $DIR/$tdir
5620         createmany -o $DIR/$tdir/t- 1000
5621         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5622         for N in $(seq 0 $((OSTCOUNT - 1))); do
5623                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5624                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5625                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5626                         '($1 == '$N') { objs += 1 } \
5627                         END { printf("%0.0f", objs) }')
5628                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5629         done
5630         unlinkmany $DIR/$tdir/t- 1000
5631
5632         NLAST=0
5633         for N in $(seq 1 $((OSTCOUNT - 1))); do
5634                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5635                         error "OST $N has less objects vs OST $NLAST" \
5636                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5637                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5638                         error "OST $N has less objects vs OST $NLAST" \
5639                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5640
5641                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5642                         error "OST $N has less #0 objects vs OST $NLAST" \
5643                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5644                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5645                         error "OST $N has less #0 objects vs OST $NLAST" \
5646                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5647                 NLAST=$N
5648         done
5649         rm -f $TMP/$tfile
5650 }
5651 run_test 51d "check object distribution"
5652
5653 test_51e() {
5654         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5655                 skip_env "ldiskfs only test"
5656         fi
5657
5658         test_mkdir -c1 $DIR/$tdir
5659         test_mkdir -c1 $DIR/$tdir/d0
5660
5661         touch $DIR/$tdir/d0/foo
5662         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5663                 error "file exceed 65000 nlink limit!"
5664         unlinkmany $DIR/$tdir/d0/f- 65001
5665         return 0
5666 }
5667 run_test 51e "check file nlink limit"
5668
5669 test_51f() {
5670         test_mkdir $DIR/$tdir
5671
5672         local max=100000
5673         local ulimit_old=$(ulimit -n)
5674         local spare=20 # number of spare fd's for scripts/libraries, etc.
5675         local mdt=$($LFS getstripe -m $DIR/$tdir)
5676         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5677
5678         echo "MDT$mdt numfree=$numfree, max=$max"
5679         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5680         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5681                 while ! ulimit -n $((numfree + spare)); do
5682                         numfree=$((numfree * 3 / 4))
5683                 done
5684                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5685         else
5686                 echo "left ulimit at $ulimit_old"
5687         fi
5688
5689         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5690                 unlinkmany $DIR/$tdir/f $numfree
5691                 error "create+open $numfree files in $DIR/$tdir failed"
5692         }
5693         ulimit -n $ulimit_old
5694
5695         # if createmany exits at 120s there will be fewer than $numfree files
5696         unlinkmany $DIR/$tdir/f $numfree || true
5697 }
5698 run_test 51f "check many open files limit"
5699
5700 test_52a() {
5701         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5702         test_mkdir $DIR/$tdir
5703         touch $DIR/$tdir/foo
5704         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5705         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5706         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5707         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5708         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5709                                         error "link worked"
5710         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5711         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5712         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5713                                                      error "lsattr"
5714         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5715         cp -r $DIR/$tdir $TMP/
5716         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5717 }
5718 run_test 52a "append-only flag test (should return errors)"
5719
5720 test_52b() {
5721         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5722         test_mkdir $DIR/$tdir
5723         touch $DIR/$tdir/foo
5724         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5725         cat test > $DIR/$tdir/foo && error "cat test worked"
5726         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5727         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5728         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5729                                         error "link worked"
5730         echo foo >> $DIR/$tdir/foo && error "echo worked"
5731         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5732         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5733         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5734         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5735                                                         error "lsattr"
5736         chattr -i $DIR/$tdir/foo || error "chattr failed"
5737
5738         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5739 }
5740 run_test 52b "immutable flag test (should return errors) ======="
5741
5742 test_53() {
5743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5744         remote_mds_nodsh && skip "remote MDS with nodsh"
5745         remote_ost_nodsh && skip "remote OST with nodsh"
5746
5747         local param
5748         local param_seq
5749         local ostname
5750         local mds_last
5751         local mds_last_seq
5752         local ost_last
5753         local ost_last_seq
5754         local ost_last_id
5755         local ostnum
5756         local node
5757         local found=false
5758         local support_last_seq=true
5759
5760         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5761                 support_last_seq=false
5762
5763         # only test MDT0000
5764         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5765         local value
5766         for value in $(do_facet $SINGLEMDS \
5767                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5768                 param=$(echo ${value[0]} | cut -d "=" -f1)
5769                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5770
5771                 if $support_last_seq; then
5772                         param_seq=$(echo $param |
5773                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5774                         mds_last_seq=$(do_facet $SINGLEMDS \
5775                                        $LCTL get_param -n $param_seq)
5776                 fi
5777                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5778
5779                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5780                 node=$(facet_active_host ost$((ostnum+1)))
5781                 param="obdfilter.$ostname.last_id"
5782                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5783                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5784                         ost_last_id=$ost_last
5785
5786                         if $support_last_seq; then
5787                                 ost_last_id=$(echo $ost_last |
5788                                               awk -F':' '{print $2}' |
5789                                               sed -e "s/^0x//g")
5790                                 ost_last_seq=$(echo $ost_last |
5791                                                awk -F':' '{print $1}')
5792                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5793                         fi
5794
5795                         if [[ $ost_last_id != $mds_last ]]; then
5796                                 error "$ost_last_id != $mds_last"
5797                         else
5798                                 found=true
5799                                 break
5800                         fi
5801                 done
5802         done
5803         $found || error "can not match last_seq/last_id for $mdtosc"
5804         return 0
5805 }
5806 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5807
5808 test_54a() {
5809         perl -MSocket -e ';' || skip "no Socket perl module installed"
5810
5811         $SOCKETSERVER $DIR/socket ||
5812                 error "$SOCKETSERVER $DIR/socket failed: $?"
5813         $SOCKETCLIENT $DIR/socket ||
5814                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5815         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5816 }
5817 run_test 54a "unix domain socket test =========================="
5818
5819 test_54b() {
5820         f="$DIR/f54b"
5821         mknod $f c 1 3
5822         chmod 0666 $f
5823         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5824 }
5825 run_test 54b "char device works in lustre ======================"
5826
5827 find_loop_dev() {
5828         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5829         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5830         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5831
5832         for i in $(seq 3 7); do
5833                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5834                 LOOPDEV=$LOOPBASE$i
5835                 LOOPNUM=$i
5836                 break
5837         done
5838 }
5839
5840 cleanup_54c() {
5841         local rc=0
5842         loopdev="$DIR/loop54c"
5843
5844         trap 0
5845         $UMOUNT $DIR/$tdir || rc=$?
5846         losetup -d $loopdev || true
5847         losetup -d $LOOPDEV || true
5848         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5849         return $rc
5850 }
5851
5852 test_54c() {
5853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5854
5855         loopdev="$DIR/loop54c"
5856
5857         find_loop_dev
5858         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5859         trap cleanup_54c EXIT
5860         mknod $loopdev b 7 $LOOPNUM
5861         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5862         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5863         losetup $loopdev $DIR/$tfile ||
5864                 error "can't set up $loopdev for $DIR/$tfile"
5865         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5866         test_mkdir $DIR/$tdir
5867         mount -t ext2 $loopdev $DIR/$tdir ||
5868                 error "error mounting $loopdev on $DIR/$tdir"
5869         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5870                 error "dd write"
5871         df $DIR/$tdir
5872         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5873                 error "dd read"
5874         cleanup_54c
5875 }
5876 run_test 54c "block device works in lustre ====================="
5877
5878 test_54d() {
5879         f="$DIR/f54d"
5880         string="aaaaaa"
5881         mknod $f p
5882         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5883 }
5884 run_test 54d "fifo device works in lustre ======================"
5885
5886 test_54e() {
5887         f="$DIR/f54e"
5888         string="aaaaaa"
5889         cp -aL /dev/console $f
5890         echo $string > $f || error "echo $string to $f failed"
5891 }
5892 run_test 54e "console/tty device works in lustre ======================"
5893
5894 test_56a() {
5895         local numfiles=3
5896         local numdirs=2
5897         local dir=$DIR/$tdir
5898
5899         rm -rf $dir
5900         test_mkdir -p $dir/dir
5901         for i in $(seq $numfiles); do
5902                 touch $dir/file$i
5903                 touch $dir/dir/file$i
5904         done
5905
5906         local numcomp=$($LFS getstripe --component-count $dir)
5907
5908         [[ $numcomp == 0 ]] && numcomp=1
5909
5910         # test lfs getstripe with --recursive
5911         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5912
5913         [[ $filenum -eq $((numfiles * 2)) ]] ||
5914                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5915         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5916         [[ $filenum -eq $numfiles ]] ||
5917                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5918         echo "$LFS getstripe showed obdidx or l_ost_idx"
5919
5920         # test lfs getstripe with file instead of dir
5921         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5922         [[ $filenum -eq 1 ]] ||
5923                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5924         echo "$LFS getstripe file1 passed"
5925
5926         #test lfs getstripe with --verbose
5927         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5928         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5929                 error "$LFS getstripe --verbose $dir: "\
5930                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5931         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5932                 error "$LFS getstripe $dir: showed lmm_magic"
5933
5934         #test lfs getstripe with -v prints lmm_fid
5935         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5936         local countfids=$((numdirs + numfiles * numcomp))
5937         [[ $filenum -eq $countfids ]] ||
5938                 error "$LFS getstripe -v $dir: "\
5939                       "got $filenum want $countfids lmm_fid"
5940         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5941                 error "$LFS getstripe $dir: showed lmm_fid by default"
5942         echo "$LFS getstripe --verbose passed"
5943
5944         #check for FID information
5945         local fid1=$($LFS getstripe --fid $dir/file1)
5946         local fid2=$($LFS getstripe --verbose $dir/file1 |
5947                      awk '/lmm_fid: / { print $2; exit; }')
5948         local fid3=$($LFS path2fid $dir/file1)
5949
5950         [ "$fid1" != "$fid2" ] &&
5951                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5952         [ "$fid1" != "$fid3" ] &&
5953                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5954         echo "$LFS getstripe --fid passed"
5955
5956         #test lfs getstripe with --obd
5957         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5958                 error "$LFS getstripe --obd wrong_uuid: should return error"
5959
5960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5961
5962         local ostidx=1
5963         local obduuid=$(ostuuid_from_index $ostidx)
5964         local found=$($LFS getstripe -r --obd $obduuid $dir |
5965                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5966
5967         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5968         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5969                 ((filenum--))
5970         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5971                 ((filenum--))
5972
5973         [[ $found -eq $filenum ]] ||
5974                 error "$LFS getstripe --obd: found $found expect $filenum"
5975         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5976                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5977                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5978                 error "$LFS getstripe --obd: should not show file on other obd"
5979         echo "$LFS getstripe --obd passed"
5980 }
5981 run_test 56a "check $LFS getstripe"
5982
5983 test_56b() {
5984         local dir=$DIR/$tdir
5985         local numdirs=3
5986
5987         test_mkdir $dir
5988         for i in $(seq $numdirs); do
5989                 test_mkdir $dir/dir$i
5990         done
5991
5992         # test lfs getdirstripe default mode is non-recursion, which is
5993         # different from lfs getstripe
5994         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5995
5996         [[ $dircnt -eq 1 ]] ||
5997                 error "$LFS getdirstripe: found $dircnt, not 1"
5998         dircnt=$($LFS getdirstripe --recursive $dir |
5999                 grep -c lmv_stripe_count)
6000         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6001                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6002 }
6003 run_test 56b "check $LFS getdirstripe"
6004
6005 test_56c() {
6006         remote_ost_nodsh && skip "remote OST with nodsh"
6007
6008         local ost_idx=0
6009         local ost_name=$(ostname_from_index $ost_idx)
6010         local old_status=$(ost_dev_status $ost_idx)
6011         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6012
6013         [[ -z "$old_status" ]] ||
6014                 skip_env "OST $ost_name is in $old_status status"
6015
6016         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6017         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6018                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6019         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6020                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6021                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6022         fi
6023
6024         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6025                 error "$LFS df -v showing inactive devices"
6026         sleep_maxage
6027
6028         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6029
6030         [[ "$new_status" =~ "D" ]] ||
6031                 error "$ost_name status is '$new_status', missing 'D'"
6032         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6033                 [[ "$new_status" =~ "N" ]] ||
6034                         error "$ost_name status is '$new_status', missing 'N'"
6035         fi
6036         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6037                 [[ "$new_status" =~ "f" ]] ||
6038                         error "$ost_name status is '$new_status', missing 'f'"
6039         fi
6040
6041         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6042         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6043                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6044         [[ -z "$p" ]] && restore_lustre_params < $p || true
6045         sleep_maxage
6046
6047         new_status=$(ost_dev_status $ost_idx)
6048         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6049                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6050         # can't check 'f' as devices may actually be on flash
6051 }
6052 run_test 56c "check 'lfs df' showing device status"
6053
6054 test_56d() {
6055         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6056         local osts=$($LFS df -v $MOUNT | grep -c OST)
6057
6058         $LFS df $MOUNT
6059
6060         (( mdts == MDSCOUNT )) ||
6061                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6062         (( osts == OSTCOUNT )) ||
6063                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6064 }
6065 run_test 56d "'lfs df -v' prints only configured devices"
6066
6067 NUMFILES=3
6068 NUMDIRS=3
6069 setup_56() {
6070         local local_tdir="$1"
6071         local local_numfiles="$2"
6072         local local_numdirs="$3"
6073         local dir_params="$4"
6074         local dir_stripe_params="$5"
6075
6076         if [ ! -d "$local_tdir" ] ; then
6077                 test_mkdir -p $dir_stripe_params $local_tdir
6078                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6079                 for i in $(seq $local_numfiles) ; do
6080                         touch $local_tdir/file$i
6081                 done
6082                 for i in $(seq $local_numdirs) ; do
6083                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6084                         for j in $(seq $local_numfiles) ; do
6085                                 touch $local_tdir/dir$i/file$j
6086                         done
6087                 done
6088         fi
6089 }
6090
6091 setup_56_special() {
6092         local local_tdir=$1
6093         local local_numfiles=$2
6094         local local_numdirs=$3
6095
6096         setup_56 $local_tdir $local_numfiles $local_numdirs
6097
6098         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6099                 for i in $(seq $local_numfiles) ; do
6100                         mknod $local_tdir/loop${i}b b 7 $i
6101                         mknod $local_tdir/null${i}c c 1 3
6102                         ln -s $local_tdir/file1 $local_tdir/link${i}
6103                 done
6104                 for i in $(seq $local_numdirs) ; do
6105                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6106                         mknod $local_tdir/dir$i/null${i}c c 1 3
6107                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6108                 done
6109         fi
6110 }
6111
6112 test_56g() {
6113         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6114         local expected=$(($NUMDIRS + 2))
6115
6116         setup_56 $dir $NUMFILES $NUMDIRS
6117
6118         # test lfs find with -name
6119         for i in $(seq $NUMFILES) ; do
6120                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6121
6122                 [ $nums -eq $expected ] ||
6123                         error "lfs find -name '*$i' $dir wrong: "\
6124                               "found $nums, expected $expected"
6125         done
6126 }
6127 run_test 56g "check lfs find -name"
6128
6129 test_56h() {
6130         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6131         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6132
6133         setup_56 $dir $NUMFILES $NUMDIRS
6134
6135         # test lfs find with ! -name
6136         for i in $(seq $NUMFILES) ; do
6137                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6138
6139                 [ $nums -eq $expected ] ||
6140                         error "lfs find ! -name '*$i' $dir wrong: "\
6141                               "found $nums, expected $expected"
6142         done
6143 }
6144 run_test 56h "check lfs find ! -name"
6145
6146 test_56i() {
6147         local dir=$DIR/$tdir
6148
6149         test_mkdir $dir
6150
6151         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6152         local out=$($cmd)
6153
6154         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6155 }
6156 run_test 56i "check 'lfs find -ost UUID' skips directories"
6157
6158 test_56j() {
6159         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6160
6161         setup_56_special $dir $NUMFILES $NUMDIRS
6162
6163         local expected=$((NUMDIRS + 1))
6164         local cmd="$LFS find -type d $dir"
6165         local nums=$($cmd | wc -l)
6166
6167         [ $nums -eq $expected ] ||
6168                 error "'$cmd' wrong: found $nums, expected $expected"
6169 }
6170 run_test 56j "check lfs find -type d"
6171
6172 test_56k() {
6173         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6174
6175         setup_56_special $dir $NUMFILES $NUMDIRS
6176
6177         local expected=$(((NUMDIRS + 1) * NUMFILES))
6178         local cmd="$LFS find -type f $dir"
6179         local nums=$($cmd | wc -l)
6180
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183 }
6184 run_test 56k "check lfs find -type f"
6185
6186 test_56l() {
6187         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6188
6189         setup_56_special $dir $NUMFILES $NUMDIRS
6190
6191         local expected=$((NUMDIRS + NUMFILES))
6192         local cmd="$LFS find -type b $dir"
6193         local nums=$($cmd | wc -l)
6194
6195         [ $nums -eq $expected ] ||
6196                 error "'$cmd' wrong: found $nums, expected $expected"
6197 }
6198 run_test 56l "check lfs find -type b"
6199
6200 test_56m() {
6201         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6202
6203         setup_56_special $dir $NUMFILES $NUMDIRS
6204
6205         local expected=$((NUMDIRS + NUMFILES))
6206         local cmd="$LFS find -type c $dir"
6207         local nums=$($cmd | wc -l)
6208         [ $nums -eq $expected ] ||
6209                 error "'$cmd' wrong: found $nums, expected $expected"
6210 }
6211 run_test 56m "check lfs find -type c"
6212
6213 test_56n() {
6214         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6215         setup_56_special $dir $NUMFILES $NUMDIRS
6216
6217         local expected=$((NUMDIRS + NUMFILES))
6218         local cmd="$LFS find -type l $dir"
6219         local nums=$($cmd | wc -l)
6220
6221         [ $nums -eq $expected ] ||
6222                 error "'$cmd' wrong: found $nums, expected $expected"
6223 }
6224 run_test 56n "check lfs find -type l"
6225
6226 test_56o() {
6227         local dir=$DIR/$tdir
6228
6229         setup_56 $dir $NUMFILES $NUMDIRS
6230         utime $dir/file1 > /dev/null || error "utime (1)"
6231         utime $dir/file2 > /dev/null || error "utime (2)"
6232         utime $dir/dir1 > /dev/null || error "utime (3)"
6233         utime $dir/dir2 > /dev/null || error "utime (4)"
6234         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6235         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6236
6237         local expected=4
6238         local nums=$($LFS find -mtime +0 $dir | wc -l)
6239
6240         [ $nums -eq $expected ] ||
6241                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6242
6243         expected=12
6244         cmd="$LFS find -mtime 0 $dir"
6245         nums=$($cmd | wc -l)
6246         [ $nums -eq $expected ] ||
6247                 error "'$cmd' wrong: found $nums, expected $expected"
6248 }
6249 run_test 56o "check lfs find -mtime for old files"
6250
6251 test_56ob() {
6252         local dir=$DIR/$tdir
6253         local expected=1
6254         local count=0
6255
6256         # just to make sure there is something that won't be found
6257         test_mkdir $dir
6258         touch $dir/$tfile.now
6259
6260         for age in year week day hour min; do
6261                 count=$((count + 1))
6262
6263                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6264                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6265                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6266
6267                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6268                 local nums=$($cmd | wc -l)
6269                 [ $nums -eq $expected ] ||
6270                         error "'$cmd' wrong: found $nums, expected $expected"
6271
6272                 cmd="$LFS find $dir -atime $count${age:0:1}"
6273                 nums=$($cmd | wc -l)
6274                 [ $nums -eq $expected ] ||
6275                         error "'$cmd' wrong: found $nums, expected $expected"
6276         done
6277
6278         sleep 2
6279         cmd="$LFS find $dir -ctime +1s -type f"
6280         nums=$($cmd | wc -l)
6281         (( $nums == $count * 2 + 1)) ||
6282                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6283 }
6284 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6285
6286 test_newerXY_base() {
6287         local x=$1
6288         local y=$2
6289         local dir=$DIR/$tdir
6290         local ref
6291         local negref
6292
6293         if [ $y == "t" ]; then
6294                 if [ $x == "b" ]; then
6295                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6296                 else
6297                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6298                 fi
6299         else
6300                 ref=$DIR/$tfile.newer.$x$y
6301                 touch $ref || error "touch $ref failed"
6302         fi
6303
6304         echo "before = $ref"
6305         sleep 2
6306         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6307         sleep 2
6308         if [ $y == "t" ]; then
6309                 if [ $x == "b" ]; then
6310                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6311                 else
6312                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6313                 fi
6314         else
6315                 negref=$DIR/$tfile.negnewer.$x$y
6316                 touch $negref || error "touch $negref failed"
6317         fi
6318
6319         echo "after = $negref"
6320         local cmd="$LFS find $dir -newer$x$y $ref"
6321         local nums=$(eval $cmd | wc -l)
6322         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6323
6324         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6325                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6326
6327         cmd="$LFS find $dir ! -newer$x$y $negref"
6328         nums=$(eval $cmd | wc -l)
6329         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6330                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6331
6332         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6333         nums=$(eval $cmd | wc -l)
6334         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6335                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6336
6337         rm -rf $DIR/*
6338 }
6339
6340 test_56oc() {
6341         test_newerXY_base "a" "a"
6342         test_newerXY_base "a" "m"
6343         test_newerXY_base "a" "c"
6344         test_newerXY_base "m" "a"
6345         test_newerXY_base "m" "m"
6346         test_newerXY_base "m" "c"
6347         test_newerXY_base "c" "a"
6348         test_newerXY_base "c" "m"
6349         test_newerXY_base "c" "c"
6350
6351         [[ -n "$sles_version" ]] &&
6352                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6353
6354         test_newerXY_base "a" "t"
6355         test_newerXY_base "m" "t"
6356         test_newerXY_base "c" "t"
6357
6358         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6359            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6360                 ! btime_supported && echo "btime unsupported" && return 0
6361
6362         test_newerXY_base "b" "b"
6363         test_newerXY_base "b" "t"
6364 }
6365 run_test 56oc "check lfs find -newerXY work"
6366
6367 btime_supported() {
6368         local dir=$DIR/$tdir
6369         local rc
6370
6371         mkdir -p $dir
6372         touch $dir/$tfile
6373         $LFS find $dir -btime -1d -type f
6374         rc=$?
6375         rm -rf $dir
6376         return $rc
6377 }
6378
6379 test_56od() {
6380         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6381                 ! btime_supported && skip "btime unsupported on MDS"
6382
6383         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6384                 ! btime_supported && skip "btime unsupported on clients"
6385
6386         local dir=$DIR/$tdir
6387         local ref=$DIR/$tfile.ref
6388         local negref=$DIR/$tfile.negref
6389
6390         mkdir $dir || error "mkdir $dir failed"
6391         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6392         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6393         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6394         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6395         touch $ref || error "touch $ref failed"
6396         # sleep 3 seconds at least
6397         sleep 3
6398
6399         local before=$(do_facet mds1 date +%s)
6400         local skew=$(($(date +%s) - before + 1))
6401
6402         if (( skew < 0 && skew > -5 )); then
6403                 sleep $((0 - skew + 1))
6404                 skew=0
6405         fi
6406
6407         # Set the dir stripe params to limit files all on MDT0,
6408         # otherwise we need to calc the max clock skew between
6409         # the client and MDTs.
6410         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6411         sleep 2
6412         touch $negref || error "touch $negref failed"
6413
6414         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6415         local nums=$($cmd | wc -l)
6416         local expected=$(((NUMFILES + 1) * NUMDIRS))
6417
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420
6421         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6422         nums=$($cmd | wc -l)
6423         expected=$((NUMFILES + 1))
6424         [ $nums -eq $expected ] ||
6425                 error "'$cmd' wrong: found $nums, expected $expected"
6426
6427         [ $skew -lt 0 ] && return
6428
6429         local after=$(do_facet mds1 date +%s)
6430         local age=$((after - before + 1 + skew))
6431
6432         cmd="$LFS find $dir -btime -${age}s -type f"
6433         nums=$($cmd | wc -l)
6434         expected=$(((NUMFILES + 1) * NUMDIRS))
6435
6436         echo "Clock skew between client and server: $skew, age:$age"
6437         [ $nums -eq $expected ] ||
6438                 error "'$cmd' wrong: found $nums, expected $expected"
6439
6440         expected=$(($NUMDIRS + 1))
6441         cmd="$LFS find $dir -btime -${age}s -type d"
6442         nums=$($cmd | wc -l)
6443         [ $nums -eq $expected ] ||
6444                 error "'$cmd' wrong: found $nums, expected $expected"
6445         rm -f $ref $negref || error "Failed to remove $ref $negref"
6446 }
6447 run_test 56od "check lfs find -btime with units"
6448
6449 test_56p() {
6450         [ $RUNAS_ID -eq $UID ] &&
6451                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6452
6453         local dir=$DIR/$tdir
6454
6455         setup_56 $dir $NUMFILES $NUMDIRS
6456         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6457
6458         local expected=$NUMFILES
6459         local cmd="$LFS find -uid $RUNAS_ID $dir"
6460         local nums=$($cmd | wc -l)
6461
6462         [ $nums -eq $expected ] ||
6463                 error "'$cmd' wrong: found $nums, expected $expected"
6464
6465         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6466         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6467         nums=$($cmd | wc -l)
6468         [ $nums -eq $expected ] ||
6469                 error "'$cmd' wrong: found $nums, expected $expected"
6470 }
6471 run_test 56p "check lfs find -uid and ! -uid"
6472
6473 test_56q() {
6474         [ $RUNAS_ID -eq $UID ] &&
6475                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6476
6477         local dir=$DIR/$tdir
6478
6479         setup_56 $dir $NUMFILES $NUMDIRS
6480         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6481
6482         local expected=$NUMFILES
6483         local cmd="$LFS find -gid $RUNAS_GID $dir"
6484         local nums=$($cmd | wc -l)
6485
6486         [ $nums -eq $expected ] ||
6487                 error "'$cmd' wrong: found $nums, expected $expected"
6488
6489         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6490         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6491         nums=$($cmd | wc -l)
6492         [ $nums -eq $expected ] ||
6493                 error "'$cmd' wrong: found $nums, expected $expected"
6494 }
6495 run_test 56q "check lfs find -gid and ! -gid"
6496
6497 test_56r() {
6498         local dir=$DIR/$tdir
6499
6500         setup_56 $dir $NUMFILES $NUMDIRS
6501
6502         local expected=12
6503         local cmd="$LFS find -size 0 -type f -lazy $dir"
6504         local nums=$($cmd | wc -l)
6505
6506         [ $nums -eq $expected ] ||
6507                 error "'$cmd' wrong: found $nums, expected $expected"
6508         cmd="$LFS find -size 0 -type f $dir"
6509         nums=$($cmd | wc -l)
6510         [ $nums -eq $expected ] ||
6511                 error "'$cmd' wrong: found $nums, expected $expected"
6512
6513         expected=0
6514         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6515         nums=$($cmd | wc -l)
6516         [ $nums -eq $expected ] ||
6517                 error "'$cmd' wrong: found $nums, expected $expected"
6518         cmd="$LFS find ! -size 0 -type f $dir"
6519         nums=$($cmd | wc -l)
6520         [ $nums -eq $expected ] ||
6521                 error "'$cmd' wrong: found $nums, expected $expected"
6522
6523         echo "test" > $dir/$tfile
6524         echo "test2" > $dir/$tfile.2 && sync
6525         expected=1
6526         cmd="$LFS find -size 5 -type f -lazy $dir"
6527         nums=$($cmd | wc -l)
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530         cmd="$LFS find -size 5 -type f $dir"
6531         nums=$($cmd | wc -l)
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534
6535         expected=1
6536         cmd="$LFS find -size +5 -type f -lazy $dir"
6537         nums=$($cmd | wc -l)
6538         [ $nums -eq $expected ] ||
6539                 error "'$cmd' wrong: found $nums, expected $expected"
6540         cmd="$LFS find -size +5 -type f $dir"
6541         nums=$($cmd | wc -l)
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544
6545         expected=2
6546         cmd="$LFS find -size +0 -type f -lazy $dir"
6547         nums=$($cmd | wc -l)
6548         [ $nums -eq $expected ] ||
6549                 error "'$cmd' wrong: found $nums, expected $expected"
6550         cmd="$LFS find -size +0 -type f $dir"
6551         nums=$($cmd | wc -l)
6552         [ $nums -eq $expected ] ||
6553                 error "'$cmd' wrong: found $nums, expected $expected"
6554
6555         expected=2
6556         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6557         nums=$($cmd | wc -l)
6558         [ $nums -eq $expected ] ||
6559                 error "'$cmd' wrong: found $nums, expected $expected"
6560         cmd="$LFS find ! -size -5 -type f $dir"
6561         nums=$($cmd | wc -l)
6562         [ $nums -eq $expected ] ||
6563                 error "'$cmd' wrong: found $nums, expected $expected"
6564
6565         expected=12
6566         cmd="$LFS find -size -5 -type f -lazy $dir"
6567         nums=$($cmd | wc -l)
6568         [ $nums -eq $expected ] ||
6569                 error "'$cmd' wrong: found $nums, expected $expected"
6570         cmd="$LFS find -size -5 -type f $dir"
6571         nums=$($cmd | wc -l)
6572         [ $nums -eq $expected ] ||
6573                 error "'$cmd' wrong: found $nums, expected $expected"
6574 }
6575 run_test 56r "check lfs find -size works"
6576
6577 test_56ra_sub() {
6578         local expected=$1
6579         local glimpses=$2
6580         local cmd="$3"
6581
6582         cancel_lru_locks $OSC
6583
6584         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6585         local nums=$($cmd | wc -l)
6586
6587         [ $nums -eq $expected ] ||
6588                 error "'$cmd' wrong: found $nums, expected $expected"
6589
6590         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6591
6592         if (( rpcs_before + glimpses != rpcs_after )); then
6593                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6594                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6595
6596                 if [[ $glimpses == 0 ]]; then
6597                         error "'$cmd' should not send glimpse RPCs to OST"
6598                 else
6599                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6600                 fi
6601         fi
6602 }
6603
6604 test_56ra() {
6605         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6606                 skip "MDS < 2.12.58 doesn't return LSOM data"
6607         local dir=$DIR/$tdir
6608         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6609
6610         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6611
6612         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6613         $LCTL set_param -n llite.*.statahead_agl=0
6614         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6615
6616         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6617         # open and close all files to ensure LSOM is updated
6618         cancel_lru_locks $OSC
6619         find $dir -type f | xargs cat > /dev/null
6620
6621         #   expect_found  glimpse_rpcs  command_to_run
6622         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6623         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6624         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6625         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6626
6627         echo "test" > $dir/$tfile
6628         echo "test2" > $dir/$tfile.2 && sync
6629         cancel_lru_locks $OSC
6630         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6631
6632         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6633         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
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
6637         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6638         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6639         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6640         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6641         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6642         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6643 }
6644 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6645
6646 test_56rb() {
6647         local dir=$DIR/$tdir
6648         local tmp=$TMP/$tfile.log
6649         local mdt_idx;
6650
6651         test_mkdir -p $dir || error "failed to mkdir $dir"
6652         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6653                 error "failed to setstripe $dir/$tfile"
6654         mdt_idx=$($LFS getdirstripe -i $dir)
6655         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6656
6657         stack_trap "rm -f $tmp" EXIT
6658         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6659         ! grep -q obd_uuid $tmp ||
6660                 error "failed to find --size +100K --ost 0 $dir"
6661         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6662         ! grep -q obd_uuid $tmp ||
6663                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6664 }
6665 run_test 56rb "check lfs find --size --ost/--mdt works"
6666
6667 test_56s() { # LU-611 #LU-9369
6668         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6669
6670         local dir=$DIR/$tdir
6671         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6672
6673         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6674         for i in $(seq $NUMDIRS); do
6675                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6676         done
6677
6678         local expected=$NUMDIRS
6679         local cmd="$LFS find -c $OSTCOUNT $dir"
6680         local nums=$($cmd | wc -l)
6681
6682         [ $nums -eq $expected ] || {
6683                 $LFS getstripe -R $dir
6684                 error "'$cmd' wrong: found $nums, expected $expected"
6685         }
6686
6687         expected=$((NUMDIRS + onestripe))
6688         cmd="$LFS find -stripe-count +0 -type f $dir"
6689         nums=$($cmd | wc -l)
6690         [ $nums -eq $expected ] || {
6691                 $LFS getstripe -R $dir
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693         }
6694
6695         expected=$onestripe
6696         cmd="$LFS find -stripe-count 1 -type f $dir"
6697         nums=$($cmd | wc -l)
6698         [ $nums -eq $expected ] || {
6699                 $LFS getstripe -R $dir
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701         }
6702
6703         cmd="$LFS find -stripe-count -2 -type f $dir"
6704         nums=$($cmd | wc -l)
6705         [ $nums -eq $expected ] || {
6706                 $LFS getstripe -R $dir
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708         }
6709
6710         expected=0
6711         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6712         nums=$($cmd | wc -l)
6713         [ $nums -eq $expected ] || {
6714                 $LFS getstripe -R $dir
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         }
6717 }
6718 run_test 56s "check lfs find -stripe-count works"
6719
6720 test_56t() { # LU-611 #LU-9369
6721         local dir=$DIR/$tdir
6722
6723         setup_56 $dir 0 $NUMDIRS
6724         for i in $(seq $NUMDIRS); do
6725                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6726         done
6727
6728         local expected=$NUMDIRS
6729         local cmd="$LFS find -S 8M $dir"
6730         local nums=$($cmd | wc -l)
6731
6732         [ $nums -eq $expected ] || {
6733                 $LFS getstripe -R $dir
6734                 error "'$cmd' wrong: found $nums, expected $expected"
6735         }
6736         rm -rf $dir
6737
6738         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6739
6740         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6741
6742         expected=$(((NUMDIRS + 1) * NUMFILES))
6743         cmd="$LFS find -stripe-size 512k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747
6748         cmd="$LFS find -stripe-size +320k -type f $dir"
6749         nums=$($cmd | wc -l)
6750         [ $nums -eq $expected ] ||
6751                 error "'$cmd' wrong: found $nums, expected $expected"
6752
6753         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6754         cmd="$LFS find -stripe-size +200k -type f $dir"
6755         nums=$($cmd | wc -l)
6756         [ $nums -eq $expected ] ||
6757                 error "'$cmd' wrong: found $nums, expected $expected"
6758
6759         cmd="$LFS find -stripe-size -640k -type f $dir"
6760         nums=$($cmd | wc -l)
6761         [ $nums -eq $expected ] ||
6762                 error "'$cmd' wrong: found $nums, expected $expected"
6763
6764         expected=4
6765         cmd="$LFS find -stripe-size 256k -type f $dir"
6766         nums=$($cmd | wc -l)
6767         [ $nums -eq $expected ] ||
6768                 error "'$cmd' wrong: found $nums, expected $expected"
6769
6770         cmd="$LFS find -stripe-size -320k -type f $dir"
6771         nums=$($cmd | wc -l)
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         expected=0
6776         cmd="$LFS find -stripe-size 1024k -type f $dir"
6777         nums=$($cmd | wc -l)
6778         [ $nums -eq $expected ] ||
6779                 error "'$cmd' wrong: found $nums, expected $expected"
6780 }
6781 run_test 56t "check lfs find -stripe-size works"
6782
6783 test_56u() { # LU-611
6784         local dir=$DIR/$tdir
6785
6786         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6787
6788         if [[ $OSTCOUNT -gt 1 ]]; then
6789                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6790                 onestripe=4
6791         else
6792                 onestripe=0
6793         fi
6794
6795         local expected=$(((NUMDIRS + 1) * NUMFILES))
6796         local cmd="$LFS find -stripe-index 0 -type f $dir"
6797         local nums=$($cmd | wc -l)
6798
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         expected=$onestripe
6803         cmd="$LFS find -stripe-index 1 -type f $dir"
6804         nums=$($cmd | wc -l)
6805         [ $nums -eq $expected ] ||
6806                 error "'$cmd' wrong: found $nums, expected $expected"
6807
6808         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812
6813         expected=0
6814         # This should produce an error and not return any files
6815         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6816         nums=$($cmd 2>/dev/null | wc -l)
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819
6820         if [[ $OSTCOUNT -gt 1 ]]; then
6821                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6822                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6823                 nums=$($cmd | wc -l)
6824                 [ $nums -eq $expected ] ||
6825                         error "'$cmd' wrong: found $nums, expected $expected"
6826         fi
6827 }
6828 run_test 56u "check lfs find -stripe-index works"
6829
6830 test_56v() {
6831         local mdt_idx=0
6832         local dir=$DIR/$tdir
6833
6834         setup_56 $dir $NUMFILES $NUMDIRS
6835
6836         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6837         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6838
6839         for file in $($LFS find -m $UUID $dir); do
6840                 file_midx=$($LFS getstripe -m $file)
6841                 [ $file_midx -eq $mdt_idx ] ||
6842                         error "lfs find -m $UUID != getstripe -m $file_midx"
6843         done
6844 }
6845 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6846
6847 test_56w() {
6848         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6850
6851         local dir=$DIR/$tdir
6852
6853         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6854
6855         local stripe_size=$($LFS getstripe -S -d $dir) ||
6856                 error "$LFS getstripe -S -d $dir failed"
6857         stripe_size=${stripe_size%% *}
6858
6859         local file_size=$((stripe_size * OSTCOUNT))
6860         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6861         local required_space=$((file_num * file_size))
6862         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6863                            head -n1)
6864         [[ $free_space -le $((required_space / 1024)) ]] &&
6865                 skip_env "need $required_space, have $free_space kbytes"
6866
6867         local dd_bs=65536
6868         local dd_count=$((file_size / dd_bs))
6869
6870         # write data into the files
6871         local i
6872         local j
6873         local file
6874
6875         for i in $(seq $NUMFILES); do
6876                 file=$dir/file$i
6877                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6878                         error "write data into $file failed"
6879         done
6880         for i in $(seq $NUMDIRS); do
6881                 for j in $(seq $NUMFILES); do
6882                         file=$dir/dir$i/file$j
6883                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6884                                 error "write data into $file failed"
6885                 done
6886         done
6887
6888         # $LFS_MIGRATE will fail if hard link migration is unsupported
6889         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6890                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6891                         error "creating links to $dir/dir1/file1 failed"
6892         fi
6893
6894         local expected=-1
6895
6896         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6897
6898         # lfs_migrate file
6899         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6900
6901         echo "$cmd"
6902         eval $cmd || error "$cmd failed"
6903
6904         check_stripe_count $dir/file1 $expected
6905
6906         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6907         then
6908                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6909                 # OST 1 if it is on OST 0. This file is small enough to
6910                 # be on only one stripe.
6911                 file=$dir/migr_1_ost
6912                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6913                         error "write data into $file failed"
6914                 local obdidx=$($LFS getstripe -i $file)
6915                 local oldmd5=$(md5sum $file)
6916                 local newobdidx=0
6917
6918                 [[ $obdidx -eq 0 ]] && newobdidx=1
6919                 cmd="$LFS migrate -i $newobdidx $file"
6920                 echo $cmd
6921                 eval $cmd || error "$cmd failed"
6922
6923                 local realobdix=$($LFS getstripe -i $file)
6924                 local newmd5=$(md5sum $file)
6925
6926                 [[ $newobdidx -ne $realobdix ]] &&
6927                         error "new OST is different (was=$obdidx, "\
6928                               "wanted=$newobdidx, got=$realobdix)"
6929                 [[ "$oldmd5" != "$newmd5" ]] &&
6930                         error "md5sum differ: $oldmd5, $newmd5"
6931         fi
6932
6933         # lfs_migrate dir
6934         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6935         echo "$cmd"
6936         eval $cmd || error "$cmd failed"
6937
6938         for j in $(seq $NUMFILES); do
6939                 check_stripe_count $dir/dir1/file$j $expected
6940         done
6941
6942         # lfs_migrate works with lfs find
6943         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6944              $LFS_MIGRATE -y -c $expected"
6945         echo "$cmd"
6946         eval $cmd || error "$cmd failed"
6947
6948         for i in $(seq 2 $NUMFILES); do
6949                 check_stripe_count $dir/file$i $expected
6950         done
6951         for i in $(seq 2 $NUMDIRS); do
6952                 for j in $(seq $NUMFILES); do
6953                 check_stripe_count $dir/dir$i/file$j $expected
6954                 done
6955         done
6956 }
6957 run_test 56w "check lfs_migrate -c stripe_count works"
6958
6959 test_56wb() {
6960         local file1=$DIR/$tdir/file1
6961         local create_pool=false
6962         local initial_pool=$($LFS getstripe -p $DIR)
6963         local pool_list=()
6964         local pool=""
6965
6966         echo -n "Creating test dir..."
6967         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6968         echo "done."
6969
6970         echo -n "Creating test file..."
6971         touch $file1 || error "cannot create file"
6972         echo "done."
6973
6974         echo -n "Detecting existing pools..."
6975         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6976
6977         if [ ${#pool_list[@]} -gt 0 ]; then
6978                 echo "${pool_list[@]}"
6979                 for thispool in "${pool_list[@]}"; do
6980                         if [[ -z "$initial_pool" ||
6981                               "$initial_pool" != "$thispool" ]]; then
6982                                 pool="$thispool"
6983                                 echo "Using existing pool '$pool'"
6984                                 break
6985                         fi
6986                 done
6987         else
6988                 echo "none detected."
6989         fi
6990         if [ -z "$pool" ]; then
6991                 pool=${POOL:-testpool}
6992                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6993                 echo -n "Creating pool '$pool'..."
6994                 create_pool=true
6995                 pool_add $pool &> /dev/null ||
6996                         error "pool_add failed"
6997                 echo "done."
6998
6999                 echo -n "Adding target to pool..."
7000                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7001                         error "pool_add_targets failed"
7002                 echo "done."
7003         fi
7004
7005         echo -n "Setting pool using -p option..."
7006         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7007                 error "migrate failed rc = $?"
7008         echo "done."
7009
7010         echo -n "Verifying test file is in pool after migrating..."
7011         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7012                 error "file was not migrated to pool $pool"
7013         echo "done."
7014
7015         echo -n "Removing test file from pool '$pool'..."
7016         # "lfs migrate $file" won't remove the file from the pool
7017         # until some striping information is changed.
7018         $LFS migrate -c 1 $file1 &> /dev/null ||
7019                 error "cannot remove from pool"
7020         [ "$($LFS getstripe -p $file1)" ] &&
7021                 error "pool still set"
7022         echo "done."
7023
7024         echo -n "Setting pool using --pool option..."
7025         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7026                 error "migrate failed rc = $?"
7027         echo "done."
7028
7029         # Clean up
7030         rm -f $file1
7031         if $create_pool; then
7032                 destroy_test_pools 2> /dev/null ||
7033                         error "destroy test pools failed"
7034         fi
7035 }
7036 run_test 56wb "check lfs_migrate pool support"
7037
7038 test_56wc() {
7039         local file1="$DIR/$tdir/file1"
7040         local parent_ssize
7041         local parent_scount
7042         local cur_ssize
7043         local cur_scount
7044         local orig_ssize
7045
7046         echo -n "Creating test dir..."
7047         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7048         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7049                 error "cannot set stripe by '-S 1M -c 1'"
7050         echo "done"
7051
7052         echo -n "Setting initial stripe for test file..."
7053         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7054                 error "cannot set stripe"
7055         cur_ssize=$($LFS getstripe -S "$file1")
7056         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7057         echo "done."
7058
7059         # File currently set to -S 512K -c 1
7060
7061         # Ensure -c and -S options are rejected when -R is set
7062         echo -n "Verifying incompatible options are detected..."
7063         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7064                 error "incompatible -c and -R options not detected"
7065         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7066                 error "incompatible -S and -R options not detected"
7067         echo "done."
7068
7069         # Ensure unrecognized options are passed through to 'lfs migrate'
7070         echo -n "Verifying -S option is passed through to lfs migrate..."
7071         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7072                 error "migration failed"
7073         cur_ssize=$($LFS getstripe -S "$file1")
7074         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7075         echo "done."
7076
7077         # File currently set to -S 1M -c 1
7078
7079         # Ensure long options are supported
7080         echo -n "Verifying long options supported..."
7081         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7082                 error "long option without argument not supported"
7083         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7084                 error "long option with argument not supported"
7085         cur_ssize=$($LFS getstripe -S "$file1")
7086         [ $cur_ssize -eq 524288 ] ||
7087                 error "migrate --stripe-size $cur_ssize != 524288"
7088         echo "done."
7089
7090         # File currently set to -S 512K -c 1
7091
7092         if [ "$OSTCOUNT" -gt 1 ]; then
7093                 echo -n "Verifying explicit stripe count can be set..."
7094                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7095                         error "migrate failed"
7096                 cur_scount=$($LFS getstripe -c "$file1")
7097                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7098                 echo "done."
7099         fi
7100
7101         # File currently set to -S 512K -c 1 or -S 512K -c 2
7102
7103         # Ensure parent striping is used if -R is set, and no stripe
7104         # count or size is specified
7105         echo -n "Setting stripe for parent directory..."
7106         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7107                 error "cannot set stripe '-S 2M -c 1'"
7108         echo "done."
7109
7110         echo -n "Verifying restripe option uses parent stripe settings..."
7111         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7112         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7113         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7114                 error "migrate failed"
7115         cur_ssize=$($LFS getstripe -S "$file1")
7116         [ $cur_ssize -eq $parent_ssize ] ||
7117                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7118         cur_scount=$($LFS getstripe -c "$file1")
7119         [ $cur_scount -eq $parent_scount ] ||
7120                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7121         echo "done."
7122
7123         # File currently set to -S 1M -c 1
7124
7125         # Ensure striping is preserved if -R is not set, and no stripe
7126         # count or size is specified
7127         echo -n "Verifying striping size preserved when not specified..."
7128         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7129         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7130                 error "cannot set stripe on parent directory"
7131         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7132                 error "migrate failed"
7133         cur_ssize=$($LFS getstripe -S "$file1")
7134         [ $cur_ssize -eq $orig_ssize ] ||
7135                 error "migrate by default $cur_ssize != $orig_ssize"
7136         echo "done."
7137
7138         # Ensure file name properly detected when final option has no argument
7139         echo -n "Verifying file name properly detected..."
7140         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7141                 error "file name interpreted as option argument"
7142         echo "done."
7143
7144         # Clean up
7145         rm -f "$file1"
7146 }
7147 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7148
7149 test_56wd() {
7150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7151
7152         local file1=$DIR/$tdir/file1
7153
7154         echo -n "Creating test dir..."
7155         test_mkdir $DIR/$tdir || error "cannot create dir"
7156         echo "done."
7157
7158         echo -n "Creating test file..."
7159         touch $file1
7160         echo "done."
7161
7162         # Ensure 'lfs migrate' will fail by using a non-existent option,
7163         # and make sure rsync is not called to recover
7164         echo -n "Make sure --no-rsync option works..."
7165         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7166                 grep -q 'refusing to fall back to rsync' ||
7167                 error "rsync was called with --no-rsync set"
7168         echo "done."
7169
7170         # Ensure rsync is called without trying 'lfs migrate' first
7171         echo -n "Make sure --rsync option works..."
7172         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7173                 grep -q 'falling back to rsync' &&
7174                 error "lfs migrate was called with --rsync set"
7175         echo "done."
7176
7177         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7178         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7179                 grep -q 'at the same time' ||
7180                 error "--rsync and --no-rsync accepted concurrently"
7181         echo "done."
7182
7183         # Clean up
7184         rm -f $file1
7185 }
7186 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7187
7188 test_56we() {
7189         local td=$DIR/$tdir
7190         local tf=$td/$tfile
7191
7192         test_mkdir $td || error "cannot create $td"
7193         touch $tf || error "cannot touch $tf"
7194
7195         echo -n "Make sure --non-direct|-D works..."
7196         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7197                 grep -q "lfs migrate --non-direct" ||
7198                 error "--non-direct option cannot work correctly"
7199         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7200                 grep -q "lfs migrate -D" ||
7201                 error "-D option cannot work correctly"
7202         echo "done."
7203 }
7204 run_test 56we "check lfs_migrate --non-direct|-D support"
7205
7206 test_56x() {
7207         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7208         check_swap_layouts_support
7209
7210         local dir=$DIR/$tdir
7211         local ref1=/etc/passwd
7212         local file1=$dir/file1
7213
7214         test_mkdir $dir || error "creating dir $dir"
7215         $LFS setstripe -c 2 $file1
7216         cp $ref1 $file1
7217         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7218         stripe=$($LFS getstripe -c $file1)
7219         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7220         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7221
7222         # clean up
7223         rm -f $file1
7224 }
7225 run_test 56x "lfs migration support"
7226
7227 test_56xa() {
7228         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7229         check_swap_layouts_support
7230
7231         local dir=$DIR/$tdir/$testnum
7232
7233         test_mkdir -p $dir
7234
7235         local ref1=/etc/passwd
7236         local file1=$dir/file1
7237
7238         $LFS setstripe -c 2 $file1
7239         cp $ref1 $file1
7240         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7241
7242         local stripe=$($LFS getstripe -c $file1)
7243
7244         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7245         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7246
7247         # clean up
7248         rm -f $file1
7249 }
7250 run_test 56xa "lfs migration --block support"
7251
7252 check_migrate_links() {
7253         local dir="$1"
7254         local file1="$dir/file1"
7255         local begin="$2"
7256         local count="$3"
7257         local runas="$4"
7258         local total_count=$(($begin + $count - 1))
7259         local symlink_count=10
7260         local uniq_count=10
7261
7262         if [ ! -f "$file1" ]; then
7263                 echo -n "creating initial file..."
7264                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7265                         error "cannot setstripe initial file"
7266                 echo "done"
7267
7268                 echo -n "creating symlinks..."
7269                 for s in $(seq 1 $symlink_count); do
7270                         ln -s "$file1" "$dir/slink$s" ||
7271                                 error "cannot create symlinks"
7272                 done
7273                 echo "done"
7274
7275                 echo -n "creating nonlinked files..."
7276                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7277                         error "cannot create nonlinked files"
7278                 echo "done"
7279         fi
7280
7281         # create hard links
7282         if [ ! -f "$dir/file$total_count" ]; then
7283                 echo -n "creating hard links $begin:$total_count..."
7284                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7285                         /dev/null || error "cannot create hard links"
7286                 echo "done"
7287         fi
7288
7289         echo -n "checking number of hard links listed in xattrs..."
7290         local fid=$($LFS getstripe -F "$file1")
7291         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7292
7293         echo "${#paths[*]}"
7294         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7295                         skip "hard link list has unexpected size, skipping test"
7296         fi
7297         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7298                         error "link names should exceed xattrs size"
7299         fi
7300
7301         echo -n "migrating files..."
7302         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7303         local rc=$?
7304         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7305         echo "done"
7306
7307         # make sure all links have been properly migrated
7308         echo -n "verifying files..."
7309         fid=$($LFS getstripe -F "$file1") ||
7310                 error "cannot get fid for file $file1"
7311         for i in $(seq 2 $total_count); do
7312                 local fid2=$($LFS getstripe -F $dir/file$i)
7313
7314                 [ "$fid2" == "$fid" ] ||
7315                         error "migrated hard link has mismatched FID"
7316         done
7317
7318         # make sure hard links were properly detected, and migration was
7319         # performed only once for the entire link set; nonlinked files should
7320         # also be migrated
7321         local actual=$(grep -c 'done' <<< "$migrate_out")
7322         local expected=$(($uniq_count + 1))
7323
7324         [ "$actual" -eq  "$expected" ] ||
7325                 error "hard links individually migrated ($actual != $expected)"
7326
7327         # make sure the correct number of hard links are present
7328         local hardlinks=$(stat -c '%h' "$file1")
7329
7330         [ $hardlinks -eq $total_count ] ||
7331                 error "num hard links $hardlinks != $total_count"
7332         echo "done"
7333
7334         return 0
7335 }
7336
7337 test_56xb() {
7338         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7339                 skip "Need MDS version at least 2.10.55"
7340
7341         local dir="$DIR/$tdir"
7342
7343         test_mkdir "$dir" || error "cannot create dir $dir"
7344
7345         echo "testing lfs migrate mode when all links fit within xattrs"
7346         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7347
7348         echo "testing rsync mode when all links fit within xattrs"
7349         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7350
7351         echo "testing lfs migrate mode when all links do not fit within xattrs"
7352         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7353
7354         echo "testing rsync mode when all links do not fit within xattrs"
7355         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7356
7357         chown -R $RUNAS_ID $dir
7358         echo "testing non-root lfs migrate mode when not all links are in xattr"
7359         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7360
7361         # clean up
7362         rm -rf $dir
7363 }
7364 run_test 56xb "lfs migration hard link support"
7365
7366 test_56xc() {
7367         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7368
7369         local dir="$DIR/$tdir"
7370
7371         test_mkdir "$dir" || error "cannot create dir $dir"
7372
7373         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7374         echo -n "Setting initial stripe for 20MB test file..."
7375         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7376                 error "cannot setstripe 20MB file"
7377         echo "done"
7378         echo -n "Sizing 20MB test file..."
7379         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7380         echo "done"
7381         echo -n "Verifying small file autostripe count is 1..."
7382         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7383                 error "cannot migrate 20MB file"
7384         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7385                 error "cannot get stripe for $dir/20mb"
7386         [ $stripe_count -eq 1 ] ||
7387                 error "unexpected stripe count $stripe_count for 20MB file"
7388         rm -f "$dir/20mb"
7389         echo "done"
7390
7391         # Test 2: File is small enough to fit within the available space on
7392         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7393         # have at least an additional 1KB for each desired stripe for test 3
7394         echo -n "Setting stripe for 1GB test file..."
7395         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7396         echo "done"
7397         echo -n "Sizing 1GB test file..."
7398         # File size is 1GB + 3KB
7399         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7400         echo "done"
7401
7402         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7403         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7404         if (( avail > 524288 * OSTCOUNT )); then
7405                 echo -n "Migrating 1GB file..."
7406                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7407                         error "cannot migrate 1GB file"
7408                 echo "done"
7409                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7410                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7411                         error "cannot getstripe for 1GB file"
7412                 [ $stripe_count -eq 2 ] ||
7413                         error "unexpected stripe count $stripe_count != 2"
7414                 echo "done"
7415         fi
7416
7417         # Test 3: File is too large to fit within the available space on
7418         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7419         if [ $OSTCOUNT -ge 3 ]; then
7420                 # The required available space is calculated as
7421                 # file size (1GB + 3KB) / OST count (3).
7422                 local kb_per_ost=349526
7423
7424                 echo -n "Migrating 1GB file with limit..."
7425                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7426                         error "cannot migrate 1GB file with limit"
7427                 echo "done"
7428
7429                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7430                 echo -n "Verifying 1GB autostripe count with limited space..."
7431                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7432                         error "unexpected stripe count $stripe_count (min 3)"
7433                 echo "done"
7434         fi
7435
7436         # clean up
7437         rm -rf $dir
7438 }
7439 run_test 56xc "lfs migration autostripe"
7440
7441 test_56xd() {
7442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7443
7444         local dir=$DIR/$tdir
7445         local f_mgrt=$dir/$tfile.mgrt
7446         local f_yaml=$dir/$tfile.yaml
7447         local f_copy=$dir/$tfile.copy
7448         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7449         local layout_copy="-c 2 -S 2M -i 1"
7450         local yamlfile=$dir/yamlfile
7451         local layout_before;
7452         local layout_after;
7453
7454         test_mkdir "$dir" || error "cannot create dir $dir"
7455         $LFS setstripe $layout_yaml $f_yaml ||
7456                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7457         $LFS getstripe --yaml $f_yaml > $yamlfile
7458         $LFS setstripe $layout_copy $f_copy ||
7459                 error "cannot setstripe $f_copy with layout $layout_copy"
7460         touch $f_mgrt
7461         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7462
7463         # 1. test option --yaml
7464         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7465                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7466         layout_before=$(get_layout_param $f_yaml)
7467         layout_after=$(get_layout_param $f_mgrt)
7468         [ "$layout_after" == "$layout_before" ] ||
7469                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7470
7471         # 2. test option --copy
7472         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7473                 error "cannot migrate $f_mgrt with --copy $f_copy"
7474         layout_before=$(get_layout_param $f_copy)
7475         layout_after=$(get_layout_param $f_mgrt)
7476         [ "$layout_after" == "$layout_before" ] ||
7477                 error "lfs_migrate --copy: $layout_after != $layout_before"
7478 }
7479 run_test 56xd "check lfs_migrate --yaml and --copy support"
7480
7481 test_56xe() {
7482         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7483
7484         local dir=$DIR/$tdir
7485         local f_comp=$dir/$tfile
7486         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7487         local layout_before=""
7488         local layout_after=""
7489
7490         test_mkdir "$dir" || error "cannot create dir $dir"
7491         $LFS setstripe $layout $f_comp ||
7492                 error "cannot setstripe $f_comp with layout $layout"
7493         layout_before=$(get_layout_param $f_comp)
7494         dd if=/dev/zero of=$f_comp bs=1M count=4
7495
7496         # 1. migrate a comp layout file by lfs_migrate
7497         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7498         layout_after=$(get_layout_param $f_comp)
7499         [ "$layout_before" == "$layout_after" ] ||
7500                 error "lfs_migrate: $layout_before != $layout_after"
7501
7502         # 2. migrate a comp layout file by lfs migrate
7503         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7504         layout_after=$(get_layout_param $f_comp)
7505         [ "$layout_before" == "$layout_after" ] ||
7506                 error "lfs migrate: $layout_before != $layout_after"
7507 }
7508 run_test 56xe "migrate a composite layout file"
7509
7510 test_56xf() {
7511         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7512
7513         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7514                 skip "Need server version at least 2.13.53"
7515
7516         local dir=$DIR/$tdir
7517         local f_comp=$dir/$tfile
7518         local layout="-E 1M -c1 -E -1 -c2"
7519         local fid_before=""
7520         local fid_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         fid_before=$($LFS getstripe --fid $f_comp)
7526         dd if=/dev/zero of=$f_comp bs=1M count=4
7527
7528         # 1. migrate a comp layout file to a comp layout
7529         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7530         fid_after=$($LFS getstripe --fid $f_comp)
7531         [ "$fid_before" == "$fid_after" ] ||
7532                 error "comp-to-comp migrate: $fid_before != $fid_after"
7533
7534         # 2. migrate a comp layout file to a plain layout
7535         $LFS migrate -c2 $f_comp ||
7536                 error "cannot migrate $f_comp by lfs migrate"
7537         fid_after=$($LFS getstripe --fid $f_comp)
7538         [ "$fid_before" == "$fid_after" ] ||
7539                 error "comp-to-plain migrate: $fid_before != $fid_after"
7540
7541         # 3. migrate a plain layout file to a comp layout
7542         $LFS migrate $layout $f_comp ||
7543                 error "cannot migrate $f_comp by lfs migrate"
7544         fid_after=$($LFS getstripe --fid $f_comp)
7545         [ "$fid_before" == "$fid_after" ] ||
7546                 error "plain-to-comp migrate: $fid_before != $fid_after"
7547 }
7548 run_test 56xf "FID is not lost during migration of a composite layout file"
7549
7550 test_56y() {
7551         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7552                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7553
7554         local res=""
7555         local dir=$DIR/$tdir
7556         local f1=$dir/file1
7557         local f2=$dir/file2
7558
7559         test_mkdir -p $dir || error "creating dir $dir"
7560         touch $f1 || error "creating std file $f1"
7561         $MULTIOP $f2 H2c || error "creating released file $f2"
7562
7563         # a directory can be raid0, so ask only for files
7564         res=$($LFS find $dir -L raid0 -type f | wc -l)
7565         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7566
7567         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7568         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7569
7570         # only files can be released, so no need to force file search
7571         res=$($LFS find $dir -L released)
7572         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7573
7574         res=$($LFS find $dir -type f \! -L released)
7575         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7576 }
7577 run_test 56y "lfs find -L raid0|released"
7578
7579 test_56z() { # LU-4824
7580         # This checks to make sure 'lfs find' continues after errors
7581         # There are two classes of errors that should be caught:
7582         # - If multiple paths are provided, all should be searched even if one
7583         #   errors out
7584         # - If errors are encountered during the search, it should not terminate
7585         #   early
7586         local dir=$DIR/$tdir
7587         local i
7588
7589         test_mkdir $dir
7590         for i in d{0..9}; do
7591                 test_mkdir $dir/$i
7592                 touch $dir/$i/$tfile
7593         done
7594         $LFS find $DIR/non_existent_dir $dir &&
7595                 error "$LFS find did not return an error"
7596         # Make a directory unsearchable. This should NOT be the last entry in
7597         # directory order.  Arbitrarily pick the 6th entry
7598         chmod 700 $($LFS find $dir -type d | sed '6!d')
7599
7600         $RUNAS $LFS find $DIR/non_existent $dir
7601         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7602
7603         # The user should be able to see 10 directories and 9 files
7604         (( count == 19 )) ||
7605                 error "$LFS find found $count != 19 entries after error"
7606 }
7607 run_test 56z "lfs find should continue after an error"
7608
7609 test_56aa() { # LU-5937
7610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7611
7612         local dir=$DIR/$tdir
7613
7614         mkdir $dir
7615         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7616
7617         createmany -o $dir/striped_dir/${tfile}- 1024
7618         local dirs=$($LFS find --size +8k $dir/)
7619
7620         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7621 }
7622 run_test 56aa "lfs find --size under striped dir"
7623
7624 test_56ab() { # LU-10705
7625         test_mkdir $DIR/$tdir
7626         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7627         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7628         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7629         # Flush writes to ensure valid blocks.  Need to be more thorough for
7630         # ZFS, since blocks are not allocated/returned to client immediately.
7631         sync_all_data
7632         wait_zfs_commit ost1 2
7633         cancel_lru_locks osc
7634         ls -ls $DIR/$tdir
7635
7636         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7637
7638         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7639
7640         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7641         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7642
7643         rm -f $DIR/$tdir/$tfile.[123]
7644 }
7645 run_test 56ab "lfs find --blocks"
7646
7647 test_56ba() {
7648         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7649                 skip "Need MDS version at least 2.10.50"
7650
7651         # Create composite files with one component
7652         local dir=$DIR/$tdir
7653
7654         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7655         # Create composite files with three components
7656         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7657         # Create non-composite files
7658         createmany -o $dir/${tfile}- 10
7659
7660         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7661
7662         [[ $nfiles == 10 ]] ||
7663                 error "lfs find -E 1M found $nfiles != 10 files"
7664
7665         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7666         [[ $nfiles == 25 ]] ||
7667                 error "lfs find ! -E 1M found $nfiles != 25 files"
7668
7669         # All files have a component that starts at 0
7670         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7671         [[ $nfiles == 35 ]] ||
7672                 error "lfs find --component-start 0 - $nfiles != 35 files"
7673
7674         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7675         [[ $nfiles == 15 ]] ||
7676                 error "lfs find --component-start 2M - $nfiles != 15 files"
7677
7678         # All files created here have a componenet that does not starts at 2M
7679         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7680         [[ $nfiles == 35 ]] ||
7681                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7682
7683         # Find files with a specified number of components
7684         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7685         [[ $nfiles == 15 ]] ||
7686                 error "lfs find --component-count 3 - $nfiles != 15 files"
7687
7688         # Remember non-composite files have a component count of zero
7689         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7690         [[ $nfiles == 10 ]] ||
7691                 error "lfs find --component-count 0 - $nfiles != 10 files"
7692
7693         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7694         [[ $nfiles == 20 ]] ||
7695                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7696
7697         # All files have a flag called "init"
7698         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7699         [[ $nfiles == 35 ]] ||
7700                 error "lfs find --component-flags init - $nfiles != 35 files"
7701
7702         # Multi-component files will have a component not initialized
7703         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7704         [[ $nfiles == 15 ]] ||
7705                 error "lfs find !--component-flags init - $nfiles != 15 files"
7706
7707         rm -rf $dir
7708
7709 }
7710 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7711
7712 test_56ca() {
7713         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7714                 skip "Need MDS version at least 2.10.57"
7715
7716         local td=$DIR/$tdir
7717         local tf=$td/$tfile
7718         local dir
7719         local nfiles
7720         local cmd
7721         local i
7722         local j
7723
7724         # create mirrored directories and mirrored files
7725         mkdir $td || error "mkdir $td failed"
7726         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7727         createmany -o $tf- 10 || error "create $tf- failed"
7728
7729         for i in $(seq 2); do
7730                 dir=$td/dir$i
7731                 mkdir $dir || error "mkdir $dir failed"
7732                 $LFS mirror create -N$((3 + i)) $dir ||
7733                         error "create mirrored dir $dir failed"
7734                 createmany -o $dir/$tfile- 10 ||
7735                         error "create $dir/$tfile- failed"
7736         done
7737
7738         # change the states of some mirrored files
7739         echo foo > $tf-6
7740         for i in $(seq 2); do
7741                 dir=$td/dir$i
7742                 for j in $(seq 4 9); do
7743                         echo foo > $dir/$tfile-$j
7744                 done
7745         done
7746
7747         # find mirrored files with specific mirror count
7748         cmd="$LFS find --mirror-count 3 --type f $td"
7749         nfiles=$($cmd | wc -l)
7750         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7751
7752         cmd="$LFS find ! --mirror-count 3 --type f $td"
7753         nfiles=$($cmd | wc -l)
7754         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7755
7756         cmd="$LFS find --mirror-count +2 --type f $td"
7757         nfiles=$($cmd | wc -l)
7758         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7759
7760         cmd="$LFS find --mirror-count -6 --type f $td"
7761         nfiles=$($cmd | wc -l)
7762         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7763
7764         # find mirrored files with specific file state
7765         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7766         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7767
7768         cmd="$LFS find --mirror-state=ro --type f $td"
7769         nfiles=$($cmd | wc -l)
7770         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7771
7772         cmd="$LFS find ! --mirror-state=ro --type f $td"
7773         nfiles=$($cmd | wc -l)
7774         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7775
7776         cmd="$LFS find --mirror-state=wp --type f $td"
7777         nfiles=$($cmd | wc -l)
7778         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7779
7780         cmd="$LFS find ! --mirror-state=sp --type f $td"
7781         nfiles=$($cmd | wc -l)
7782         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7783 }
7784 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7785
7786 test_56da() { # LU-14179
7787         local path=$DIR/$tdir
7788
7789         test_mkdir $path
7790         cd $path
7791
7792         local longdir=$(str_repeat 'a' 255)
7793
7794         for i in {1..15}; do
7795                 path=$path/$longdir
7796                 test_mkdir $longdir
7797                 cd $longdir
7798         done
7799
7800         local len=${#path}
7801         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7802
7803         test_mkdir $lastdir
7804         cd $lastdir
7805         # PATH_MAX-1
7806         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7807
7808         # NAME_MAX
7809         touch $(str_repeat 'f' 255)
7810
7811         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7812                 error "lfs find reported an error"
7813
7814         rm -rf $DIR/$tdir
7815 }
7816 run_test 56da "test lfs find with long paths"
7817
7818 test_57a() {
7819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7820         # note test will not do anything if MDS is not local
7821         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7822                 skip_env "ldiskfs only test"
7823         fi
7824         remote_mds_nodsh && skip "remote MDS with nodsh"
7825
7826         local MNTDEV="osd*.*MDT*.mntdev"
7827         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7828         [ -z "$DEV" ] && error "can't access $MNTDEV"
7829         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7830                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7831                         error "can't access $DEV"
7832                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7833                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7834                 rm $TMP/t57a.dump
7835         done
7836 }
7837 run_test 57a "verify MDS filesystem created with large inodes =="
7838
7839 test_57b() {
7840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7841         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7842                 skip_env "ldiskfs only test"
7843         fi
7844         remote_mds_nodsh && skip "remote MDS with nodsh"
7845
7846         local dir=$DIR/$tdir
7847         local filecount=100
7848         local file1=$dir/f1
7849         local fileN=$dir/f$filecount
7850
7851         rm -rf $dir || error "removing $dir"
7852         test_mkdir -c1 $dir
7853         local mdtidx=$($LFS getstripe -m $dir)
7854         local mdtname=MDT$(printf %04x $mdtidx)
7855         local facet=mds$((mdtidx + 1))
7856
7857         echo "mcreating $filecount files"
7858         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7859
7860         # verify that files do not have EAs yet
7861         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7862                 error "$file1 has an EA"
7863         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7864                 error "$fileN has an EA"
7865
7866         sync
7867         sleep 1
7868         df $dir  #make sure we get new statfs data
7869         local mdsfree=$(do_facet $facet \
7870                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7871         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7872         local file
7873
7874         echo "opening files to create objects/EAs"
7875         for file in $(seq -f $dir/f%g 1 $filecount); do
7876                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7877                         error "opening $file"
7878         done
7879
7880         # verify that files have EAs now
7881         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7882         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7883
7884         sleep 1  #make sure we get new statfs data
7885         df $dir
7886         local mdsfree2=$(do_facet $facet \
7887                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7888         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7889
7890         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7891                 if [ "$mdsfree" != "$mdsfree2" ]; then
7892                         error "MDC before $mdcfree != after $mdcfree2"
7893                 else
7894                         echo "MDC before $mdcfree != after $mdcfree2"
7895                         echo "unable to confirm if MDS has large inodes"
7896                 fi
7897         fi
7898         rm -rf $dir
7899 }
7900 run_test 57b "default LOV EAs are stored inside large inodes ==="
7901
7902 test_58() {
7903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7904         [ -z "$(which wiretest 2>/dev/null)" ] &&
7905                         skip_env "could not find wiretest"
7906
7907         wiretest
7908 }
7909 run_test 58 "verify cross-platform wire constants =============="
7910
7911 test_59() {
7912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7913
7914         echo "touch 130 files"
7915         createmany -o $DIR/f59- 130
7916         echo "rm 130 files"
7917         unlinkmany $DIR/f59- 130
7918         sync
7919         # wait for commitment of removal
7920         wait_delete_completed
7921 }
7922 run_test 59 "verify cancellation of llog records async ========="
7923
7924 TEST60_HEAD="test_60 run $RANDOM"
7925 test_60a() {
7926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7927         remote_mgs_nodsh && skip "remote MGS with nodsh"
7928         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7929                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7930                         skip_env "missing subtest run-llog.sh"
7931
7932         log "$TEST60_HEAD - from kernel mode"
7933         do_facet mgs "$LCTL dk > /dev/null"
7934         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7935         do_facet mgs $LCTL dk > $TMP/$tfile
7936
7937         # LU-6388: test llog_reader
7938         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7939         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7940         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7941                         skip_env "missing llog_reader"
7942         local fstype=$(facet_fstype mgs)
7943         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7944                 skip_env "Only for ldiskfs or zfs type mgs"
7945
7946         local mntpt=$(facet_mntpt mgs)
7947         local mgsdev=$(mgsdevname 1)
7948         local fid_list
7949         local fid
7950         local rec_list
7951         local rec
7952         local rec_type
7953         local obj_file
7954         local path
7955         local seq
7956         local oid
7957         local pass=true
7958
7959         #get fid and record list
7960         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7961                 tail -n 4))
7962         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7963                 tail -n 4))
7964         #remount mgs as ldiskfs or zfs type
7965         stop mgs || error "stop mgs failed"
7966         mount_fstype mgs || error "remount mgs failed"
7967         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7968                 fid=${fid_list[i]}
7969                 rec=${rec_list[i]}
7970                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7971                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7972                 oid=$((16#$oid))
7973
7974                 case $fstype in
7975                         ldiskfs )
7976                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7977                         zfs )
7978                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7979                 esac
7980                 echo "obj_file is $obj_file"
7981                 do_facet mgs $llog_reader $obj_file
7982
7983                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7984                         awk '{ print $3 }' | sed -e "s/^type=//g")
7985                 if [ $rec_type != $rec ]; then
7986                         echo "FAILED test_60a wrong record type $rec_type," \
7987                               "should be $rec"
7988                         pass=false
7989                         break
7990                 fi
7991
7992                 #check obj path if record type is LLOG_LOGID_MAGIC
7993                 if [ "$rec" == "1064553b" ]; then
7994                         path=$(do_facet mgs $llog_reader $obj_file |
7995                                 grep "path=" | awk '{ print $NF }' |
7996                                 sed -e "s/^path=//g")
7997                         if [ $obj_file != $mntpt/$path ]; then
7998                                 echo "FAILED test_60a wrong obj path" \
7999                                       "$montpt/$path, should be $obj_file"
8000                                 pass=false
8001                                 break
8002                         fi
8003                 fi
8004         done
8005         rm -f $TMP/$tfile
8006         #restart mgs before "error", otherwise it will block the next test
8007         stop mgs || error "stop mgs failed"
8008         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8009         $pass || error "test failed, see FAILED test_60a messages for specifics"
8010 }
8011 run_test 60a "llog_test run from kernel module and test llog_reader"
8012
8013 test_60b() { # bug 6411
8014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8015
8016         dmesg > $DIR/$tfile
8017         LLOG_COUNT=$(do_facet mgs dmesg |
8018                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8019                           /llog_[a-z]*.c:[0-9]/ {
8020                                 if (marker)
8021                                         from_marker++
8022                                 from_begin++
8023                           }
8024                           END {
8025                                 if (marker)
8026                                         print from_marker
8027                                 else
8028                                         print from_begin
8029                           }")
8030
8031         [[ $LLOG_COUNT -gt 120 ]] &&
8032                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8033 }
8034 run_test 60b "limit repeated messages from CERROR/CWARN"
8035
8036 test_60c() {
8037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8038
8039         echo "create 5000 files"
8040         createmany -o $DIR/f60c- 5000
8041 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8042         lctl set_param fail_loc=0x80000137
8043         unlinkmany $DIR/f60c- 5000
8044         lctl set_param fail_loc=0
8045 }
8046 run_test 60c "unlink file when mds full"
8047
8048 test_60d() {
8049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8050
8051         SAVEPRINTK=$(lctl get_param -n printk)
8052         # verify "lctl mark" is even working"
8053         MESSAGE="test message ID $RANDOM $$"
8054         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8055         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8056
8057         lctl set_param printk=0 || error "set lnet.printk failed"
8058         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8059         MESSAGE="new test message ID $RANDOM $$"
8060         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8061         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8062         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8063
8064         lctl set_param -n printk="$SAVEPRINTK"
8065 }
8066 run_test 60d "test printk console message masking"
8067
8068 test_60e() {
8069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8070         remote_mds_nodsh && skip "remote MDS with nodsh"
8071
8072         touch $DIR/$tfile
8073 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8074         do_facet mds1 lctl set_param fail_loc=0x15b
8075         rm $DIR/$tfile
8076 }
8077 run_test 60e "no space while new llog is being created"
8078
8079 test_60f() {
8080         local old_path=$($LCTL get_param -n debug_path)
8081
8082         stack_trap "$LCTL set_param debug_path=$old_path"
8083         stack_trap "rm -f $TMP/$tfile*"
8084         rm -f $TMP/$tfile* 2> /dev/null
8085         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8086         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8087         test_mkdir $DIR/$tdir
8088         # retry in case the open is cached and not released
8089         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8090                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8091                 sleep 0.1
8092         done
8093         ls $TMP/$tfile*
8094         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8095 }
8096 run_test 60f "change debug_path works"
8097
8098 test_60g() {
8099         local pid
8100         local i
8101
8102         test_mkdir -c $MDSCOUNT $DIR/$tdir
8103
8104         (
8105                 local index=0
8106                 while true; do
8107                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8108                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8109                                 2>/dev/null
8110                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8111                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8112                         index=$((index + 1))
8113                 done
8114         ) &
8115
8116         pid=$!
8117
8118         for i in {0..100}; do
8119                 # define OBD_FAIL_OSD_TXN_START    0x19a
8120                 local index=$((i % MDSCOUNT + 1))
8121
8122                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8123                         > /dev/null
8124                 sleep 0.01
8125         done
8126
8127         kill -9 $pid
8128
8129         for i in $(seq $MDSCOUNT); do
8130                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8131         done
8132
8133         mkdir $DIR/$tdir/new || error "mkdir failed"
8134         rmdir $DIR/$tdir/new || error "rmdir failed"
8135
8136         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8137                 -t namespace
8138         for i in $(seq $MDSCOUNT); do
8139                 wait_update_facet mds$i "$LCTL get_param -n \
8140                         mdd.$(facet_svc mds$i).lfsck_namespace |
8141                         awk '/^status/ { print \\\$2 }'" "completed"
8142         done
8143
8144         ls -R $DIR/$tdir || error "ls failed"
8145         rm -rf $DIR/$tdir || error "rmdir failed"
8146 }
8147 run_test 60g "transaction abort won't cause MDT hung"
8148
8149 test_60h() {
8150         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8151                 skip "Need MDS version at least 2.12.52"
8152         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8153
8154         local f
8155
8156         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8157         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8158         for fail_loc in 0x80000188 0x80000189; do
8159                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8160                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8161                         error "mkdir $dir-$fail_loc failed"
8162                 for i in {0..10}; do
8163                         # create may fail on missing stripe
8164                         echo $i > $DIR/$tdir-$fail_loc/$i
8165                 done
8166                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8167                         error "getdirstripe $tdir-$fail_loc failed"
8168                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8169                         error "migrate $tdir-$fail_loc failed"
8170                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8171                         error "getdirstripe $tdir-$fail_loc failed"
8172                 pushd $DIR/$tdir-$fail_loc
8173                 for f in *; do
8174                         echo $f | cmp $f - || error "$f data mismatch"
8175                 done
8176                 popd
8177                 rm -rf $DIR/$tdir-$fail_loc
8178         done
8179 }
8180 run_test 60h "striped directory with missing stripes can be accessed"
8181
8182 test_61a() {
8183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8184
8185         f="$DIR/f61"
8186         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8187         cancel_lru_locks osc
8188         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8189         sync
8190 }
8191 run_test 61a "mmap() writes don't make sync hang ================"
8192
8193 test_61b() {
8194         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8195 }
8196 run_test 61b "mmap() of unstriped file is successful"
8197
8198 # bug 2330 - insufficient obd_match error checking causes LBUG
8199 test_62() {
8200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8201
8202         f="$DIR/f62"
8203         echo foo > $f
8204         cancel_lru_locks osc
8205         lctl set_param fail_loc=0x405
8206         cat $f && error "cat succeeded, expect -EIO"
8207         lctl set_param fail_loc=0
8208 }
8209 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8210 # match every page all of the time.
8211 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8212
8213 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8214 # Though this test is irrelevant anymore, it helped to reveal some
8215 # other grant bugs (LU-4482), let's keep it.
8216 test_63a() {   # was test_63
8217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8218
8219         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8220
8221         for i in `seq 10` ; do
8222                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8223                 sleep 5
8224                 kill $!
8225                 sleep 1
8226         done
8227
8228         rm -f $DIR/f63 || true
8229 }
8230 run_test 63a "Verify oig_wait interruption does not crash ======="
8231
8232 # bug 2248 - async write errors didn't return to application on sync
8233 # bug 3677 - async write errors left page locked
8234 test_63b() {
8235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8236
8237         debugsave
8238         lctl set_param debug=-1
8239
8240         # ensure we have a grant to do async writes
8241         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8242         rm $DIR/$tfile
8243
8244         sync    # sync lest earlier test intercept the fail_loc
8245
8246         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8247         lctl set_param fail_loc=0x80000406
8248         $MULTIOP $DIR/$tfile Owy && \
8249                 error "sync didn't return ENOMEM"
8250         sync; sleep 2; sync     # do a real sync this time to flush page
8251         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8252                 error "locked page left in cache after async error" || true
8253         debugrestore
8254 }
8255 run_test 63b "async write errors should be returned to fsync ==="
8256
8257 test_64a () {
8258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8259
8260         lfs df $DIR
8261         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8262 }
8263 run_test 64a "verify filter grant calculations (in kernel) ====="
8264
8265 test_64b () {
8266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8267
8268         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8269 }
8270 run_test 64b "check out-of-space detection on client"
8271
8272 test_64c() {
8273         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8274 }
8275 run_test 64c "verify grant shrink"
8276
8277 import_param() {
8278         local tgt=$1
8279         local param=$2
8280
8281         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8282 }
8283
8284 # this does exactly what osc_request.c:osc_announce_cached() does in
8285 # order to calculate max amount of grants to ask from server
8286 want_grant() {
8287         local tgt=$1
8288
8289         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8290         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8291
8292         ((rpc_in_flight++));
8293         nrpages=$((nrpages * rpc_in_flight))
8294
8295         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8296
8297         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8298
8299         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8300         local undirty=$((nrpages * PAGE_SIZE))
8301
8302         local max_extent_pages
8303         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8304         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8305         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8306         local grant_extent_tax
8307         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8308
8309         undirty=$((undirty + nrextents * grant_extent_tax))
8310
8311         echo $undirty
8312 }
8313
8314 # this is size of unit for grant allocation. It should be equal to
8315 # what tgt_grant.c:tgt_grant_chunk() calculates
8316 grant_chunk() {
8317         local tgt=$1
8318         local max_brw_size
8319         local grant_extent_tax
8320
8321         max_brw_size=$(import_param $tgt max_brw_size)
8322
8323         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8324
8325         echo $(((max_brw_size + grant_extent_tax) * 2))
8326 }
8327
8328 test_64d() {
8329         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8330                 skip "OST < 2.10.55 doesn't limit grants enough"
8331
8332         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8333
8334         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8335                 skip "no grant_param connect flag"
8336
8337         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8338
8339         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8340         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8341
8342
8343         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8344         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8345
8346         $LFS setstripe $DIR/$tfile -i 0 -c 1
8347         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8348         ddpid=$!
8349
8350         while kill -0 $ddpid; do
8351                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8352
8353                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8354                         kill $ddpid
8355                         error "cur_grant $cur_grant > $max_cur_granted"
8356                 fi
8357
8358                 sleep 1
8359         done
8360 }
8361 run_test 64d "check grant limit exceed"
8362
8363 check_grants() {
8364         local tgt=$1
8365         local expected=$2
8366         local msg=$3
8367         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8368
8369         ((cur_grants == expected)) ||
8370                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8371 }
8372
8373 round_up_p2() {
8374         echo $((($1 + $2 - 1) & ~($2 - 1)))
8375 }
8376
8377 test_64e() {
8378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8379         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8380                 skip "Need OSS version at least 2.11.56"
8381
8382         # Remount client to reset grant
8383         remount_client $MOUNT || error "failed to remount client"
8384         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8385
8386         local init_grants=$(import_param $osc_tgt initial_grant)
8387
8388         check_grants $osc_tgt $init_grants "init grants"
8389
8390         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8391         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8392         local gbs=$(import_param $osc_tgt grant_block_size)
8393
8394         # write random number of bytes from max_brw_size / 4 to max_brw_size
8395         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8396         # align for direct io
8397         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8398         # round to grant consumption unit
8399         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8400
8401         local grants=$((wb_round_up + extent_tax))
8402
8403         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8404
8405         # define OBD_FAIL_TGT_NO_GRANT 0x725
8406         # make the server not grant more back
8407         do_facet ost1 $LCTL set_param fail_loc=0x725
8408         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8409
8410         do_facet ost1 $LCTL set_param fail_loc=0
8411
8412         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8413
8414         rm -f $DIR/$tfile || error "rm failed"
8415
8416         # Remount client to reset grant
8417         remount_client $MOUNT || error "failed to remount client"
8418         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8419
8420         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8421
8422         # define OBD_FAIL_TGT_NO_GRANT 0x725
8423         # make the server not grant more back
8424         do_facet ost1 $LCTL set_param fail_loc=0x725
8425         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8426         do_facet ost1 $LCTL set_param fail_loc=0
8427
8428         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8429 }
8430 run_test 64e "check grant consumption (no grant allocation)"
8431
8432 test_64f() {
8433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8434
8435         # Remount client to reset grant
8436         remount_client $MOUNT || error "failed to remount client"
8437         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8438
8439         local init_grants=$(import_param $osc_tgt initial_grant)
8440         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8441         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8442         local gbs=$(import_param $osc_tgt grant_block_size)
8443         local chunk=$(grant_chunk $osc_tgt)
8444
8445         # write random number of bytes from max_brw_size / 4 to max_brw_size
8446         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8447         # align for direct io
8448         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8449         # round to grant consumption unit
8450         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8451
8452         local grants=$((wb_round_up + extent_tax))
8453
8454         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8455         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8456                 error "error writing to $DIR/$tfile"
8457
8458         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8459                 "direct io with grant allocation"
8460
8461         rm -f $DIR/$tfile || error "rm failed"
8462
8463         # Remount client to reset grant
8464         remount_client $MOUNT || error "failed to remount client"
8465         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8466
8467         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8468
8469         local cmd="oO_WRONLY:w${write_bytes}_yc"
8470
8471         $MULTIOP $DIR/$tfile $cmd &
8472         MULTIPID=$!
8473         sleep 1
8474
8475         check_grants $osc_tgt $((init_grants - grants)) \
8476                 "buffered io, not write rpc"
8477
8478         kill -USR1 $MULTIPID
8479         wait
8480
8481         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8482                 "buffered io, one RPC"
8483 }
8484 run_test 64f "check grant consumption (with grant allocation)"
8485
8486 # bug 1414 - set/get directories' stripe info
8487 test_65a() {
8488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8489
8490         test_mkdir $DIR/$tdir
8491         touch $DIR/$tdir/f1
8492         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8493 }
8494 run_test 65a "directory with no stripe info"
8495
8496 test_65b() {
8497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8498
8499         test_mkdir $DIR/$tdir
8500         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8501
8502         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8503                                                 error "setstripe"
8504         touch $DIR/$tdir/f2
8505         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8506 }
8507 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8508
8509 test_65c() {
8510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8511         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8512
8513         test_mkdir $DIR/$tdir
8514         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8515
8516         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8517                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8518         touch $DIR/$tdir/f3
8519         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8520 }
8521 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8522
8523 test_65d() {
8524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8525
8526         test_mkdir $DIR/$tdir
8527         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8528         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8529
8530         if [[ $STRIPECOUNT -le 0 ]]; then
8531                 sc=1
8532         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8533                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8534                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8535         else
8536                 sc=$(($STRIPECOUNT - 1))
8537         fi
8538         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8539         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8540         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8541                 error "lverify failed"
8542 }
8543 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8544
8545 test_65e() {
8546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8547
8548         test_mkdir $DIR/$tdir
8549
8550         $LFS setstripe $DIR/$tdir || error "setstripe"
8551         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8552                                         error "no stripe info failed"
8553         touch $DIR/$tdir/f6
8554         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8555 }
8556 run_test 65e "directory setstripe defaults"
8557
8558 test_65f() {
8559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8560
8561         test_mkdir $DIR/${tdir}f
8562         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8563                 error "setstripe succeeded" || true
8564 }
8565 run_test 65f "dir setstripe permission (should return error) ==="
8566
8567 test_65g() {
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569
8570         test_mkdir $DIR/$tdir
8571         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8572
8573         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8574                 error "setstripe -S failed"
8575         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8576         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8577                 error "delete default stripe failed"
8578 }
8579 run_test 65g "directory setstripe -d"
8580
8581 test_65h() {
8582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8583
8584         test_mkdir $DIR/$tdir
8585         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8586
8587         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8588                 error "setstripe -S failed"
8589         test_mkdir $DIR/$tdir/dd1
8590         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8591                 error "stripe info inherit failed"
8592 }
8593 run_test 65h "directory stripe info inherit ===================="
8594
8595 test_65i() {
8596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8597
8598         save_layout_restore_at_exit $MOUNT
8599
8600         # bug6367: set non-default striping on root directory
8601         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8602
8603         # bug12836: getstripe on -1 default directory striping
8604         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8605
8606         # bug12836: getstripe -v on -1 default directory striping
8607         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8608
8609         # bug12836: new find on -1 default directory striping
8610         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8611 }
8612 run_test 65i "various tests to set root directory striping"
8613
8614 test_65j() { # bug6367
8615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8616
8617         sync; sleep 1
8618
8619         # if we aren't already remounting for each test, do so for this test
8620         if [ "$I_MOUNTED" = "yes" ]; then
8621                 cleanup || error "failed to unmount"
8622                 setup
8623         fi
8624
8625         save_layout_restore_at_exit $MOUNT
8626
8627         $LFS setstripe -d $MOUNT || error "setstripe failed"
8628 }
8629 run_test 65j "set default striping on root directory (bug 6367)="
8630
8631 cleanup_65k() {
8632         rm -rf $DIR/$tdir
8633         wait_delete_completed
8634         do_facet $SINGLEMDS "lctl set_param -n \
8635                 osp.$ost*MDT0000.max_create_count=$max_count"
8636         do_facet $SINGLEMDS "lctl set_param -n \
8637                 osp.$ost*MDT0000.create_count=$count"
8638         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8639         echo $INACTIVE_OSC "is Activate"
8640
8641         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8642 }
8643
8644 test_65k() { # bug11679
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8647         remote_mds_nodsh && skip "remote MDS with nodsh"
8648
8649         local disable_precreate=true
8650         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8651                 disable_precreate=false
8652
8653         echo "Check OST status: "
8654         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8655                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8656
8657         for OSC in $MDS_OSCS; do
8658                 echo $OSC "is active"
8659                 do_facet $SINGLEMDS lctl --device %$OSC activate
8660         done
8661
8662         for INACTIVE_OSC in $MDS_OSCS; do
8663                 local ost=$(osc_to_ost $INACTIVE_OSC)
8664                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8665                                lov.*md*.target_obd |
8666                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8667
8668                 mkdir -p $DIR/$tdir
8669                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8670                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8671
8672                 echo "Deactivate: " $INACTIVE_OSC
8673                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8674
8675                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8676                               osp.$ost*MDT0000.create_count")
8677                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8678                                   osp.$ost*MDT0000.max_create_count")
8679                 $disable_precreate &&
8680                         do_facet $SINGLEMDS "lctl set_param -n \
8681                                 osp.$ost*MDT0000.max_create_count=0"
8682
8683                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8684                         [ -f $DIR/$tdir/$idx ] && continue
8685                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8686                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8687                                 { cleanup_65k;
8688                                   error "setstripe $idx should succeed"; }
8689                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8690                 done
8691                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8692                 rmdir $DIR/$tdir
8693
8694                 do_facet $SINGLEMDS "lctl set_param -n \
8695                         osp.$ost*MDT0000.max_create_count=$max_count"
8696                 do_facet $SINGLEMDS "lctl set_param -n \
8697                         osp.$ost*MDT0000.create_count=$count"
8698                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8699                 echo $INACTIVE_OSC "is Activate"
8700
8701                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8702         done
8703 }
8704 run_test 65k "validate manual striping works properly with deactivated OSCs"
8705
8706 test_65l() { # bug 12836
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         test_mkdir -p $DIR/$tdir/test_dir
8710         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8711         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8712 }
8713 run_test 65l "lfs find on -1 stripe dir ========================"
8714
8715 test_65m() {
8716         local layout=$(save_layout $MOUNT)
8717         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8718                 restore_layout $MOUNT $layout
8719                 error "setstripe should fail by non-root users"
8720         }
8721         true
8722 }
8723 run_test 65m "normal user can't set filesystem default stripe"
8724
8725 test_65n() {
8726         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8727         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8728                 skip "Need MDS version at least 2.12.50"
8729         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8730
8731         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8732         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8733         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8734
8735         local root_layout=$(save_layout $MOUNT)
8736         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8737
8738         # new subdirectory under root directory should not inherit
8739         # the default layout from root
8740         local dir1=$MOUNT/$tdir-1
8741         mkdir $dir1 || error "mkdir $dir1 failed"
8742         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8743                 error "$dir1 shouldn't have LOV EA"
8744
8745         # delete the default layout on root directory
8746         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8747
8748         local dir2=$MOUNT/$tdir-2
8749         mkdir $dir2 || error "mkdir $dir2 failed"
8750         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8751                 error "$dir2 shouldn't have LOV EA"
8752
8753         # set a new striping pattern on root directory
8754         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8755         local new_def_stripe_size=$((def_stripe_size * 2))
8756         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8757                 error "set stripe size on $MOUNT failed"
8758
8759         # new file created in $dir2 should inherit the new stripe size from
8760         # the filesystem default
8761         local file2=$dir2/$tfile-2
8762         touch $file2 || error "touch $file2 failed"
8763
8764         local file2_stripe_size=$($LFS getstripe -S $file2)
8765         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8766         {
8767                 echo "file2_stripe_size: '$file2_stripe_size'"
8768                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8769                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8770         }
8771
8772         local dir3=$MOUNT/$tdir-3
8773         mkdir $dir3 || error "mkdir $dir3 failed"
8774         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8775         # the root layout, which is the actual default layout that will be used
8776         # when new files are created in $dir3.
8777         local dir3_layout=$(get_layout_param $dir3)
8778         local root_dir_layout=$(get_layout_param $MOUNT)
8779         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8780         {
8781                 echo "dir3_layout: '$dir3_layout'"
8782                 echo "root_dir_layout: '$root_dir_layout'"
8783                 error "$dir3 should show the default layout from $MOUNT"
8784         }
8785
8786         # set OST pool on root directory
8787         local pool=$TESTNAME
8788         pool_add $pool || error "add $pool failed"
8789         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8790                 error "add targets to $pool failed"
8791
8792         $LFS setstripe -p $pool $MOUNT ||
8793                 error "set OST pool on $MOUNT failed"
8794
8795         # new file created in $dir3 should inherit the pool from
8796         # the filesystem default
8797         local file3=$dir3/$tfile-3
8798         touch $file3 || error "touch $file3 failed"
8799
8800         local file3_pool=$($LFS getstripe -p $file3)
8801         [[ "$file3_pool" = "$pool" ]] ||
8802                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8803
8804         local dir4=$MOUNT/$tdir-4
8805         mkdir $dir4 || error "mkdir $dir4 failed"
8806         local dir4_layout=$(get_layout_param $dir4)
8807         root_dir_layout=$(get_layout_param $MOUNT)
8808         echo "$LFS getstripe -d $dir4"
8809         $LFS getstripe -d $dir4
8810         echo "$LFS getstripe -d $MOUNT"
8811         $LFS getstripe -d $MOUNT
8812         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8813         {
8814                 echo "dir4_layout: '$dir4_layout'"
8815                 echo "root_dir_layout: '$root_dir_layout'"
8816                 error "$dir4 should show the default layout from $MOUNT"
8817         }
8818
8819         # new file created in $dir4 should inherit the pool from
8820         # the filesystem default
8821         local file4=$dir4/$tfile-4
8822         touch $file4 || error "touch $file4 failed"
8823
8824         local file4_pool=$($LFS getstripe -p $file4)
8825         [[ "$file4_pool" = "$pool" ]] ||
8826                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8827
8828         # new subdirectory under non-root directory should inherit
8829         # the default layout from its parent directory
8830         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8831                 error "set directory layout on $dir4 failed"
8832
8833         local dir5=$dir4/$tdir-5
8834         mkdir $dir5 || error "mkdir $dir5 failed"
8835
8836         dir4_layout=$(get_layout_param $dir4)
8837         local dir5_layout=$(get_layout_param $dir5)
8838         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8839         {
8840                 echo "dir4_layout: '$dir4_layout'"
8841                 echo "dir5_layout: '$dir5_layout'"
8842                 error "$dir5 should inherit the default layout from $dir4"
8843         }
8844
8845         # though subdir under ROOT doesn't inherit default layout, but
8846         # its sub dir/file should be created with default layout.
8847         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8848         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8849                 skip "Need MDS version at least 2.12.59"
8850
8851         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8852         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8853         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8854
8855         if [ $default_lmv_hash == "none" ]; then
8856                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8857         else
8858                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8859                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8860         fi
8861
8862         $LFS setdirstripe -D -c 2 $MOUNT ||
8863                 error "setdirstripe -D -c 2 failed"
8864         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8865         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8866         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8867 }
8868 run_test 65n "don't inherit default layout from root for new subdirectories"
8869
8870 # bug 2543 - update blocks count on client
8871 test_66() {
8872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8873
8874         COUNT=${COUNT:-8}
8875         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8876         sync; sync_all_data; sync; sync_all_data
8877         cancel_lru_locks osc
8878         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8879         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8880 }
8881 run_test 66 "update inode blocks count on client ==============="
8882
8883 meminfo() {
8884         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8885 }
8886
8887 swap_used() {
8888         swapon -s | awk '($1 == "'$1'") { print $4 }'
8889 }
8890
8891 # bug5265, obdfilter oa2dentry return -ENOENT
8892 # #define OBD_FAIL_SRV_ENOENT 0x217
8893 test_69() {
8894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8895         remote_ost_nodsh && skip "remote OST with nodsh"
8896
8897         f="$DIR/$tfile"
8898         $LFS setstripe -c 1 -i 0 $f
8899
8900         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8901
8902         do_facet ost1 lctl set_param fail_loc=0x217
8903         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8904         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8905
8906         do_facet ost1 lctl set_param fail_loc=0
8907         $DIRECTIO write $f 0 2 || error "write error"
8908
8909         cancel_lru_locks osc
8910         $DIRECTIO read $f 0 1 || error "read error"
8911
8912         do_facet ost1 lctl set_param fail_loc=0x217
8913         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8914
8915         do_facet ost1 lctl set_param fail_loc=0
8916         rm -f $f
8917 }
8918 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8919
8920 test_71() {
8921         test_mkdir $DIR/$tdir
8922         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8923         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8924 }
8925 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8926
8927 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8929         [ "$RUNAS_ID" = "$UID" ] &&
8930                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8931         # Check that testing environment is properly set up. Skip if not
8932         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8933                 skip_env "User $RUNAS_ID does not exist - skipping"
8934
8935         touch $DIR/$tfile
8936         chmod 777 $DIR/$tfile
8937         chmod ug+s $DIR/$tfile
8938         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8939                 error "$RUNAS dd $DIR/$tfile failed"
8940         # See if we are still setuid/sgid
8941         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8942                 error "S/gid is not dropped on write"
8943         # Now test that MDS is updated too
8944         cancel_lru_locks mdc
8945         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8946                 error "S/gid is not dropped on MDS"
8947         rm -f $DIR/$tfile
8948 }
8949 run_test 72a "Test that remove suid works properly (bug5695) ===="
8950
8951 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8952         local perm
8953
8954         [ "$RUNAS_ID" = "$UID" ] &&
8955                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8956         [ "$RUNAS_ID" -eq 0 ] &&
8957                 skip_env "RUNAS_ID = 0 -- skipping"
8958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8959         # Check that testing environment is properly set up. Skip if not
8960         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8961                 skip_env "User $RUNAS_ID does not exist - skipping"
8962
8963         touch $DIR/${tfile}-f{g,u}
8964         test_mkdir $DIR/${tfile}-dg
8965         test_mkdir $DIR/${tfile}-du
8966         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8967         chmod g+s $DIR/${tfile}-{f,d}g
8968         chmod u+s $DIR/${tfile}-{f,d}u
8969         for perm in 777 2777 4777; do
8970                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8971                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8972                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8973                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8974         done
8975         true
8976 }
8977 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8978
8979 # bug 3462 - multiple simultaneous MDC requests
8980 test_73() {
8981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8982
8983         test_mkdir $DIR/d73-1
8984         test_mkdir $DIR/d73-2
8985         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8986         pid1=$!
8987
8988         lctl set_param fail_loc=0x80000129
8989         $MULTIOP $DIR/d73-1/f73-2 Oc &
8990         sleep 1
8991         lctl set_param fail_loc=0
8992
8993         $MULTIOP $DIR/d73-2/f73-3 Oc &
8994         pid3=$!
8995
8996         kill -USR1 $pid1
8997         wait $pid1 || return 1
8998
8999         sleep 25
9000
9001         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9002         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9003         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9004
9005         rm -rf $DIR/d73-*
9006 }
9007 run_test 73 "multiple MDC requests (should not deadlock)"
9008
9009 test_74a() { # bug 6149, 6184
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         touch $DIR/f74a
9013         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9014         #
9015         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9016         # will spin in a tight reconnection loop
9017         $LCTL set_param fail_loc=0x8000030e
9018         # get any lock that won't be difficult - lookup works.
9019         ls $DIR/f74a
9020         $LCTL set_param fail_loc=0
9021         rm -f $DIR/f74a
9022         true
9023 }
9024 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9025
9026 test_74b() { # bug 13310
9027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9028
9029         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9030         #
9031         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9032         # will spin in a tight reconnection loop
9033         $LCTL set_param fail_loc=0x8000030e
9034         # get a "difficult" lock
9035         touch $DIR/f74b
9036         $LCTL set_param fail_loc=0
9037         rm -f $DIR/f74b
9038         true
9039 }
9040 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9041
9042 test_74c() {
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044
9045         #define OBD_FAIL_LDLM_NEW_LOCK
9046         $LCTL set_param fail_loc=0x319
9047         touch $DIR/$tfile && error "touch successful"
9048         $LCTL set_param fail_loc=0
9049         true
9050 }
9051 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9052
9053 slab_lic=/sys/kernel/slab/lustre_inode_cache
9054 num_objects() {
9055         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9056         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9057                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9058 }
9059
9060 test_76a() { # Now for b=20433, added originally in b=1443
9061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9062
9063         cancel_lru_locks osc
9064         # there may be some slab objects cached per core
9065         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9066         local before=$(num_objects)
9067         local count=$((512 * cpus))
9068         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9069         local margin=$((count / 10))
9070         if [[ -f $slab_lic/aliases ]]; then
9071                 local aliases=$(cat $slab_lic/aliases)
9072                 (( aliases > 0 )) && margin=$((margin * aliases))
9073         fi
9074
9075         echo "before slab objects: $before"
9076         for i in $(seq $count); do
9077                 touch $DIR/$tfile
9078                 rm -f $DIR/$tfile
9079         done
9080         cancel_lru_locks osc
9081         local after=$(num_objects)
9082         echo "created: $count, after slab objects: $after"
9083         # shared slab counts are not very accurate, allow significant margin
9084         # the main goal is that the cache growth is not permanently > $count
9085         while (( after > before + margin )); do
9086                 sleep 1
9087                 after=$(num_objects)
9088                 wait=$((wait + 1))
9089                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9090                 if (( wait > 60 )); then
9091                         error "inode slab grew from $before+$margin to $after"
9092                 fi
9093         done
9094 }
9095 run_test 76a "confirm clients recycle inodes properly ===="
9096
9097 test_76b() {
9098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9099         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9100
9101         local count=512
9102         local before=$(num_objects)
9103
9104         for i in $(seq $count); do
9105                 mkdir $DIR/$tdir
9106                 rmdir $DIR/$tdir
9107         done
9108
9109         local after=$(num_objects)
9110         local wait=0
9111
9112         while (( after > before )); do
9113                 sleep 1
9114                 after=$(num_objects)
9115                 wait=$((wait + 1))
9116                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9117                 if (( wait > 60 )); then
9118                         error "inode slab grew from $before to $after"
9119                 fi
9120         done
9121
9122         echo "slab objects before: $before, after: $after"
9123 }
9124 run_test 76b "confirm clients recycle directory inodes properly ===="
9125
9126 export ORIG_CSUM=""
9127 set_checksums()
9128 {
9129         # Note: in sptlrpc modes which enable its own bulk checksum, the
9130         # original crc32_le bulk checksum will be automatically disabled,
9131         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9132         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9133         # In this case set_checksums() will not be no-op, because sptlrpc
9134         # bulk checksum will be enabled all through the test.
9135
9136         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9137         lctl set_param -n osc.*.checksums $1
9138         return 0
9139 }
9140
9141 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9142                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9143 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9144                              tr -d [] | head -n1)}
9145 set_checksum_type()
9146 {
9147         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9148         rc=$?
9149         log "set checksum type to $1, rc = $rc"
9150         return $rc
9151 }
9152
9153 get_osc_checksum_type()
9154 {
9155         # arugment 1: OST name, like OST0000
9156         ost=$1
9157         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9158                         sed 's/.*\[\(.*\)\].*/\1/g')
9159         rc=$?
9160         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9161         echo $checksum_type
9162 }
9163
9164 F77_TMP=$TMP/f77-temp
9165 F77SZ=8
9166 setup_f77() {
9167         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9168                 error "error writing to $F77_TMP"
9169 }
9170
9171 test_77a() { # bug 10889
9172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9173         $GSS && skip_env "could not run with gss"
9174
9175         [ ! -f $F77_TMP ] && setup_f77
9176         set_checksums 1
9177         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9178         set_checksums 0
9179         rm -f $DIR/$tfile
9180 }
9181 run_test 77a "normal checksum read/write operation"
9182
9183 test_77b() { # bug 10889
9184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9185         $GSS && skip_env "could not run with gss"
9186
9187         [ ! -f $F77_TMP ] && setup_f77
9188         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9189         $LCTL set_param fail_loc=0x80000409
9190         set_checksums 1
9191
9192         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9193                 error "dd error: $?"
9194         $LCTL set_param fail_loc=0
9195
9196         for algo in $CKSUM_TYPES; do
9197                 cancel_lru_locks osc
9198                 set_checksum_type $algo
9199                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9200                 $LCTL set_param fail_loc=0x80000408
9201                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9202                 $LCTL set_param fail_loc=0
9203         done
9204         set_checksums 0
9205         set_checksum_type $ORIG_CSUM_TYPE
9206         rm -f $DIR/$tfile
9207 }
9208 run_test 77b "checksum error on client write, read"
9209
9210 cleanup_77c() {
9211         trap 0
9212         set_checksums 0
9213         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9214         $check_ost &&
9215                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9216         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9217         $check_ost && [ -n "$ost_file_prefix" ] &&
9218                 do_facet ost1 rm -f ${ost_file_prefix}\*
9219 }
9220
9221 test_77c() {
9222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9223         $GSS && skip_env "could not run with gss"
9224         remote_ost_nodsh && skip "remote OST with nodsh"
9225
9226         local bad1
9227         local osc_file_prefix
9228         local osc_file
9229         local check_ost=false
9230         local ost_file_prefix
9231         local ost_file
9232         local orig_cksum
9233         local dump_cksum
9234         local fid
9235
9236         # ensure corruption will occur on first OSS/OST
9237         $LFS setstripe -i 0 $DIR/$tfile
9238
9239         [ ! -f $F77_TMP ] && setup_f77
9240         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9241                 error "dd write error: $?"
9242         fid=$($LFS path2fid $DIR/$tfile)
9243
9244         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9245         then
9246                 check_ost=true
9247                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9248                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9249         else
9250                 echo "OSS do not support bulk pages dump upon error"
9251         fi
9252
9253         osc_file_prefix=$($LCTL get_param -n debug_path)
9254         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9255
9256         trap cleanup_77c EXIT
9257
9258         set_checksums 1
9259         # enable bulk pages dump upon error on Client
9260         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9261         # enable bulk pages dump upon error on OSS
9262         $check_ost &&
9263                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9264
9265         # flush Client cache to allow next read to reach OSS
9266         cancel_lru_locks osc
9267
9268         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9269         $LCTL set_param fail_loc=0x80000408
9270         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9271         $LCTL set_param fail_loc=0
9272
9273         rm -f $DIR/$tfile
9274
9275         # check cksum dump on Client
9276         osc_file=$(ls ${osc_file_prefix}*)
9277         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9278         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9279         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9280         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9281         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9282                      cksum)
9283         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9284         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9285                 error "dump content does not match on Client"
9286
9287         $check_ost || skip "No need to check cksum dump on OSS"
9288
9289         # check cksum dump on OSS
9290         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9291         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9292         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9293         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9294         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9295                 error "dump content does not match on OSS"
9296
9297         cleanup_77c
9298 }
9299 run_test 77c "checksum error on client read with debug"
9300
9301 test_77d() { # bug 10889
9302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9303         $GSS && skip_env "could not run with gss"
9304
9305         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9306         $LCTL set_param fail_loc=0x80000409
9307         set_checksums 1
9308         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9309                 error "direct write: rc=$?"
9310         $LCTL set_param fail_loc=0
9311         set_checksums 0
9312
9313         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9314         $LCTL set_param fail_loc=0x80000408
9315         set_checksums 1
9316         cancel_lru_locks osc
9317         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9318                 error "direct read: rc=$?"
9319         $LCTL set_param fail_loc=0
9320         set_checksums 0
9321 }
9322 run_test 77d "checksum error on OST direct write, read"
9323
9324 test_77f() { # bug 10889
9325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9326         $GSS && skip_env "could not run with gss"
9327
9328         set_checksums 1
9329         for algo in $CKSUM_TYPES; do
9330                 cancel_lru_locks osc
9331                 set_checksum_type $algo
9332                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9333                 $LCTL set_param fail_loc=0x409
9334                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9335                         error "direct write succeeded"
9336                 $LCTL set_param fail_loc=0
9337         done
9338         set_checksum_type $ORIG_CSUM_TYPE
9339         set_checksums 0
9340 }
9341 run_test 77f "repeat checksum error on write (expect error)"
9342
9343 test_77g() { # bug 10889
9344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9345         $GSS && skip_env "could not run with gss"
9346         remote_ost_nodsh && skip "remote OST with nodsh"
9347
9348         [ ! -f $F77_TMP ] && setup_f77
9349
9350         local file=$DIR/$tfile
9351         stack_trap "rm -f $file" EXIT
9352
9353         $LFS setstripe -c 1 -i 0 $file
9354         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9355         do_facet ost1 lctl set_param fail_loc=0x8000021a
9356         set_checksums 1
9357         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9358                 error "write error: rc=$?"
9359         do_facet ost1 lctl set_param fail_loc=0
9360         set_checksums 0
9361
9362         cancel_lru_locks osc
9363         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9364         do_facet ost1 lctl set_param fail_loc=0x8000021b
9365         set_checksums 1
9366         cmp $F77_TMP $file || error "file compare failed"
9367         do_facet ost1 lctl set_param fail_loc=0
9368         set_checksums 0
9369 }
9370 run_test 77g "checksum error on OST write, read"
9371
9372 test_77k() { # LU-10906
9373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9374         $GSS && skip_env "could not run with gss"
9375
9376         local cksum_param="osc.$FSNAME*.checksums"
9377         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9378         local checksum
9379         local i
9380
9381         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9382         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9383         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9384
9385         for i in 0 1; do
9386                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9387                         error "failed to set checksum=$i on MGS"
9388                 wait_update $HOSTNAME "$get_checksum" $i
9389                 #remount
9390                 echo "remount client, checksum should be $i"
9391                 remount_client $MOUNT || error "failed to remount client"
9392                 checksum=$(eval $get_checksum)
9393                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9394         done
9395         # remove persistent param to avoid races with checksum mountopt below
9396         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9397                 error "failed to delete checksum on MGS"
9398
9399         for opt in "checksum" "nochecksum"; do
9400                 #remount with mount option
9401                 echo "remount client with option $opt, checksum should be $i"
9402                 umount_client $MOUNT || error "failed to umount client"
9403                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9404                         error "failed to mount client with option '$opt'"
9405                 checksum=$(eval $get_checksum)
9406                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9407                 i=$((i - 1))
9408         done
9409
9410         remount_client $MOUNT || error "failed to remount client"
9411 }
9412 run_test 77k "enable/disable checksum correctly"
9413
9414 test_77l() {
9415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9416         $GSS && skip_env "could not run with gss"
9417
9418         set_checksums 1
9419         stack_trap "set_checksums $ORIG_CSUM" EXIT
9420         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9421
9422         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9423
9424         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9425         for algo in $CKSUM_TYPES; do
9426                 set_checksum_type $algo || error "fail to set checksum type $algo"
9427                 osc_algo=$(get_osc_checksum_type OST0000)
9428                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9429
9430                 # no locks, no reqs to let the connection idle
9431                 cancel_lru_locks osc
9432                 lru_resize_disable osc
9433                 wait_osc_import_state client ost1 IDLE
9434
9435                 # ensure ost1 is connected
9436                 stat $DIR/$tfile >/dev/null || error "can't stat"
9437                 wait_osc_import_state client ost1 FULL
9438
9439                 osc_algo=$(get_osc_checksum_type OST0000)
9440                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9441         done
9442         return 0
9443 }
9444 run_test 77l "preferred checksum type is remembered after reconnected"
9445
9446 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9447 rm -f $F77_TMP
9448 unset F77_TMP
9449
9450 cleanup_test_78() {
9451         trap 0
9452         rm -f $DIR/$tfile
9453 }
9454
9455 test_78() { # bug 10901
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457         remote_ost || skip_env "local OST"
9458
9459         NSEQ=5
9460         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9461         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9462         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9463         echo "MemTotal: $MEMTOTAL"
9464
9465         # reserve 256MB of memory for the kernel and other running processes,
9466         # and then take 1/2 of the remaining memory for the read/write buffers.
9467         if [ $MEMTOTAL -gt 512 ] ;then
9468                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9469         else
9470                 # for those poor memory-starved high-end clusters...
9471                 MEMTOTAL=$((MEMTOTAL / 2))
9472         fi
9473         echo "Mem to use for directio: $MEMTOTAL"
9474
9475         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9476         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9477         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9478         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9479                 head -n1)
9480         echo "Smallest OST: $SMALLESTOST"
9481         [[ $SMALLESTOST -lt 10240 ]] &&
9482                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9483
9484         trap cleanup_test_78 EXIT
9485
9486         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9487                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9488
9489         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9490         echo "File size: $F78SIZE"
9491         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9492         for i in $(seq 1 $NSEQ); do
9493                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9494                 echo directIO rdwr round $i of $NSEQ
9495                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9496         done
9497
9498         cleanup_test_78
9499 }
9500 run_test 78 "handle large O_DIRECT writes correctly ============"
9501
9502 test_79() { # bug 12743
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504
9505         wait_delete_completed
9506
9507         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9508         BKFREE=$(calc_osc_kbytes kbytesfree)
9509         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9510
9511         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9512         DFTOTAL=`echo $STRING | cut -d, -f1`
9513         DFUSED=`echo $STRING  | cut -d, -f2`
9514         DFAVAIL=`echo $STRING | cut -d, -f3`
9515         DFFREE=$(($DFTOTAL - $DFUSED))
9516
9517         ALLOWANCE=$((64 * $OSTCOUNT))
9518
9519         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9520            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9521                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9522         fi
9523         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9524            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9525                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9526         fi
9527         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9528            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9529                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9530         fi
9531 }
9532 run_test 79 "df report consistency check ======================="
9533
9534 test_80() { # bug 10718
9535         remote_ost_nodsh && skip "remote OST with nodsh"
9536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9537
9538         # relax strong synchronous semantics for slow backends like ZFS
9539         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9540                 local soc="obdfilter.*.sync_lock_cancel"
9541                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9542
9543                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9544                 if [ -z "$save" ]; then
9545                         soc="obdfilter.*.sync_on_lock_cancel"
9546                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9547                 fi
9548
9549                 if [ "$save" != "never" ]; then
9550                         local hosts=$(comma_list $(osts_nodes))
9551
9552                         do_nodes $hosts $LCTL set_param $soc=never
9553                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9554                 fi
9555         fi
9556
9557         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9558         sync; sleep 1; sync
9559         local before=$(date +%s)
9560         cancel_lru_locks osc
9561         local after=$(date +%s)
9562         local diff=$((after - before))
9563         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9564
9565         rm -f $DIR/$tfile
9566 }
9567 run_test 80 "Page eviction is equally fast at high offsets too"
9568
9569 test_81a() { # LU-456
9570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9571         remote_ost_nodsh && skip "remote OST with nodsh"
9572
9573         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9574         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9575         do_facet ost1 lctl set_param fail_loc=0x80000228
9576
9577         # write should trigger a retry and success
9578         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9579         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9580         RC=$?
9581         if [ $RC -ne 0 ] ; then
9582                 error "write should success, but failed for $RC"
9583         fi
9584 }
9585 run_test 81a "OST should retry write when get -ENOSPC ==============="
9586
9587 test_81b() { # LU-456
9588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9589         remote_ost_nodsh && skip "remote OST with nodsh"
9590
9591         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9592         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9593         do_facet ost1 lctl set_param fail_loc=0x228
9594
9595         # write should retry several times and return -ENOSPC finally
9596         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9597         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9598         RC=$?
9599         ENOSPC=28
9600         if [ $RC -ne $ENOSPC ] ; then
9601                 error "dd should fail for -ENOSPC, but succeed."
9602         fi
9603 }
9604 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9605
9606 test_99() {
9607         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9608
9609         test_mkdir $DIR/$tdir.cvsroot
9610         chown $RUNAS_ID $DIR/$tdir.cvsroot
9611
9612         cd $TMP
9613         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9614
9615         cd /etc/init.d
9616         # some versions of cvs import exit(1) when asked to import links or
9617         # files they can't read.  ignore those files.
9618         local toignore=$(find . -type l -printf '-I %f\n' -o \
9619                          ! -perm /4 -printf '-I %f\n')
9620         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9621                 $tdir.reposname vtag rtag
9622
9623         cd $DIR
9624         test_mkdir $DIR/$tdir.reposname
9625         chown $RUNAS_ID $DIR/$tdir.reposname
9626         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9627
9628         cd $DIR/$tdir.reposname
9629         $RUNAS touch foo99
9630         $RUNAS cvs add -m 'addmsg' foo99
9631         $RUNAS cvs update
9632         $RUNAS cvs commit -m 'nomsg' foo99
9633         rm -fr $DIR/$tdir.cvsroot
9634 }
9635 run_test 99 "cvs strange file/directory operations"
9636
9637 test_100() {
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639         [[ "$NETTYPE" =~ tcp ]] ||
9640                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9641         remote_ost_nodsh && skip "remote OST with nodsh"
9642         remote_mds_nodsh && skip "remote MDS with nodsh"
9643         remote_servers ||
9644                 skip "useless for local single node setup"
9645
9646         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9647                 [ "$PROT" != "tcp" ] && continue
9648                 RPORT=$(echo $REMOTE | cut -d: -f2)
9649                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9650
9651                 rc=0
9652                 LPORT=`echo $LOCAL | cut -d: -f2`
9653                 if [ $LPORT -ge 1024 ]; then
9654                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9655                         netstat -tna
9656                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9657                 fi
9658         done
9659         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9660 }
9661 run_test 100 "check local port using privileged port ==========="
9662
9663 function get_named_value()
9664 {
9665     local tag=$1
9666
9667     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9668 }
9669
9670 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9671                    awk '/^max_cached_mb/ { print $2 }')
9672
9673 cleanup_101a() {
9674         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9675         trap 0
9676 }
9677
9678 test_101a() {
9679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9680
9681         local s
9682         local discard
9683         local nreads=10000
9684         local cache_limit=32
9685
9686         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9687         trap cleanup_101a EXIT
9688         $LCTL set_param -n llite.*.read_ahead_stats=0
9689         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9690
9691         #
9692         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9693         #
9694         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9695         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9696
9697         discard=0
9698         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9699                    get_named_value 'read.but.discarded'); do
9700                         discard=$(($discard + $s))
9701         done
9702         cleanup_101a
9703
9704         $LCTL get_param osc.*-osc*.rpc_stats
9705         $LCTL get_param llite.*.read_ahead_stats
9706
9707         # Discard is generally zero, but sometimes a few random reads line up
9708         # and trigger larger readahead, which is wasted & leads to discards.
9709         if [[ $(($discard)) -gt $nreads ]]; then
9710                 error "too many ($discard) discarded pages"
9711         fi
9712         rm -f $DIR/$tfile || true
9713 }
9714 run_test 101a "check read-ahead for random reads"
9715
9716 setup_test101bc() {
9717         test_mkdir $DIR/$tdir
9718         local ssize=$1
9719         local FILE_LENGTH=$2
9720         STRIPE_OFFSET=0
9721
9722         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9723
9724         local list=$(comma_list $(osts_nodes))
9725         set_osd_param $list '' read_cache_enable 0
9726         set_osd_param $list '' writethrough_cache_enable 0
9727
9728         trap cleanup_test101bc EXIT
9729         # prepare the read-ahead file
9730         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9731
9732         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9733                                 count=$FILE_SIZE_MB 2> /dev/null
9734
9735 }
9736
9737 cleanup_test101bc() {
9738         trap 0
9739         rm -rf $DIR/$tdir
9740         rm -f $DIR/$tfile
9741
9742         local list=$(comma_list $(osts_nodes))
9743         set_osd_param $list '' read_cache_enable 1
9744         set_osd_param $list '' writethrough_cache_enable 1
9745 }
9746
9747 calc_total() {
9748         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9749 }
9750
9751 ra_check_101() {
9752         local READ_SIZE=$1
9753         local STRIPE_SIZE=$2
9754         local FILE_LENGTH=$3
9755         local RA_INC=1048576
9756         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9757         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9758                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9759         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9760                   get_named_value 'read.but.discarded' | calc_total)
9761         if [[ $DISCARD -gt $discard_limit ]]; then
9762                 $LCTL get_param llite.*.read_ahead_stats
9763                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9764         else
9765                 echo "Read-ahead success for size ${READ_SIZE}"
9766         fi
9767 }
9768
9769 test_101b() {
9770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9771         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9772
9773         local STRIPE_SIZE=1048576
9774         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9775
9776         if [ $SLOW == "yes" ]; then
9777                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9778         else
9779                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9780         fi
9781
9782         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9783
9784         # prepare the read-ahead file
9785         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9786         cancel_lru_locks osc
9787         for BIDX in 2 4 8 16 32 64 128 256
9788         do
9789                 local BSIZE=$((BIDX*4096))
9790                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9791                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9792                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9793                 $LCTL set_param -n llite.*.read_ahead_stats=0
9794                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9795                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9796                 cancel_lru_locks osc
9797                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9798         done
9799         cleanup_test101bc
9800         true
9801 }
9802 run_test 101b "check stride-io mode read-ahead ================="
9803
9804 test_101c() {
9805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9806
9807         local STRIPE_SIZE=1048576
9808         local FILE_LENGTH=$((STRIPE_SIZE*100))
9809         local nreads=10000
9810         local rsize=65536
9811         local osc_rpc_stats
9812
9813         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9814
9815         cancel_lru_locks osc
9816         $LCTL set_param osc.*.rpc_stats=0
9817         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9818         $LCTL get_param osc.*.rpc_stats
9819         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9820                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9821                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9822                 local size
9823
9824                 if [ $lines -le 20 ]; then
9825                         echo "continue debug"
9826                         continue
9827                 fi
9828                 for size in 1 2 4 8; do
9829                         local rpc=$(echo "$stats" |
9830                                     awk '($1 == "'$size':") {print $2; exit; }')
9831                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9832                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9833                 done
9834                 echo "$osc_rpc_stats check passed!"
9835         done
9836         cleanup_test101bc
9837         true
9838 }
9839 run_test 101c "check stripe_size aligned read-ahead"
9840
9841 test_101d() {
9842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9843
9844         local file=$DIR/$tfile
9845         local sz_MB=${FILESIZE_101d:-80}
9846         local ra_MB=${READAHEAD_MB:-40}
9847
9848         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9849         [ $free_MB -lt $sz_MB ] &&
9850                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9851
9852         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9853         $LFS setstripe -c -1 $file || error "setstripe failed"
9854
9855         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9856         echo Cancel LRU locks on lustre client to flush the client cache
9857         cancel_lru_locks osc
9858
9859         echo Disable read-ahead
9860         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9861         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9862         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9863         $LCTL get_param -n llite.*.max_read_ahead_mb
9864
9865         echo "Reading the test file $file with read-ahead disabled"
9866         local sz_KB=$((sz_MB * 1024 / 4))
9867         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9868         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9869         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9870                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9871
9872         echo "Cancel LRU locks on lustre client to flush the client cache"
9873         cancel_lru_locks osc
9874         echo Enable read-ahead with ${ra_MB}MB
9875         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9876
9877         echo "Reading the test file $file with read-ahead enabled"
9878         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9879                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9880
9881         echo "read-ahead disabled time read $raOFF"
9882         echo "read-ahead enabled time read $raON"
9883
9884         rm -f $file
9885         wait_delete_completed
9886
9887         # use awk for this check instead of bash because it handles decimals
9888         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9889                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9890 }
9891 run_test 101d "file read with and without read-ahead enabled"
9892
9893 test_101e() {
9894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9895
9896         local file=$DIR/$tfile
9897         local size_KB=500  #KB
9898         local count=100
9899         local bsize=1024
9900
9901         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9902         local need_KB=$((count * size_KB))
9903         [[ $free_KB -le $need_KB ]] &&
9904                 skip_env "Need free space $need_KB, have $free_KB"
9905
9906         echo "Creating $count ${size_KB}K test files"
9907         for ((i = 0; i < $count; i++)); do
9908                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9909         done
9910
9911         echo "Cancel LRU locks on lustre client to flush the client cache"
9912         cancel_lru_locks $OSC
9913
9914         echo "Reset readahead stats"
9915         $LCTL set_param -n llite.*.read_ahead_stats=0
9916
9917         for ((i = 0; i < $count; i++)); do
9918                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9919         done
9920
9921         $LCTL get_param llite.*.max_cached_mb
9922         $LCTL get_param llite.*.read_ahead_stats
9923         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9924                      get_named_value 'misses' | calc_total)
9925
9926         for ((i = 0; i < $count; i++)); do
9927                 rm -rf $file.$i 2>/dev/null
9928         done
9929
9930         #10000 means 20% reads are missing in readahead
9931         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9932 }
9933 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9934
9935 test_101f() {
9936         which iozone || skip_env "no iozone installed"
9937
9938         local old_debug=$($LCTL get_param debug)
9939         old_debug=${old_debug#*=}
9940         $LCTL set_param debug="reada mmap"
9941
9942         # create a test file
9943         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9944
9945         echo Cancel LRU locks on lustre client to flush the client cache
9946         cancel_lru_locks osc
9947
9948         echo Reset readahead stats
9949         $LCTL set_param -n llite.*.read_ahead_stats=0
9950
9951         echo mmap read the file with small block size
9952         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9953                 > /dev/null 2>&1
9954
9955         echo checking missing pages
9956         $LCTL get_param llite.*.read_ahead_stats
9957         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9958                         get_named_value 'misses' | calc_total)
9959
9960         $LCTL set_param debug="$old_debug"
9961         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9962         rm -f $DIR/$tfile
9963 }
9964 run_test 101f "check mmap read performance"
9965
9966 test_101g_brw_size_test() {
9967         local mb=$1
9968         local pages=$((mb * 1048576 / PAGE_SIZE))
9969         local file=$DIR/$tfile
9970
9971         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9972                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9973         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9974                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9975                         return 2
9976         done
9977
9978         stack_trap "rm -f $file" EXIT
9979         $LCTL set_param -n osc.*.rpc_stats=0
9980
9981         # 10 RPCs should be enough for the test
9982         local count=10
9983         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9984                 { error "dd write ${mb} MB blocks failed"; return 3; }
9985         cancel_lru_locks osc
9986         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9987                 { error "dd write ${mb} MB blocks failed"; return 4; }
9988
9989         # calculate number of full-sized read and write RPCs
9990         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9991                 sed -n '/pages per rpc/,/^$/p' |
9992                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9993                 END { print reads,writes }'))
9994         # allow one extra full-sized read RPC for async readahead
9995         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9996                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9997         [[ ${rpcs[1]} == $count ]] ||
9998                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9999 }
10000
10001 test_101g() {
10002         remote_ost_nodsh && skip "remote OST with nodsh"
10003
10004         local rpcs
10005         local osts=$(get_facets OST)
10006         local list=$(comma_list $(osts_nodes))
10007         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10008         local brw_size="obdfilter.*.brw_size"
10009
10010         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10011
10012         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10013
10014         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10015                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10016                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10017            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10018                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10019                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10020
10021                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10022                         suffix="M"
10023
10024                 if [[ $orig_mb -lt 16 ]]; then
10025                         save_lustre_params $osts "$brw_size" > $p
10026                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10027                                 error "set 16MB RPC size failed"
10028
10029                         echo "remount client to enable new RPC size"
10030                         remount_client $MOUNT || error "remount_client failed"
10031                 fi
10032
10033                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10034                 # should be able to set brw_size=12, but no rpc_stats for that
10035                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10036         fi
10037
10038         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10039
10040         if [[ $orig_mb -lt 16 ]]; then
10041                 restore_lustre_params < $p
10042                 remount_client $MOUNT || error "remount_client restore failed"
10043         fi
10044
10045         rm -f $p $DIR/$tfile
10046 }
10047 run_test 101g "Big bulk(4/16 MiB) readahead"
10048
10049 test_101h() {
10050         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10051
10052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10053                 error "dd 70M file failed"
10054         echo Cancel LRU locks on lustre client to flush the client cache
10055         cancel_lru_locks osc
10056
10057         echo "Reset readahead stats"
10058         $LCTL set_param -n llite.*.read_ahead_stats 0
10059
10060         echo "Read 10M of data but cross 64M bundary"
10061         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10062         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10063                      get_named_value 'misses' | calc_total)
10064         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10065         rm -f $p $DIR/$tfile
10066 }
10067 run_test 101h "Readahead should cover current read window"
10068
10069 test_101i() {
10070         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10071                 error "dd 10M file failed"
10072
10073         local max_per_file_mb=$($LCTL get_param -n \
10074                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10075         cancel_lru_locks osc
10076         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10077         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10078                 error "set max_read_ahead_per_file_mb to 1 failed"
10079
10080         echo "Reset readahead stats"
10081         $LCTL set_param llite.*.read_ahead_stats=0
10082
10083         dd if=$DIR/$tfile of=/dev/null bs=2M
10084
10085         $LCTL get_param llite.*.read_ahead_stats
10086         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10087                      awk '/misses/ { print $2 }')
10088         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10089         rm -f $DIR/$tfile
10090 }
10091 run_test 101i "allow current readahead to exceed reservation"
10092
10093 test_101j() {
10094         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10095                 error "setstripe $DIR/$tfile failed"
10096         local file_size=$((1048576 * 16))
10097         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10098         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10099
10100         echo Disable read-ahead
10101         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10102
10103         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10104         for blk in $PAGE_SIZE 1048576 $file_size; do
10105                 cancel_lru_locks osc
10106                 echo "Reset readahead stats"
10107                 $LCTL set_param -n llite.*.read_ahead_stats=0
10108                 local count=$(($file_size / $blk))
10109                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10110                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10111                              get_named_value 'failed.to.fast.read' | calc_total)
10112                 $LCTL get_param -n llite.*.read_ahead_stats
10113                 [ $miss -eq $count ] || error "expected $count got $miss"
10114         done
10115
10116         rm -f $p $DIR/$tfile
10117 }
10118 run_test 101j "A complete read block should be submitted when no RA"
10119
10120 setup_test102() {
10121         test_mkdir $DIR/$tdir
10122         chown $RUNAS_ID $DIR/$tdir
10123         STRIPE_SIZE=65536
10124         STRIPE_OFFSET=1
10125         STRIPE_COUNT=$OSTCOUNT
10126         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10127
10128         trap cleanup_test102 EXIT
10129         cd $DIR
10130         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10131         cd $DIR/$tdir
10132         for num in 1 2 3 4; do
10133                 for count in $(seq 1 $STRIPE_COUNT); do
10134                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10135                                 local size=`expr $STRIPE_SIZE \* $num`
10136                                 local file=file"$num-$idx-$count"
10137                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10138                         done
10139                 done
10140         done
10141
10142         cd $DIR
10143         $1 tar cf $TMP/f102.tar $tdir --xattrs
10144 }
10145
10146 cleanup_test102() {
10147         trap 0
10148         rm -f $TMP/f102.tar
10149         rm -rf $DIR/d0.sanity/d102
10150 }
10151
10152 test_102a() {
10153         [ "$UID" != 0 ] && skip "must run as root"
10154         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10155                 skip_env "must have user_xattr"
10156
10157         [ -z "$(which setfattr 2>/dev/null)" ] &&
10158                 skip_env "could not find setfattr"
10159
10160         local testfile=$DIR/$tfile
10161
10162         touch $testfile
10163         echo "set/get xattr..."
10164         setfattr -n trusted.name1 -v value1 $testfile ||
10165                 error "setfattr -n trusted.name1=value1 $testfile failed"
10166         getfattr -n trusted.name1 $testfile 2> /dev/null |
10167           grep "trusted.name1=.value1" ||
10168                 error "$testfile missing trusted.name1=value1"
10169
10170         setfattr -n user.author1 -v author1 $testfile ||
10171                 error "setfattr -n user.author1=author1 $testfile failed"
10172         getfattr -n user.author1 $testfile 2> /dev/null |
10173           grep "user.author1=.author1" ||
10174                 error "$testfile missing trusted.author1=author1"
10175
10176         echo "listxattr..."
10177         setfattr -n trusted.name2 -v value2 $testfile ||
10178                 error "$testfile unable to set trusted.name2"
10179         setfattr -n trusted.name3 -v value3 $testfile ||
10180                 error "$testfile unable to set trusted.name3"
10181         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10182             grep "trusted.name" | wc -l) -eq 3 ] ||
10183                 error "$testfile missing 3 trusted.name xattrs"
10184
10185         setfattr -n user.author2 -v author2 $testfile ||
10186                 error "$testfile unable to set user.author2"
10187         setfattr -n user.author3 -v author3 $testfile ||
10188                 error "$testfile unable to set user.author3"
10189         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10190             grep "user.author" | wc -l) -eq 3 ] ||
10191                 error "$testfile missing 3 user.author xattrs"
10192
10193         echo "remove xattr..."
10194         setfattr -x trusted.name1 $testfile ||
10195                 error "$testfile error deleting trusted.name1"
10196         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10197                 error "$testfile did not delete trusted.name1 xattr"
10198
10199         setfattr -x user.author1 $testfile ||
10200                 error "$testfile error deleting user.author1"
10201         echo "set lustre special xattr ..."
10202         $LFS setstripe -c1 $testfile
10203         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10204                 awk -F "=" '/trusted.lov/ { print $2 }' )
10205         setfattr -n "trusted.lov" -v $lovea $testfile ||
10206                 error "$testfile doesn't ignore setting trusted.lov again"
10207         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10208                 error "$testfile allow setting invalid trusted.lov"
10209         rm -f $testfile
10210 }
10211 run_test 102a "user xattr test =================================="
10212
10213 check_102b_layout() {
10214         local layout="$*"
10215         local testfile=$DIR/$tfile
10216
10217         echo "test layout '$layout'"
10218         $LFS setstripe $layout $testfile || error "setstripe failed"
10219         $LFS getstripe -y $testfile
10220
10221         echo "get/set/list trusted.lov xattr ..." # b=10930
10222         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10223         [[ "$value" =~ "trusted.lov" ]] ||
10224                 error "can't get trusted.lov from $testfile"
10225         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10226                 error "getstripe failed"
10227
10228         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10229
10230         value=$(cut -d= -f2 <<<$value)
10231         # LU-13168: truncated xattr should fail if short lov_user_md header
10232         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10233                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10234         for len in $lens; do
10235                 echo "setfattr $len $testfile.2"
10236                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10237                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10238         done
10239         local stripe_size=$($LFS getstripe -S $testfile.2)
10240         local stripe_count=$($LFS getstripe -c $testfile.2)
10241         [[ $stripe_size -eq 65536 ]] ||
10242                 error "stripe size $stripe_size != 65536"
10243         [[ $stripe_count -eq $stripe_count_orig ]] ||
10244                 error "stripe count $stripe_count != $stripe_count_orig"
10245         rm $testfile $testfile.2
10246 }
10247
10248 test_102b() {
10249         [ -z "$(which setfattr 2>/dev/null)" ] &&
10250                 skip_env "could not find setfattr"
10251         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10252
10253         # check plain layout
10254         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10255
10256         # and also check composite layout
10257         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10258
10259 }
10260 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10261
10262 test_102c() {
10263         [ -z "$(which setfattr 2>/dev/null)" ] &&
10264                 skip_env "could not find setfattr"
10265         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10266
10267         # b10930: get/set/list lustre.lov xattr
10268         echo "get/set/list lustre.lov xattr ..."
10269         test_mkdir $DIR/$tdir
10270         chown $RUNAS_ID $DIR/$tdir
10271         local testfile=$DIR/$tdir/$tfile
10272         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10273                 error "setstripe failed"
10274         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10275                 error "getstripe failed"
10276         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10277         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10278
10279         local testfile2=${testfile}2
10280         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10281                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10282
10283         $RUNAS $MCREATE $testfile2
10284         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10285         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10286         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10287         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10288         [ $stripe_count -eq $STRIPECOUNT ] ||
10289                 error "stripe count $stripe_count != $STRIPECOUNT"
10290 }
10291 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10292
10293 compare_stripe_info1() {
10294         local stripe_index_all_zero=true
10295
10296         for num in 1 2 3 4; do
10297                 for count in $(seq 1 $STRIPE_COUNT); do
10298                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10299                                 local size=$((STRIPE_SIZE * num))
10300                                 local file=file"$num-$offset-$count"
10301                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10302                                 [[ $stripe_size -ne $size ]] &&
10303                                     error "$file: size $stripe_size != $size"
10304                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10305                                 # allow fewer stripes to be created, ORI-601
10306                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10307                                     error "$file: count $stripe_count != $count"
10308                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10309                                 [[ $stripe_index -ne 0 ]] &&
10310                                         stripe_index_all_zero=false
10311                         done
10312                 done
10313         done
10314         $stripe_index_all_zero &&
10315                 error "all files are being extracted starting from OST index 0"
10316         return 0
10317 }
10318
10319 have_xattrs_include() {
10320         tar --help | grep -q xattrs-include &&
10321                 echo --xattrs-include="lustre.*"
10322 }
10323
10324 test_102d() {
10325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10326         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10327
10328         XINC=$(have_xattrs_include)
10329         setup_test102
10330         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10331         cd $DIR/$tdir/$tdir
10332         compare_stripe_info1
10333 }
10334 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10335
10336 test_102f() {
10337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10338         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10339
10340         XINC=$(have_xattrs_include)
10341         setup_test102
10342         test_mkdir $DIR/$tdir.restore
10343         cd $DIR
10344         tar cf - --xattrs $tdir | tar xf - \
10345                 -C $DIR/$tdir.restore --xattrs $XINC
10346         cd $DIR/$tdir.restore/$tdir
10347         compare_stripe_info1
10348 }
10349 run_test 102f "tar copy files, not keep osts"
10350
10351 grow_xattr() {
10352         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10353                 skip "must have user_xattr"
10354         [ -z "$(which setfattr 2>/dev/null)" ] &&
10355                 skip_env "could not find setfattr"
10356         [ -z "$(which getfattr 2>/dev/null)" ] &&
10357                 skip_env "could not find getfattr"
10358
10359         local xsize=${1:-1024}  # in bytes
10360         local file=$DIR/$tfile
10361         local value="$(generate_string $xsize)"
10362         local xbig=trusted.big
10363         local toobig=$2
10364
10365         touch $file
10366         log "save $xbig on $file"
10367         if [ -z "$toobig" ]
10368         then
10369                 setfattr -n $xbig -v $value $file ||
10370                         error "saving $xbig on $file failed"
10371         else
10372                 setfattr -n $xbig -v $value $file &&
10373                         error "saving $xbig on $file succeeded"
10374                 return 0
10375         fi
10376
10377         local orig=$(get_xattr_value $xbig $file)
10378         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10379
10380         local xsml=trusted.sml
10381         log "save $xsml on $file"
10382         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10383
10384         local new=$(get_xattr_value $xbig $file)
10385         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10386
10387         log "grow $xsml on $file"
10388         setfattr -n $xsml -v "$value" $file ||
10389                 error "growing $xsml on $file failed"
10390
10391         new=$(get_xattr_value $xbig $file)
10392         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10393         log "$xbig still valid after growing $xsml"
10394
10395         rm -f $file
10396 }
10397
10398 test_102h() { # bug 15777
10399         grow_xattr 1024
10400 }
10401 run_test 102h "grow xattr from inside inode to external block"
10402
10403 test_102ha() {
10404         large_xattr_enabled || skip_env "ea_inode feature disabled"
10405
10406         echo "setting xattr of max xattr size: $(max_xattr_size)"
10407         grow_xattr $(max_xattr_size)
10408
10409         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10410         echo "This should fail:"
10411         grow_xattr $(($(max_xattr_size) + 10)) 1
10412 }
10413 run_test 102ha "grow xattr from inside inode to external inode"
10414
10415 test_102i() { # bug 17038
10416         [ -z "$(which getfattr 2>/dev/null)" ] &&
10417                 skip "could not find getfattr"
10418
10419         touch $DIR/$tfile
10420         ln -s $DIR/$tfile $DIR/${tfile}link
10421         getfattr -n trusted.lov $DIR/$tfile ||
10422                 error "lgetxattr on $DIR/$tfile failed"
10423         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10424                 grep -i "no such attr" ||
10425                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10426         rm -f $DIR/$tfile $DIR/${tfile}link
10427 }
10428 run_test 102i "lgetxattr test on symbolic link ============"
10429
10430 test_102j() {
10431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10432         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10433
10434         XINC=$(have_xattrs_include)
10435         setup_test102 "$RUNAS"
10436         chown $RUNAS_ID $DIR/$tdir
10437         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10438         cd $DIR/$tdir/$tdir
10439         compare_stripe_info1 "$RUNAS"
10440 }
10441 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10442
10443 test_102k() {
10444         [ -z "$(which setfattr 2>/dev/null)" ] &&
10445                 skip "could not find setfattr"
10446
10447         touch $DIR/$tfile
10448         # b22187 just check that does not crash for regular file.
10449         setfattr -n trusted.lov $DIR/$tfile
10450         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10451         local test_kdir=$DIR/$tdir
10452         test_mkdir $test_kdir
10453         local default_size=$($LFS getstripe -S $test_kdir)
10454         local default_count=$($LFS getstripe -c $test_kdir)
10455         local default_offset=$($LFS getstripe -i $test_kdir)
10456         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10457                 error 'dir setstripe failed'
10458         setfattr -n trusted.lov $test_kdir
10459         local stripe_size=$($LFS getstripe -S $test_kdir)
10460         local stripe_count=$($LFS getstripe -c $test_kdir)
10461         local stripe_offset=$($LFS getstripe -i $test_kdir)
10462         [ $stripe_size -eq $default_size ] ||
10463                 error "stripe size $stripe_size != $default_size"
10464         [ $stripe_count -eq $default_count ] ||
10465                 error "stripe count $stripe_count != $default_count"
10466         [ $stripe_offset -eq $default_offset ] ||
10467                 error "stripe offset $stripe_offset != $default_offset"
10468         rm -rf $DIR/$tfile $test_kdir
10469 }
10470 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10471
10472 test_102l() {
10473         [ -z "$(which getfattr 2>/dev/null)" ] &&
10474                 skip "could not find getfattr"
10475
10476         # LU-532 trusted. xattr is invisible to non-root
10477         local testfile=$DIR/$tfile
10478
10479         touch $testfile
10480
10481         echo "listxattr as user..."
10482         chown $RUNAS_ID $testfile
10483         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10484             grep -q "trusted" &&
10485                 error "$testfile trusted xattrs are user visible"
10486
10487         return 0;
10488 }
10489 run_test 102l "listxattr size test =================================="
10490
10491 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10492         local path=$DIR/$tfile
10493         touch $path
10494
10495         listxattr_size_check $path || error "listattr_size_check $path failed"
10496 }
10497 run_test 102m "Ensure listxattr fails on small bufffer ========"
10498
10499 cleanup_test102
10500
10501 getxattr() { # getxattr path name
10502         # Return the base64 encoding of the value of xattr name on path.
10503         local path=$1
10504         local name=$2
10505
10506         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10507         # file: $path
10508         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10509         #
10510         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10511
10512         getfattr --absolute-names --encoding=base64 --name=$name $path |
10513                 awk -F= -v name=$name '$1 == name {
10514                         print substr($0, index($0, "=") + 1);
10515         }'
10516 }
10517
10518 test_102n() { # LU-4101 mdt: protect internal xattrs
10519         [ -z "$(which setfattr 2>/dev/null)" ] &&
10520                 skip "could not find setfattr"
10521         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10522         then
10523                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10524         fi
10525
10526         local file0=$DIR/$tfile.0
10527         local file1=$DIR/$tfile.1
10528         local xattr0=$TMP/$tfile.0
10529         local xattr1=$TMP/$tfile.1
10530         local namelist="lov lma lmv link fid version som hsm"
10531         local name
10532         local value
10533
10534         rm -rf $file0 $file1 $xattr0 $xattr1
10535         touch $file0 $file1
10536
10537         # Get 'before' xattrs of $file1.
10538         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10539
10540         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10541                 namelist+=" lfsck_namespace"
10542         for name in $namelist; do
10543                 # Try to copy xattr from $file0 to $file1.
10544                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10545
10546                 setfattr --name=trusted.$name --value="$value" $file1 ||
10547                         error "setxattr 'trusted.$name' failed"
10548
10549                 # Try to set a garbage xattr.
10550                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10551
10552                 if [[ x$name == "xlov" ]]; then
10553                         setfattr --name=trusted.lov --value="$value" $file1 &&
10554                         error "setxattr invalid 'trusted.lov' success"
10555                 else
10556                         setfattr --name=trusted.$name --value="$value" $file1 ||
10557                                 error "setxattr invalid 'trusted.$name' failed"
10558                 fi
10559
10560                 # Try to remove the xattr from $file1. We don't care if this
10561                 # appears to succeed or fail, we just don't want there to be
10562                 # any changes or crashes.
10563                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10564         done
10565
10566         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10567         then
10568                 name="lfsck_ns"
10569                 # Try to copy xattr from $file0 to $file1.
10570                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10571
10572                 setfattr --name=trusted.$name --value="$value" $file1 ||
10573                         error "setxattr 'trusted.$name' failed"
10574
10575                 # Try to set a garbage xattr.
10576                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10577
10578                 setfattr --name=trusted.$name --value="$value" $file1 ||
10579                         error "setxattr 'trusted.$name' failed"
10580
10581                 # Try to remove the xattr from $file1. We don't care if this
10582                 # appears to succeed or fail, we just don't want there to be
10583                 # any changes or crashes.
10584                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10585         fi
10586
10587         # Get 'after' xattrs of file1.
10588         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10589
10590         if ! diff $xattr0 $xattr1; then
10591                 error "before and after xattrs of '$file1' differ"
10592         fi
10593
10594         rm -rf $file0 $file1 $xattr0 $xattr1
10595
10596         return 0
10597 }
10598 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10599
10600 test_102p() { # LU-4703 setxattr did not check ownership
10601         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10602                 skip "MDS needs to be at least 2.5.56"
10603
10604         local testfile=$DIR/$tfile
10605
10606         touch $testfile
10607
10608         echo "setfacl as user..."
10609         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10610         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10611
10612         echo "setfattr as user..."
10613         setfacl -m "u:$RUNAS_ID:---" $testfile
10614         $RUNAS setfattr -x system.posix_acl_access $testfile
10615         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10616 }
10617 run_test 102p "check setxattr(2) correctly fails without permission"
10618
10619 test_102q() {
10620         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10621                 skip "MDS needs to be at least 2.6.92"
10622
10623         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10624 }
10625 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10626
10627 test_102r() {
10628         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10629                 skip "MDS needs to be at least 2.6.93"
10630
10631         touch $DIR/$tfile || error "touch"
10632         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10633         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10634         rm $DIR/$tfile || error "rm"
10635
10636         #normal directory
10637         mkdir -p $DIR/$tdir || error "mkdir"
10638         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10639         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10640         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10641                 error "$testfile error deleting user.author1"
10642         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10643                 grep "user.$(basename $tdir)" &&
10644                 error "$tdir did not delete user.$(basename $tdir)"
10645         rmdir $DIR/$tdir || error "rmdir"
10646
10647         #striped directory
10648         test_mkdir $DIR/$tdir
10649         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10650         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10651         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10652                 error "$testfile error deleting user.author1"
10653         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10654                 grep "user.$(basename $tdir)" &&
10655                 error "$tdir did not delete user.$(basename $tdir)"
10656         rmdir $DIR/$tdir || error "rm striped dir"
10657 }
10658 run_test 102r "set EAs with empty values"
10659
10660 test_102s() {
10661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10662                 skip "MDS needs to be at least 2.11.52"
10663
10664         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10665
10666         save_lustre_params client "llite.*.xattr_cache" > $save
10667
10668         for cache in 0 1; do
10669                 lctl set_param llite.*.xattr_cache=$cache
10670
10671                 rm -f $DIR/$tfile
10672                 touch $DIR/$tfile || error "touch"
10673                 for prefix in lustre security system trusted user; do
10674                         # Note getxattr() may fail with 'Operation not
10675                         # supported' or 'No such attribute' depending
10676                         # on prefix and cache.
10677                         getfattr -n $prefix.n102s $DIR/$tfile &&
10678                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10679                 done
10680         done
10681
10682         restore_lustre_params < $save
10683 }
10684 run_test 102s "getting nonexistent xattrs should fail"
10685
10686 test_102t() {
10687         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10688                 skip "MDS needs to be at least 2.11.52"
10689
10690         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10691
10692         save_lustre_params client "llite.*.xattr_cache" > $save
10693
10694         for cache in 0 1; do
10695                 lctl set_param llite.*.xattr_cache=$cache
10696
10697                 for buf_size in 0 256; do
10698                         rm -f $DIR/$tfile
10699                         touch $DIR/$tfile || error "touch"
10700                         setfattr -n user.multiop $DIR/$tfile
10701                         $MULTIOP $DIR/$tfile oa$buf_size ||
10702                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10703                 done
10704         done
10705
10706         restore_lustre_params < $save
10707 }
10708 run_test 102t "zero length xattr values handled correctly"
10709
10710 run_acl_subtest()
10711 {
10712     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10713     return $?
10714 }
10715
10716 test_103a() {
10717         [ "$UID" != 0 ] && skip "must run as root"
10718         $GSS && skip_env "could not run under gss"
10719         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10720                 skip_env "must have acl enabled"
10721         [ -z "$(which setfacl 2>/dev/null)" ] &&
10722                 skip_env "could not find setfacl"
10723         remote_mds_nodsh && skip "remote MDS with nodsh"
10724
10725         gpasswd -a daemon bin                           # LU-5641
10726         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10727
10728         declare -a identity_old
10729
10730         for num in $(seq $MDSCOUNT); do
10731                 switch_identity $num true || identity_old[$num]=$?
10732         done
10733
10734         SAVE_UMASK=$(umask)
10735         umask 0022
10736         mkdir -p $DIR/$tdir
10737         cd $DIR/$tdir
10738
10739         echo "performing cp ..."
10740         run_acl_subtest cp || error "run_acl_subtest cp failed"
10741         echo "performing getfacl-noacl..."
10742         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10743         echo "performing misc..."
10744         run_acl_subtest misc || error  "misc test failed"
10745         echo "performing permissions..."
10746         run_acl_subtest permissions || error "permissions failed"
10747         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10748         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10749                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10750                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10751         then
10752                 echo "performing permissions xattr..."
10753                 run_acl_subtest permissions_xattr ||
10754                         error "permissions_xattr failed"
10755         fi
10756         echo "performing setfacl..."
10757         run_acl_subtest setfacl || error  "setfacl test failed"
10758
10759         # inheritance test got from HP
10760         echo "performing inheritance..."
10761         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10762         chmod +x make-tree || error "chmod +x failed"
10763         run_acl_subtest inheritance || error "inheritance test failed"
10764         rm -f make-tree
10765
10766         echo "LU-974 ignore umask when acl is enabled..."
10767         run_acl_subtest 974 || error "LU-974 umask test failed"
10768         if [ $MDSCOUNT -ge 2 ]; then
10769                 run_acl_subtest 974_remote ||
10770                         error "LU-974 umask test failed under remote dir"
10771         fi
10772
10773         echo "LU-2561 newly created file is same size as directory..."
10774         if [ "$mds1_FSTYPE" != "zfs" ]; then
10775                 run_acl_subtest 2561 || error "LU-2561 test failed"
10776         else
10777                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10778         fi
10779
10780         run_acl_subtest 4924 || error "LU-4924 test failed"
10781
10782         cd $SAVE_PWD
10783         umask $SAVE_UMASK
10784
10785         for num in $(seq $MDSCOUNT); do
10786                 if [ "${identity_old[$num]}" = 1 ]; then
10787                         switch_identity $num false || identity_old[$num]=$?
10788                 fi
10789         done
10790 }
10791 run_test 103a "acl test"
10792
10793 test_103b() {
10794         declare -a pids
10795         local U
10796
10797         for U in {0..511}; do
10798                 {
10799                 local O=$(printf "%04o" $U)
10800
10801                 umask $(printf "%04o" $((511 ^ $O)))
10802                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10803                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10804
10805                 (( $S == ($O & 0666) )) ||
10806                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10807
10808                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10809                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10810                 (( $S == ($O & 0666) )) ||
10811                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10812
10813                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10814                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10815                 (( $S == ($O & 0666) )) ||
10816                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10817                 rm -f $DIR/$tfile.[smp]$0
10818                 } &
10819                 local pid=$!
10820
10821                 # limit the concurrently running threads to 64. LU-11878
10822                 local idx=$((U % 64))
10823                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10824                 pids[idx]=$pid
10825         done
10826         wait
10827 }
10828 run_test 103b "umask lfs setstripe"
10829
10830 test_103c() {
10831         mkdir -p $DIR/$tdir
10832         cp -rp $DIR/$tdir $DIR/$tdir.bak
10833
10834         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10835                 error "$DIR/$tdir shouldn't contain default ACL"
10836         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10837                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10838         true
10839 }
10840 run_test 103c "'cp -rp' won't set empty acl"
10841
10842 test_103e() {
10843         local numacl
10844         local fileacl
10845         local saved_debug=$($LCTL get_param -n debug)
10846
10847         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10848                 skip "MDS needs to be at least 2.14.0"
10849
10850         large_xattr_enabled || skip_env "ea_inode feature disabled"
10851
10852         mkdir -p $DIR/$tdir
10853         # add big LOV EA to cause reply buffer overflow earlier
10854         $LFS setstripe -C 1000 $DIR/$tdir
10855         lctl set_param mdc.*-mdc*.stats=clear
10856
10857         $LCTL set_param debug=0
10858         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10859         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10860
10861         # add a large number of default ACLs (expect 8000+ for 2.13+)
10862         for U in {2..7000}; do
10863                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10864                         error "Able to add just $U default ACLs"
10865         done
10866         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10867         echo "$numacl default ACLs created"
10868
10869         stat $DIR/$tdir || error "Cannot stat directory"
10870         # check file creation
10871         touch $DIR/$tdir/$tfile ||
10872                 error "failed to create $tfile with $numacl default ACLs"
10873         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10874         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10875         echo "$fileacl ACLs were inherited"
10876         (( $fileacl == $numacl )) ||
10877                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10878         # check that new ACLs creation adds new ACLs to inherited ACLs
10879         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10880                 error "Cannot set new ACL"
10881         numacl=$((numacl + 1))
10882         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10883         (( $fileacl == $numacl )) ||
10884                 error "failed to add new ACL: $fileacl != $numacl as expected"
10885         # adds more ACLs to a file to reach their maximum at 8000+
10886         numacl=0
10887         for U in {20000..25000}; do
10888                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10889                 numacl=$((numacl + 1))
10890         done
10891         echo "Added $numacl more ACLs to the file"
10892         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10893         echo "Total $fileacl ACLs in file"
10894         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10895         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10896         rmdir $DIR/$tdir || error "Cannot remove directory"
10897 }
10898 run_test 103e "inheritance of big amount of default ACLs"
10899
10900 test_103f() {
10901         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
10902                 skip "MDS needs to be at least 2.14.51"
10903
10904         large_xattr_enabled || skip_env "ea_inode feature disabled"
10905
10906         # enable changelog to consume more internal MDD buffers
10907         changelog_register
10908
10909         mkdir -p $DIR/$tdir
10910         # add big LOV EA
10911         $LFS setstripe -C 1000 $DIR/$tdir
10912         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
10913         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
10914         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
10915         rmdir $DIR/$tdir || error "Cannot remove directory"
10916 }
10917 run_test 103f "changelog doesn't interfere with default ACLs buffers"
10918
10919 test_104a() {
10920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10921
10922         touch $DIR/$tfile
10923         lfs df || error "lfs df failed"
10924         lfs df -ih || error "lfs df -ih failed"
10925         lfs df -h $DIR || error "lfs df -h $DIR failed"
10926         lfs df -i $DIR || error "lfs df -i $DIR failed"
10927         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10928         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10929
10930         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10931         lctl --device %$OSC deactivate
10932         lfs df || error "lfs df with deactivated OSC failed"
10933         lctl --device %$OSC activate
10934         # wait the osc back to normal
10935         wait_osc_import_ready client ost
10936
10937         lfs df || error "lfs df with reactivated OSC failed"
10938         rm -f $DIR/$tfile
10939 }
10940 run_test 104a "lfs df [-ih] [path] test ========================="
10941
10942 test_104b() {
10943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10944         [ $RUNAS_ID -eq $UID ] &&
10945                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10946
10947         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10948                         grep "Permission denied" | wc -l)))
10949         if [ $denied_cnt -ne 0 ]; then
10950                 error "lfs check servers test failed"
10951         fi
10952 }
10953 run_test 104b "$RUNAS lfs check servers test ===================="
10954
10955 #
10956 # Verify $1 is within range of $2.
10957 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
10958 # $1 is <= 2% of $2. Else Fail.
10959 #
10960 value_in_range() {
10961         # Strip all units (M, G, T)
10962         actual=$(echo $1 | tr -d A-Z)
10963         expect=$(echo $2 | tr -d A-Z)
10964
10965         expect_lo=$(($expect * 98 / 100)) # 2% below
10966         expect_hi=$(($expect * 102 / 100)) # 2% above
10967
10968         # permit 2% drift above and below
10969         (( $actual >= $expect_lo && $actual <= $expect_hi ))
10970 }
10971
10972 test_104c() {
10973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10974         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
10975
10976         local ost_param="osd-zfs.$FSNAME-OST0000."
10977         local mdt_param="osd-zfs.$FSNAME-MDT0000."
10978         local ofacets=$(get_facets OST)
10979         local mfacets=$(get_facets MDS)
10980         local saved_ost_blocks=
10981         local saved_mdt_blocks=
10982
10983         echo "Before recordsize change"
10984         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
10985         df=($(df -h | grep "/mnt/lustre"$))
10986
10987         # For checking.
10988         echo "lfs output : ${lfs_df[*]}"
10989         echo "df  output : ${df[*]}"
10990
10991         for facet in ${ofacets//,/ }; do
10992                 if [ -z $saved_ost_blocks ]; then
10993                         saved_ost_blocks=$(do_facet $facet \
10994                                 lctl get_param -n $ost_param.blocksize)
10995                         echo "OST Blocksize: $saved_ost_blocks"
10996                 fi
10997                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
10998                 do_facet $facet zfs set recordsize=32768 $ost
10999         done
11000
11001         # BS too small. Sufficient for functional testing.
11002         for facet in ${mfacets//,/ }; do
11003                 if [ -z $saved_mdt_blocks ]; then
11004                         saved_mdt_blocks=$(do_facet $facet \
11005                                 lctl get_param -n $mdt_param.blocksize)
11006                         echo "MDT Blocksize: $saved_mdt_blocks"
11007                 fi
11008                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11009                 do_facet $facet zfs set recordsize=32768 $mdt
11010         done
11011
11012         # Give new values chance to reflect change
11013         sleep 2
11014
11015         echo "After recordsize change"
11016         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11017         df_after=($(df -h | grep "/mnt/lustre"$))
11018
11019         # For checking.
11020         echo "lfs output : ${lfs_df_after[*]}"
11021         echo "df  output : ${df_after[*]}"
11022
11023         # Verify lfs df
11024         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11025                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11026         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11027                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11028         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11029                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11030
11031         # Verify df
11032         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11033                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11034         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11035                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11036         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11037                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11038
11039         # Restore MDT recordize back to original
11040         for facet in ${mfacets//,/ }; do
11041                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11042                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11043         done
11044
11045         # Restore OST recordize back to original
11046         for facet in ${ofacets//,/ }; do
11047                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11048                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11049         done
11050
11051         return 0
11052 }
11053 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11054
11055 test_105a() {
11056         # doesn't work on 2.4 kernels
11057         touch $DIR/$tfile
11058         if $(flock_is_enabled); then
11059                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11060         else
11061                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11062         fi
11063         rm -f $DIR/$tfile
11064 }
11065 run_test 105a "flock when mounted without -o flock test ========"
11066
11067 test_105b() {
11068         touch $DIR/$tfile
11069         if $(flock_is_enabled); then
11070                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11071         else
11072                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11073         fi
11074         rm -f $DIR/$tfile
11075 }
11076 run_test 105b "fcntl when mounted without -o flock test ========"
11077
11078 test_105c() {
11079         touch $DIR/$tfile
11080         if $(flock_is_enabled); then
11081                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11082         else
11083                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11084         fi
11085         rm -f $DIR/$tfile
11086 }
11087 run_test 105c "lockf when mounted without -o flock test"
11088
11089 test_105d() { # bug 15924
11090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11091
11092         test_mkdir $DIR/$tdir
11093         flock_is_enabled || skip_env "mount w/o flock enabled"
11094         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11095         $LCTL set_param fail_loc=0x80000315
11096         flocks_test 2 $DIR/$tdir
11097 }
11098 run_test 105d "flock race (should not freeze) ========"
11099
11100 test_105e() { # bug 22660 && 22040
11101         flock_is_enabled || skip_env "mount w/o flock enabled"
11102
11103         touch $DIR/$tfile
11104         flocks_test 3 $DIR/$tfile
11105 }
11106 run_test 105e "Two conflicting flocks from same process"
11107
11108 test_106() { #bug 10921
11109         test_mkdir $DIR/$tdir
11110         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11111         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11112 }
11113 run_test 106 "attempt exec of dir followed by chown of that dir"
11114
11115 test_107() {
11116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11117
11118         CDIR=`pwd`
11119         local file=core
11120
11121         cd $DIR
11122         rm -f $file
11123
11124         local save_pattern=$(sysctl -n kernel.core_pattern)
11125         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11126         sysctl -w kernel.core_pattern=$file
11127         sysctl -w kernel.core_uses_pid=0
11128
11129         ulimit -c unlimited
11130         sleep 60 &
11131         SLEEPPID=$!
11132
11133         sleep 1
11134
11135         kill -s 11 $SLEEPPID
11136         wait $SLEEPPID
11137         if [ -e $file ]; then
11138                 size=`stat -c%s $file`
11139                 [ $size -eq 0 ] && error "Fail to create core file $file"
11140         else
11141                 error "Fail to create core file $file"
11142         fi
11143         rm -f $file
11144         sysctl -w kernel.core_pattern=$save_pattern
11145         sysctl -w kernel.core_uses_pid=$save_uses_pid
11146         cd $CDIR
11147 }
11148 run_test 107 "Coredump on SIG"
11149
11150 test_110() {
11151         test_mkdir $DIR/$tdir
11152         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11153         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11154                 error "mkdir with 256 char should fail, but did not"
11155         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11156                 error "create with 255 char failed"
11157         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11158                 error "create with 256 char should fail, but did not"
11159
11160         ls -l $DIR/$tdir
11161         rm -rf $DIR/$tdir
11162 }
11163 run_test 110 "filename length checking"
11164
11165 #
11166 # Purpose: To verify dynamic thread (OSS) creation.
11167 #
11168 test_115() {
11169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11170         remote_ost_nodsh && skip "remote OST with nodsh"
11171
11172         # Lustre does not stop service threads once they are started.
11173         # Reset number of running threads to default.
11174         stopall
11175         setupall
11176
11177         local OSTIO_pre
11178         local save_params="$TMP/sanity-$TESTNAME.parameters"
11179
11180         # Get ll_ost_io count before I/O
11181         OSTIO_pre=$(do_facet ost1 \
11182                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11183         # Exit if lustre is not running (ll_ost_io not running).
11184         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11185
11186         echo "Starting with $OSTIO_pre threads"
11187         local thread_max=$((OSTIO_pre * 2))
11188         local rpc_in_flight=$((thread_max * 2))
11189         # Number of I/O Process proposed to be started.
11190         local nfiles
11191         local facets=$(get_facets OST)
11192
11193         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11194         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11195
11196         # Set in_flight to $rpc_in_flight
11197         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11198                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11199         nfiles=${rpc_in_flight}
11200         # Set ost thread_max to $thread_max
11201         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11202
11203         # 5 Minutes should be sufficient for max number of OSS
11204         # threads(thread_max) to be created.
11205         local timeout=300
11206
11207         # Start I/O.
11208         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11209         test_mkdir $DIR/$tdir
11210         for i in $(seq $nfiles); do
11211                 local file=$DIR/$tdir/${tfile}-$i
11212                 $LFS setstripe -c -1 -i 0 $file
11213                 ($WTL $file $timeout)&
11214         done
11215
11216         # I/O Started - Wait for thread_started to reach thread_max or report
11217         # error if thread_started is more than thread_max.
11218         echo "Waiting for thread_started to reach thread_max"
11219         local thread_started=0
11220         local end_time=$((SECONDS + timeout))
11221
11222         while [ $SECONDS -le $end_time ] ; do
11223                 echo -n "."
11224                 # Get ost i/o thread_started count.
11225                 thread_started=$(do_facet ost1 \
11226                         "$LCTL get_param \
11227                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11228                 # Break out if thread_started is equal/greater than thread_max
11229                 if [[ $thread_started -ge $thread_max ]]; then
11230                         echo ll_ost_io thread_started $thread_started, \
11231                                 equal/greater than thread_max $thread_max
11232                         break
11233                 fi
11234                 sleep 1
11235         done
11236
11237         # Cleanup - We have the numbers, Kill i/o jobs if running.
11238         jobcount=($(jobs -p))
11239         for i in $(seq 0 $((${#jobcount[@]}-1)))
11240         do
11241                 kill -9 ${jobcount[$i]}
11242                 if [ $? -ne 0 ] ; then
11243                         echo Warning: \
11244                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11245                 fi
11246         done
11247
11248         # Cleanup files left by WTL binary.
11249         for i in $(seq $nfiles); do
11250                 local file=$DIR/$tdir/${tfile}-$i
11251                 rm -rf $file
11252                 if [ $? -ne 0 ] ; then
11253                         echo "Warning: Failed to delete file $file"
11254                 fi
11255         done
11256
11257         restore_lustre_params <$save_params
11258         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11259
11260         # Error out if no new thread has started or Thread started is greater
11261         # than thread max.
11262         if [[ $thread_started -le $OSTIO_pre ||
11263                         $thread_started -gt $thread_max ]]; then
11264                 error "ll_ost_io: thread_started $thread_started" \
11265                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11266                       "No new thread started or thread started greater " \
11267                       "than thread_max."
11268         fi
11269 }
11270 run_test 115 "verify dynamic thread creation===================="
11271
11272 free_min_max () {
11273         wait_delete_completed
11274         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11275         echo "OST kbytes available: ${AVAIL[@]}"
11276         MAXV=${AVAIL[0]}
11277         MAXI=0
11278         MINV=${AVAIL[0]}
11279         MINI=0
11280         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11281                 #echo OST $i: ${AVAIL[i]}kb
11282                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11283                         MAXV=${AVAIL[i]}
11284                         MAXI=$i
11285                 fi
11286                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11287                         MINV=${AVAIL[i]}
11288                         MINI=$i
11289                 fi
11290         done
11291         echo "Min free space: OST $MINI: $MINV"
11292         echo "Max free space: OST $MAXI: $MAXV"
11293 }
11294
11295 test_116a() { # was previously test_116()
11296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11297         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11298         remote_mds_nodsh && skip "remote MDS with nodsh"
11299
11300         echo -n "Free space priority "
11301         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11302                 head -n1
11303         declare -a AVAIL
11304         free_min_max
11305
11306         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11307         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11308         trap simple_cleanup_common EXIT
11309
11310         # Check if we need to generate uneven OSTs
11311         test_mkdir -p $DIR/$tdir/OST${MINI}
11312         local FILL=$((MINV / 4))
11313         local DIFF=$((MAXV - MINV))
11314         local DIFF2=$((DIFF * 100 / MINV))
11315
11316         local threshold=$(do_facet $SINGLEMDS \
11317                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11318         threshold=${threshold%%%}
11319         echo -n "Check for uneven OSTs: "
11320         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11321
11322         if [[ $DIFF2 -gt $threshold ]]; then
11323                 echo "ok"
11324                 echo "Don't need to fill OST$MINI"
11325         else
11326                 # generate uneven OSTs. Write 2% over the QOS threshold value
11327                 echo "no"
11328                 DIFF=$((threshold - DIFF2 + 2))
11329                 DIFF2=$((MINV * DIFF / 100))
11330                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11331                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11332                         error "setstripe failed"
11333                 DIFF=$((DIFF2 / 2048))
11334                 i=0
11335                 while [ $i -lt $DIFF ]; do
11336                         i=$((i + 1))
11337                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11338                                 bs=2M count=1 2>/dev/null
11339                         echo -n .
11340                 done
11341                 echo .
11342                 sync
11343                 sleep_maxage
11344                 free_min_max
11345         fi
11346
11347         DIFF=$((MAXV - MINV))
11348         DIFF2=$((DIFF * 100 / MINV))
11349         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11350         if [ $DIFF2 -gt $threshold ]; then
11351                 echo "ok"
11352         else
11353                 echo "failed - QOS mode won't be used"
11354                 simple_cleanup_common
11355                 skip "QOS imbalance criteria not met"
11356         fi
11357
11358         MINI1=$MINI
11359         MINV1=$MINV
11360         MAXI1=$MAXI
11361         MAXV1=$MAXV
11362
11363         # now fill using QOS
11364         $LFS setstripe -c 1 $DIR/$tdir
11365         FILL=$((FILL / 200))
11366         if [ $FILL -gt 600 ]; then
11367                 FILL=600
11368         fi
11369         echo "writing $FILL files to QOS-assigned OSTs"
11370         i=0
11371         while [ $i -lt $FILL ]; do
11372                 i=$((i + 1))
11373                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11374                         count=1 2>/dev/null
11375                 echo -n .
11376         done
11377         echo "wrote $i 200k files"
11378         sync
11379         sleep_maxage
11380
11381         echo "Note: free space may not be updated, so measurements might be off"
11382         free_min_max
11383         DIFF2=$((MAXV - MINV))
11384         echo "free space delta: orig $DIFF final $DIFF2"
11385         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11386         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11387         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11388         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11389         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11390         if [[ $DIFF -gt 0 ]]; then
11391                 FILL=$((DIFF2 * 100 / DIFF - 100))
11392                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11393         fi
11394
11395         # Figure out which files were written where
11396         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11397                awk '/'$MINI1': / {print $2; exit}')
11398         echo $UUID
11399         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11400         echo "$MINC files created on smaller OST $MINI1"
11401         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11402                awk '/'$MAXI1': / {print $2; exit}')
11403         echo $UUID
11404         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11405         echo "$MAXC files created on larger OST $MAXI1"
11406         if [[ $MINC -gt 0 ]]; then
11407                 FILL=$((MAXC * 100 / MINC - 100))
11408                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11409         fi
11410         [[ $MAXC -gt $MINC ]] ||
11411                 error_ignore LU-9 "stripe QOS didn't balance free space"
11412         simple_cleanup_common
11413 }
11414 run_test 116a "stripe QOS: free space balance ==================="
11415
11416 test_116b() { # LU-2093
11417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11418         remote_mds_nodsh && skip "remote MDS with nodsh"
11419
11420 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11421         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11422                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11423         [ -z "$old_rr" ] && skip "no QOS"
11424         do_facet $SINGLEMDS lctl set_param \
11425                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11426         mkdir -p $DIR/$tdir
11427         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11428         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11429         do_facet $SINGLEMDS lctl set_param fail_loc=0
11430         rm -rf $DIR/$tdir
11431         do_facet $SINGLEMDS lctl set_param \
11432                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11433 }
11434 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11435
11436 test_117() # bug 10891
11437 {
11438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11439
11440         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11441         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11442         lctl set_param fail_loc=0x21e
11443         > $DIR/$tfile || error "truncate failed"
11444         lctl set_param fail_loc=0
11445         echo "Truncate succeeded."
11446         rm -f $DIR/$tfile
11447 }
11448 run_test 117 "verify osd extend =========="
11449
11450 NO_SLOW_RESENDCOUNT=4
11451 export OLD_RESENDCOUNT=""
11452 set_resend_count () {
11453         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11454         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11455         lctl set_param -n $PROC_RESENDCOUNT $1
11456         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11457 }
11458
11459 # for reduce test_118* time (b=14842)
11460 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11461
11462 # Reset async IO behavior after error case
11463 reset_async() {
11464         FILE=$DIR/reset_async
11465
11466         # Ensure all OSCs are cleared
11467         $LFS setstripe -c -1 $FILE
11468         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11469         sync
11470         rm $FILE
11471 }
11472
11473 test_118a() #bug 11710
11474 {
11475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11476
11477         reset_async
11478
11479         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11480         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11481         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11482
11483         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11484                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11485                 return 1;
11486         fi
11487         rm -f $DIR/$tfile
11488 }
11489 run_test 118a "verify O_SYNC works =========="
11490
11491 test_118b()
11492 {
11493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11494         remote_ost_nodsh && skip "remote OST with nodsh"
11495
11496         reset_async
11497
11498         #define OBD_FAIL_SRV_ENOENT 0x217
11499         set_nodes_failloc "$(osts_nodes)" 0x217
11500         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11501         RC=$?
11502         set_nodes_failloc "$(osts_nodes)" 0
11503         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11504         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11505                     grep -c writeback)
11506
11507         if [[ $RC -eq 0 ]]; then
11508                 error "Must return error due to dropped pages, rc=$RC"
11509                 return 1;
11510         fi
11511
11512         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11513                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11514                 return 1;
11515         fi
11516
11517         echo "Dirty pages not leaked on ENOENT"
11518
11519         # Due to the above error the OSC will issue all RPCs syncronously
11520         # until a subsequent RPC completes successfully without error.
11521         $MULTIOP $DIR/$tfile Ow4096yc
11522         rm -f $DIR/$tfile
11523
11524         return 0
11525 }
11526 run_test 118b "Reclaim dirty pages on fatal error =========="
11527
11528 test_118c()
11529 {
11530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11531
11532         # for 118c, restore the original resend count, LU-1940
11533         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11534                                 set_resend_count $OLD_RESENDCOUNT
11535         remote_ost_nodsh && skip "remote OST with nodsh"
11536
11537         reset_async
11538
11539         #define OBD_FAIL_OST_EROFS               0x216
11540         set_nodes_failloc "$(osts_nodes)" 0x216
11541
11542         # multiop should block due to fsync until pages are written
11543         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11544         MULTIPID=$!
11545         sleep 1
11546
11547         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11548                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11549         fi
11550
11551         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11552                     grep -c writeback)
11553         if [[ $WRITEBACK -eq 0 ]]; then
11554                 error "No page in writeback, writeback=$WRITEBACK"
11555         fi
11556
11557         set_nodes_failloc "$(osts_nodes)" 0
11558         wait $MULTIPID
11559         RC=$?
11560         if [[ $RC -ne 0 ]]; then
11561                 error "Multiop fsync failed, rc=$RC"
11562         fi
11563
11564         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11565         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11566                     grep -c writeback)
11567         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11568                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11569         fi
11570
11571         rm -f $DIR/$tfile
11572         echo "Dirty pages flushed via fsync on EROFS"
11573         return 0
11574 }
11575 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11576
11577 # continue to use small resend count to reduce test_118* time (b=14842)
11578 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11579
11580 test_118d()
11581 {
11582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11583         remote_ost_nodsh && skip "remote OST with nodsh"
11584
11585         reset_async
11586
11587         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11588         set_nodes_failloc "$(osts_nodes)" 0x214
11589         # multiop should block due to fsync until pages are written
11590         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11591         MULTIPID=$!
11592         sleep 1
11593
11594         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11595                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11596         fi
11597
11598         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11599                     grep -c writeback)
11600         if [[ $WRITEBACK -eq 0 ]]; then
11601                 error "No page in writeback, writeback=$WRITEBACK"
11602         fi
11603
11604         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11605         set_nodes_failloc "$(osts_nodes)" 0
11606
11607         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11608         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11609                     grep -c writeback)
11610         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11611                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11612         fi
11613
11614         rm -f $DIR/$tfile
11615         echo "Dirty pages gaurenteed flushed via fsync"
11616         return 0
11617 }
11618 run_test 118d "Fsync validation inject a delay of the bulk =========="
11619
11620 test_118f() {
11621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11622
11623         reset_async
11624
11625         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11626         lctl set_param fail_loc=0x8000040a
11627
11628         # Should simulate EINVAL error which is fatal
11629         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11630         RC=$?
11631         if [[ $RC -eq 0 ]]; then
11632                 error "Must return error due to dropped pages, rc=$RC"
11633         fi
11634
11635         lctl set_param fail_loc=0x0
11636
11637         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11638         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11639         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11640                     grep -c writeback)
11641         if [[ $LOCKED -ne 0 ]]; then
11642                 error "Locked pages remain in cache, locked=$LOCKED"
11643         fi
11644
11645         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11646                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11647         fi
11648
11649         rm -f $DIR/$tfile
11650         echo "No pages locked after fsync"
11651
11652         reset_async
11653         return 0
11654 }
11655 run_test 118f "Simulate unrecoverable OSC side error =========="
11656
11657 test_118g() {
11658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11659
11660         reset_async
11661
11662         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11663         lctl set_param fail_loc=0x406
11664
11665         # simulate local -ENOMEM
11666         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11667         RC=$?
11668
11669         lctl set_param fail_loc=0
11670         if [[ $RC -eq 0 ]]; then
11671                 error "Must return error due to dropped pages, rc=$RC"
11672         fi
11673
11674         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11675         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11676         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11677                         grep -c writeback)
11678         if [[ $LOCKED -ne 0 ]]; then
11679                 error "Locked pages remain in cache, locked=$LOCKED"
11680         fi
11681
11682         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11683                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11684         fi
11685
11686         rm -f $DIR/$tfile
11687         echo "No pages locked after fsync"
11688
11689         reset_async
11690         return 0
11691 }
11692 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11693
11694 test_118h() {
11695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11696         remote_ost_nodsh && skip "remote OST with nodsh"
11697
11698         reset_async
11699
11700         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11701         set_nodes_failloc "$(osts_nodes)" 0x20e
11702         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11703         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11704         RC=$?
11705
11706         set_nodes_failloc "$(osts_nodes)" 0
11707         if [[ $RC -eq 0 ]]; then
11708                 error "Must return error due to dropped pages, rc=$RC"
11709         fi
11710
11711         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11712         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11713         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11714                     grep -c writeback)
11715         if [[ $LOCKED -ne 0 ]]; then
11716                 error "Locked pages remain in cache, locked=$LOCKED"
11717         fi
11718
11719         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11720                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11721         fi
11722
11723         rm -f $DIR/$tfile
11724         echo "No pages locked after fsync"
11725
11726         return 0
11727 }
11728 run_test 118h "Verify timeout in handling recoverables errors  =========="
11729
11730 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11731
11732 test_118i() {
11733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11734         remote_ost_nodsh && skip "remote OST with nodsh"
11735
11736         reset_async
11737
11738         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11739         set_nodes_failloc "$(osts_nodes)" 0x20e
11740
11741         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11742         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11743         PID=$!
11744         sleep 5
11745         set_nodes_failloc "$(osts_nodes)" 0
11746
11747         wait $PID
11748         RC=$?
11749         if [[ $RC -ne 0 ]]; then
11750                 error "got error, but should be not, rc=$RC"
11751         fi
11752
11753         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11754         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11755         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11756         if [[ $LOCKED -ne 0 ]]; then
11757                 error "Locked pages remain in cache, locked=$LOCKED"
11758         fi
11759
11760         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11761                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11762         fi
11763
11764         rm -f $DIR/$tfile
11765         echo "No pages locked after fsync"
11766
11767         return 0
11768 }
11769 run_test 118i "Fix error before timeout in recoverable error  =========="
11770
11771 [ "$SLOW" = "no" ] && set_resend_count 4
11772
11773 test_118j() {
11774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11775         remote_ost_nodsh && skip "remote OST with nodsh"
11776
11777         reset_async
11778
11779         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11780         set_nodes_failloc "$(osts_nodes)" 0x220
11781
11782         # return -EIO from OST
11783         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11784         RC=$?
11785         set_nodes_failloc "$(osts_nodes)" 0x0
11786         if [[ $RC -eq 0 ]]; then
11787                 error "Must return error due to dropped pages, rc=$RC"
11788         fi
11789
11790         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11791         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11792         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11793         if [[ $LOCKED -ne 0 ]]; then
11794                 error "Locked pages remain in cache, locked=$LOCKED"
11795         fi
11796
11797         # in recoverable error on OST we want resend and stay until it finished
11798         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11799                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11800         fi
11801
11802         rm -f $DIR/$tfile
11803         echo "No pages locked after fsync"
11804
11805         return 0
11806 }
11807 run_test 118j "Simulate unrecoverable OST side error =========="
11808
11809 test_118k()
11810 {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812         remote_ost_nodsh && skip "remote OSTs with nodsh"
11813
11814         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11815         set_nodes_failloc "$(osts_nodes)" 0x20e
11816         test_mkdir $DIR/$tdir
11817
11818         for ((i=0;i<10;i++)); do
11819                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11820                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11821                 SLEEPPID=$!
11822                 sleep 0.500s
11823                 kill $SLEEPPID
11824                 wait $SLEEPPID
11825         done
11826
11827         set_nodes_failloc "$(osts_nodes)" 0
11828         rm -rf $DIR/$tdir
11829 }
11830 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11831
11832 test_118l() # LU-646
11833 {
11834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11835
11836         test_mkdir $DIR/$tdir
11837         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11838         rm -rf $DIR/$tdir
11839 }
11840 run_test 118l "fsync dir"
11841
11842 test_118m() # LU-3066
11843 {
11844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11845
11846         test_mkdir $DIR/$tdir
11847         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11848         rm -rf $DIR/$tdir
11849 }
11850 run_test 118m "fdatasync dir ========="
11851
11852 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11853
11854 test_118n()
11855 {
11856         local begin
11857         local end
11858
11859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11860         remote_ost_nodsh && skip "remote OSTs with nodsh"
11861
11862         # Sleep to avoid a cached response.
11863         #define OBD_STATFS_CACHE_SECONDS 1
11864         sleep 2
11865
11866         # Inject a 10 second delay in the OST_STATFS handler.
11867         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11868         set_nodes_failloc "$(osts_nodes)" 0x242
11869
11870         begin=$SECONDS
11871         stat --file-system $MOUNT > /dev/null
11872         end=$SECONDS
11873
11874         set_nodes_failloc "$(osts_nodes)" 0
11875
11876         if ((end - begin > 20)); then
11877             error "statfs took $((end - begin)) seconds, expected 10"
11878         fi
11879 }
11880 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11881
11882 test_119a() # bug 11737
11883 {
11884         BSIZE=$((512 * 1024))
11885         directio write $DIR/$tfile 0 1 $BSIZE
11886         # We ask to read two blocks, which is more than a file size.
11887         # directio will indicate an error when requested and actual
11888         # sizes aren't equeal (a normal situation in this case) and
11889         # print actual read amount.
11890         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11891         if [ "$NOB" != "$BSIZE" ]; then
11892                 error "read $NOB bytes instead of $BSIZE"
11893         fi
11894         rm -f $DIR/$tfile
11895 }
11896 run_test 119a "Short directIO read must return actual read amount"
11897
11898 test_119b() # bug 11737
11899 {
11900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11901
11902         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11903         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11904         sync
11905         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11906                 error "direct read failed"
11907         rm -f $DIR/$tfile
11908 }
11909 run_test 119b "Sparse directIO read must return actual read amount"
11910
11911 test_119c() # bug 13099
11912 {
11913         BSIZE=1048576
11914         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11915         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11916         rm -f $DIR/$tfile
11917 }
11918 run_test 119c "Testing for direct read hitting hole"
11919
11920 test_119d() # bug 15950
11921 {
11922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11923
11924         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11925         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11926         BSIZE=1048576
11927         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11928         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11929         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11930         lctl set_param fail_loc=0x40d
11931         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11932         pid_dio=$!
11933         sleep 1
11934         cat $DIR/$tfile > /dev/null &
11935         lctl set_param fail_loc=0
11936         pid_reads=$!
11937         wait $pid_dio
11938         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11939         sleep 2
11940         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11941         error "the read rpcs have not completed in 2s"
11942         rm -f $DIR/$tfile
11943         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11944 }
11945 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11946
11947 test_120a() {
11948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11949         remote_mds_nodsh && skip "remote MDS with nodsh"
11950         test_mkdir -i0 -c1 $DIR/$tdir
11951         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11952                 skip_env "no early lock cancel on server"
11953
11954         lru_resize_disable mdc
11955         lru_resize_disable osc
11956         cancel_lru_locks mdc
11957         # asynchronous object destroy at MDT could cause bl ast to client
11958         cancel_lru_locks osc
11959
11960         stat $DIR/$tdir > /dev/null
11961         can1=$(do_facet mds1 \
11962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11963                awk '/ldlm_cancel/ {print $2}')
11964         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11965                awk '/ldlm_bl_callback/ {print $2}')
11966         test_mkdir -i0 -c1 $DIR/$tdir/d1
11967         can2=$(do_facet mds1 \
11968                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11969                awk '/ldlm_cancel/ {print $2}')
11970         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11971                awk '/ldlm_bl_callback/ {print $2}')
11972         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11973         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11974         lru_resize_enable mdc
11975         lru_resize_enable osc
11976 }
11977 run_test 120a "Early Lock Cancel: mkdir test"
11978
11979 test_120b() {
11980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11981         remote_mds_nodsh && skip "remote MDS with nodsh"
11982         test_mkdir $DIR/$tdir
11983         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11984                 skip_env "no early lock cancel on server"
11985
11986         lru_resize_disable mdc
11987         lru_resize_disable osc
11988         cancel_lru_locks mdc
11989         stat $DIR/$tdir > /dev/null
11990         can1=$(do_facet $SINGLEMDS \
11991                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11992                awk '/ldlm_cancel/ {print $2}')
11993         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11994                awk '/ldlm_bl_callback/ {print $2}')
11995         touch $DIR/$tdir/f1
11996         can2=$(do_facet $SINGLEMDS \
11997                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11998                awk '/ldlm_cancel/ {print $2}')
11999         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12000                awk '/ldlm_bl_callback/ {print $2}')
12001         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12002         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12003         lru_resize_enable mdc
12004         lru_resize_enable osc
12005 }
12006 run_test 120b "Early Lock Cancel: create test"
12007
12008 test_120c() {
12009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12010         remote_mds_nodsh && skip "remote MDS with nodsh"
12011         test_mkdir -i0 -c1 $DIR/$tdir
12012         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12013                 skip "no early lock cancel on server"
12014
12015         lru_resize_disable mdc
12016         lru_resize_disable osc
12017         test_mkdir -i0 -c1 $DIR/$tdir/d1
12018         test_mkdir -i0 -c1 $DIR/$tdir/d2
12019         touch $DIR/$tdir/d1/f1
12020         cancel_lru_locks mdc
12021         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12022         can1=$(do_facet mds1 \
12023                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12024                awk '/ldlm_cancel/ {print $2}')
12025         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12026                awk '/ldlm_bl_callback/ {print $2}')
12027         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12028         can2=$(do_facet mds1 \
12029                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12030                awk '/ldlm_cancel/ {print $2}')
12031         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12032                awk '/ldlm_bl_callback/ {print $2}')
12033         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12034         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12035         lru_resize_enable mdc
12036         lru_resize_enable osc
12037 }
12038 run_test 120c "Early Lock Cancel: link test"
12039
12040 test_120d() {
12041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12042         remote_mds_nodsh && skip "remote MDS with nodsh"
12043         test_mkdir -i0 -c1 $DIR/$tdir
12044         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12045                 skip_env "no early lock cancel on server"
12046
12047         lru_resize_disable mdc
12048         lru_resize_disable osc
12049         touch $DIR/$tdir
12050         cancel_lru_locks mdc
12051         stat $DIR/$tdir > /dev/null
12052         can1=$(do_facet mds1 \
12053                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12054                awk '/ldlm_cancel/ {print $2}')
12055         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12056                awk '/ldlm_bl_callback/ {print $2}')
12057         chmod a+x $DIR/$tdir
12058         can2=$(do_facet mds1 \
12059                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12060                awk '/ldlm_cancel/ {print $2}')
12061         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12062                awk '/ldlm_bl_callback/ {print $2}')
12063         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12064         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12065         lru_resize_enable mdc
12066         lru_resize_enable osc
12067 }
12068 run_test 120d "Early Lock Cancel: setattr test"
12069
12070 test_120e() {
12071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12072         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12073                 skip_env "no early lock cancel on server"
12074         remote_mds_nodsh && skip "remote MDS with nodsh"
12075
12076         local dlmtrace_set=false
12077
12078         test_mkdir -i0 -c1 $DIR/$tdir
12079         lru_resize_disable mdc
12080         lru_resize_disable osc
12081         ! $LCTL get_param debug | grep -q dlmtrace &&
12082                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12083         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12084         cancel_lru_locks mdc
12085         cancel_lru_locks osc
12086         dd if=$DIR/$tdir/f1 of=/dev/null
12087         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12088         # XXX client can not do early lock cancel of OST lock
12089         # during unlink (LU-4206), so cancel osc lock now.
12090         sleep 2
12091         cancel_lru_locks osc
12092         can1=$(do_facet mds1 \
12093                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12094                awk '/ldlm_cancel/ {print $2}')
12095         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12096                awk '/ldlm_bl_callback/ {print $2}')
12097         unlink $DIR/$tdir/f1
12098         sleep 5
12099         can2=$(do_facet mds1 \
12100                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12101                awk '/ldlm_cancel/ {print $2}')
12102         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12103                awk '/ldlm_bl_callback/ {print $2}')
12104         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12105                 $LCTL dk $TMP/cancel.debug.txt
12106         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12107                 $LCTL dk $TMP/blocking.debug.txt
12108         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12109         lru_resize_enable mdc
12110         lru_resize_enable osc
12111 }
12112 run_test 120e "Early Lock Cancel: unlink test"
12113
12114 test_120f() {
12115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12116         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12117                 skip_env "no early lock cancel on server"
12118         remote_mds_nodsh && skip "remote MDS with nodsh"
12119
12120         test_mkdir -i0 -c1 $DIR/$tdir
12121         lru_resize_disable mdc
12122         lru_resize_disable osc
12123         test_mkdir -i0 -c1 $DIR/$tdir/d1
12124         test_mkdir -i0 -c1 $DIR/$tdir/d2
12125         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12126         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12127         cancel_lru_locks mdc
12128         cancel_lru_locks osc
12129         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12130         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12131         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12132         # XXX client can not do early lock cancel of OST lock
12133         # during rename (LU-4206), so cancel osc lock now.
12134         sleep 2
12135         cancel_lru_locks osc
12136         can1=$(do_facet mds1 \
12137                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12138                awk '/ldlm_cancel/ {print $2}')
12139         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12140                awk '/ldlm_bl_callback/ {print $2}')
12141         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12142         sleep 5
12143         can2=$(do_facet mds1 \
12144                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12145                awk '/ldlm_cancel/ {print $2}')
12146         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12147                awk '/ldlm_bl_callback/ {print $2}')
12148         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12149         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12150         lru_resize_enable mdc
12151         lru_resize_enable osc
12152 }
12153 run_test 120f "Early Lock Cancel: rename test"
12154
12155 test_120g() {
12156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12157         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12158                 skip_env "no early lock cancel on server"
12159         remote_mds_nodsh && skip "remote MDS with nodsh"
12160
12161         lru_resize_disable mdc
12162         lru_resize_disable osc
12163         count=10000
12164         echo create $count files
12165         test_mkdir $DIR/$tdir
12166         cancel_lru_locks mdc
12167         cancel_lru_locks osc
12168         t0=$(date +%s)
12169
12170         can0=$(do_facet $SINGLEMDS \
12171                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12172                awk '/ldlm_cancel/ {print $2}')
12173         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12174                awk '/ldlm_bl_callback/ {print $2}')
12175         createmany -o $DIR/$tdir/f $count
12176         sync
12177         can1=$(do_facet $SINGLEMDS \
12178                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12179                awk '/ldlm_cancel/ {print $2}')
12180         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12181                awk '/ldlm_bl_callback/ {print $2}')
12182         t1=$(date +%s)
12183         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12184         echo rm $count files
12185         rm -r $DIR/$tdir
12186         sync
12187         can2=$(do_facet $SINGLEMDS \
12188                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12189                awk '/ldlm_cancel/ {print $2}')
12190         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12191                awk '/ldlm_bl_callback/ {print $2}')
12192         t2=$(date +%s)
12193         echo total: $count removes in $((t2-t1))
12194         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12195         sleep 2
12196         # wait for commitment of removal
12197         lru_resize_enable mdc
12198         lru_resize_enable osc
12199 }
12200 run_test 120g "Early Lock Cancel: performance test"
12201
12202 test_121() { #bug #10589
12203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12204
12205         rm -rf $DIR/$tfile
12206         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12207 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12208         lctl set_param fail_loc=0x310
12209         cancel_lru_locks osc > /dev/null
12210         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12211         lctl set_param fail_loc=0
12212         [[ $reads -eq $writes ]] ||
12213                 error "read $reads blocks, must be $writes blocks"
12214 }
12215 run_test 121 "read cancel race ========="
12216
12217 test_123a_base() { # was test 123, statahead(bug 11401)
12218         local lsx="$1"
12219
12220         SLOWOK=0
12221         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12222                 log "testing UP system. Performance may be lower than expected."
12223                 SLOWOK=1
12224         fi
12225
12226         rm -rf $DIR/$tdir
12227         test_mkdir $DIR/$tdir
12228         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12229         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12230         MULT=10
12231         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12232                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12233
12234                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12235                 lctl set_param -n llite.*.statahead_max 0
12236                 lctl get_param llite.*.statahead_max
12237                 cancel_lru_locks mdc
12238                 cancel_lru_locks osc
12239                 stime=$(date +%s)
12240                 time $lsx $DIR/$tdir | wc -l
12241                 etime=$(date +%s)
12242                 delta=$((etime - stime))
12243                 log "$lsx $i files without statahead: $delta sec"
12244                 lctl set_param llite.*.statahead_max=$max
12245
12246                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12247                         grep "statahead wrong:" | awk '{print $3}')
12248                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12249                 cancel_lru_locks mdc
12250                 cancel_lru_locks osc
12251                 stime=$(date +%s)
12252                 time $lsx $DIR/$tdir | wc -l
12253                 etime=$(date +%s)
12254                 delta_sa=$((etime - stime))
12255                 log "$lsx $i files with statahead: $delta_sa sec"
12256                 lctl get_param -n llite.*.statahead_stats
12257                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12258                         grep "statahead wrong:" | awk '{print $3}')
12259
12260                 [[ $swrong -lt $ewrong ]] &&
12261                         log "statahead was stopped, maybe too many locks held!"
12262                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12263
12264                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12265                         max=$(lctl get_param -n llite.*.statahead_max |
12266                                 head -n 1)
12267                         lctl set_param -n llite.*.statahead_max 0
12268                         lctl get_param llite.*.statahead_max
12269                         cancel_lru_locks mdc
12270                         cancel_lru_locks osc
12271                         stime=$(date +%s)
12272                         time $lsx $DIR/$tdir | wc -l
12273                         etime=$(date +%s)
12274                         delta=$((etime - stime))
12275                         log "$lsx $i files again without statahead: $delta sec"
12276                         lctl set_param llite.*.statahead_max=$max
12277                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12278                                 if [  $SLOWOK -eq 0 ]; then
12279                                         error "$lsx $i files is slower with statahead!"
12280                                 else
12281                                         log "$lsx $i files is slower with statahead!"
12282                                 fi
12283                                 break
12284                         fi
12285                 fi
12286
12287                 [ $delta -gt 20 ] && break
12288                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12289                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12290         done
12291         log "$lsx done"
12292
12293         stime=$(date +%s)
12294         rm -r $DIR/$tdir
12295         sync
12296         etime=$(date +%s)
12297         delta=$((etime - stime))
12298         log "rm -r $DIR/$tdir/: $delta seconds"
12299         log "rm done"
12300         lctl get_param -n llite.*.statahead_stats
12301 }
12302
12303 test_123aa() {
12304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12305
12306         test_123a_base "ls -l"
12307 }
12308 run_test 123aa "verify statahead work"
12309
12310 test_123ab() {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312
12313         statx_supported || skip_env "Test must be statx() syscall supported"
12314
12315         test_123a_base "$STATX -l"
12316 }
12317 run_test 123ab "verify statahead work by using statx"
12318
12319 test_123ac() {
12320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12321
12322         statx_supported || skip_env "Test must be statx() syscall supported"
12323
12324         local rpcs_before
12325         local rpcs_after
12326         local agl_before
12327         local agl_after
12328
12329         cancel_lru_locks $OSC
12330         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12331         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12332                 awk '/agl.total:/ {print $3}')
12333         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12334         test_123a_base "$STATX --cached=always -D"
12335         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12336                 awk '/agl.total:/ {print $3}')
12337         [ $agl_before -eq $agl_after ] ||
12338                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12339         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12340         [ $rpcs_after -eq $rpcs_before ] ||
12341                 error "$STATX should not send glimpse RPCs to $OSC"
12342 }
12343 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12344
12345 test_123b () { # statahead(bug 15027)
12346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12347
12348         test_mkdir $DIR/$tdir
12349         createmany -o $DIR/$tdir/$tfile-%d 1000
12350
12351         cancel_lru_locks mdc
12352         cancel_lru_locks osc
12353
12354 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12355         lctl set_param fail_loc=0x80000803
12356         ls -lR $DIR/$tdir > /dev/null
12357         log "ls done"
12358         lctl set_param fail_loc=0x0
12359         lctl get_param -n llite.*.statahead_stats
12360         rm -r $DIR/$tdir
12361         sync
12362
12363 }
12364 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12365
12366 test_123c() {
12367         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12368
12369         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12370         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12371         touch $DIR/$tdir.1/{1..3}
12372         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12373
12374         remount_client $MOUNT
12375
12376         $MULTIOP $DIR/$tdir.0 Q
12377
12378         # let statahead to complete
12379         ls -l $DIR/$tdir.0 > /dev/null
12380
12381         testid=$(echo $TESTNAME | tr '_' ' ')
12382         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12383                 error "statahead warning" || true
12384 }
12385 run_test 123c "Can not initialize inode warning on DNE statahead"
12386
12387 test_124a() {
12388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12389         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12390                 skip_env "no lru resize on server"
12391
12392         local NR=2000
12393
12394         test_mkdir $DIR/$tdir
12395
12396         log "create $NR files at $DIR/$tdir"
12397         createmany -o $DIR/$tdir/f $NR ||
12398                 error "failed to create $NR files in $DIR/$tdir"
12399
12400         cancel_lru_locks mdc
12401         ls -l $DIR/$tdir > /dev/null
12402
12403         local NSDIR=""
12404         local LRU_SIZE=0
12405         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12406                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12407                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12408                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12409                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12410                         log "NSDIR=$NSDIR"
12411                         log "NS=$(basename $NSDIR)"
12412                         break
12413                 fi
12414         done
12415
12416         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12417                 skip "Not enough cached locks created!"
12418         fi
12419         log "LRU=$LRU_SIZE"
12420
12421         local SLEEP=30
12422
12423         # We know that lru resize allows one client to hold $LIMIT locks
12424         # for 10h. After that locks begin to be killed by client.
12425         local MAX_HRS=10
12426         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12427         log "LIMIT=$LIMIT"
12428         if [ $LIMIT -lt $LRU_SIZE ]; then
12429                 skip "Limit is too small $LIMIT"
12430         fi
12431
12432         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12433         # killing locks. Some time was spent for creating locks. This means
12434         # that up to the moment of sleep finish we must have killed some of
12435         # them (10-100 locks). This depends on how fast ther were created.
12436         # Many of them were touched in almost the same moment and thus will
12437         # be killed in groups.
12438         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12439
12440         # Use $LRU_SIZE_B here to take into account real number of locks
12441         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12442         local LRU_SIZE_B=$LRU_SIZE
12443         log "LVF=$LVF"
12444         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12445         log "OLD_LVF=$OLD_LVF"
12446         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12447
12448         # Let's make sure that we really have some margin. Client checks
12449         # cached locks every 10 sec.
12450         SLEEP=$((SLEEP+20))
12451         log "Sleep ${SLEEP} sec"
12452         local SEC=0
12453         while ((SEC<$SLEEP)); do
12454                 echo -n "..."
12455                 sleep 5
12456                 SEC=$((SEC+5))
12457                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12458                 echo -n "$LRU_SIZE"
12459         done
12460         echo ""
12461         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12462         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12463
12464         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12465                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12466                 unlinkmany $DIR/$tdir/f $NR
12467                 return
12468         }
12469
12470         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12471         log "unlink $NR files at $DIR/$tdir"
12472         unlinkmany $DIR/$tdir/f $NR
12473 }
12474 run_test 124a "lru resize ======================================="
12475
12476 get_max_pool_limit()
12477 {
12478         local limit=$($LCTL get_param \
12479                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12480         local max=0
12481         for l in $limit; do
12482                 if [[ $l -gt $max ]]; then
12483                         max=$l
12484                 fi
12485         done
12486         echo $max
12487 }
12488
12489 test_124b() {
12490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12491         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12492                 skip_env "no lru resize on server"
12493
12494         LIMIT=$(get_max_pool_limit)
12495
12496         NR=$(($(default_lru_size)*20))
12497         if [[ $NR -gt $LIMIT ]]; then
12498                 log "Limit lock number by $LIMIT locks"
12499                 NR=$LIMIT
12500         fi
12501
12502         IFree=$(mdsrate_inodes_available)
12503         if [ $IFree -lt $NR ]; then
12504                 log "Limit lock number by $IFree inodes"
12505                 NR=$IFree
12506         fi
12507
12508         lru_resize_disable mdc
12509         test_mkdir -p $DIR/$tdir/disable_lru_resize
12510
12511         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12512         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12513         cancel_lru_locks mdc
12514         stime=`date +%s`
12515         PID=""
12516         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12517         PID="$PID $!"
12518         sleep 2
12519         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12520         PID="$PID $!"
12521         sleep 2
12522         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12523         PID="$PID $!"
12524         wait $PID
12525         etime=`date +%s`
12526         nolruresize_delta=$((etime-stime))
12527         log "ls -la time: $nolruresize_delta seconds"
12528         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12529         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12530
12531         lru_resize_enable mdc
12532         test_mkdir -p $DIR/$tdir/enable_lru_resize
12533
12534         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12535         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12536         cancel_lru_locks mdc
12537         stime=`date +%s`
12538         PID=""
12539         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12540         PID="$PID $!"
12541         sleep 2
12542         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12543         PID="$PID $!"
12544         sleep 2
12545         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12546         PID="$PID $!"
12547         wait $PID
12548         etime=`date +%s`
12549         lruresize_delta=$((etime-stime))
12550         log "ls -la time: $lruresize_delta seconds"
12551         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12552
12553         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12554                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12555         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12556                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12557         else
12558                 log "lru resize performs the same with no lru resize"
12559         fi
12560         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12561 }
12562 run_test 124b "lru resize (performance test) ======================="
12563
12564 test_124c() {
12565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12566         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12567                 skip_env "no lru resize on server"
12568
12569         # cache ununsed locks on client
12570         local nr=100
12571         cancel_lru_locks mdc
12572         test_mkdir $DIR/$tdir
12573         createmany -o $DIR/$tdir/f $nr ||
12574                 error "failed to create $nr files in $DIR/$tdir"
12575         ls -l $DIR/$tdir > /dev/null
12576
12577         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12578         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12579         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12580         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12581         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12582
12583         # set lru_max_age to 1 sec
12584         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12585         echo "sleep $((recalc_p * 2)) seconds..."
12586         sleep $((recalc_p * 2))
12587
12588         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12589         # restore lru_max_age
12590         $LCTL set_param -n $nsdir.lru_max_age $max_age
12591         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12592         unlinkmany $DIR/$tdir/f $nr
12593 }
12594 run_test 124c "LRUR cancel very aged locks"
12595
12596 test_124d() {
12597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12598         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12599                 skip_env "no lru resize on server"
12600
12601         # cache ununsed locks on client
12602         local nr=100
12603
12604         lru_resize_disable mdc
12605         stack_trap "lru_resize_enable mdc" EXIT
12606
12607         cancel_lru_locks mdc
12608
12609         # asynchronous object destroy at MDT could cause bl ast to client
12610         test_mkdir $DIR/$tdir
12611         createmany -o $DIR/$tdir/f $nr ||
12612                 error "failed to create $nr files in $DIR/$tdir"
12613         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12614
12615         ls -l $DIR/$tdir > /dev/null
12616
12617         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12618         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12619         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12620         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12621
12622         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12623
12624         # set lru_max_age to 1 sec
12625         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12626         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12627
12628         echo "sleep $((recalc_p * 2)) seconds..."
12629         sleep $((recalc_p * 2))
12630
12631         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12632
12633         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12634 }
12635 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12636
12637 test_125() { # 13358
12638         $LCTL get_param -n llite.*.client_type | grep -q local ||
12639                 skip "must run as local client"
12640         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12641                 skip_env "must have acl enabled"
12642         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12643
12644         test_mkdir $DIR/$tdir
12645         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12646         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12647         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12648 }
12649 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12650
12651 test_126() { # bug 12829/13455
12652         $GSS && skip_env "must run as gss disabled"
12653         $LCTL get_param -n llite.*.client_type | grep -q local ||
12654                 skip "must run as local client"
12655         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12656
12657         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12658         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12659         rm -f $DIR/$tfile
12660         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12661 }
12662 run_test 126 "check that the fsgid provided by the client is taken into account"
12663
12664 test_127a() { # bug 15521
12665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12666         local name count samp unit min max sum sumsq
12667
12668         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12669         echo "stats before reset"
12670         $LCTL get_param osc.*.stats
12671         $LCTL set_param osc.*.stats=0
12672         local fsize=$((2048 * 1024))
12673
12674         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12675         cancel_lru_locks osc
12676         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12677
12678         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12679         stack_trap "rm -f $TMP/$tfile.tmp"
12680         while read name count samp unit min max sum sumsq; do
12681                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12682                 [ ! $min ] && error "Missing min value for $name proc entry"
12683                 eval $name=$count || error "Wrong proc format"
12684
12685                 case $name in
12686                 read_bytes|write_bytes)
12687                         [[ "$unit" =~ "bytes" ]] ||
12688                                 error "unit is not 'bytes': $unit"
12689                         (( $min >= 4096 )) || error "min is too small: $min"
12690                         (( $min <= $fsize )) || error "min is too big: $min"
12691                         (( $max >= 4096 )) || error "max is too small: $max"
12692                         (( $max <= $fsize )) || error "max is too big: $max"
12693                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12694                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12695                                 error "sumsquare is too small: $sumsq"
12696                         (( $sumsq <= $fsize * $fsize )) ||
12697                                 error "sumsquare is too big: $sumsq"
12698                         ;;
12699                 ost_read|ost_write)
12700                         [[ "$unit" =~ "usec" ]] ||
12701                                 error "unit is not 'usec': $unit"
12702                         ;;
12703                 *)      ;;
12704                 esac
12705         done < $DIR/$tfile.tmp
12706
12707         #check that we actually got some stats
12708         [ "$read_bytes" ] || error "Missing read_bytes stats"
12709         [ "$write_bytes" ] || error "Missing write_bytes stats"
12710         [ "$read_bytes" != 0 ] || error "no read done"
12711         [ "$write_bytes" != 0 ] || error "no write done"
12712 }
12713 run_test 127a "verify the client stats are sane"
12714
12715 test_127b() { # bug LU-333
12716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12717         local name count samp unit min max sum sumsq
12718
12719         echo "stats before reset"
12720         $LCTL get_param llite.*.stats
12721         $LCTL set_param llite.*.stats=0
12722
12723         # perform 2 reads and writes so MAX is different from SUM.
12724         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12725         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12726         cancel_lru_locks osc
12727         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12728         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12729
12730         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12731         stack_trap "rm -f $TMP/$tfile.tmp"
12732         while read name count samp unit min max sum sumsq; do
12733                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12734                 eval $name=$count || error "Wrong proc format"
12735
12736                 case $name in
12737                 read_bytes|write_bytes)
12738                         [[ "$unit" =~ "bytes" ]] ||
12739                                 error "unit is not 'bytes': $unit"
12740                         (( $count == 2 )) || error "count is not 2: $count"
12741                         (( $min == $PAGE_SIZE )) ||
12742                                 error "min is not $PAGE_SIZE: $min"
12743                         (( $max == $PAGE_SIZE )) ||
12744                                 error "max is not $PAGE_SIZE: $max"
12745                         (( $sum == $PAGE_SIZE * 2 )) ||
12746                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12747                         ;;
12748                 read|write)
12749                         [[ "$unit" =~ "usec" ]] ||
12750                                 error "unit is not 'usec': $unit"
12751                         ;;
12752                 *)      ;;
12753                 esac
12754         done < $TMP/$tfile.tmp
12755
12756         #check that we actually got some stats
12757         [ "$read_bytes" ] || error "Missing read_bytes stats"
12758         [ "$write_bytes" ] || error "Missing write_bytes stats"
12759         [ "$read_bytes" != 0 ] || error "no read done"
12760         [ "$write_bytes" != 0 ] || error "no write done"
12761 }
12762 run_test 127b "verify the llite client stats are sane"
12763
12764 test_127c() { # LU-12394
12765         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12766         local size
12767         local bsize
12768         local reads
12769         local writes
12770         local count
12771
12772         $LCTL set_param llite.*.extents_stats=1
12773         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12774
12775         # Use two stripes so there is enough space in default config
12776         $LFS setstripe -c 2 $DIR/$tfile
12777
12778         # Extent stats start at 0-4K and go in power of two buckets
12779         # LL_HIST_START = 12 --> 2^12 = 4K
12780         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12781         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12782         # small configs
12783         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12784                 do
12785                 # Write and read, 2x each, second time at a non-zero offset
12786                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12787                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12788                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12789                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12790                 rm -f $DIR/$tfile
12791         done
12792
12793         $LCTL get_param llite.*.extents_stats
12794
12795         count=2
12796         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12797                 do
12798                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12799                                 grep -m 1 $bsize)
12800                 reads=$(echo $bucket | awk '{print $5}')
12801                 writes=$(echo $bucket | awk '{print $9}')
12802                 [ "$reads" -eq $count ] ||
12803                         error "$reads reads in < $bsize bucket, expect $count"
12804                 [ "$writes" -eq $count ] ||
12805                         error "$writes writes in < $bsize bucket, expect $count"
12806         done
12807
12808         # Test mmap write and read
12809         $LCTL set_param llite.*.extents_stats=c
12810         size=512
12811         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12812         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12813         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12814
12815         $LCTL get_param llite.*.extents_stats
12816
12817         count=$(((size*1024) / PAGE_SIZE))
12818
12819         bsize=$((2 * PAGE_SIZE / 1024))K
12820
12821         bucket=$($LCTL get_param -n llite.*.extents_stats |
12822                         grep -m 1 $bsize)
12823         reads=$(echo $bucket | awk '{print $5}')
12824         writes=$(echo $bucket | awk '{print $9}')
12825         # mmap writes fault in the page first, creating an additonal read
12826         [ "$reads" -eq $((2 * count)) ] ||
12827                 error "$reads reads in < $bsize bucket, expect $count"
12828         [ "$writes" -eq $count ] ||
12829                 error "$writes writes in < $bsize bucket, expect $count"
12830 }
12831 run_test 127c "test llite extent stats with regular & mmap i/o"
12832
12833 test_128() { # bug 15212
12834         touch $DIR/$tfile
12835         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12836                 find $DIR/$tfile
12837                 find $DIR/$tfile
12838         EOF
12839
12840         result=$(grep error $TMP/$tfile.log)
12841         rm -f $DIR/$tfile $TMP/$tfile.log
12842         [ -z "$result" ] ||
12843                 error "consecutive find's under interactive lfs failed"
12844 }
12845 run_test 128 "interactive lfs for 2 consecutive find's"
12846
12847 set_dir_limits () {
12848         local mntdev
12849         local canondev
12850         local node
12851
12852         local ldproc=/proc/fs/ldiskfs
12853         local facets=$(get_facets MDS)
12854
12855         for facet in ${facets//,/ }; do
12856                 canondev=$(ldiskfs_canon \
12857                            *.$(convert_facet2label $facet).mntdev $facet)
12858                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12859                         ldproc=/sys/fs/ldiskfs
12860                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12861                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12862         done
12863 }
12864
12865 check_mds_dmesg() {
12866         local facets=$(get_facets MDS)
12867         for facet in ${facets//,/ }; do
12868                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12869         done
12870         return 1
12871 }
12872
12873 test_129() {
12874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12875         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12876                 skip "Need MDS version with at least 2.5.56"
12877         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12878                 skip_env "ldiskfs only test"
12879         fi
12880         remote_mds_nodsh && skip "remote MDS with nodsh"
12881
12882         local ENOSPC=28
12883         local has_warning=false
12884
12885         rm -rf $DIR/$tdir
12886         mkdir -p $DIR/$tdir
12887
12888         # block size of mds1
12889         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12890         set_dir_limits $maxsize $((maxsize * 6 / 8))
12891         stack_trap "set_dir_limits 0 0"
12892         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12893         local dirsize=$(stat -c%s "$DIR/$tdir")
12894         local nfiles=0
12895         while (( $dirsize <= $maxsize )); do
12896                 $MCREATE $DIR/$tdir/file_base_$nfiles
12897                 rc=$?
12898                 # check two errors:
12899                 # ENOSPC for ext4 max_dir_size, which has been used since
12900                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12901                 if (( rc == ENOSPC )); then
12902                         set_dir_limits 0 0
12903                         echo "rc=$rc returned as expected after $nfiles files"
12904
12905                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12906                                 error "create failed w/o dir size limit"
12907
12908                         # messages may be rate limited if test is run repeatedly
12909                         check_mds_dmesg '"is approaching max"' ||
12910                                 echo "warning message should be output"
12911                         check_mds_dmesg '"has reached max"' ||
12912                                 echo "reached message should be output"
12913
12914                         dirsize=$(stat -c%s "$DIR/$tdir")
12915
12916                         [[ $dirsize -ge $maxsize ]] && return 0
12917                         error "dirsize $dirsize < $maxsize after $nfiles files"
12918                 elif (( rc != 0 )); then
12919                         break
12920                 fi
12921                 nfiles=$((nfiles + 1))
12922                 dirsize=$(stat -c%s "$DIR/$tdir")
12923         done
12924
12925         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12926 }
12927 run_test 129 "test directory size limit ========================"
12928
12929 OLDIFS="$IFS"
12930 cleanup_130() {
12931         trap 0
12932         IFS="$OLDIFS"
12933 }
12934
12935 test_130a() {
12936         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12937         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12938
12939         trap cleanup_130 EXIT RETURN
12940
12941         local fm_file=$DIR/$tfile
12942         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12943         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12944                 error "dd failed for $fm_file"
12945
12946         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12947         filefrag -ves $fm_file
12948         RC=$?
12949         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12950                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12951         [ $RC != 0 ] && error "filefrag $fm_file failed"
12952
12953         filefrag_op=$(filefrag -ve -k $fm_file |
12954                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12955         lun=$($LFS getstripe -i $fm_file)
12956
12957         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12958         IFS=$'\n'
12959         tot_len=0
12960         for line in $filefrag_op
12961         do
12962                 frag_lun=`echo $line | cut -d: -f5`
12963                 ext_len=`echo $line | cut -d: -f4`
12964                 if (( $frag_lun != $lun )); then
12965                         cleanup_130
12966                         error "FIEMAP on 1-stripe file($fm_file) failed"
12967                         return
12968                 fi
12969                 (( tot_len += ext_len ))
12970         done
12971
12972         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12973                 cleanup_130
12974                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12975                 return
12976         fi
12977
12978         cleanup_130
12979
12980         echo "FIEMAP on single striped file succeeded"
12981 }
12982 run_test 130a "FIEMAP (1-stripe file)"
12983
12984 test_130b() {
12985         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12986
12987         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12988         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12989
12990         trap cleanup_130 EXIT RETURN
12991
12992         local fm_file=$DIR/$tfile
12993         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12994                         error "setstripe on $fm_file"
12995         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12996                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12997
12998         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12999                 error "dd failed on $fm_file"
13000
13001         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13002         filefrag_op=$(filefrag -ve -k $fm_file |
13003                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13004
13005         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13006                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13007
13008         IFS=$'\n'
13009         tot_len=0
13010         num_luns=1
13011         for line in $filefrag_op
13012         do
13013                 frag_lun=$(echo $line | cut -d: -f5 |
13014                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13015                 ext_len=$(echo $line | cut -d: -f4)
13016                 if (( $frag_lun != $last_lun )); then
13017                         if (( tot_len != 1024 )); then
13018                                 cleanup_130
13019                                 error "FIEMAP on $fm_file failed; returned " \
13020                                 "len $tot_len for OST $last_lun instead of 1024"
13021                                 return
13022                         else
13023                                 (( num_luns += 1 ))
13024                                 tot_len=0
13025                         fi
13026                 fi
13027                 (( tot_len += ext_len ))
13028                 last_lun=$frag_lun
13029         done
13030         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13031                 cleanup_130
13032                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13033                         "luns or wrong len for OST $last_lun"
13034                 return
13035         fi
13036
13037         cleanup_130
13038
13039         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13040 }
13041 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13042
13043 test_130c() {
13044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13045
13046         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13047         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13048
13049         trap cleanup_130 EXIT RETURN
13050
13051         local fm_file=$DIR/$tfile
13052         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13053         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13054                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13055
13056         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13057                         error "dd failed on $fm_file"
13058
13059         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13060         filefrag_op=$(filefrag -ve -k $fm_file |
13061                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13062
13063         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13064                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13065
13066         IFS=$'\n'
13067         tot_len=0
13068         num_luns=1
13069         for line in $filefrag_op
13070         do
13071                 frag_lun=$(echo $line | cut -d: -f5 |
13072                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13073                 ext_len=$(echo $line | cut -d: -f4)
13074                 if (( $frag_lun != $last_lun )); then
13075                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13076                         if (( logical != 512 )); then
13077                                 cleanup_130
13078                                 error "FIEMAP on $fm_file failed; returned " \
13079                                 "logical start for lun $logical instead of 512"
13080                                 return
13081                         fi
13082                         if (( tot_len != 512 )); then
13083                                 cleanup_130
13084                                 error "FIEMAP on $fm_file failed; returned " \
13085                                 "len $tot_len for OST $last_lun instead of 1024"
13086                                 return
13087                         else
13088                                 (( num_luns += 1 ))
13089                                 tot_len=0
13090                         fi
13091                 fi
13092                 (( tot_len += ext_len ))
13093                 last_lun=$frag_lun
13094         done
13095         if (( num_luns != 2 || tot_len != 512 )); then
13096                 cleanup_130
13097                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13098                         "luns or wrong len for OST $last_lun"
13099                 return
13100         fi
13101
13102         cleanup_130
13103
13104         echo "FIEMAP on 2-stripe file with hole succeeded"
13105 }
13106 run_test 130c "FIEMAP (2-stripe file with hole)"
13107
13108 test_130d() {
13109         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13110
13111         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13112         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13113
13114         trap cleanup_130 EXIT RETURN
13115
13116         local fm_file=$DIR/$tfile
13117         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13118                         error "setstripe on $fm_file"
13119         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13120                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13121
13122         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13123         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13124                 error "dd failed on $fm_file"
13125
13126         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13127         filefrag_op=$(filefrag -ve -k $fm_file |
13128                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13129
13130         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13131                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13132
13133         IFS=$'\n'
13134         tot_len=0
13135         num_luns=1
13136         for line in $filefrag_op
13137         do
13138                 frag_lun=$(echo $line | cut -d: -f5 |
13139                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13140                 ext_len=$(echo $line | cut -d: -f4)
13141                 if (( $frag_lun != $last_lun )); then
13142                         if (( tot_len != 1024 )); then
13143                                 cleanup_130
13144                                 error "FIEMAP on $fm_file failed; returned " \
13145                                 "len $tot_len for OST $last_lun instead of 1024"
13146                                 return
13147                         else
13148                                 (( num_luns += 1 ))
13149                                 tot_len=0
13150                         fi
13151                 fi
13152                 (( tot_len += ext_len ))
13153                 last_lun=$frag_lun
13154         done
13155         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13156                 cleanup_130
13157                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13158                         "luns or wrong len for OST $last_lun"
13159                 return
13160         fi
13161
13162         cleanup_130
13163
13164         echo "FIEMAP on N-stripe file succeeded"
13165 }
13166 run_test 130d "FIEMAP (N-stripe file)"
13167
13168 test_130e() {
13169         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13170
13171         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13172         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13173
13174         trap cleanup_130 EXIT RETURN
13175
13176         local fm_file=$DIR/$tfile
13177         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13178
13179         NUM_BLKS=512
13180         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13181         for ((i = 0; i < $NUM_BLKS; i++)); do
13182                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13183                         conv=notrunc > /dev/null 2>&1
13184         done
13185
13186         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13187         filefrag_op=$(filefrag -ve -k $fm_file |
13188                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13189
13190         last_lun=$(echo $filefrag_op | cut -d: -f5)
13191
13192         IFS=$'\n'
13193         tot_len=0
13194         num_luns=1
13195         for line in $filefrag_op; do
13196                 frag_lun=$(echo $line | cut -d: -f5)
13197                 ext_len=$(echo $line | cut -d: -f4)
13198                 if [[ "$frag_lun" != "$last_lun" ]]; then
13199                         if (( tot_len != $EXPECTED_LEN )); then
13200                                 cleanup_130
13201                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13202                         else
13203                                 (( num_luns += 1 ))
13204                                 tot_len=0
13205                         fi
13206                 fi
13207                 (( tot_len += ext_len ))
13208                 last_lun=$frag_lun
13209         done
13210         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13211                 cleanup_130
13212                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13213         fi
13214
13215         echo "FIEMAP with continuation calls succeeded"
13216 }
13217 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13218
13219 test_130f() {
13220         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13221         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13222
13223         local fm_file=$DIR/$tfile
13224         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13225                 error "multiop create with lov_delay_create on $fm_file"
13226
13227         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13228         filefrag_extents=$(filefrag -vek $fm_file |
13229                            awk '/extents? found/ { print $2 }')
13230         if [[ "$filefrag_extents" != "0" ]]; then
13231                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13232         fi
13233
13234         rm -f $fm_file
13235 }
13236 run_test 130f "FIEMAP (unstriped file)"
13237
13238 test_130g() {
13239         local file=$DIR/$tfile
13240         local nr=$((OSTCOUNT * 100))
13241
13242         $LFS setstripe -C $nr $file ||
13243                 error "failed to setstripe -C $nr $file"
13244
13245         dd if=/dev/zero of=$file count=$nr bs=1M
13246         sync
13247         nr=$($LFS getstripe -c $file)
13248
13249         local extents=$(filefrag -v $file |
13250                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13251
13252         echo "filefrag list $extents extents in file with stripecount $nr"
13253         if (( extents < nr )); then
13254                 $LFS getstripe $file
13255                 filefrag -v $file
13256                 error "filefrag printed $extents < $nr extents"
13257         fi
13258
13259         rm -f $file
13260 }
13261 run_test 130g "FIEMAP (overstripe file)"
13262
13263 # Test for writev/readv
13264 test_131a() {
13265         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13266                 error "writev test failed"
13267         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13268                 error "readv failed"
13269         rm -f $DIR/$tfile
13270 }
13271 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13272
13273 test_131b() {
13274         local fsize=$((524288 + 1048576 + 1572864))
13275         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13276                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13277                         error "append writev test failed"
13278
13279         ((fsize += 1572864 + 1048576))
13280         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13281                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13282                         error "append writev test failed"
13283         rm -f $DIR/$tfile
13284 }
13285 run_test 131b "test append writev"
13286
13287 test_131c() {
13288         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13289         error "NOT PASS"
13290 }
13291 run_test 131c "test read/write on file w/o objects"
13292
13293 test_131d() {
13294         rwv -f $DIR/$tfile -w -n 1 1572864
13295         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13296         if [ "$NOB" != 1572864 ]; then
13297                 error "Short read filed: read $NOB bytes instead of 1572864"
13298         fi
13299         rm -f $DIR/$tfile
13300 }
13301 run_test 131d "test short read"
13302
13303 test_131e() {
13304         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13305         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13306         error "read hitting hole failed"
13307         rm -f $DIR/$tfile
13308 }
13309 run_test 131e "test read hitting hole"
13310
13311 check_stats() {
13312         local facet=$1
13313         local op=$2
13314         local want=${3:-0}
13315         local res
13316
13317         case $facet in
13318         mds*) res=$(do_facet $facet \
13319                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13320                  ;;
13321         ost*) res=$(do_facet $facet \
13322                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13323                  ;;
13324         *) error "Wrong facet '$facet'" ;;
13325         esac
13326         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13327         # if the argument $3 is zero, it means any stat increment is ok.
13328         if [[ $want -gt 0 ]]; then
13329                 local count=$(echo $res | awk '{ print $2 }')
13330                 [[ $count -ne $want ]] &&
13331                         error "The $op counter on $facet is $count, not $want"
13332         fi
13333 }
13334
13335 test_133a() {
13336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13337         remote_ost_nodsh && skip "remote OST with nodsh"
13338         remote_mds_nodsh && skip "remote MDS with nodsh"
13339         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13340                 skip_env "MDS doesn't support rename stats"
13341
13342         local testdir=$DIR/${tdir}/stats_testdir
13343
13344         mkdir -p $DIR/${tdir}
13345
13346         # clear stats.
13347         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13348         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13349
13350         # verify mdt stats first.
13351         mkdir ${testdir} || error "mkdir failed"
13352         check_stats $SINGLEMDS "mkdir" 1
13353         touch ${testdir}/${tfile} || error "touch failed"
13354         check_stats $SINGLEMDS "open" 1
13355         check_stats $SINGLEMDS "close" 1
13356         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13357                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13358                 check_stats $SINGLEMDS "mknod" 2
13359         }
13360         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13361         check_stats $SINGLEMDS "unlink" 1
13362         rm -f ${testdir}/${tfile} || error "file remove failed"
13363         check_stats $SINGLEMDS "unlink" 2
13364
13365         # remove working dir and check mdt stats again.
13366         rmdir ${testdir} || error "rmdir failed"
13367         check_stats $SINGLEMDS "rmdir" 1
13368
13369         local testdir1=$DIR/${tdir}/stats_testdir1
13370         mkdir -p ${testdir}
13371         mkdir -p ${testdir1}
13372         touch ${testdir1}/test1
13373         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13374         check_stats $SINGLEMDS "crossdir_rename" 1
13375
13376         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13377         check_stats $SINGLEMDS "samedir_rename" 1
13378
13379         rm -rf $DIR/${tdir}
13380 }
13381 run_test 133a "Verifying MDT stats ========================================"
13382
13383 test_133b() {
13384         local res
13385
13386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13387         remote_ost_nodsh && skip "remote OST with nodsh"
13388         remote_mds_nodsh && skip "remote MDS with nodsh"
13389
13390         local testdir=$DIR/${tdir}/stats_testdir
13391
13392         mkdir -p ${testdir} || error "mkdir failed"
13393         touch ${testdir}/${tfile} || error "touch failed"
13394         cancel_lru_locks mdc
13395
13396         # clear stats.
13397         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13398         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13399
13400         # extra mdt stats verification.
13401         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13402         check_stats $SINGLEMDS "setattr" 1
13403         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13404         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13405         then            # LU-1740
13406                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13407                 check_stats $SINGLEMDS "getattr" 1
13408         fi
13409         rm -rf $DIR/${tdir}
13410
13411         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13412         # so the check below is not reliable
13413         [ $MDSCOUNT -eq 1 ] || return 0
13414
13415         # Sleep to avoid a cached response.
13416         #define OBD_STATFS_CACHE_SECONDS 1
13417         sleep 2
13418         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13419         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13420         $LFS df || error "lfs failed"
13421         check_stats $SINGLEMDS "statfs" 1
13422
13423         # check aggregated statfs (LU-10018)
13424         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13425                 return 0
13426         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13427                 return 0
13428         sleep 2
13429         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13430         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13431         df $DIR
13432         check_stats $SINGLEMDS "statfs" 1
13433
13434         # We want to check that the client didn't send OST_STATFS to
13435         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13436         # extra care is needed here.
13437         if remote_mds; then
13438                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13439                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13440
13441                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13442                 [ "$res" ] && error "OST got STATFS"
13443         fi
13444
13445         return 0
13446 }
13447 run_test 133b "Verifying extra MDT stats =================================="
13448
13449 test_133c() {
13450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13451         remote_ost_nodsh && skip "remote OST with nodsh"
13452         remote_mds_nodsh && skip "remote MDS with nodsh"
13453
13454         local testdir=$DIR/$tdir/stats_testdir
13455
13456         test_mkdir -p $testdir
13457
13458         # verify obdfilter stats.
13459         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13460         sync
13461         cancel_lru_locks osc
13462         wait_delete_completed
13463
13464         # clear stats.
13465         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13466         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13467
13468         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13469                 error "dd failed"
13470         sync
13471         cancel_lru_locks osc
13472         check_stats ost1 "write" 1
13473
13474         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13475         check_stats ost1 "read" 1
13476
13477         > $testdir/$tfile || error "truncate failed"
13478         check_stats ost1 "punch" 1
13479
13480         rm -f $testdir/$tfile || error "file remove failed"
13481         wait_delete_completed
13482         check_stats ost1 "destroy" 1
13483
13484         rm -rf $DIR/$tdir
13485 }
13486 run_test 133c "Verifying OST stats ========================================"
13487
13488 order_2() {
13489         local value=$1
13490         local orig=$value
13491         local order=1
13492
13493         while [ $value -ge 2 ]; do
13494                 order=$((order*2))
13495                 value=$((value/2))
13496         done
13497
13498         if [ $orig -gt $order ]; then
13499                 order=$((order*2))
13500         fi
13501         echo $order
13502 }
13503
13504 size_in_KMGT() {
13505     local value=$1
13506     local size=('K' 'M' 'G' 'T');
13507     local i=0
13508     local size_string=$value
13509
13510     while [ $value -ge 1024 ]; do
13511         if [ $i -gt 3 ]; then
13512             #T is the biggest unit we get here, if that is bigger,
13513             #just return XXXT
13514             size_string=${value}T
13515             break
13516         fi
13517         value=$((value >> 10))
13518         if [ $value -lt 1024 ]; then
13519             size_string=${value}${size[$i]}
13520             break
13521         fi
13522         i=$((i + 1))
13523     done
13524
13525     echo $size_string
13526 }
13527
13528 get_rename_size() {
13529         local size=$1
13530         local context=${2:-.}
13531         local sample=$(do_facet $SINGLEMDS $LCTL \
13532                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13533                 grep -A1 $context |
13534                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13535         echo $sample
13536 }
13537
13538 test_133d() {
13539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13540         remote_ost_nodsh && skip "remote OST with nodsh"
13541         remote_mds_nodsh && skip "remote MDS with nodsh"
13542         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13543                 skip_env "MDS doesn't support rename stats"
13544
13545         local testdir1=$DIR/${tdir}/stats_testdir1
13546         local testdir2=$DIR/${tdir}/stats_testdir2
13547         mkdir -p $DIR/${tdir}
13548
13549         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13550
13551         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13552         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13553
13554         createmany -o $testdir1/test 512 || error "createmany failed"
13555
13556         # check samedir rename size
13557         mv ${testdir1}/test0 ${testdir1}/test_0
13558
13559         local testdir1_size=$(ls -l $DIR/${tdir} |
13560                 awk '/stats_testdir1/ {print $5}')
13561         local testdir2_size=$(ls -l $DIR/${tdir} |
13562                 awk '/stats_testdir2/ {print $5}')
13563
13564         testdir1_size=$(order_2 $testdir1_size)
13565         testdir2_size=$(order_2 $testdir2_size)
13566
13567         testdir1_size=$(size_in_KMGT $testdir1_size)
13568         testdir2_size=$(size_in_KMGT $testdir2_size)
13569
13570         echo "source rename dir size: ${testdir1_size}"
13571         echo "target rename dir size: ${testdir2_size}"
13572
13573         local cmd="do_facet $SINGLEMDS $LCTL "
13574         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13575
13576         eval $cmd || error "$cmd failed"
13577         local samedir=$($cmd | grep 'same_dir')
13578         local same_sample=$(get_rename_size $testdir1_size)
13579         [ -z "$samedir" ] && error "samedir_rename_size count error"
13580         [[ $same_sample -eq 1 ]] ||
13581                 error "samedir_rename_size error $same_sample"
13582         echo "Check same dir rename stats success"
13583
13584         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13585
13586         # check crossdir rename size
13587         mv ${testdir1}/test_0 ${testdir2}/test_0
13588
13589         testdir1_size=$(ls -l $DIR/${tdir} |
13590                 awk '/stats_testdir1/ {print $5}')
13591         testdir2_size=$(ls -l $DIR/${tdir} |
13592                 awk '/stats_testdir2/ {print $5}')
13593
13594         testdir1_size=$(order_2 $testdir1_size)
13595         testdir2_size=$(order_2 $testdir2_size)
13596
13597         testdir1_size=$(size_in_KMGT $testdir1_size)
13598         testdir2_size=$(size_in_KMGT $testdir2_size)
13599
13600         echo "source rename dir size: ${testdir1_size}"
13601         echo "target rename dir size: ${testdir2_size}"
13602
13603         eval $cmd || error "$cmd failed"
13604         local crossdir=$($cmd | grep 'crossdir')
13605         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13606         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13607         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13608         [[ $src_sample -eq 1 ]] ||
13609                 error "crossdir_rename_size error $src_sample"
13610         [[ $tgt_sample -eq 1 ]] ||
13611                 error "crossdir_rename_size error $tgt_sample"
13612         echo "Check cross dir rename stats success"
13613         rm -rf $DIR/${tdir}
13614 }
13615 run_test 133d "Verifying rename_stats ========================================"
13616
13617 test_133e() {
13618         remote_mds_nodsh && skip "remote MDS with nodsh"
13619         remote_ost_nodsh && skip "remote OST with nodsh"
13620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13621
13622         local testdir=$DIR/${tdir}/stats_testdir
13623         local ctr f0 f1 bs=32768 count=42 sum
13624
13625         mkdir -p ${testdir} || error "mkdir failed"
13626
13627         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13628
13629         for ctr in {write,read}_bytes; do
13630                 sync
13631                 cancel_lru_locks osc
13632
13633                 do_facet ost1 $LCTL set_param -n \
13634                         "obdfilter.*.exports.clear=clear"
13635
13636                 if [ $ctr = write_bytes ]; then
13637                         f0=/dev/zero
13638                         f1=${testdir}/${tfile}
13639                 else
13640                         f0=${testdir}/${tfile}
13641                         f1=/dev/null
13642                 fi
13643
13644                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13645                         error "dd failed"
13646                 sync
13647                 cancel_lru_locks osc
13648
13649                 sum=$(do_facet ost1 $LCTL get_param \
13650                         "obdfilter.*.exports.*.stats" |
13651                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13652                                 $1 == ctr { sum += $7 }
13653                                 END { printf("%0.0f", sum) }')
13654
13655                 if ((sum != bs * count)); then
13656                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13657                 fi
13658         done
13659
13660         rm -rf $DIR/${tdir}
13661 }
13662 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13663
13664 test_133f() {
13665         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13666                 skip "too old lustre for get_param -R ($facet_ver)"
13667
13668         # verifying readability.
13669         $LCTL get_param -R '*' &> /dev/null
13670
13671         # Verifing writability with badarea_io.
13672         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13673                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13674                 error "client badarea_io failed"
13675
13676         # remount the FS in case writes/reads /proc break the FS
13677         cleanup || error "failed to unmount"
13678         setup || error "failed to setup"
13679 }
13680 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13681
13682 test_133g() {
13683         remote_mds_nodsh && skip "remote MDS with nodsh"
13684         remote_ost_nodsh && skip "remote OST with nodsh"
13685
13686         local facet
13687         for facet in mds1 ost1; do
13688                 local facet_ver=$(lustre_version_code $facet)
13689                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13690                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13691                 else
13692                         log "$facet: too old lustre for get_param -R"
13693                 fi
13694                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13695                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13696                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13697                                 xargs badarea_io" ||
13698                                         error "$facet badarea_io failed"
13699                 else
13700                         skip_noexit "$facet: too old lustre for get_param -R"
13701                 fi
13702         done
13703
13704         # remount the FS in case writes/reads /proc break the FS
13705         cleanup || error "failed to unmount"
13706         setup || error "failed to setup"
13707 }
13708 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13709
13710 test_133h() {
13711         remote_mds_nodsh && skip "remote MDS with nodsh"
13712         remote_ost_nodsh && skip "remote OST with nodsh"
13713         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13714                 skip "Need MDS version at least 2.9.54"
13715
13716         local facet
13717         for facet in client mds1 ost1; do
13718                 # Get the list of files that are missing the terminating newline
13719                 local plist=$(do_facet $facet
13720                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13721                 local ent
13722                 for ent in $plist; do
13723                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13724                                 awk -v FS='\v' -v RS='\v\v' \
13725                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13726                                         print FILENAME}'" 2>/dev/null)
13727                         [ -z $missing ] || {
13728                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13729                                 error "file does not end with newline: $facet-$ent"
13730                         }
13731                 done
13732         done
13733 }
13734 run_test 133h "Proc files should end with newlines"
13735
13736 test_134a() {
13737         remote_mds_nodsh && skip "remote MDS with nodsh"
13738         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13739                 skip "Need MDS version at least 2.7.54"
13740
13741         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13742         cancel_lru_locks mdc
13743
13744         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13745         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13746         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13747
13748         local nr=1000
13749         createmany -o $DIR/$tdir/f $nr ||
13750                 error "failed to create $nr files in $DIR/$tdir"
13751         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13752
13753         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13754         do_facet mds1 $LCTL set_param fail_loc=0x327
13755         do_facet mds1 $LCTL set_param fail_val=500
13756         touch $DIR/$tdir/m
13757
13758         echo "sleep 10 seconds ..."
13759         sleep 10
13760         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13761
13762         do_facet mds1 $LCTL set_param fail_loc=0
13763         do_facet mds1 $LCTL set_param fail_val=0
13764         [ $lck_cnt -lt $unused ] ||
13765                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13766
13767         rm $DIR/$tdir/m
13768         unlinkmany $DIR/$tdir/f $nr
13769 }
13770 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13771
13772 test_134b() {
13773         remote_mds_nodsh && skip "remote MDS with nodsh"
13774         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13775                 skip "Need MDS version at least 2.7.54"
13776
13777         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13778         cancel_lru_locks mdc
13779
13780         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13781                         ldlm.lock_reclaim_threshold_mb)
13782         # disable reclaim temporarily
13783         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13784
13785         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13786         do_facet mds1 $LCTL set_param fail_loc=0x328
13787         do_facet mds1 $LCTL set_param fail_val=500
13788
13789         $LCTL set_param debug=+trace
13790
13791         local nr=600
13792         createmany -o $DIR/$tdir/f $nr &
13793         local create_pid=$!
13794
13795         echo "Sleep $TIMEOUT seconds ..."
13796         sleep $TIMEOUT
13797         if ! ps -p $create_pid  > /dev/null 2>&1; then
13798                 do_facet mds1 $LCTL set_param fail_loc=0
13799                 do_facet mds1 $LCTL set_param fail_val=0
13800                 do_facet mds1 $LCTL set_param \
13801                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13802                 error "createmany finished incorrectly!"
13803         fi
13804         do_facet mds1 $LCTL set_param fail_loc=0
13805         do_facet mds1 $LCTL set_param fail_val=0
13806         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13807         wait $create_pid || return 1
13808
13809         unlinkmany $DIR/$tdir/f $nr
13810 }
13811 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13812
13813 test_135() {
13814         remote_mds_nodsh && skip "remote MDS with nodsh"
13815         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13816                 skip "Need MDS version at least 2.13.50"
13817         local fname
13818
13819         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13820
13821 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13822         #set only one record at plain llog
13823         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13824
13825         #fill already existed plain llog each 64767
13826         #wrapping whole catalog
13827         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13828
13829         createmany -o $DIR/$tdir/$tfile_ 64700
13830         for (( i = 0; i < 64700; i = i + 2 ))
13831         do
13832                 rm $DIR/$tdir/$tfile_$i &
13833                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13834                 local pid=$!
13835                 wait $pid
13836         done
13837
13838         #waiting osp synchronization
13839         wait_delete_completed
13840 }
13841 run_test 135 "Race catalog processing"
13842
13843 test_136() {
13844         remote_mds_nodsh && skip "remote MDS with nodsh"
13845         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13846                 skip "Need MDS version at least 2.13.50"
13847         local fname
13848
13849         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13850         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13851         #set only one record at plain llog
13852 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13853         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13854
13855         #fill already existed 2 plain llogs each 64767
13856         #wrapping whole catalog
13857         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13858         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13859         wait_delete_completed
13860
13861         createmany -o $DIR/$tdir/$tfile_ 10
13862         sleep 25
13863
13864         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13865         for (( i = 0; i < 10; i = i + 3 ))
13866         do
13867                 rm $DIR/$tdir/$tfile_$i &
13868                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13869                 local pid=$!
13870                 wait $pid
13871                 sleep 7
13872                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13873         done
13874
13875         #waiting osp synchronization
13876         wait_delete_completed
13877 }
13878 run_test 136 "Race catalog processing 2"
13879
13880 test_140() { #bug-17379
13881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13882
13883         test_mkdir $DIR/$tdir
13884         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13885         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13886
13887         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13888         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13889         local i=0
13890         while i=$((i + 1)); do
13891                 test_mkdir $i
13892                 cd $i || error "Changing to $i"
13893                 ln -s ../stat stat || error "Creating stat symlink"
13894                 # Read the symlink until ELOOP present,
13895                 # not LBUGing the system is considered success,
13896                 # we didn't overrun the stack.
13897                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13898                 if [ $ret -ne 0 ]; then
13899                         if [ $ret -eq 40 ]; then
13900                                 break  # -ELOOP
13901                         else
13902                                 error "Open stat symlink"
13903                                         return
13904                         fi
13905                 fi
13906         done
13907         i=$((i - 1))
13908         echo "The symlink depth = $i"
13909         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13910                 error "Invalid symlink depth"
13911
13912         # Test recursive symlink
13913         ln -s symlink_self symlink_self
13914         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13915         echo "open symlink_self returns $ret"
13916         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13917 }
13918 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13919
13920 test_150a() {
13921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13922
13923         local TF="$TMP/$tfile"
13924
13925         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13926         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13927         cp $TF $DIR/$tfile
13928         cancel_lru_locks $OSC
13929         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13930         remount_client $MOUNT
13931         df -P $MOUNT
13932         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13933
13934         $TRUNCATE $TF 6000
13935         $TRUNCATE $DIR/$tfile 6000
13936         cancel_lru_locks $OSC
13937         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13938
13939         echo "12345" >>$TF
13940         echo "12345" >>$DIR/$tfile
13941         cancel_lru_locks $OSC
13942         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13943
13944         echo "12345" >>$TF
13945         echo "12345" >>$DIR/$tfile
13946         cancel_lru_locks $OSC
13947         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13948 }
13949 run_test 150a "truncate/append tests"
13950
13951 test_150b() {
13952         check_set_fallocate_or_skip
13953
13954         touch $DIR/$tfile
13955         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13956         check_fallocate $DIR/$tfile || error "fallocate failed"
13957 }
13958 run_test 150b "Verify fallocate (prealloc) functionality"
13959
13960 test_150bb() {
13961         check_set_fallocate_or_skip
13962
13963         touch $DIR/$tfile
13964         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13965         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13966         > $DIR/$tfile
13967         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13968         # precomputed md5sum for 20MB of zeroes
13969         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13970         local sum=($(md5sum $DIR/$tfile))
13971
13972         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13973
13974         check_set_fallocate 1
13975
13976         > $DIR/$tfile
13977         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13978         sum=($(md5sum $DIR/$tfile))
13979
13980         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13981 }
13982 run_test 150bb "Verify fallocate modes both zero space"
13983
13984 test_150c() {
13985         check_set_fallocate_or_skip
13986
13987         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13988         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13989         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13990         sync; sync_all_data
13991         cancel_lru_locks $OSC
13992         sleep 5
13993         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13994         want=$((OSTCOUNT * 1048576))
13995
13996         # Must allocate all requested space, not more than 5% extra
13997         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13998                 error "bytes $bytes is not $want"
13999
14000         rm -f $DIR/$tfile
14001         # verify fallocate on PFL file
14002         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14003                 error "Create $DIR/$tfile failed"
14004         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14005                         error "fallocate failed"
14006         sync; sync_all_data
14007         cancel_lru_locks $OSC
14008         sleep 5
14009         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14010         local want=$((1024 * 1048576))
14011
14012         # Must allocate all requested space, not more than 5% extra
14013         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14014                 error "bytes $bytes is not $want"
14015 }
14016 run_test 150c "Verify fallocate Size and Blocks"
14017
14018 test_150d() {
14019         check_set_fallocate_or_skip
14020
14021         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14022         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14023         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14024         sync; sync_all_data
14025         cancel_lru_locks $OSC
14026         sleep 5
14027         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14028         local want=$((OSTCOUNT * 1048576))
14029
14030         # Must allocate all requested space, not more than 5% extra
14031         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14032                 error "bytes $bytes is not $want"
14033 }
14034 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14035
14036 test_150e() {
14037         check_set_fallocate_or_skip
14038
14039         echo "df before:"
14040         $LFS df
14041         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14042         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14043                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14044
14045         # Find OST with Minimum Size
14046         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14047                        sort -un | head -1)
14048
14049         # Get 100MB per OST of the available space to reduce run time
14050         # else 60% of the available space if we are running SLOW tests
14051         if [ $SLOW == "no" ]; then
14052                 local space=$((1024 * 100 * OSTCOUNT))
14053         else
14054                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14055         fi
14056
14057         fallocate -l${space}k $DIR/$tfile ||
14058                 error "fallocate ${space}k $DIR/$tfile failed"
14059         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14060
14061         # get size immediately after fallocate. This should be correctly
14062         # updated
14063         local size=$(stat -c '%s' $DIR/$tfile)
14064         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14065
14066         # Sleep for a while for statfs to get updated. And not pull from cache.
14067         sleep 2
14068
14069         echo "df after fallocate:"
14070         $LFS df
14071
14072         (( size / 1024 == space )) || error "size $size != requested $space"
14073         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14074                 error "used $used < space $space"
14075
14076         rm $DIR/$tfile || error "rm failed"
14077         sync
14078         wait_delete_completed
14079
14080         echo "df after unlink:"
14081         $LFS df
14082 }
14083 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14084
14085 test_150f() {
14086         local size
14087         local blocks
14088         local want_size_before=20480 # in bytes
14089         local want_blocks_before=40 # 512 sized blocks
14090         local want_blocks_after=24  # 512 sized blocks
14091         local length=$(((want_blocks_before - want_blocks_after) * 512))
14092
14093         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14094                 skip "need at least 2.14.0 for fallocate punch"
14095
14096         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14097                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14098         fi
14099
14100         check_set_fallocate_or_skip
14101         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14102
14103         echo "Verify fallocate punch: Range within the file range"
14104         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14105                 error "dd failed for bs 4096 and count 5"
14106
14107         # Call fallocate with punch range which is within the file range
14108         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14109                 error "fallocate failed: offset 4096 and length $length"
14110         # client must see changes immediately after fallocate
14111         size=$(stat -c '%s' $DIR/$tfile)
14112         blocks=$(stat -c '%b' $DIR/$tfile)
14113
14114         # Verify punch worked.
14115         (( blocks == want_blocks_after )) ||
14116                 error "punch failed: blocks $blocks != $want_blocks_after"
14117
14118         (( size == want_size_before )) ||
14119                 error "punch failed: size $size != $want_size_before"
14120
14121         # Verify there is hole in file
14122         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14123         # precomputed md5sum
14124         local expect="4a9a834a2db02452929c0a348273b4aa"
14125
14126         cksum=($(md5sum $DIR/$tfile))
14127         [[ "${cksum[0]}" == "$expect" ]] ||
14128                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14129
14130         # Start second sub-case for fallocate punch.
14131         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14132         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14133                 error "dd failed for bs 4096 and count 5"
14134
14135         # Punch range less than block size will have no change in block count
14136         want_blocks_after=40  # 512 sized blocks
14137
14138         # Punch overlaps two blocks and less than blocksize
14139         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14140                 error "fallocate failed: offset 4000 length 3000"
14141         size=$(stat -c '%s' $DIR/$tfile)
14142         blocks=$(stat -c '%b' $DIR/$tfile)
14143
14144         # Verify punch worked.
14145         (( blocks == want_blocks_after )) ||
14146                 error "punch failed: blocks $blocks != $want_blocks_after"
14147
14148         (( size == want_size_before )) ||
14149                 error "punch failed: size $size != $want_size_before"
14150
14151         # Verify if range is really zero'ed out. We expect Zeros.
14152         # precomputed md5sum
14153         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14154         cksum=($(md5sum $DIR/$tfile))
14155         [[ "${cksum[0]}" == "$expect" ]] ||
14156                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14157 }
14158 run_test 150f "Verify fallocate punch functionality"
14159
14160 test_150g() {
14161         local space
14162         local size
14163         local blocks
14164         local blocks_after
14165         local size_after
14166         local BS=4096 # Block size in bytes
14167
14168         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14169                 skip "need at least 2.14.0 for fallocate punch"
14170
14171         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14172                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14173         fi
14174
14175         check_set_fallocate_or_skip
14176         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14177
14178         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14179                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14180
14181         # Get 100MB per OST of the available space to reduce run time
14182         # else 60% of the available space if we are running SLOW tests
14183         if [ $SLOW == "no" ]; then
14184                 space=$((1024 * 100 * OSTCOUNT))
14185         else
14186                 # Find OST with Minimum Size
14187                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14188                         sort -un | head -1)
14189                 echo "min size OST: $space"
14190                 space=$(((space * 60)/100 * OSTCOUNT))
14191         fi
14192         # space in 1k units, round to 4k blocks
14193         local blkcount=$((space * 1024 / $BS))
14194
14195         echo "Verify fallocate punch: Very large Range"
14196         fallocate -l${space}k $DIR/$tfile ||
14197                 error "fallocate ${space}k $DIR/$tfile failed"
14198         # write 1M at the end, start and in the middle
14199         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14200                 error "dd failed: bs $BS count 256"
14201         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14202                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14203         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14204                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14205
14206         # Gather stats.
14207         size=$(stat -c '%s' $DIR/$tfile)
14208
14209         # gather punch length.
14210         local punch_size=$((size - (BS * 2)))
14211
14212         echo "punch_size = $punch_size"
14213         echo "size - punch_size: $((size - punch_size))"
14214         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14215
14216         # Call fallocate to punch all except 2 blocks. We leave the
14217         # first and the last block
14218         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14219         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14220                 error "fallocate failed: offset $BS length $punch_size"
14221
14222         size_after=$(stat -c '%s' $DIR/$tfile)
14223         blocks_after=$(stat -c '%b' $DIR/$tfile)
14224
14225         # Verify punch worked.
14226         # Size should be kept
14227         (( size == size_after )) ||
14228                 error "punch failed: size $size != $size_after"
14229
14230         # two 4k data blocks to remain plus possible 1 extra extent block
14231         (( blocks_after <= ((BS / 512) * 3) )) ||
14232                 error "too many blocks remains: $blocks_after"
14233
14234         # Verify that file has hole between the first and the last blocks
14235         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14236         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14237
14238         echo "Hole at [$hole_start, $hole_end)"
14239         (( hole_start == BS )) ||
14240                 error "no hole at offset $BS after punch"
14241
14242         (( hole_end == BS + punch_size )) ||
14243                 error "data at offset $hole_end < $((BS + punch_size))"
14244 }
14245 run_test 150g "Verify fallocate punch on large range"
14246
14247 #LU-2902 roc_hit was not able to read all values from lproc
14248 function roc_hit_init() {
14249         local list=$(comma_list $(osts_nodes))
14250         local dir=$DIR/$tdir-check
14251         local file=$dir/$tfile
14252         local BEFORE
14253         local AFTER
14254         local idx
14255
14256         test_mkdir $dir
14257         #use setstripe to do a write to every ost
14258         for i in $(seq 0 $((OSTCOUNT-1))); do
14259                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14260                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14261                 idx=$(printf %04x $i)
14262                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14263                         awk '$1 == "cache_access" {sum += $7}
14264                                 END { printf("%0.0f", sum) }')
14265
14266                 cancel_lru_locks osc
14267                 cat $file >/dev/null
14268
14269                 AFTER=$(get_osd_param $list *OST*$idx stats |
14270                         awk '$1 == "cache_access" {sum += $7}
14271                                 END { printf("%0.0f", sum) }')
14272
14273                 echo BEFORE:$BEFORE AFTER:$AFTER
14274                 if ! let "AFTER - BEFORE == 4"; then
14275                         rm -rf $dir
14276                         error "roc_hit is not safe to use"
14277                 fi
14278                 rm $file
14279         done
14280
14281         rm -rf $dir
14282 }
14283
14284 function roc_hit() {
14285         local list=$(comma_list $(osts_nodes))
14286         echo $(get_osd_param $list '' stats |
14287                 awk '$1 == "cache_hit" {sum += $7}
14288                         END { printf("%0.0f", sum) }')
14289 }
14290
14291 function set_cache() {
14292         local on=1
14293
14294         if [ "$2" == "off" ]; then
14295                 on=0;
14296         fi
14297         local list=$(comma_list $(osts_nodes))
14298         set_osd_param $list '' $1_cache_enable $on
14299
14300         cancel_lru_locks osc
14301 }
14302
14303 test_151() {
14304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14305         remote_ost_nodsh && skip "remote OST with nodsh"
14306
14307         local CPAGES=3
14308         local list=$(comma_list $(osts_nodes))
14309
14310         # check whether obdfilter is cache capable at all
14311         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14312                 skip "not cache-capable obdfilter"
14313         fi
14314
14315         # check cache is enabled on all obdfilters
14316         if get_osd_param $list '' read_cache_enable | grep 0; then
14317                 skip "oss cache is disabled"
14318         fi
14319
14320         set_osd_param $list '' writethrough_cache_enable 1
14321
14322         # check write cache is enabled on all obdfilters
14323         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14324                 skip "oss write cache is NOT enabled"
14325         fi
14326
14327         roc_hit_init
14328
14329         #define OBD_FAIL_OBD_NO_LRU  0x609
14330         do_nodes $list $LCTL set_param fail_loc=0x609
14331
14332         # pages should be in the case right after write
14333         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14334                 error "dd failed"
14335
14336         local BEFORE=$(roc_hit)
14337         cancel_lru_locks osc
14338         cat $DIR/$tfile >/dev/null
14339         local AFTER=$(roc_hit)
14340
14341         do_nodes $list $LCTL set_param fail_loc=0
14342
14343         if ! let "AFTER - BEFORE == CPAGES"; then
14344                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14345         fi
14346
14347         cancel_lru_locks osc
14348         # invalidates OST cache
14349         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14350         set_osd_param $list '' read_cache_enable 0
14351         cat $DIR/$tfile >/dev/null
14352
14353         # now data shouldn't be found in the cache
14354         BEFORE=$(roc_hit)
14355         cancel_lru_locks osc
14356         cat $DIR/$tfile >/dev/null
14357         AFTER=$(roc_hit)
14358         if let "AFTER - BEFORE != 0"; then
14359                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14360         fi
14361
14362         set_osd_param $list '' read_cache_enable 1
14363         rm -f $DIR/$tfile
14364 }
14365 run_test 151 "test cache on oss and controls ==============================="
14366
14367 test_152() {
14368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14369
14370         local TF="$TMP/$tfile"
14371
14372         # simulate ENOMEM during write
14373 #define OBD_FAIL_OST_NOMEM      0x226
14374         lctl set_param fail_loc=0x80000226
14375         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14376         cp $TF $DIR/$tfile
14377         sync || error "sync failed"
14378         lctl set_param fail_loc=0
14379
14380         # discard client's cache
14381         cancel_lru_locks osc
14382
14383         # simulate ENOMEM during read
14384         lctl set_param fail_loc=0x80000226
14385         cmp $TF $DIR/$tfile || error "cmp failed"
14386         lctl set_param fail_loc=0
14387
14388         rm -f $TF
14389 }
14390 run_test 152 "test read/write with enomem ============================"
14391
14392 test_153() {
14393         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14394 }
14395 run_test 153 "test if fdatasync does not crash ======================="
14396
14397 dot_lustre_fid_permission_check() {
14398         local fid=$1
14399         local ffid=$MOUNT/.lustre/fid/$fid
14400         local test_dir=$2
14401
14402         echo "stat fid $fid"
14403         stat $ffid > /dev/null || error "stat $ffid failed."
14404         echo "touch fid $fid"
14405         touch $ffid || error "touch $ffid failed."
14406         echo "write to fid $fid"
14407         cat /etc/hosts > $ffid || error "write $ffid failed."
14408         echo "read fid $fid"
14409         diff /etc/hosts $ffid || error "read $ffid failed."
14410         echo "append write to fid $fid"
14411         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14412         echo "rename fid $fid"
14413         mv $ffid $test_dir/$tfile.1 &&
14414                 error "rename $ffid to $tfile.1 should fail."
14415         touch $test_dir/$tfile.1
14416         mv $test_dir/$tfile.1 $ffid &&
14417                 error "rename $tfile.1 to $ffid should fail."
14418         rm -f $test_dir/$tfile.1
14419         echo "truncate fid $fid"
14420         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14421         echo "link fid $fid"
14422         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14423         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14424                 echo "setfacl fid $fid"
14425                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14426                 echo "getfacl fid $fid"
14427                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14428         fi
14429         echo "unlink fid $fid"
14430         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14431         echo "mknod fid $fid"
14432         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14433
14434         fid=[0xf00000400:0x1:0x0]
14435         ffid=$MOUNT/.lustre/fid/$fid
14436
14437         echo "stat non-exist fid $fid"
14438         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14439         echo "write to non-exist fid $fid"
14440         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14441         echo "link new fid $fid"
14442         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14443
14444         mkdir -p $test_dir/$tdir
14445         touch $test_dir/$tdir/$tfile
14446         fid=$($LFS path2fid $test_dir/$tdir)
14447         rc=$?
14448         [ $rc -ne 0 ] &&
14449                 error "error: could not get fid for $test_dir/$dir/$tfile."
14450
14451         ffid=$MOUNT/.lustre/fid/$fid
14452
14453         echo "ls $fid"
14454         ls $ffid > /dev/null || error "ls $ffid failed."
14455         echo "touch $fid/$tfile.1"
14456         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14457
14458         echo "touch $MOUNT/.lustre/fid/$tfile"
14459         touch $MOUNT/.lustre/fid/$tfile && \
14460                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14461
14462         echo "setxattr to $MOUNT/.lustre/fid"
14463         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14464
14465         echo "listxattr for $MOUNT/.lustre/fid"
14466         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14467
14468         echo "delxattr from $MOUNT/.lustre/fid"
14469         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14470
14471         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14472         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14473                 error "touch invalid fid should fail."
14474
14475         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14476         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14477                 error "touch non-normal fid should fail."
14478
14479         echo "rename $tdir to $MOUNT/.lustre/fid"
14480         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14481                 error "rename to $MOUNT/.lustre/fid should fail."
14482
14483         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14484         then            # LU-3547
14485                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14486                 local new_obf_mode=777
14487
14488                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14489                 chmod $new_obf_mode $DIR/.lustre/fid ||
14490                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14491
14492                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14493                 [ $obf_mode -eq $new_obf_mode ] ||
14494                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14495
14496                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14497                 chmod $old_obf_mode $DIR/.lustre/fid ||
14498                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14499         fi
14500
14501         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14502         fid=$($LFS path2fid $test_dir/$tfile-2)
14503
14504         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14505         then # LU-5424
14506                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14507                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14508                         error "create lov data thru .lustre failed"
14509         fi
14510         echo "cp /etc/passwd $test_dir/$tfile-2"
14511         cp /etc/passwd $test_dir/$tfile-2 ||
14512                 error "copy to $test_dir/$tfile-2 failed."
14513         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14514         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14515                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14516
14517         rm -rf $test_dir/tfile.lnk
14518         rm -rf $test_dir/$tfile-2
14519 }
14520
14521 test_154A() {
14522         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14523                 skip "Need MDS version at least 2.4.1"
14524
14525         local tf=$DIR/$tfile
14526         touch $tf
14527
14528         local fid=$($LFS path2fid $tf)
14529         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14530
14531         # check that we get the same pathname back
14532         local rootpath
14533         local found
14534         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14535                 echo "$rootpath $fid"
14536                 found=$($LFS fid2path $rootpath "$fid")
14537                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14538                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14539         done
14540
14541         # check wrong root path format
14542         rootpath=$MOUNT"_wrong"
14543         found=$($LFS fid2path $rootpath "$fid")
14544         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14545 }
14546 run_test 154A "lfs path2fid and fid2path basic checks"
14547
14548 test_154B() {
14549         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14550                 skip "Need MDS version at least 2.4.1"
14551
14552         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14553         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14554         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14555         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14556
14557         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14558         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14559
14560         # check that we get the same pathname
14561         echo "PFID: $PFID, name: $name"
14562         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14563         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14564         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14565                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14566
14567         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14568 }
14569 run_test 154B "verify the ll_decode_linkea tool"
14570
14571 test_154a() {
14572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14573         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14574         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14575                 skip "Need MDS version at least 2.2.51"
14576         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14577
14578         cp /etc/hosts $DIR/$tfile
14579
14580         fid=$($LFS path2fid $DIR/$tfile)
14581         rc=$?
14582         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14583
14584         dot_lustre_fid_permission_check "$fid" $DIR ||
14585                 error "dot lustre permission check $fid failed"
14586
14587         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14588
14589         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14590
14591         touch $MOUNT/.lustre/file &&
14592                 error "creation is not allowed under .lustre"
14593
14594         mkdir $MOUNT/.lustre/dir &&
14595                 error "mkdir is not allowed under .lustre"
14596
14597         rm -rf $DIR/$tfile
14598 }
14599 run_test 154a "Open-by-FID"
14600
14601 test_154b() {
14602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14603         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14605         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14606                 skip "Need MDS version at least 2.2.51"
14607
14608         local remote_dir=$DIR/$tdir/remote_dir
14609         local MDTIDX=1
14610         local rc=0
14611
14612         mkdir -p $DIR/$tdir
14613         $LFS mkdir -i $MDTIDX $remote_dir ||
14614                 error "create remote directory failed"
14615
14616         cp /etc/hosts $remote_dir/$tfile
14617
14618         fid=$($LFS path2fid $remote_dir/$tfile)
14619         rc=$?
14620         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14621
14622         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14623                 error "dot lustre permission check $fid failed"
14624         rm -rf $DIR/$tdir
14625 }
14626 run_test 154b "Open-by-FID for remote directory"
14627
14628 test_154c() {
14629         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14630                 skip "Need MDS version at least 2.4.1"
14631
14632         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14633         local FID1=$($LFS path2fid $DIR/$tfile.1)
14634         local FID2=$($LFS path2fid $DIR/$tfile.2)
14635         local FID3=$($LFS path2fid $DIR/$tfile.3)
14636
14637         local N=1
14638         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14639                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14640                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14641                 local want=FID$N
14642                 [ "$FID" = "${!want}" ] ||
14643                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14644                 N=$((N + 1))
14645         done
14646
14647         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14648         do
14649                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14650                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14651                 N=$((N + 1))
14652         done
14653 }
14654 run_test 154c "lfs path2fid and fid2path multiple arguments"
14655
14656 test_154d() {
14657         remote_mds_nodsh && skip "remote MDS with nodsh"
14658         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14659                 skip "Need MDS version at least 2.5.53"
14660
14661         if remote_mds; then
14662                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14663         else
14664                 nid="0@lo"
14665         fi
14666         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14667         local fd
14668         local cmd
14669
14670         rm -f $DIR/$tfile
14671         touch $DIR/$tfile
14672
14673         local fid=$($LFS path2fid $DIR/$tfile)
14674         # Open the file
14675         fd=$(free_fd)
14676         cmd="exec $fd<$DIR/$tfile"
14677         eval $cmd
14678         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14679         echo "$fid_list" | grep "$fid"
14680         rc=$?
14681
14682         cmd="exec $fd>/dev/null"
14683         eval $cmd
14684         if [ $rc -ne 0 ]; then
14685                 error "FID $fid not found in open files list $fid_list"
14686         fi
14687 }
14688 run_test 154d "Verify open file fid"
14689
14690 test_154e()
14691 {
14692         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14693                 skip "Need MDS version at least 2.6.50"
14694
14695         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14696                 error ".lustre returned by readdir"
14697         fi
14698 }
14699 run_test 154e ".lustre is not returned by readdir"
14700
14701 test_154f() {
14702         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14703
14704         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14705         test_mkdir -p -c1 $DIR/$tdir/d
14706         # test dirs inherit from its stripe
14707         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14708         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14709         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14710         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14711         touch $DIR/f
14712
14713         # get fid of parents
14714         local FID0=$($LFS path2fid $DIR/$tdir/d)
14715         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14716         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14717         local FID3=$($LFS path2fid $DIR)
14718
14719         # check that path2fid --parents returns expected <parent_fid>/name
14720         # 1) test for a directory (single parent)
14721         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14722         [ "$parent" == "$FID0/foo1" ] ||
14723                 error "expected parent: $FID0/foo1, got: $parent"
14724
14725         # 2) test for a file with nlink > 1 (multiple parents)
14726         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14727         echo "$parent" | grep -F "$FID1/$tfile" ||
14728                 error "$FID1/$tfile not returned in parent list"
14729         echo "$parent" | grep -F "$FID2/link" ||
14730                 error "$FID2/link not returned in parent list"
14731
14732         # 3) get parent by fid
14733         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14734         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14735         echo "$parent" | grep -F "$FID1/$tfile" ||
14736                 error "$FID1/$tfile not returned in parent list (by fid)"
14737         echo "$parent" | grep -F "$FID2/link" ||
14738                 error "$FID2/link not returned in parent list (by fid)"
14739
14740         # 4) test for entry in root directory
14741         parent=$($LFS path2fid --parents $DIR/f)
14742         echo "$parent" | grep -F "$FID3/f" ||
14743                 error "$FID3/f not returned in parent list"
14744
14745         # 5) test it on root directory
14746         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14747                 error "$MOUNT should not have parents"
14748
14749         # enable xattr caching and check that linkea is correctly updated
14750         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14751         save_lustre_params client "llite.*.xattr_cache" > $save
14752         lctl set_param llite.*.xattr_cache 1
14753
14754         # 6.1) linkea update on rename
14755         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14756
14757         # get parents by fid
14758         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14759         # foo1 should no longer be returned in parent list
14760         echo "$parent" | grep -F "$FID1" &&
14761                 error "$FID1 should no longer be in parent list"
14762         # the new path should appear
14763         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14764                 error "$FID2/$tfile.moved is not in parent list"
14765
14766         # 6.2) linkea update on unlink
14767         rm -f $DIR/$tdir/d/foo2/link
14768         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14769         # foo2/link should no longer be returned in parent list
14770         echo "$parent" | grep -F "$FID2/link" &&
14771                 error "$FID2/link should no longer be in parent list"
14772         true
14773
14774         rm -f $DIR/f
14775         restore_lustre_params < $save
14776         rm -f $save
14777 }
14778 run_test 154f "get parent fids by reading link ea"
14779
14780 test_154g()
14781 {
14782         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14783         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14784            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14785                 skip "Need MDS version at least 2.6.92"
14786
14787         mkdir -p $DIR/$tdir
14788         llapi_fid_test -d $DIR/$tdir
14789 }
14790 run_test 154g "various llapi FID tests"
14791
14792 test_155_small_load() {
14793     local temp=$TMP/$tfile
14794     local file=$DIR/$tfile
14795
14796     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14797         error "dd of=$temp bs=6096 count=1 failed"
14798     cp $temp $file
14799     cancel_lru_locks $OSC
14800     cmp $temp $file || error "$temp $file differ"
14801
14802     $TRUNCATE $temp 6000
14803     $TRUNCATE $file 6000
14804     cmp $temp $file || error "$temp $file differ (truncate1)"
14805
14806     echo "12345" >>$temp
14807     echo "12345" >>$file
14808     cmp $temp $file || error "$temp $file differ (append1)"
14809
14810     echo "12345" >>$temp
14811     echo "12345" >>$file
14812     cmp $temp $file || error "$temp $file differ (append2)"
14813
14814     rm -f $temp $file
14815     true
14816 }
14817
14818 test_155_big_load() {
14819         remote_ost_nodsh && skip "remote OST with nodsh"
14820
14821         local temp=$TMP/$tfile
14822         local file=$DIR/$tfile
14823
14824         free_min_max
14825         local cache_size=$(do_facet ost$((MAXI+1)) \
14826                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14827         local large_file_size=$((cache_size * 2))
14828
14829         echo "OSS cache size: $cache_size KB"
14830         echo "Large file size: $large_file_size KB"
14831
14832         [ $MAXV -le $large_file_size ] &&
14833                 skip_env "max available OST size needs > $large_file_size KB"
14834
14835         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14836
14837         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14838                 error "dd of=$temp bs=$large_file_size count=1k failed"
14839         cp $temp $file
14840         ls -lh $temp $file
14841         cancel_lru_locks osc
14842         cmp $temp $file || error "$temp $file differ"
14843
14844         rm -f $temp $file
14845         true
14846 }
14847
14848 save_writethrough() {
14849         local facets=$(get_facets OST)
14850
14851         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14852 }
14853
14854 test_155a() {
14855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14856
14857         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14858
14859         save_writethrough $p
14860
14861         set_cache read on
14862         set_cache writethrough on
14863         test_155_small_load
14864         restore_lustre_params < $p
14865         rm -f $p
14866 }
14867 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14868
14869 test_155b() {
14870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14871
14872         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14873
14874         save_writethrough $p
14875
14876         set_cache read on
14877         set_cache writethrough off
14878         test_155_small_load
14879         restore_lustre_params < $p
14880         rm -f $p
14881 }
14882 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14883
14884 test_155c() {
14885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14886
14887         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14888
14889         save_writethrough $p
14890
14891         set_cache read off
14892         set_cache writethrough on
14893         test_155_small_load
14894         restore_lustre_params < $p
14895         rm -f $p
14896 }
14897 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14898
14899 test_155d() {
14900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14901
14902         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14903
14904         save_writethrough $p
14905
14906         set_cache read off
14907         set_cache writethrough off
14908         test_155_small_load
14909         restore_lustre_params < $p
14910         rm -f $p
14911 }
14912 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14913
14914 test_155e() {
14915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14916
14917         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14918
14919         save_writethrough $p
14920
14921         set_cache read on
14922         set_cache writethrough on
14923         test_155_big_load
14924         restore_lustre_params < $p
14925         rm -f $p
14926 }
14927 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14928
14929 test_155f() {
14930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14931
14932         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14933
14934         save_writethrough $p
14935
14936         set_cache read on
14937         set_cache writethrough off
14938         test_155_big_load
14939         restore_lustre_params < $p
14940         rm -f $p
14941 }
14942 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14943
14944 test_155g() {
14945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14946
14947         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14948
14949         save_writethrough $p
14950
14951         set_cache read off
14952         set_cache writethrough on
14953         test_155_big_load
14954         restore_lustre_params < $p
14955         rm -f $p
14956 }
14957 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14958
14959 test_155h() {
14960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14961
14962         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14963
14964         save_writethrough $p
14965
14966         set_cache read off
14967         set_cache writethrough off
14968         test_155_big_load
14969         restore_lustre_params < $p
14970         rm -f $p
14971 }
14972 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14973
14974 test_156() {
14975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14976         remote_ost_nodsh && skip "remote OST with nodsh"
14977         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14978                 skip "stats not implemented on old servers"
14979         [ "$ost1_FSTYPE" = "zfs" ] &&
14980                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14981
14982         local CPAGES=3
14983         local BEFORE
14984         local AFTER
14985         local file="$DIR/$tfile"
14986         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14987
14988         save_writethrough $p
14989         roc_hit_init
14990
14991         log "Turn on read and write cache"
14992         set_cache read on
14993         set_cache writethrough on
14994
14995         log "Write data and read it back."
14996         log "Read should be satisfied from the cache."
14997         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14998         BEFORE=$(roc_hit)
14999         cancel_lru_locks osc
15000         cat $file >/dev/null
15001         AFTER=$(roc_hit)
15002         if ! let "AFTER - BEFORE == CPAGES"; then
15003                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15004         else
15005                 log "cache hits: before: $BEFORE, after: $AFTER"
15006         fi
15007
15008         log "Read again; it should be satisfied from the cache."
15009         BEFORE=$AFTER
15010         cancel_lru_locks osc
15011         cat $file >/dev/null
15012         AFTER=$(roc_hit)
15013         if ! let "AFTER - BEFORE == CPAGES"; then
15014                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15015         else
15016                 log "cache hits:: before: $BEFORE, after: $AFTER"
15017         fi
15018
15019         log "Turn off the read cache and turn on the write cache"
15020         set_cache read off
15021         set_cache writethrough on
15022
15023         log "Read again; it should be satisfied from the cache."
15024         BEFORE=$(roc_hit)
15025         cancel_lru_locks osc
15026         cat $file >/dev/null
15027         AFTER=$(roc_hit)
15028         if ! let "AFTER - BEFORE == CPAGES"; then
15029                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15030         else
15031                 log "cache hits:: before: $BEFORE, after: $AFTER"
15032         fi
15033
15034         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15035                 # > 2.12.56 uses pagecache if cached
15036                 log "Read again; it should not be satisfied from the cache."
15037                 BEFORE=$AFTER
15038                 cancel_lru_locks osc
15039                 cat $file >/dev/null
15040                 AFTER=$(roc_hit)
15041                 if ! let "AFTER - BEFORE == 0"; then
15042                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15043                 else
15044                         log "cache hits:: before: $BEFORE, after: $AFTER"
15045                 fi
15046         fi
15047
15048         log "Write data and read it back."
15049         log "Read should be satisfied from the cache."
15050         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15051         BEFORE=$(roc_hit)
15052         cancel_lru_locks osc
15053         cat $file >/dev/null
15054         AFTER=$(roc_hit)
15055         if ! let "AFTER - BEFORE == CPAGES"; then
15056                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15057         else
15058                 log "cache hits:: before: $BEFORE, after: $AFTER"
15059         fi
15060
15061         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15062                 # > 2.12.56 uses pagecache if cached
15063                 log "Read again; it should not be satisfied from the cache."
15064                 BEFORE=$AFTER
15065                 cancel_lru_locks osc
15066                 cat $file >/dev/null
15067                 AFTER=$(roc_hit)
15068                 if ! let "AFTER - BEFORE == 0"; then
15069                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15070                 else
15071                         log "cache hits:: before: $BEFORE, after: $AFTER"
15072                 fi
15073         fi
15074
15075         log "Turn off read and write cache"
15076         set_cache read off
15077         set_cache writethrough off
15078
15079         log "Write data and read it back"
15080         log "It should not be satisfied from the cache."
15081         rm -f $file
15082         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15083         cancel_lru_locks osc
15084         BEFORE=$(roc_hit)
15085         cat $file >/dev/null
15086         AFTER=$(roc_hit)
15087         if ! let "AFTER - BEFORE == 0"; then
15088                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15089         else
15090                 log "cache hits:: before: $BEFORE, after: $AFTER"
15091         fi
15092
15093         log "Turn on the read cache and turn off the write cache"
15094         set_cache read on
15095         set_cache writethrough off
15096
15097         log "Write data and read it back"
15098         log "It should not be satisfied from the cache."
15099         rm -f $file
15100         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15101         BEFORE=$(roc_hit)
15102         cancel_lru_locks osc
15103         cat $file >/dev/null
15104         AFTER=$(roc_hit)
15105         if ! let "AFTER - BEFORE == 0"; then
15106                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15107         else
15108                 log "cache hits:: before: $BEFORE, after: $AFTER"
15109         fi
15110
15111         log "Read again; it should be satisfied from the cache."
15112         BEFORE=$(roc_hit)
15113         cancel_lru_locks osc
15114         cat $file >/dev/null
15115         AFTER=$(roc_hit)
15116         if ! let "AFTER - BEFORE == CPAGES"; then
15117                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15118         else
15119                 log "cache hits:: before: $BEFORE, after: $AFTER"
15120         fi
15121
15122         restore_lustre_params < $p
15123         rm -f $p $file
15124 }
15125 run_test 156 "Verification of tunables"
15126
15127 test_160a() {
15128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15129         remote_mds_nodsh && skip "remote MDS with nodsh"
15130         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15131                 skip "Need MDS version at least 2.2.0"
15132
15133         changelog_register || error "changelog_register failed"
15134         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15135         changelog_users $SINGLEMDS | grep -q $cl_user ||
15136                 error "User $cl_user not found in changelog_users"
15137
15138         # change something
15139         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15140         changelog_clear 0 || error "changelog_clear failed"
15141         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15142         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15143         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15144         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15145         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15146         rm $DIR/$tdir/pics/desktop.jpg
15147
15148         changelog_dump | tail -10
15149
15150         echo "verifying changelog mask"
15151         changelog_chmask "-MKDIR"
15152         changelog_chmask "-CLOSE"
15153
15154         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15155         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15156
15157         changelog_chmask "+MKDIR"
15158         changelog_chmask "+CLOSE"
15159
15160         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15161         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15162
15163         changelog_dump | tail -10
15164         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15165         CLOSES=$(changelog_dump | grep -c "CLOSE")
15166         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15167         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15168
15169         # verify contents
15170         echo "verifying target fid"
15171         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15172         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15173         [ "$fidc" == "$fidf" ] ||
15174                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15175         echo "verifying parent fid"
15176         # The FID returned from the Changelog may be the directory shard on
15177         # a different MDT, and not the FID returned by path2fid on the parent.
15178         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15179         # since this is what will matter when recreating this file in the tree.
15180         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15181         local pathp=$($LFS fid2path $MOUNT "$fidp")
15182         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15183                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15184
15185         echo "getting records for $cl_user"
15186         changelog_users $SINGLEMDS
15187         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15188         local nclr=3
15189         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15190                 error "changelog_clear failed"
15191         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15192         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15193         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15194                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15195
15196         local min0_rec=$(changelog_users $SINGLEMDS |
15197                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15198         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15199                           awk '{ print $1; exit; }')
15200
15201         changelog_dump | tail -n 5
15202         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15203         [ $first_rec == $((min0_rec + 1)) ] ||
15204                 error "first index should be $min0_rec + 1 not $first_rec"
15205
15206         # LU-3446 changelog index reset on MDT restart
15207         local cur_rec1=$(changelog_users $SINGLEMDS |
15208                          awk '/^current.index:/ { print $NF }')
15209         changelog_clear 0 ||
15210                 error "clear all changelog records for $cl_user failed"
15211         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15212         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15213                 error "Fail to start $SINGLEMDS"
15214         local cur_rec2=$(changelog_users $SINGLEMDS |
15215                          awk '/^current.index:/ { print $NF }')
15216         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15217         [ $cur_rec1 == $cur_rec2 ] ||
15218                 error "current index should be $cur_rec1 not $cur_rec2"
15219
15220         echo "verifying users from this test are deregistered"
15221         changelog_deregister || error "changelog_deregister failed"
15222         changelog_users $SINGLEMDS | grep -q $cl_user &&
15223                 error "User '$cl_user' still in changelog_users"
15224
15225         # lctl get_param -n mdd.*.changelog_users
15226         # current index: 144
15227         # ID    index (idle seconds)
15228         # cl3   144 (2)
15229         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15230                 # this is the normal case where all users were deregistered
15231                 # make sure no new records are added when no users are present
15232                 local last_rec1=$(changelog_users $SINGLEMDS |
15233                                   awk '/^current.index:/ { print $NF }')
15234                 touch $DIR/$tdir/chloe
15235                 local last_rec2=$(changelog_users $SINGLEMDS |
15236                                   awk '/^current.index:/ { print $NF }')
15237                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15238                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15239         else
15240                 # any changelog users must be leftovers from a previous test
15241                 changelog_users $SINGLEMDS
15242                 echo "other changelog users; can't verify off"
15243         fi
15244 }
15245 run_test 160a "changelog sanity"
15246
15247 test_160b() { # LU-3587
15248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15249         remote_mds_nodsh && skip "remote MDS with nodsh"
15250         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15251                 skip "Need MDS version at least 2.2.0"
15252
15253         changelog_register || error "changelog_register failed"
15254         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15255         changelog_users $SINGLEMDS | grep -q $cl_user ||
15256                 error "User '$cl_user' not found in changelog_users"
15257
15258         local longname1=$(str_repeat a 255)
15259         local longname2=$(str_repeat b 255)
15260
15261         cd $DIR
15262         echo "creating very long named file"
15263         touch $longname1 || error "create of '$longname1' failed"
15264         echo "renaming very long named file"
15265         mv $longname1 $longname2
15266
15267         changelog_dump | grep RENME | tail -n 5
15268         rm -f $longname2
15269 }
15270 run_test 160b "Verify that very long rename doesn't crash in changelog"
15271
15272 test_160c() {
15273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15274         remote_mds_nodsh && skip "remote MDS with nodsh"
15275
15276         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15277                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15278                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15279                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15280
15281         local rc=0
15282
15283         # Registration step
15284         changelog_register || error "changelog_register failed"
15285
15286         rm -rf $DIR/$tdir
15287         mkdir -p $DIR/$tdir
15288         $MCREATE $DIR/$tdir/foo_160c
15289         changelog_chmask "-TRUNC"
15290         $TRUNCATE $DIR/$tdir/foo_160c 200
15291         changelog_chmask "+TRUNC"
15292         $TRUNCATE $DIR/$tdir/foo_160c 199
15293         changelog_dump | tail -n 5
15294         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15295         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15296 }
15297 run_test 160c "verify that changelog log catch the truncate event"
15298
15299 test_160d() {
15300         remote_mds_nodsh && skip "remote MDS with nodsh"
15301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15303         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15304                 skip "Need MDS version at least 2.7.60"
15305
15306         # Registration step
15307         changelog_register || error "changelog_register failed"
15308
15309         mkdir -p $DIR/$tdir/migrate_dir
15310         changelog_clear 0 || error "changelog_clear failed"
15311
15312         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15313         changelog_dump | tail -n 5
15314         local migrates=$(changelog_dump | grep -c "MIGRT")
15315         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15316 }
15317 run_test 160d "verify that changelog log catch the migrate event"
15318
15319 test_160e() {
15320         remote_mds_nodsh && skip "remote MDS with nodsh"
15321
15322         # Create a user
15323         changelog_register || error "changelog_register failed"
15324
15325         # Delete a future user (expect fail)
15326         local MDT0=$(facet_svc $SINGLEMDS)
15327         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15328         local rc=$?
15329
15330         if [ $rc -eq 0 ]; then
15331                 error "Deleted non-existant user cl77"
15332         elif [ $rc -ne 2 ]; then
15333                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15334         fi
15335
15336         # Clear to a bad index (1 billion should be safe)
15337         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15338         rc=$?
15339
15340         if [ $rc -eq 0 ]; then
15341                 error "Successfully cleared to invalid CL index"
15342         elif [ $rc -ne 22 ]; then
15343                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15344         fi
15345 }
15346 run_test 160e "changelog negative testing (should return errors)"
15347
15348 test_160f() {
15349         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15350         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15351                 skip "Need MDS version at least 2.10.56"
15352
15353         local mdts=$(comma_list $(mdts_nodes))
15354
15355         # Create a user
15356         changelog_register || error "first changelog_register failed"
15357         changelog_register || error "second changelog_register failed"
15358         local cl_users
15359         declare -A cl_user1
15360         declare -A cl_user2
15361         local user_rec1
15362         local user_rec2
15363         local i
15364
15365         # generate some changelog records to accumulate on each MDT
15366         # use all_char because created files should be evenly distributed
15367         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15368                 error "test_mkdir $tdir failed"
15369         log "$(date +%s): creating first files"
15370         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15371                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15372                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15373         done
15374
15375         # check changelogs have been generated
15376         local start=$SECONDS
15377         local idle_time=$((MDSCOUNT * 5 + 5))
15378         local nbcl=$(changelog_dump | wc -l)
15379         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15380
15381         for param in "changelog_max_idle_time=$idle_time" \
15382                      "changelog_gc=1" \
15383                      "changelog_min_gc_interval=2" \
15384                      "changelog_min_free_cat_entries=3"; do
15385                 local MDT0=$(facet_svc $SINGLEMDS)
15386                 local var="${param%=*}"
15387                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15388
15389                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15390                 do_nodes $mdts $LCTL set_param mdd.*.$param
15391         done
15392
15393         # force cl_user2 to be idle (1st part), but also cancel the
15394         # cl_user1 records so that it is not evicted later in the test.
15395         local sleep1=$((idle_time / 2))
15396         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15397         sleep $sleep1
15398
15399         # simulate changelog catalog almost full
15400         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15401         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15402
15403         for i in $(seq $MDSCOUNT); do
15404                 cl_users=(${CL_USERS[mds$i]})
15405                 cl_user1[mds$i]="${cl_users[0]}"
15406                 cl_user2[mds$i]="${cl_users[1]}"
15407
15408                 [ -n "${cl_user1[mds$i]}" ] ||
15409                         error "mds$i: no user registered"
15410                 [ -n "${cl_user2[mds$i]}" ] ||
15411                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15412
15413                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15414                 [ -n "$user_rec1" ] ||
15415                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15416                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15417                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15418                 [ -n "$user_rec2" ] ||
15419                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15420                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15421                      "$user_rec1 + 2 == $user_rec2"
15422                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15423                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15424                               "$user_rec1 + 2, but is $user_rec2"
15425                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15426                 [ -n "$user_rec2" ] ||
15427                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15428                 [ $user_rec1 == $user_rec2 ] ||
15429                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15430                               "$user_rec1, but is $user_rec2"
15431         done
15432
15433         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15434         local sleep2=$((idle_time - (SECONDS - start) + 1))
15435         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15436         sleep $sleep2
15437
15438         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15439         # cl_user1 should be OK because it recently processed records.
15440         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15441         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15442                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15443                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15444         done
15445
15446         # ensure gc thread is done
15447         for i in $(mdts_nodes); do
15448                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15449                         error "$i: GC-thread not done"
15450         done
15451
15452         local first_rec
15453         for (( i = 1; i <= MDSCOUNT; i++ )); do
15454                 # check cl_user1 still registered
15455                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15456                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15457                 # check cl_user2 unregistered
15458                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15459                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15460
15461                 # check changelogs are present and starting at $user_rec1 + 1
15462                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15463                 [ -n "$user_rec1" ] ||
15464                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15465                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15466                             awk '{ print $1; exit; }')
15467
15468                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15469                 [ $((user_rec1 + 1)) == $first_rec ] ||
15470                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15471         done
15472 }
15473 run_test 160f "changelog garbage collect (timestamped users)"
15474
15475 test_160g() {
15476         remote_mds_nodsh && skip "remote MDS with nodsh"
15477         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15478                 skip "Need MDS version at least 2.10.56"
15479
15480         local mdts=$(comma_list $(mdts_nodes))
15481
15482         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15483         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15484
15485         # Create a user
15486         changelog_register || error "first changelog_register failed"
15487         changelog_register || error "second changelog_register failed"
15488         local cl_users
15489         declare -A cl_user1
15490         declare -A cl_user2
15491         local user_rec1
15492         local user_rec2
15493         local i
15494
15495         # generate some changelog records to accumulate on each MDT
15496         # use all_char because created files should be evenly distributed
15497         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15498                 error "test_mkdir $tdir failed"
15499         for ((i = 0; i < MDSCOUNT; i++)); do
15500                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15501                         error "create $DIR/$tdir/d$i.1 failed"
15502         done
15503
15504         # check changelogs have been generated
15505         local nbcl=$(changelog_dump | wc -l)
15506         (( $nbcl > 0 )) || error "no changelogs found"
15507
15508         # reduce the max_idle_indexes value to make sure we exceed it
15509         for param in "changelog_max_idle_indexes=1" \
15510                      "changelog_gc=1" \
15511                      "changelog_min_gc_interval=2" \
15512                      "changelog_min_free_cat_entries=3"; do
15513                 local MDT0=$(facet_svc $SINGLEMDS)
15514                 local var="${param%=*}"
15515                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15516
15517                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15518                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15519                         error "unable to set mdd.*.$param"
15520         done
15521
15522         # simulate changelog catalog almost full
15523         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15524         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15525
15526         local start=$SECONDS
15527         for i in $(seq $MDSCOUNT); do
15528                 cl_users=(${CL_USERS[mds$i]})
15529                 cl_user1[mds$i]="${cl_users[0]}"
15530                 cl_user2[mds$i]="${cl_users[1]}"
15531
15532                 [ -n "${cl_user1[mds$i]}" ] ||
15533                         error "mds$i: no user registered"
15534                 [ -n "${cl_user2[mds$i]}" ] ||
15535                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15536
15537                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15538                 [ -n "$user_rec1" ] ||
15539                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15540                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15541                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15542                 [ -n "$user_rec2" ] ||
15543                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15544                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15545                      "$user_rec1 + 2 == $user_rec2"
15546                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15547                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15548                               "$user_rec1 + 2, but is $user_rec2"
15549                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15550                 [ -n "$user_rec2" ] ||
15551                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15552                 [ $user_rec1 == $user_rec2 ] ||
15553                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15554                               "$user_rec1, but is $user_rec2"
15555         done
15556
15557         # ensure we are past the previous changelog_min_gc_interval set above
15558         local sleep2=$((start + 2 - SECONDS))
15559         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15560
15561         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15562         # cl_user1 should be OK because it recently processed records.
15563         for ((i = 0; i < MDSCOUNT; i++)); do
15564                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15565                         error "create $DIR/$tdir/d$i.3 failed"
15566         done
15567
15568         # ensure gc thread is done
15569         for i in $(mdts_nodes); do
15570                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15571                         error "$i: GC-thread not done"
15572         done
15573
15574         local first_rec
15575         for (( i = 1; i <= MDSCOUNT; i++ )); do
15576                 # check cl_user1 still registered
15577                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15578                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15579                 # check cl_user2 unregistered
15580                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15581                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15582
15583                 # check changelogs are present and starting at $user_rec1 + 1
15584                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15585                 [ -n "$user_rec1" ] ||
15586                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15587                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15588                             awk '{ print $1; exit; }')
15589
15590                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15591                 [ $((user_rec1 + 1)) == $first_rec ] ||
15592                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15593         done
15594 }
15595 run_test 160g "changelog garbage collect (old users)"
15596
15597 test_160h() {
15598         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15599         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15600                 skip "Need MDS version at least 2.10.56"
15601
15602         local mdts=$(comma_list $(mdts_nodes))
15603
15604         # Create a user
15605         changelog_register || error "first changelog_register failed"
15606         changelog_register || error "second changelog_register failed"
15607         local cl_users
15608         declare -A cl_user1
15609         declare -A cl_user2
15610         local user_rec1
15611         local user_rec2
15612         local i
15613
15614         # generate some changelog records to accumulate on each MDT
15615         # use all_char because created files should be evenly distributed
15616         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15617                 error "test_mkdir $tdir failed"
15618         for ((i = 0; i < MDSCOUNT; i++)); do
15619                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15620                         error "create $DIR/$tdir/d$i.1 failed"
15621         done
15622
15623         # check changelogs have been generated
15624         local nbcl=$(changelog_dump | wc -l)
15625         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15626
15627         for param in "changelog_max_idle_time=10" \
15628                      "changelog_gc=1" \
15629                      "changelog_min_gc_interval=2"; do
15630                 local MDT0=$(facet_svc $SINGLEMDS)
15631                 local var="${param%=*}"
15632                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15633
15634                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15635                 do_nodes $mdts $LCTL set_param mdd.*.$param
15636         done
15637
15638         # force cl_user2 to be idle (1st part)
15639         sleep 9
15640
15641         for i in $(seq $MDSCOUNT); do
15642                 cl_users=(${CL_USERS[mds$i]})
15643                 cl_user1[mds$i]="${cl_users[0]}"
15644                 cl_user2[mds$i]="${cl_users[1]}"
15645
15646                 [ -n "${cl_user1[mds$i]}" ] ||
15647                         error "mds$i: no user registered"
15648                 [ -n "${cl_user2[mds$i]}" ] ||
15649                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15650
15651                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15652                 [ -n "$user_rec1" ] ||
15653                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15654                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15655                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15656                 [ -n "$user_rec2" ] ||
15657                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15658                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15659                      "$user_rec1 + 2 == $user_rec2"
15660                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15661                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15662                               "$user_rec1 + 2, but is $user_rec2"
15663                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15664                 [ -n "$user_rec2" ] ||
15665                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15666                 [ $user_rec1 == $user_rec2 ] ||
15667                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15668                               "$user_rec1, but is $user_rec2"
15669         done
15670
15671         # force cl_user2 to be idle (2nd part) and to reach
15672         # changelog_max_idle_time
15673         sleep 2
15674
15675         # force each GC-thread start and block then
15676         # one per MDT/MDD, set fail_val accordingly
15677         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15678         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15679
15680         # generate more changelogs to trigger fail_loc
15681         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15682                 error "create $DIR/$tdir/${tfile}bis failed"
15683
15684         # stop MDT to stop GC-thread, should be done in back-ground as it will
15685         # block waiting for the thread to be released and exit
15686         declare -A stop_pids
15687         for i in $(seq $MDSCOUNT); do
15688                 stop mds$i &
15689                 stop_pids[mds$i]=$!
15690         done
15691
15692         for i in $(mdts_nodes); do
15693                 local facet
15694                 local nb=0
15695                 local facets=$(facets_up_on_host $i)
15696
15697                 for facet in ${facets//,/ }; do
15698                         if [[ $facet == mds* ]]; then
15699                                 nb=$((nb + 1))
15700                         fi
15701                 done
15702                 # ensure each MDS's gc threads are still present and all in "R"
15703                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15704                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15705                         error "$i: expected $nb GC-thread"
15706                 wait_update $i \
15707                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15708                         "R" 20 ||
15709                         error "$i: GC-thread not found in R-state"
15710                 # check umounts of each MDT on MDS have reached kthread_stop()
15711                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15712                         error "$i: expected $nb umount"
15713                 wait_update $i \
15714                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15715                         error "$i: umount not found in D-state"
15716         done
15717
15718         # release all GC-threads
15719         do_nodes $mdts $LCTL set_param fail_loc=0
15720
15721         # wait for MDT stop to complete
15722         for i in $(seq $MDSCOUNT); do
15723                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15724         done
15725
15726         # XXX
15727         # may try to check if any orphan changelog records are present
15728         # via ldiskfs/zfs and llog_reader...
15729
15730         # re-start/mount MDTs
15731         for i in $(seq $MDSCOUNT); do
15732                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15733                         error "Fail to start mds$i"
15734         done
15735
15736         local first_rec
15737         for i in $(seq $MDSCOUNT); do
15738                 # check cl_user1 still registered
15739                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15740                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15741                 # check cl_user2 unregistered
15742                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15743                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15744
15745                 # check changelogs are present and starting at $user_rec1 + 1
15746                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15747                 [ -n "$user_rec1" ] ||
15748                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15749                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15750                             awk '{ print $1; exit; }')
15751
15752                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15753                 [ $((user_rec1 + 1)) == $first_rec ] ||
15754                         error "mds$i: first index should be $user_rec1 + 1, " \
15755                               "but is $first_rec"
15756         done
15757 }
15758 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15759               "during mount"
15760
15761 test_160i() {
15762
15763         local mdts=$(comma_list $(mdts_nodes))
15764
15765         changelog_register || error "first changelog_register failed"
15766
15767         # generate some changelog records to accumulate on each MDT
15768         # use all_char because created files should be evenly distributed
15769         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15770                 error "test_mkdir $tdir failed"
15771         for ((i = 0; i < MDSCOUNT; i++)); do
15772                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15773                         error "create $DIR/$tdir/d$i.1 failed"
15774         done
15775
15776         # check changelogs have been generated
15777         local nbcl=$(changelog_dump | wc -l)
15778         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15779
15780         # simulate race between register and unregister
15781         # XXX as fail_loc is set per-MDS, with DNE configs the race
15782         # simulation will only occur for one MDT per MDS and for the
15783         # others the normal race scenario will take place
15784         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15785         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15786         do_nodes $mdts $LCTL set_param fail_val=1
15787
15788         # unregister 1st user
15789         changelog_deregister &
15790         local pid1=$!
15791         # wait some time for deregister work to reach race rdv
15792         sleep 2
15793         # register 2nd user
15794         changelog_register || error "2nd user register failed"
15795
15796         wait $pid1 || error "1st user deregister failed"
15797
15798         local i
15799         local last_rec
15800         declare -A LAST_REC
15801         for i in $(seq $MDSCOUNT); do
15802                 if changelog_users mds$i | grep "^cl"; then
15803                         # make sure new records are added with one user present
15804                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15805                                           awk '/^current.index:/ { print $NF }')
15806                 else
15807                         error "mds$i has no user registered"
15808                 fi
15809         done
15810
15811         # generate more changelog records to accumulate on each MDT
15812         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15813                 error "create $DIR/$tdir/${tfile}bis failed"
15814
15815         for i in $(seq $MDSCOUNT); do
15816                 last_rec=$(changelog_users $SINGLEMDS |
15817                            awk '/^current.index:/ { print $NF }')
15818                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15819                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15820                         error "changelogs are off on mds$i"
15821         done
15822 }
15823 run_test 160i "changelog user register/unregister race"
15824
15825 test_160j() {
15826         remote_mds_nodsh && skip "remote MDS with nodsh"
15827         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15828                 skip "Need MDS version at least 2.12.56"
15829
15830         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15831         stack_trap "umount $MOUNT2" EXIT
15832
15833         changelog_register || error "first changelog_register failed"
15834         stack_trap "changelog_deregister" EXIT
15835
15836         # generate some changelog
15837         # use all_char because created files should be evenly distributed
15838         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15839                 error "mkdir $tdir failed"
15840         for ((i = 0; i < MDSCOUNT; i++)); do
15841                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15842                         error "create $DIR/$tdir/d$i.1 failed"
15843         done
15844
15845         # open the changelog device
15846         exec 3>/dev/changelog-$FSNAME-MDT0000
15847         stack_trap "exec 3>&-" EXIT
15848         exec 4</dev/changelog-$FSNAME-MDT0000
15849         stack_trap "exec 4<&-" EXIT
15850
15851         # umount the first lustre mount
15852         umount $MOUNT
15853         stack_trap "mount_client $MOUNT" EXIT
15854
15855         # read changelog, which may or may not fail, but should not crash
15856         cat <&4 >/dev/null
15857
15858         # clear changelog
15859         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15860         changelog_users $SINGLEMDS | grep -q $cl_user ||
15861                 error "User $cl_user not found in changelog_users"
15862
15863         printf 'clear:'$cl_user':0' >&3
15864 }
15865 run_test 160j "client can be umounted while its chanangelog is being used"
15866
15867 test_160k() {
15868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15869         remote_mds_nodsh && skip "remote MDS with nodsh"
15870
15871         mkdir -p $DIR/$tdir/1/1
15872
15873         changelog_register || error "changelog_register failed"
15874         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15875
15876         changelog_users $SINGLEMDS | grep -q $cl_user ||
15877                 error "User '$cl_user' not found in changelog_users"
15878 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15879         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15880         rmdir $DIR/$tdir/1/1 & sleep 1
15881         mkdir $DIR/$tdir/2
15882         touch $DIR/$tdir/2/2
15883         rm -rf $DIR/$tdir/2
15884
15885         wait
15886         sleep 4
15887
15888         changelog_dump | grep rmdir || error "rmdir not recorded"
15889 }
15890 run_test 160k "Verify that changelog records are not lost"
15891
15892 # Verifies that a file passed as a parameter has recently had an operation
15893 # performed on it that has generated an MTIME changelog which contains the
15894 # correct parent FID. As files might reside on a different MDT from the
15895 # parent directory in DNE configurations, the FIDs are translated to paths
15896 # before being compared, which should be identical
15897 compare_mtime_changelog() {
15898         local file="${1}"
15899         local mdtidx
15900         local mtime
15901         local cl_fid
15902         local pdir
15903         local dir
15904
15905         mdtidx=$($LFS getstripe --mdt-index $file)
15906         mdtidx=$(printf "%04x" $mdtidx)
15907
15908         # Obtain the parent FID from the MTIME changelog
15909         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15910         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15911
15912         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15913         [ -z "$cl_fid" ] && error "parent FID not present"
15914
15915         # Verify that the path for the parent FID is the same as the path for
15916         # the test directory
15917         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15918
15919         dir=$(dirname $1)
15920
15921         [[ "${pdir%/}" == "$dir" ]] ||
15922                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15923 }
15924
15925 test_160l() {
15926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15927
15928         remote_mds_nodsh && skip "remote MDS with nodsh"
15929         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15930                 skip "Need MDS version at least 2.13.55"
15931
15932         local cl_user
15933
15934         changelog_register || error "changelog_register failed"
15935         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15936
15937         changelog_users $SINGLEMDS | grep -q $cl_user ||
15938                 error "User '$cl_user' not found in changelog_users"
15939
15940         # Clear some types so that MTIME changelogs are generated
15941         changelog_chmask "-CREAT"
15942         changelog_chmask "-CLOSE"
15943
15944         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15945
15946         # Test CL_MTIME during setattr
15947         touch $DIR/$tdir/$tfile
15948         compare_mtime_changelog $DIR/$tdir/$tfile
15949
15950         # Test CL_MTIME during close
15951         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15952         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15953 }
15954 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15955
15956 test_160m() {
15957         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15958         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
15959                 skip "Need MDS version at least 2.14.51"
15960         local cl_users
15961         local cl_user1
15962         local cl_user2
15963         local pid1
15964
15965         # Create a user
15966         changelog_register || error "first changelog_register failed"
15967         changelog_register || error "second changelog_register failed"
15968
15969         cl_users=(${CL_USERS[mds1]})
15970         cl_user1="${cl_users[0]}"
15971         cl_user2="${cl_users[1]}"
15972         # generate some changelog records to accumulate on MDT0
15973         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
15974         createmany -m $DIR/$tdir/$tfile 50 ||
15975                 error "create $DIR/$tdir/$tfile failed"
15976         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
15977         rm -f $DIR/$tdir
15978
15979         # check changelogs have been generated
15980         local nbcl=$(changelog_dump | wc -l)
15981         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15982
15983 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
15984         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
15985
15986         __changelog_clear mds1 $cl_user1 +10
15987         __changelog_clear mds1 $cl_user2 0 &
15988         pid1=$!
15989         sleep 2
15990         __changelog_clear mds1 $cl_user1 0 ||
15991                 error "fail to cancel record for $cl_user1"
15992         wait $pid1
15993         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
15994 }
15995 run_test 160m "Changelog clear race"
15996
15997
15998 test_161a() {
15999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16000
16001         test_mkdir -c1 $DIR/$tdir
16002         cp /etc/hosts $DIR/$tdir/$tfile
16003         test_mkdir -c1 $DIR/$tdir/foo1
16004         test_mkdir -c1 $DIR/$tdir/foo2
16005         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16007         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16008         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16009         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16010         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16011                 $LFS fid2path $DIR $FID
16012                 error "bad link ea"
16013         fi
16014         # middle
16015         rm $DIR/$tdir/foo2/zachary
16016         # last
16017         rm $DIR/$tdir/foo2/thor
16018         # first
16019         rm $DIR/$tdir/$tfile
16020         # rename
16021         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16022         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16023                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16024         rm $DIR/$tdir/foo2/maggie
16025
16026         # overflow the EA
16027         local longname=$tfile.avg_len_is_thirty_two_
16028         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16029                 error_noexit 'failed to unlink many hardlinks'" EXIT
16030         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16031                 error "failed to hardlink many files"
16032         links=$($LFS fid2path $DIR $FID | wc -l)
16033         echo -n "${links}/1000 links in link EA"
16034         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16035 }
16036 run_test 161a "link ea sanity"
16037
16038 test_161b() {
16039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16040         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16041
16042         local MDTIDX=1
16043         local remote_dir=$DIR/$tdir/remote_dir
16044
16045         mkdir -p $DIR/$tdir
16046         $LFS mkdir -i $MDTIDX $remote_dir ||
16047                 error "create remote directory failed"
16048
16049         cp /etc/hosts $remote_dir/$tfile
16050         mkdir -p $remote_dir/foo1
16051         mkdir -p $remote_dir/foo2
16052         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16053         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16054         ln $remote_dir/$tfile $remote_dir/foo1/luna
16055         ln $remote_dir/$tfile $remote_dir/foo2/thor
16056
16057         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16058                      tr -d ']')
16059         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16060                 $LFS fid2path $DIR $FID
16061                 error "bad link ea"
16062         fi
16063         # middle
16064         rm $remote_dir/foo2/zachary
16065         # last
16066         rm $remote_dir/foo2/thor
16067         # first
16068         rm $remote_dir/$tfile
16069         # rename
16070         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16071         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16072         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16073                 $LFS fid2path $DIR $FID
16074                 error "bad link rename"
16075         fi
16076         rm $remote_dir/foo2/maggie
16077
16078         # overflow the EA
16079         local longname=filename_avg_len_is_thirty_two_
16080         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16081                 error "failed to hardlink many files"
16082         links=$($LFS fid2path $DIR $FID | wc -l)
16083         echo -n "${links}/1000 links in link EA"
16084         [[ ${links} -gt 60 ]] ||
16085                 error "expected at least 60 links in link EA"
16086         unlinkmany $remote_dir/foo2/$longname 1000 ||
16087         error "failed to unlink many hardlinks"
16088 }
16089 run_test 161b "link ea sanity under remote directory"
16090
16091 test_161c() {
16092         remote_mds_nodsh && skip "remote MDS with nodsh"
16093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16094         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16095                 skip "Need MDS version at least 2.1.5"
16096
16097         # define CLF_RENAME_LAST 0x0001
16098         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16099         changelog_register || error "changelog_register failed"
16100
16101         rm -rf $DIR/$tdir
16102         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16103         touch $DIR/$tdir/foo_161c
16104         touch $DIR/$tdir/bar_161c
16105         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16106         changelog_dump | grep RENME | tail -n 5
16107         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16108         changelog_clear 0 || error "changelog_clear failed"
16109         if [ x$flags != "x0x1" ]; then
16110                 error "flag $flags is not 0x1"
16111         fi
16112
16113         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16114         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16115         touch $DIR/$tdir/foo_161c
16116         touch $DIR/$tdir/bar_161c
16117         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16118         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16119         changelog_dump | grep RENME | tail -n 5
16120         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16121         changelog_clear 0 || error "changelog_clear failed"
16122         if [ x$flags != "x0x0" ]; then
16123                 error "flag $flags is not 0x0"
16124         fi
16125         echo "rename overwrite a target having nlink > 1," \
16126                 "changelog record has flags of $flags"
16127
16128         # rename doesn't overwrite a target (changelog flag 0x0)
16129         touch $DIR/$tdir/foo_161c
16130         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16131         changelog_dump | grep RENME | tail -n 5
16132         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16133         changelog_clear 0 || error "changelog_clear failed"
16134         if [ x$flags != "x0x0" ]; then
16135                 error "flag $flags is not 0x0"
16136         fi
16137         echo "rename doesn't overwrite a target," \
16138                 "changelog record has flags of $flags"
16139
16140         # define CLF_UNLINK_LAST 0x0001
16141         # unlink a file having nlink = 1 (changelog flag 0x1)
16142         rm -f $DIR/$tdir/foo2_161c
16143         changelog_dump | grep UNLNK | tail -n 5
16144         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16145         changelog_clear 0 || error "changelog_clear failed"
16146         if [ x$flags != "x0x1" ]; then
16147                 error "flag $flags is not 0x1"
16148         fi
16149         echo "unlink a file having nlink = 1," \
16150                 "changelog record has flags of $flags"
16151
16152         # unlink a file having nlink > 1 (changelog flag 0x0)
16153         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16154         rm -f $DIR/$tdir/foobar_161c
16155         changelog_dump | grep UNLNK | tail -n 5
16156         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16157         changelog_clear 0 || error "changelog_clear failed"
16158         if [ x$flags != "x0x0" ]; then
16159                 error "flag $flags is not 0x0"
16160         fi
16161         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16162 }
16163 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16164
16165 test_161d() {
16166         remote_mds_nodsh && skip "remote MDS with nodsh"
16167         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16168
16169         local pid
16170         local fid
16171
16172         changelog_register || error "changelog_register failed"
16173
16174         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16175         # interfer with $MOUNT/.lustre/fid/ access
16176         mkdir $DIR/$tdir
16177         [[ $? -eq 0 ]] || error "mkdir failed"
16178
16179         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16180         $LCTL set_param fail_loc=0x8000140c
16181         # 5s pause
16182         $LCTL set_param fail_val=5
16183
16184         # create file
16185         echo foofoo > $DIR/$tdir/$tfile &
16186         pid=$!
16187
16188         # wait for create to be delayed
16189         sleep 2
16190
16191         ps -p $pid
16192         [[ $? -eq 0 ]] || error "create should be blocked"
16193
16194         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16195         stack_trap "rm -f $tempfile"
16196         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16197         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16198         # some delay may occur during ChangeLog publishing and file read just
16199         # above, that could allow file write to happen finally
16200         [[ -s $tempfile ]] && echo "file should be empty"
16201
16202         $LCTL set_param fail_loc=0
16203
16204         wait $pid
16205         [[ $? -eq 0 ]] || error "create failed"
16206 }
16207 run_test 161d "create with concurrent .lustre/fid access"
16208
16209 check_path() {
16210         local expected="$1"
16211         shift
16212         local fid="$2"
16213
16214         local path
16215         path=$($LFS fid2path "$@")
16216         local rc=$?
16217
16218         if [ $rc -ne 0 ]; then
16219                 error "path looked up of '$expected' failed: rc=$rc"
16220         elif [ "$path" != "$expected" ]; then
16221                 error "path looked up '$path' instead of '$expected'"
16222         else
16223                 echo "FID '$fid' resolves to path '$path' as expected"
16224         fi
16225 }
16226
16227 test_162a() { # was test_162
16228         test_mkdir -p -c1 $DIR/$tdir/d2
16229         touch $DIR/$tdir/d2/$tfile
16230         touch $DIR/$tdir/d2/x1
16231         touch $DIR/$tdir/d2/x2
16232         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16233         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16234         # regular file
16235         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16236         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16237
16238         # softlink
16239         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16240         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16241         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16242
16243         # softlink to wrong file
16244         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16245         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16246         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16247
16248         # hardlink
16249         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16250         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16251         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16252         # fid2path dir/fsname should both work
16253         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16254         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16255
16256         # hardlink count: check that there are 2 links
16257         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16258         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16259
16260         # hardlink indexing: remove the first link
16261         rm $DIR/$tdir/d2/p/q/r/hlink
16262         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16263 }
16264 run_test 162a "path lookup sanity"
16265
16266 test_162b() {
16267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16269
16270         mkdir $DIR/$tdir
16271         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16272                                 error "create striped dir failed"
16273
16274         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16275                                         tail -n 1 | awk '{print $2}')
16276         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16277
16278         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16279         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16280
16281         # regular file
16282         for ((i=0;i<5;i++)); do
16283                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16284                         error "get fid for f$i failed"
16285                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16286
16287                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16288                         error "get fid for d$i failed"
16289                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16290         done
16291
16292         return 0
16293 }
16294 run_test 162b "striped directory path lookup sanity"
16295
16296 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16297 test_162c() {
16298         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16299                 skip "Need MDS version at least 2.7.51"
16300
16301         local lpath=$tdir.local
16302         local rpath=$tdir.remote
16303
16304         test_mkdir $DIR/$lpath
16305         test_mkdir $DIR/$rpath
16306
16307         for ((i = 0; i <= 101; i++)); do
16308                 lpath="$lpath/$i"
16309                 mkdir $DIR/$lpath
16310                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16311                         error "get fid for local directory $DIR/$lpath failed"
16312                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16313
16314                 rpath="$rpath/$i"
16315                 test_mkdir $DIR/$rpath
16316                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16317                         error "get fid for remote directory $DIR/$rpath failed"
16318                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16319         done
16320
16321         return 0
16322 }
16323 run_test 162c "fid2path works with paths 100 or more directories deep"
16324
16325 oalr_event_count() {
16326         local event="${1}"
16327         local trace="${2}"
16328
16329         awk -v name="${FSNAME}-OST0000" \
16330             -v event="${event}" \
16331             '$1 == "TRACE" && $2 == event && $3 == name' \
16332             "${trace}" |
16333         wc -l
16334 }
16335
16336 oalr_expect_event_count() {
16337         local event="${1}"
16338         local trace="${2}"
16339         local expect="${3}"
16340         local count
16341
16342         count=$(oalr_event_count "${event}" "${trace}")
16343         if ((count == expect)); then
16344                 return 0
16345         fi
16346
16347         error_noexit "${event} event count was '${count}', expected ${expect}"
16348         cat "${trace}" >&2
16349         exit 1
16350 }
16351
16352 cleanup_165() {
16353         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16354         stop ost1
16355         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16356 }
16357
16358 setup_165() {
16359         sync # Flush previous IOs so we can count log entries.
16360         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16361         stack_trap cleanup_165 EXIT
16362 }
16363
16364 test_165a() {
16365         local trace="/tmp/${tfile}.trace"
16366         local rc
16367         local count
16368
16369         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16370                 skip "OFD access log unsupported"
16371
16372         setup_165
16373         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16374         sleep 5
16375
16376         do_facet ost1 ofd_access_log_reader --list
16377         stop ost1
16378
16379         do_facet ost1 killall -TERM ofd_access_log_reader
16380         wait
16381         rc=$?
16382
16383         if ((rc != 0)); then
16384                 error "ofd_access_log_reader exited with rc = '${rc}'"
16385         fi
16386
16387         # Parse trace file for discovery events:
16388         oalr_expect_event_count alr_log_add "${trace}" 1
16389         oalr_expect_event_count alr_log_eof "${trace}" 1
16390         oalr_expect_event_count alr_log_free "${trace}" 1
16391 }
16392 run_test 165a "ofd access log discovery"
16393
16394 test_165b() {
16395         local trace="/tmp/${tfile}.trace"
16396         local file="${DIR}/${tfile}"
16397         local pfid1
16398         local pfid2
16399         local -a entry
16400         local rc
16401         local count
16402         local size
16403         local flags
16404
16405         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16406                 skip "OFD access log unsupported"
16407
16408         setup_165
16409         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16410         sleep 5
16411
16412         do_facet ost1 ofd_access_log_reader --list
16413
16414         lfs setstripe -c 1 -i 0 "${file}"
16415         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16416                 error "cannot create '${file}'"
16417
16418         sleep 5
16419         do_facet ost1 killall -TERM ofd_access_log_reader
16420         wait
16421         rc=$?
16422
16423         if ((rc != 0)); then
16424                 error "ofd_access_log_reader exited with rc = '${rc}'"
16425         fi
16426
16427         oalr_expect_event_count alr_log_entry "${trace}" 1
16428
16429         pfid1=$($LFS path2fid "${file}")
16430
16431         # 1     2             3   4    5     6   7    8    9     10
16432         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16433         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16434
16435         echo "entry = '${entry[*]}'" >&2
16436
16437         pfid2=${entry[4]}
16438         if [[ "${pfid1}" != "${pfid2}" ]]; then
16439                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16440         fi
16441
16442         size=${entry[8]}
16443         if ((size != 1048576)); then
16444                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16445         fi
16446
16447         flags=${entry[10]}
16448         if [[ "${flags}" != "w" ]]; then
16449                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16450         fi
16451
16452         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16453         sleep 5
16454
16455         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16456                 error "cannot read '${file}'"
16457         sleep 5
16458
16459         do_facet ost1 killall -TERM ofd_access_log_reader
16460         wait
16461         rc=$?
16462
16463         if ((rc != 0)); then
16464                 error "ofd_access_log_reader exited with rc = '${rc}'"
16465         fi
16466
16467         oalr_expect_event_count alr_log_entry "${trace}" 1
16468
16469         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16470         echo "entry = '${entry[*]}'" >&2
16471
16472         pfid2=${entry[4]}
16473         if [[ "${pfid1}" != "${pfid2}" ]]; then
16474                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16475         fi
16476
16477         size=${entry[8]}
16478         if ((size != 524288)); then
16479                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16480         fi
16481
16482         flags=${entry[10]}
16483         if [[ "${flags}" != "r" ]]; then
16484                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16485         fi
16486 }
16487 run_test 165b "ofd access log entries are produced and consumed"
16488
16489 test_165c() {
16490         local trace="/tmp/${tfile}.trace"
16491         local file="${DIR}/${tdir}/${tfile}"
16492
16493         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16494                 skip "OFD access log unsupported"
16495
16496         test_mkdir "${DIR}/${tdir}"
16497
16498         setup_165
16499         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16500         sleep 5
16501
16502         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16503
16504         # 4096 / 64 = 64. Create twice as many entries.
16505         for ((i = 0; i < 128; i++)); do
16506                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16507                         error "cannot create file"
16508         done
16509
16510         sync
16511
16512         do_facet ost1 killall -TERM ofd_access_log_reader
16513         wait
16514         rc=$?
16515         if ((rc != 0)); then
16516                 error "ofd_access_log_reader exited with rc = '${rc}'"
16517         fi
16518
16519         unlinkmany  "${file}-%d" 128
16520 }
16521 run_test 165c "full ofd access logs do not block IOs"
16522
16523 oal_get_read_count() {
16524         local stats="$1"
16525
16526         # STATS lustre-OST0001 alr_read_count 1
16527
16528         do_facet ost1 cat "${stats}" |
16529         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16530              END { print count; }'
16531 }
16532
16533 oal_expect_read_count() {
16534         local stats="$1"
16535         local count
16536         local expect="$2"
16537
16538         # Ask ofd_access_log_reader to write stats.
16539         do_facet ost1 killall -USR1 ofd_access_log_reader
16540
16541         # Allow some time for things to happen.
16542         sleep 1
16543
16544         count=$(oal_get_read_count "${stats}")
16545         if ((count == expect)); then
16546                 return 0
16547         fi
16548
16549         error_noexit "bad read count, got ${count}, expected ${expect}"
16550         do_facet ost1 cat "${stats}" >&2
16551         exit 1
16552 }
16553
16554 test_165d() {
16555         local stats="/tmp/${tfile}.stats"
16556         local file="${DIR}/${tdir}/${tfile}"
16557         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16558
16559         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16560                 skip "OFD access log unsupported"
16561
16562         test_mkdir "${DIR}/${tdir}"
16563
16564         setup_165
16565         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16566         sleep 5
16567
16568         lfs setstripe -c 1 -i 0 "${file}"
16569
16570         do_facet ost1 lctl set_param "${param}=rw"
16571         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16572                 error "cannot create '${file}'"
16573         oal_expect_read_count "${stats}" 1
16574
16575         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16576                 error "cannot read '${file}'"
16577         oal_expect_read_count "${stats}" 2
16578
16579         do_facet ost1 lctl set_param "${param}=r"
16580         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16581                 error "cannot create '${file}'"
16582         oal_expect_read_count "${stats}" 2
16583
16584         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16585                 error "cannot read '${file}'"
16586         oal_expect_read_count "${stats}" 3
16587
16588         do_facet ost1 lctl set_param "${param}=w"
16589         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16590                 error "cannot create '${file}'"
16591         oal_expect_read_count "${stats}" 4
16592
16593         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16594                 error "cannot read '${file}'"
16595         oal_expect_read_count "${stats}" 4
16596
16597         do_facet ost1 lctl set_param "${param}=0"
16598         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16599                 error "cannot create '${file}'"
16600         oal_expect_read_count "${stats}" 4
16601
16602         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16603                 error "cannot read '${file}'"
16604         oal_expect_read_count "${stats}" 4
16605
16606         do_facet ost1 killall -TERM ofd_access_log_reader
16607         wait
16608         rc=$?
16609         if ((rc != 0)); then
16610                 error "ofd_access_log_reader exited with rc = '${rc}'"
16611         fi
16612 }
16613 run_test 165d "ofd_access_log mask works"
16614
16615 test_165e() {
16616         local stats="/tmp/${tfile}.stats"
16617         local file0="${DIR}/${tdir}-0/${tfile}"
16618         local file1="${DIR}/${tdir}-1/${tfile}"
16619
16620         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16621                 skip "OFD access log unsupported"
16622
16623         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16624
16625         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16626         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16627
16628         lfs setstripe -c 1 -i 0 "${file0}"
16629         lfs setstripe -c 1 -i 0 "${file1}"
16630
16631         setup_165
16632         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16633         sleep 5
16634
16635         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16636                 error "cannot create '${file0}'"
16637         sync
16638         oal_expect_read_count "${stats}" 0
16639
16640         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16641                 error "cannot create '${file1}'"
16642         sync
16643         oal_expect_read_count "${stats}" 1
16644
16645         do_facet ost1 killall -TERM ofd_access_log_reader
16646         wait
16647         rc=$?
16648         if ((rc != 0)); then
16649                 error "ofd_access_log_reader exited with rc = '${rc}'"
16650         fi
16651 }
16652 run_test 165e "ofd_access_log MDT index filter works"
16653
16654 test_165f() {
16655         local trace="/tmp/${tfile}.trace"
16656         local rc
16657         local count
16658
16659         setup_165
16660         do_facet ost1 timeout 60 ofd_access_log_reader \
16661                 --exit-on-close --debug=- --trace=- > "${trace}" &
16662         sleep 5
16663         stop ost1
16664
16665         wait
16666         rc=$?
16667
16668         if ((rc != 0)); then
16669                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16670                 cat "${trace}"
16671                 exit 1
16672         fi
16673 }
16674 run_test 165f "ofd_access_log_reader --exit-on-close works"
16675
16676 test_169() {
16677         # do directio so as not to populate the page cache
16678         log "creating a 10 Mb file"
16679         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16680                 error "multiop failed while creating a file"
16681         log "starting reads"
16682         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16683         log "truncating the file"
16684         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16685                 error "multiop failed while truncating the file"
16686         log "killing dd"
16687         kill %+ || true # reads might have finished
16688         echo "wait until dd is finished"
16689         wait
16690         log "removing the temporary file"
16691         rm -rf $DIR/$tfile || error "tmp file removal failed"
16692 }
16693 run_test 169 "parallel read and truncate should not deadlock"
16694
16695 test_170() {
16696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16697
16698         $LCTL clear     # bug 18514
16699         $LCTL debug_daemon start $TMP/${tfile}_log_good
16700         touch $DIR/$tfile
16701         $LCTL debug_daemon stop
16702         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16703                 error "sed failed to read log_good"
16704
16705         $LCTL debug_daemon start $TMP/${tfile}_log_good
16706         rm -rf $DIR/$tfile
16707         $LCTL debug_daemon stop
16708
16709         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16710                error "lctl df log_bad failed"
16711
16712         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16713         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16714
16715         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16716         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16717
16718         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16719                 error "bad_line good_line1 good_line2 are empty"
16720
16721         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16722         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16723         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16724
16725         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16726         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16727         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16728
16729         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16730                 error "bad_line_new good_line_new are empty"
16731
16732         local expected_good=$((good_line1 + good_line2*2))
16733
16734         rm -f $TMP/${tfile}*
16735         # LU-231, short malformed line may not be counted into bad lines
16736         if [ $bad_line -ne $bad_line_new ] &&
16737                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16738                 error "expected $bad_line bad lines, but got $bad_line_new"
16739                 return 1
16740         fi
16741
16742         if [ $expected_good -ne $good_line_new ]; then
16743                 error "expected $expected_good good lines, but got $good_line_new"
16744                 return 2
16745         fi
16746         true
16747 }
16748 run_test 170 "test lctl df to handle corrupted log ====================="
16749
16750 test_171() { # bug20592
16751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16752
16753         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16754         $LCTL set_param fail_loc=0x50e
16755         $LCTL set_param fail_val=3000
16756         multiop_bg_pause $DIR/$tfile O_s || true
16757         local MULTIPID=$!
16758         kill -USR1 $MULTIPID
16759         # cause log dump
16760         sleep 3
16761         wait $MULTIPID
16762         if dmesg | grep "recursive fault"; then
16763                 error "caught a recursive fault"
16764         fi
16765         $LCTL set_param fail_loc=0
16766         true
16767 }
16768 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16769
16770 # it would be good to share it with obdfilter-survey/iokit-libecho code
16771 setup_obdecho_osc () {
16772         local rc=0
16773         local ost_nid=$1
16774         local obdfilter_name=$2
16775         echo "Creating new osc for $obdfilter_name on $ost_nid"
16776         # make sure we can find loopback nid
16777         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16778
16779         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16780                            ${obdfilter_name}_osc_UUID || rc=2; }
16781         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16782                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16783         return $rc
16784 }
16785
16786 cleanup_obdecho_osc () {
16787         local obdfilter_name=$1
16788         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16789         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16790         return 0
16791 }
16792
16793 obdecho_test() {
16794         local OBD=$1
16795         local node=$2
16796         local pages=${3:-64}
16797         local rc=0
16798         local id
16799
16800         local count=10
16801         local obd_size=$(get_obd_size $node $OBD)
16802         local page_size=$(get_page_size $node)
16803         if [[ -n "$obd_size" ]]; then
16804                 local new_count=$((obd_size / (pages * page_size / 1024)))
16805                 [[ $new_count -ge $count ]] || count=$new_count
16806         fi
16807
16808         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16809         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16810                            rc=2; }
16811         if [ $rc -eq 0 ]; then
16812             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16813             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16814         fi
16815         echo "New object id is $id"
16816         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16817                            rc=4; }
16818         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16819                            "test_brw $count w v $pages $id" || rc=4; }
16820         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16821                            rc=4; }
16822         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16823                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16824         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16825                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16826         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16827         return $rc
16828 }
16829
16830 test_180a() {
16831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16832
16833         if ! [ -d /sys/fs/lustre/echo_client ] &&
16834            ! module_loaded obdecho; then
16835                 load_module obdecho/obdecho &&
16836                         stack_trap "rmmod obdecho" EXIT ||
16837                         error "unable to load obdecho on client"
16838         fi
16839
16840         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16841         local host=$($LCTL get_param -n osc.$osc.import |
16842                      awk '/current_connection:/ { print $2 }' )
16843         local target=$($LCTL get_param -n osc.$osc.import |
16844                        awk '/target:/ { print $2 }' )
16845         target=${target%_UUID}
16846
16847         if [ -n "$target" ]; then
16848                 setup_obdecho_osc $host $target &&
16849                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16850                         { error "obdecho setup failed with $?"; return; }
16851
16852                 obdecho_test ${target}_osc client ||
16853                         error "obdecho_test failed on ${target}_osc"
16854         else
16855                 $LCTL get_param osc.$osc.import
16856                 error "there is no osc.$osc.import target"
16857         fi
16858 }
16859 run_test 180a "test obdecho on osc"
16860
16861 test_180b() {
16862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16863         remote_ost_nodsh && skip "remote OST with nodsh"
16864
16865         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16866                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16867                 error "failed to load module obdecho"
16868
16869         local target=$(do_facet ost1 $LCTL dl |
16870                        awk '/obdfilter/ { print $4; exit; }')
16871
16872         if [ -n "$target" ]; then
16873                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16874         else
16875                 do_facet ost1 $LCTL dl
16876                 error "there is no obdfilter target on ost1"
16877         fi
16878 }
16879 run_test 180b "test obdecho directly on obdfilter"
16880
16881 test_180c() { # LU-2598
16882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16883         remote_ost_nodsh && skip "remote OST with nodsh"
16884         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16885                 skip "Need MDS version at least 2.4.0"
16886
16887         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16888                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16889                 error "failed to load module obdecho"
16890
16891         local target=$(do_facet ost1 $LCTL dl |
16892                        awk '/obdfilter/ { print $4; exit; }')
16893
16894         if [ -n "$target" ]; then
16895                 local pages=16384 # 64MB bulk I/O RPC size
16896
16897                 obdecho_test "$target" ost1 "$pages" ||
16898                         error "obdecho_test with pages=$pages failed with $?"
16899         else
16900                 do_facet ost1 $LCTL dl
16901                 error "there is no obdfilter target on ost1"
16902         fi
16903 }
16904 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16905
16906 test_181() { # bug 22177
16907         test_mkdir $DIR/$tdir
16908         # create enough files to index the directory
16909         createmany -o $DIR/$tdir/foobar 4000
16910         # print attributes for debug purpose
16911         lsattr -d .
16912         # open dir
16913         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16914         MULTIPID=$!
16915         # remove the files & current working dir
16916         unlinkmany $DIR/$tdir/foobar 4000
16917         rmdir $DIR/$tdir
16918         kill -USR1 $MULTIPID
16919         wait $MULTIPID
16920         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16921         return 0
16922 }
16923 run_test 181 "Test open-unlinked dir ========================"
16924
16925 test_182() {
16926         local fcount=1000
16927         local tcount=10
16928
16929         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16930
16931         $LCTL set_param mdc.*.rpc_stats=clear
16932
16933         for (( i = 0; i < $tcount; i++ )) ; do
16934                 mkdir $DIR/$tdir/$i
16935         done
16936
16937         for (( i = 0; i < $tcount; i++ )) ; do
16938                 createmany -o $DIR/$tdir/$i/f- $fcount &
16939         done
16940         wait
16941
16942         for (( i = 0; i < $tcount; i++ )) ; do
16943                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16944         done
16945         wait
16946
16947         $LCTL get_param mdc.*.rpc_stats
16948
16949         rm -rf $DIR/$tdir
16950 }
16951 run_test 182 "Test parallel modify metadata operations ================"
16952
16953 test_183() { # LU-2275
16954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16955         remote_mds_nodsh && skip "remote MDS with nodsh"
16956         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16957                 skip "Need MDS version at least 2.3.56"
16958
16959         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16960         echo aaa > $DIR/$tdir/$tfile
16961
16962 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16963         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16964
16965         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16966         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16967
16968         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16969
16970         # Flush negative dentry cache
16971         touch $DIR/$tdir/$tfile
16972
16973         # We are not checking for any leaked references here, they'll
16974         # become evident next time we do cleanup with module unload.
16975         rm -rf $DIR/$tdir
16976 }
16977 run_test 183 "No crash or request leak in case of strange dispositions ========"
16978
16979 # test suite 184 is for LU-2016, LU-2017
16980 test_184a() {
16981         check_swap_layouts_support
16982
16983         dir0=$DIR/$tdir/$testnum
16984         test_mkdir -p -c1 $dir0
16985         ref1=/etc/passwd
16986         ref2=/etc/group
16987         file1=$dir0/f1
16988         file2=$dir0/f2
16989         $LFS setstripe -c1 $file1
16990         cp $ref1 $file1
16991         $LFS setstripe -c2 $file2
16992         cp $ref2 $file2
16993         gen1=$($LFS getstripe -g $file1)
16994         gen2=$($LFS getstripe -g $file2)
16995
16996         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16997         gen=$($LFS getstripe -g $file1)
16998         [[ $gen1 != $gen ]] ||
16999                 "Layout generation on $file1 does not change"
17000         gen=$($LFS getstripe -g $file2)
17001         [[ $gen2 != $gen ]] ||
17002                 "Layout generation on $file2 does not change"
17003
17004         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17005         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17006
17007         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17008 }
17009 run_test 184a "Basic layout swap"
17010
17011 test_184b() {
17012         check_swap_layouts_support
17013
17014         dir0=$DIR/$tdir/$testnum
17015         mkdir -p $dir0 || error "creating dir $dir0"
17016         file1=$dir0/f1
17017         file2=$dir0/f2
17018         file3=$dir0/f3
17019         dir1=$dir0/d1
17020         dir2=$dir0/d2
17021         mkdir $dir1 $dir2
17022         $LFS setstripe -c1 $file1
17023         $LFS setstripe -c2 $file2
17024         $LFS setstripe -c1 $file3
17025         chown $RUNAS_ID $file3
17026         gen1=$($LFS getstripe -g $file1)
17027         gen2=$($LFS getstripe -g $file2)
17028
17029         $LFS swap_layouts $dir1 $dir2 &&
17030                 error "swap of directories layouts should fail"
17031         $LFS swap_layouts $dir1 $file1 &&
17032                 error "swap of directory and file layouts should fail"
17033         $RUNAS $LFS swap_layouts $file1 $file2 &&
17034                 error "swap of file we cannot write should fail"
17035         $LFS swap_layouts $file1 $file3 &&
17036                 error "swap of file with different owner should fail"
17037         /bin/true # to clear error code
17038 }
17039 run_test 184b "Forbidden layout swap (will generate errors)"
17040
17041 test_184c() {
17042         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17043         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17044         check_swap_layouts_support
17045         check_swap_layout_no_dom $DIR
17046
17047         local dir0=$DIR/$tdir/$testnum
17048         mkdir -p $dir0 || error "creating dir $dir0"
17049
17050         local ref1=$dir0/ref1
17051         local ref2=$dir0/ref2
17052         local file1=$dir0/file1
17053         local file2=$dir0/file2
17054         # create a file large enough for the concurrent test
17055         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17056         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17057         echo "ref file size: ref1($(stat -c %s $ref1))," \
17058              "ref2($(stat -c %s $ref2))"
17059
17060         cp $ref2 $file2
17061         dd if=$ref1 of=$file1 bs=16k &
17062         local DD_PID=$!
17063
17064         # Make sure dd starts to copy file, but wait at most 5 seconds
17065         local loops=0
17066         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17067
17068         $LFS swap_layouts $file1 $file2
17069         local rc=$?
17070         wait $DD_PID
17071         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17072         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17073
17074         # how many bytes copied before swapping layout
17075         local copied=$(stat -c %s $file2)
17076         local remaining=$(stat -c %s $ref1)
17077         remaining=$((remaining - copied))
17078         echo "Copied $copied bytes before swapping layout..."
17079
17080         cmp -n $copied $file1 $ref2 | grep differ &&
17081                 error "Content mismatch [0, $copied) of ref2 and file1"
17082         cmp -n $copied $file2 $ref1 ||
17083                 error "Content mismatch [0, $copied) of ref1 and file2"
17084         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17085                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17086
17087         # clean up
17088         rm -f $ref1 $ref2 $file1 $file2
17089 }
17090 run_test 184c "Concurrent write and layout swap"
17091
17092 test_184d() {
17093         check_swap_layouts_support
17094         check_swap_layout_no_dom $DIR
17095         [ -z "$(which getfattr 2>/dev/null)" ] &&
17096                 skip_env "no getfattr command"
17097
17098         local file1=$DIR/$tdir/$tfile-1
17099         local file2=$DIR/$tdir/$tfile-2
17100         local file3=$DIR/$tdir/$tfile-3
17101         local lovea1
17102         local lovea2
17103
17104         mkdir -p $DIR/$tdir
17105         touch $file1 || error "create $file1 failed"
17106         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17107                 error "create $file2 failed"
17108         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17109                 error "create $file3 failed"
17110         lovea1=$(get_layout_param $file1)
17111
17112         $LFS swap_layouts $file2 $file3 ||
17113                 error "swap $file2 $file3 layouts failed"
17114         $LFS swap_layouts $file1 $file2 ||
17115                 error "swap $file1 $file2 layouts failed"
17116
17117         lovea2=$(get_layout_param $file2)
17118         echo "$lovea1"
17119         echo "$lovea2"
17120         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17121
17122         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17123         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17124 }
17125 run_test 184d "allow stripeless layouts swap"
17126
17127 test_184e() {
17128         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17129                 skip "Need MDS version at least 2.6.94"
17130         check_swap_layouts_support
17131         check_swap_layout_no_dom $DIR
17132         [ -z "$(which getfattr 2>/dev/null)" ] &&
17133                 skip_env "no getfattr command"
17134
17135         local file1=$DIR/$tdir/$tfile-1
17136         local file2=$DIR/$tdir/$tfile-2
17137         local file3=$DIR/$tdir/$tfile-3
17138         local lovea
17139
17140         mkdir -p $DIR/$tdir
17141         touch $file1 || error "create $file1 failed"
17142         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17143                 error "create $file2 failed"
17144         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17145                 error "create $file3 failed"
17146
17147         $LFS swap_layouts $file1 $file2 ||
17148                 error "swap $file1 $file2 layouts failed"
17149
17150         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17151         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17152
17153         echo 123 > $file1 || error "Should be able to write into $file1"
17154
17155         $LFS swap_layouts $file1 $file3 ||
17156                 error "swap $file1 $file3 layouts failed"
17157
17158         echo 123 > $file1 || error "Should be able to write into $file1"
17159
17160         rm -rf $file1 $file2 $file3
17161 }
17162 run_test 184e "Recreate layout after stripeless layout swaps"
17163
17164 test_184f() {
17165         # Create a file with name longer than sizeof(struct stat) ==
17166         # 144 to see if we can get chars from the file name to appear
17167         # in the returned striping. Note that 'f' == 0x66.
17168         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17169
17170         mkdir -p $DIR/$tdir
17171         mcreate $DIR/$tdir/$file
17172         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17173                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17174         fi
17175 }
17176 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17177
17178 test_185() { # LU-2441
17179         # LU-3553 - no volatile file support in old servers
17180         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17181                 skip "Need MDS version at least 2.3.60"
17182
17183         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17184         touch $DIR/$tdir/spoo
17185         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17186         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17187                 error "cannot create/write a volatile file"
17188         [ "$FILESET" == "" ] &&
17189         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17190                 error "FID is still valid after close"
17191
17192         multiop_bg_pause $DIR/$tdir vVw4096_c
17193         local multi_pid=$!
17194
17195         local OLD_IFS=$IFS
17196         IFS=":"
17197         local fidv=($fid)
17198         IFS=$OLD_IFS
17199         # assume that the next FID for this client is sequential, since stdout
17200         # is unfortunately eaten by multiop_bg_pause
17201         local n=$((${fidv[1]} + 1))
17202         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17203         if [ "$FILESET" == "" ]; then
17204                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17205                         error "FID is missing before close"
17206         fi
17207         kill -USR1 $multi_pid
17208         # 1 second delay, so if mtime change we will see it
17209         sleep 1
17210         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17211         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17212 }
17213 run_test 185 "Volatile file support"
17214
17215 function create_check_volatile() {
17216         local idx=$1
17217         local tgt
17218
17219         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17220         local PID=$!
17221         sleep 1
17222         local FID=$(cat /tmp/${tfile}.fid)
17223         [ "$FID" == "" ] && error "can't get FID for volatile"
17224         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17225         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17226         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17227         kill -USR1 $PID
17228         wait
17229         sleep 1
17230         cancel_lru_locks mdc # flush opencache
17231         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17232         return 0
17233 }
17234
17235 test_185a(){
17236         # LU-12516 - volatile creation via .lustre
17237         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17238                 skip "Need MDS version at least 2.3.55"
17239
17240         create_check_volatile 0
17241         [ $MDSCOUNT -lt 2 ] && return 0
17242
17243         # DNE case
17244         create_check_volatile 1
17245
17246         return 0
17247 }
17248 run_test 185a "Volatile file creation in .lustre/fid/"
17249
17250 test_187a() {
17251         remote_mds_nodsh && skip "remote MDS with nodsh"
17252         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17253                 skip "Need MDS version at least 2.3.0"
17254
17255         local dir0=$DIR/$tdir/$testnum
17256         mkdir -p $dir0 || error "creating dir $dir0"
17257
17258         local file=$dir0/file1
17259         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17260         local dv1=$($LFS data_version $file)
17261         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17262         local dv2=$($LFS data_version $file)
17263         [[ $dv1 != $dv2 ]] ||
17264                 error "data version did not change on write $dv1 == $dv2"
17265
17266         # clean up
17267         rm -f $file1
17268 }
17269 run_test 187a "Test data version change"
17270
17271 test_187b() {
17272         remote_mds_nodsh && skip "remote MDS with nodsh"
17273         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17274                 skip "Need MDS version at least 2.3.0"
17275
17276         local dir0=$DIR/$tdir/$testnum
17277         mkdir -p $dir0 || error "creating dir $dir0"
17278
17279         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17280         [[ ${DV[0]} != ${DV[1]} ]] ||
17281                 error "data version did not change on write"\
17282                       " ${DV[0]} == ${DV[1]}"
17283
17284         # clean up
17285         rm -f $file1
17286 }
17287 run_test 187b "Test data version change on volatile file"
17288
17289 test_200() {
17290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17291         remote_mgs_nodsh && skip "remote MGS with nodsh"
17292         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17293
17294         local POOL=${POOL:-cea1}
17295         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17296         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17297         # Pool OST targets
17298         local first_ost=0
17299         local last_ost=$(($OSTCOUNT - 1))
17300         local ost_step=2
17301         local ost_list=$(seq $first_ost $ost_step $last_ost)
17302         local ost_range="$first_ost $last_ost $ost_step"
17303         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17304         local file_dir=$POOL_ROOT/file_tst
17305         local subdir=$test_path/subdir
17306         local rc=0
17307
17308         while : ; do
17309                 # former test_200a test_200b
17310                 pool_add $POOL                          || { rc=$? ; break; }
17311                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17312                 # former test_200c test_200d
17313                 mkdir -p $test_path
17314                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17315                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17316                 mkdir -p $subdir
17317                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17318                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17319                                                         || { rc=$? ; break; }
17320                 # former test_200e test_200f
17321                 local files=$((OSTCOUNT*3))
17322                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17323                                                         || { rc=$? ; break; }
17324                 pool_create_files $POOL $file_dir $files "$ost_list" \
17325                                                         || { rc=$? ; break; }
17326                 # former test_200g test_200h
17327                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17328                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17329
17330                 # former test_201a test_201b test_201c
17331                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17332
17333                 local f=$test_path/$tfile
17334                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17335                 pool_remove $POOL $f                    || { rc=$? ; break; }
17336                 break
17337         done
17338
17339         destroy_test_pools
17340
17341         return $rc
17342 }
17343 run_test 200 "OST pools"
17344
17345 # usage: default_attr <count | size | offset>
17346 default_attr() {
17347         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17348 }
17349
17350 # usage: check_default_stripe_attr
17351 check_default_stripe_attr() {
17352         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17353         case $1 in
17354         --stripe-count|-c)
17355                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17356         --stripe-size|-S)
17357                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17358         --stripe-index|-i)
17359                 EXPECTED=-1;;
17360         *)
17361                 error "unknown getstripe attr '$1'"
17362         esac
17363
17364         [ $ACTUAL == $EXPECTED ] ||
17365                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17366 }
17367
17368 test_204a() {
17369         test_mkdir $DIR/$tdir
17370         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17371
17372         check_default_stripe_attr --stripe-count
17373         check_default_stripe_attr --stripe-size
17374         check_default_stripe_attr --stripe-index
17375 }
17376 run_test 204a "Print default stripe attributes"
17377
17378 test_204b() {
17379         test_mkdir $DIR/$tdir
17380         $LFS setstripe --stripe-count 1 $DIR/$tdir
17381
17382         check_default_stripe_attr --stripe-size
17383         check_default_stripe_attr --stripe-index
17384 }
17385 run_test 204b "Print default stripe size and offset"
17386
17387 test_204c() {
17388         test_mkdir $DIR/$tdir
17389         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17390
17391         check_default_stripe_attr --stripe-count
17392         check_default_stripe_attr --stripe-index
17393 }
17394 run_test 204c "Print default stripe count and offset"
17395
17396 test_204d() {
17397         test_mkdir $DIR/$tdir
17398         $LFS setstripe --stripe-index 0 $DIR/$tdir
17399
17400         check_default_stripe_attr --stripe-count
17401         check_default_stripe_attr --stripe-size
17402 }
17403 run_test 204d "Print default stripe count and size"
17404
17405 test_204e() {
17406         test_mkdir $DIR/$tdir
17407         $LFS setstripe -d $DIR/$tdir
17408
17409         check_default_stripe_attr --stripe-count --raw
17410         check_default_stripe_attr --stripe-size --raw
17411         check_default_stripe_attr --stripe-index --raw
17412 }
17413 run_test 204e "Print raw stripe attributes"
17414
17415 test_204f() {
17416         test_mkdir $DIR/$tdir
17417         $LFS setstripe --stripe-count 1 $DIR/$tdir
17418
17419         check_default_stripe_attr --stripe-size --raw
17420         check_default_stripe_attr --stripe-index --raw
17421 }
17422 run_test 204f "Print raw stripe size and offset"
17423
17424 test_204g() {
17425         test_mkdir $DIR/$tdir
17426         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17427
17428         check_default_stripe_attr --stripe-count --raw
17429         check_default_stripe_attr --stripe-index --raw
17430 }
17431 run_test 204g "Print raw stripe count and offset"
17432
17433 test_204h() {
17434         test_mkdir $DIR/$tdir
17435         $LFS setstripe --stripe-index 0 $DIR/$tdir
17436
17437         check_default_stripe_attr --stripe-count --raw
17438         check_default_stripe_attr --stripe-size --raw
17439 }
17440 run_test 204h "Print raw stripe count and size"
17441
17442 # Figure out which job scheduler is being used, if any,
17443 # or use a fake one
17444 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17445         JOBENV=SLURM_JOB_ID
17446 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17447         JOBENV=LSB_JOBID
17448 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17449         JOBENV=PBS_JOBID
17450 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17451         JOBENV=LOADL_STEP_ID
17452 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17453         JOBENV=JOB_ID
17454 else
17455         $LCTL list_param jobid_name > /dev/null 2>&1
17456         if [ $? -eq 0 ]; then
17457                 JOBENV=nodelocal
17458         else
17459                 JOBENV=FAKE_JOBID
17460         fi
17461 fi
17462 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17463
17464 verify_jobstats() {
17465         local cmd=($1)
17466         shift
17467         local facets="$@"
17468
17469 # we don't really need to clear the stats for this test to work, since each
17470 # command has a unique jobid, but it makes debugging easier if needed.
17471 #       for facet in $facets; do
17472 #               local dev=$(convert_facet2label $facet)
17473 #               # clear old jobstats
17474 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17475 #       done
17476
17477         # use a new JobID for each test, or we might see an old one
17478         [ "$JOBENV" = "FAKE_JOBID" ] &&
17479                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17480
17481         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17482
17483         [ "$JOBENV" = "nodelocal" ] && {
17484                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17485                 $LCTL set_param jobid_name=$FAKE_JOBID
17486                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17487         }
17488
17489         log "Test: ${cmd[*]}"
17490         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17491
17492         if [ $JOBENV = "FAKE_JOBID" ]; then
17493                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17494         else
17495                 ${cmd[*]}
17496         fi
17497
17498         # all files are created on OST0000
17499         for facet in $facets; do
17500                 local stats="*.$(convert_facet2label $facet).job_stats"
17501
17502                 # strip out libtool wrappers for in-tree executables
17503                 if [ $(do_facet $facet lctl get_param $stats |
17504                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17505                         do_facet $facet lctl get_param $stats
17506                         error "No jobstats for $JOBVAL found on $facet::$stats"
17507                 fi
17508         done
17509 }
17510
17511 jobstats_set() {
17512         local new_jobenv=$1
17513
17514         set_persistent_param_and_check client "jobid_var" \
17515                 "$FSNAME.sys.jobid_var" $new_jobenv
17516 }
17517
17518 test_205a() { # Job stats
17519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17520         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17521                 skip "Need MDS version with at least 2.7.1"
17522         remote_mgs_nodsh && skip "remote MGS with nodsh"
17523         remote_mds_nodsh && skip "remote MDS with nodsh"
17524         remote_ost_nodsh && skip "remote OST with nodsh"
17525         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17526                 skip "Server doesn't support jobstats"
17527         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17528
17529         local old_jobenv=$($LCTL get_param -n jobid_var)
17530         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17531
17532         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17533                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17534         else
17535                 stack_trap "do_facet mgs $PERM_CMD \
17536                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17537         fi
17538         changelog_register
17539
17540         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17541                                 mdt.*.job_cleanup_interval | head -n 1)
17542         local new_interval=5
17543         do_facet $SINGLEMDS \
17544                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17545         stack_trap "do_facet $SINGLEMDS \
17546                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17547         local start=$SECONDS
17548
17549         local cmd
17550         # mkdir
17551         cmd="mkdir $DIR/$tdir"
17552         verify_jobstats "$cmd" "$SINGLEMDS"
17553         # rmdir
17554         cmd="rmdir $DIR/$tdir"
17555         verify_jobstats "$cmd" "$SINGLEMDS"
17556         # mkdir on secondary MDT
17557         if [ $MDSCOUNT -gt 1 ]; then
17558                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17559                 verify_jobstats "$cmd" "mds2"
17560         fi
17561         # mknod
17562         cmd="mknod $DIR/$tfile c 1 3"
17563         verify_jobstats "$cmd" "$SINGLEMDS"
17564         # unlink
17565         cmd="rm -f $DIR/$tfile"
17566         verify_jobstats "$cmd" "$SINGLEMDS"
17567         # create all files on OST0000 so verify_jobstats can find OST stats
17568         # open & close
17569         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17570         verify_jobstats "$cmd" "$SINGLEMDS"
17571         # setattr
17572         cmd="touch $DIR/$tfile"
17573         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17574         # write
17575         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17576         verify_jobstats "$cmd" "ost1"
17577         # read
17578         cancel_lru_locks osc
17579         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17580         verify_jobstats "$cmd" "ost1"
17581         # truncate
17582         cmd="$TRUNCATE $DIR/$tfile 0"
17583         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17584         # rename
17585         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17586         verify_jobstats "$cmd" "$SINGLEMDS"
17587         # jobstats expiry - sleep until old stats should be expired
17588         local left=$((new_interval + 5 - (SECONDS - start)))
17589         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17590                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17591                         "0" $left
17592         cmd="mkdir $DIR/$tdir.expire"
17593         verify_jobstats "$cmd" "$SINGLEMDS"
17594         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17595             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17596
17597         # Ensure that jobid are present in changelog (if supported by MDS)
17598         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17599                 changelog_dump | tail -10
17600                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17601                 [ $jobids -eq 9 ] ||
17602                         error "Wrong changelog jobid count $jobids != 9"
17603
17604                 # LU-5862
17605                 JOBENV="disable"
17606                 jobstats_set $JOBENV
17607                 touch $DIR/$tfile
17608                 changelog_dump | grep $tfile
17609                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17610                 [ $jobids -eq 0 ] ||
17611                         error "Unexpected jobids when jobid_var=$JOBENV"
17612         fi
17613
17614         # test '%j' access to environment variable - if supported
17615         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17616                 JOBENV="JOBCOMPLEX"
17617                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17618
17619                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17620         fi
17621
17622         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17623                 JOBENV="JOBCOMPLEX"
17624                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17625
17626                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17627         fi
17628
17629         # test '%j' access to per-session jobid - if supported
17630         if lctl list_param jobid_this_session > /dev/null 2>&1
17631         then
17632                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17633                 lctl set_param jobid_this_session=$USER
17634
17635                 JOBENV="JOBCOMPLEX"
17636                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17637
17638                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17639         fi
17640 }
17641 run_test 205a "Verify job stats"
17642
17643 # LU-13117, LU-13597
17644 test_205b() {
17645         job_stats="mdt.*.job_stats"
17646         $LCTL set_param $job_stats=clear
17647         # Setting jobid_var to USER might not be supported
17648         $LCTL set_param jobid_var=USER || true
17649         $LCTL set_param jobid_name="%e.%u"
17650         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17651         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17652                 grep "job_id:.*foolish" &&
17653                         error "Unexpected jobid found"
17654         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17655                 grep "open:.*min.*max.*sum" ||
17656                         error "wrong job_stats format found"
17657 }
17658 run_test 205b "Verify job stats jobid and output format"
17659
17660 # LU-13733
17661 test_205c() {
17662         $LCTL set_param llite.*.stats=0
17663         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17664         $LCTL get_param llite.*.stats
17665         $LCTL get_param llite.*.stats | grep \
17666                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17667                         error "wrong client stats format found"
17668 }
17669 run_test 205c "Verify client stats format"
17670
17671 # LU-1480, LU-1773 and LU-1657
17672 test_206() {
17673         mkdir -p $DIR/$tdir
17674         $LFS setstripe -c -1 $DIR/$tdir
17675 #define OBD_FAIL_LOV_INIT 0x1403
17676         $LCTL set_param fail_loc=0xa0001403
17677         $LCTL set_param fail_val=1
17678         touch $DIR/$tdir/$tfile || true
17679 }
17680 run_test 206 "fail lov_init_raid0() doesn't lbug"
17681
17682 test_207a() {
17683         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17684         local fsz=`stat -c %s $DIR/$tfile`
17685         cancel_lru_locks mdc
17686
17687         # do not return layout in getattr intent
17688 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17689         $LCTL set_param fail_loc=0x170
17690         local sz=`stat -c %s $DIR/$tfile`
17691
17692         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17693
17694         rm -rf $DIR/$tfile
17695 }
17696 run_test 207a "can refresh layout at glimpse"
17697
17698 test_207b() {
17699         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17700         local cksum=`md5sum $DIR/$tfile`
17701         local fsz=`stat -c %s $DIR/$tfile`
17702         cancel_lru_locks mdc
17703         cancel_lru_locks osc
17704
17705         # do not return layout in getattr intent
17706 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17707         $LCTL set_param fail_loc=0x171
17708
17709         # it will refresh layout after the file is opened but before read issues
17710         echo checksum is "$cksum"
17711         echo "$cksum" |md5sum -c --quiet || error "file differs"
17712
17713         rm -rf $DIR/$tfile
17714 }
17715 run_test 207b "can refresh layout at open"
17716
17717 test_208() {
17718         # FIXME: in this test suite, only RD lease is used. This is okay
17719         # for now as only exclusive open is supported. After generic lease
17720         # is done, this test suite should be revised. - Jinshan
17721
17722         remote_mds_nodsh && skip "remote MDS with nodsh"
17723         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17724                 skip "Need MDS version at least 2.4.52"
17725
17726         echo "==== test 1: verify get lease work"
17727         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17728
17729         echo "==== test 2: verify lease can be broken by upcoming open"
17730         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17731         local PID=$!
17732         sleep 1
17733
17734         $MULTIOP $DIR/$tfile oO_RDONLY:c
17735         kill -USR1 $PID && wait $PID || error "break lease error"
17736
17737         echo "==== test 3: verify lease can't be granted if an open already exists"
17738         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17739         local PID=$!
17740         sleep 1
17741
17742         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17743         kill -USR1 $PID && wait $PID || error "open file error"
17744
17745         echo "==== test 4: lease can sustain over recovery"
17746         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17747         PID=$!
17748         sleep 1
17749
17750         fail mds1
17751
17752         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17753
17754         echo "==== test 5: lease broken can't be regained by replay"
17755         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17756         PID=$!
17757         sleep 1
17758
17759         # open file to break lease and then recovery
17760         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17761         fail mds1
17762
17763         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17764
17765         rm -f $DIR/$tfile
17766 }
17767 run_test 208 "Exclusive open"
17768
17769 test_209() {
17770         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17771                 skip_env "must have disp_stripe"
17772
17773         touch $DIR/$tfile
17774         sync; sleep 5; sync;
17775
17776         echo 3 > /proc/sys/vm/drop_caches
17777         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17778                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17779         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17780
17781         # open/close 500 times
17782         for i in $(seq 500); do
17783                 cat $DIR/$tfile
17784         done
17785
17786         echo 3 > /proc/sys/vm/drop_caches
17787         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17788                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17789         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17790
17791         echo "before: $req_before, after: $req_after"
17792         [ $((req_after - req_before)) -ge 300 ] &&
17793                 error "open/close requests are not freed"
17794         return 0
17795 }
17796 run_test 209 "read-only open/close requests should be freed promptly"
17797
17798 test_210() {
17799         local pid
17800
17801         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17802         pid=$!
17803         sleep 1
17804
17805         $LFS getstripe $DIR/$tfile
17806         kill -USR1 $pid
17807         wait $pid || error "multiop failed"
17808
17809         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17810         pid=$!
17811         sleep 1
17812
17813         $LFS getstripe $DIR/$tfile
17814         kill -USR1 $pid
17815         wait $pid || error "multiop failed"
17816 }
17817 run_test 210 "lfs getstripe does not break leases"
17818
17819 test_212() {
17820         size=`date +%s`
17821         size=$((size % 8192 + 1))
17822         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17823         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17824         rm -f $DIR/f212 $DIR/f212.xyz
17825 }
17826 run_test 212 "Sendfile test ============================================"
17827
17828 test_213() {
17829         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17830         cancel_lru_locks osc
17831         lctl set_param fail_loc=0x8000040f
17832         # generate a read lock
17833         cat $DIR/$tfile > /dev/null
17834         # write to the file, it will try to cancel the above read lock.
17835         cat /etc/hosts >> $DIR/$tfile
17836 }
17837 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17838
17839 test_214() { # for bug 20133
17840         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17841         for (( i=0; i < 340; i++ )) ; do
17842                 touch $DIR/$tdir/d214c/a$i
17843         done
17844
17845         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17846         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17847         ls $DIR/d214c || error "ls $DIR/d214c failed"
17848         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17849         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17850 }
17851 run_test 214 "hash-indexed directory test - bug 20133"
17852
17853 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17854 create_lnet_proc_files() {
17855         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17856 }
17857
17858 # counterpart of create_lnet_proc_files
17859 remove_lnet_proc_files() {
17860         rm -f $TMP/lnet_$1.sys
17861 }
17862
17863 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17864 # 3rd arg as regexp for body
17865 check_lnet_proc_stats() {
17866         local l=$(cat "$TMP/lnet_$1" |wc -l)
17867         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17868
17869         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17870 }
17871
17872 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17873 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17874 # optional and can be regexp for 2nd line (lnet.routes case)
17875 check_lnet_proc_entry() {
17876         local blp=2          # blp stands for 'position of 1st line of body'
17877         [ -z "$5" ] || blp=3 # lnet.routes case
17878
17879         local l=$(cat "$TMP/lnet_$1" |wc -l)
17880         # subtracting one from $blp because the body can be empty
17881         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17882
17883         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17884                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17885
17886         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17887                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17888
17889         # bail out if any unexpected line happened
17890         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17891         [ "$?" != 0 ] || error "$2 misformatted"
17892 }
17893
17894 test_215() { # for bugs 18102, 21079, 21517
17895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17896
17897         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17898         local P='[1-9][0-9]*'           # positive numeric
17899         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17900         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17901         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17902         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17903
17904         local L1 # regexp for 1st line
17905         local L2 # regexp for 2nd line (optional)
17906         local BR # regexp for the rest (body)
17907
17908         # lnet.stats should look as 11 space-separated non-negative numerics
17909         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17910         create_lnet_proc_files "stats"
17911         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17912         remove_lnet_proc_files "stats"
17913
17914         # lnet.routes should look like this:
17915         # Routing disabled/enabled
17916         # net hops priority state router
17917         # where net is a string like tcp0, hops > 0, priority >= 0,
17918         # state is up/down,
17919         # router is a string like 192.168.1.1@tcp2
17920         L1="^Routing (disabled|enabled)$"
17921         L2="^net +hops +priority +state +router$"
17922         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17923         create_lnet_proc_files "routes"
17924         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17925         remove_lnet_proc_files "routes"
17926
17927         # lnet.routers should look like this:
17928         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17929         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17930         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17931         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17932         L1="^ref +rtr_ref +alive +router$"
17933         BR="^$P +$P +(up|down) +$NID$"
17934         create_lnet_proc_files "routers"
17935         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17936         remove_lnet_proc_files "routers"
17937
17938         # lnet.peers should look like this:
17939         # nid refs state last max rtr min tx min queue
17940         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17941         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17942         # numeric (0 or >0 or <0), queue >= 0.
17943         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17944         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17945         create_lnet_proc_files "peers"
17946         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17947         remove_lnet_proc_files "peers"
17948
17949         # lnet.buffers  should look like this:
17950         # pages count credits min
17951         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17952         L1="^pages +count +credits +min$"
17953         BR="^ +$N +$N +$I +$I$"
17954         create_lnet_proc_files "buffers"
17955         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17956         remove_lnet_proc_files "buffers"
17957
17958         # lnet.nis should look like this:
17959         # nid status alive refs peer rtr max tx min
17960         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17961         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17962         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17963         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17964         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17965         create_lnet_proc_files "nis"
17966         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17967         remove_lnet_proc_files "nis"
17968
17969         # can we successfully write to lnet.stats?
17970         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17971 }
17972 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17973
17974 test_216() { # bug 20317
17975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17976         remote_ost_nodsh && skip "remote OST with nodsh"
17977
17978         local node
17979         local facets=$(get_facets OST)
17980         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17981
17982         save_lustre_params client "osc.*.contention_seconds" > $p
17983         save_lustre_params $facets \
17984                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17985         save_lustre_params $facets \
17986                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17987         save_lustre_params $facets \
17988                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17989         clear_stats osc.*.osc_stats
17990
17991         # agressive lockless i/o settings
17992         do_nodes $(comma_list $(osts_nodes)) \
17993                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17994                         ldlm.namespaces.filter-*.contended_locks=0 \
17995                         ldlm.namespaces.filter-*.contention_seconds=60"
17996         lctl set_param -n osc.*.contention_seconds=60
17997
17998         $DIRECTIO write $DIR/$tfile 0 10 4096
17999         $CHECKSTAT -s 40960 $DIR/$tfile
18000
18001         # disable lockless i/o
18002         do_nodes $(comma_list $(osts_nodes)) \
18003                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18004                         ldlm.namespaces.filter-*.contended_locks=32 \
18005                         ldlm.namespaces.filter-*.contention_seconds=0"
18006         lctl set_param -n osc.*.contention_seconds=0
18007         clear_stats osc.*.osc_stats
18008
18009         dd if=/dev/zero of=$DIR/$tfile count=0
18010         $CHECKSTAT -s 0 $DIR/$tfile
18011
18012         restore_lustre_params <$p
18013         rm -f $p
18014         rm $DIR/$tfile
18015 }
18016 run_test 216 "check lockless direct write updates file size and kms correctly"
18017
18018 test_217() { # bug 22430
18019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18020
18021         local node
18022         local nid
18023
18024         for node in $(nodes_list); do
18025                 nid=$(host_nids_address $node $NETTYPE)
18026                 if [[ $nid = *-* ]] ; then
18027                         echo "lctl ping $(h2nettype $nid)"
18028                         lctl ping $(h2nettype $nid)
18029                 else
18030                         echo "skipping $node (no hyphen detected)"
18031                 fi
18032         done
18033 }
18034 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18035
18036 test_218() {
18037        # do directio so as not to populate the page cache
18038        log "creating a 10 Mb file"
18039        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18040        log "starting reads"
18041        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18042        log "truncating the file"
18043        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18044        log "killing dd"
18045        kill %+ || true # reads might have finished
18046        echo "wait until dd is finished"
18047        wait
18048        log "removing the temporary file"
18049        rm -rf $DIR/$tfile || error "tmp file removal failed"
18050 }
18051 run_test 218 "parallel read and truncate should not deadlock"
18052
18053 test_219() {
18054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18055
18056         # write one partial page
18057         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18058         # set no grant so vvp_io_commit_write will do sync write
18059         $LCTL set_param fail_loc=0x411
18060         # write a full page at the end of file
18061         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18062
18063         $LCTL set_param fail_loc=0
18064         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18065         $LCTL set_param fail_loc=0x411
18066         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18067
18068         # LU-4201
18069         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18070         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18071 }
18072 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18073
18074 test_220() { #LU-325
18075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18076         remote_ost_nodsh && skip "remote OST with nodsh"
18077         remote_mds_nodsh && skip "remote MDS with nodsh"
18078         remote_mgs_nodsh && skip "remote MGS with nodsh"
18079
18080         local OSTIDX=0
18081
18082         # create on MDT0000 so the last_id and next_id are correct
18083         mkdir $DIR/$tdir
18084         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18085         OST=${OST%_UUID}
18086
18087         # on the mdt's osc
18088         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18089         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18090                         osp.$mdtosc_proc1.prealloc_last_id)
18091         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18092                         osp.$mdtosc_proc1.prealloc_next_id)
18093
18094         $LFS df -i
18095
18096         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18097         #define OBD_FAIL_OST_ENOINO              0x229
18098         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18099         create_pool $FSNAME.$TESTNAME || return 1
18100         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18101
18102         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18103
18104         MDSOBJS=$((last_id - next_id))
18105         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18106
18107         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18108         echo "OST still has $count kbytes free"
18109
18110         echo "create $MDSOBJS files @next_id..."
18111         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18112
18113         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18114                         osp.$mdtosc_proc1.prealloc_last_id)
18115         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18116                         osp.$mdtosc_proc1.prealloc_next_id)
18117
18118         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18119         $LFS df -i
18120
18121         echo "cleanup..."
18122
18123         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18124         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18125
18126         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18127                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18128         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18129                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18130         echo "unlink $MDSOBJS files @$next_id..."
18131         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18132 }
18133 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18134
18135 test_221() {
18136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18137
18138         dd if=`which date` of=$MOUNT/date oflag=sync
18139         chmod +x $MOUNT/date
18140
18141         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18142         $LCTL set_param fail_loc=0x80001401
18143
18144         $MOUNT/date > /dev/null
18145         rm -f $MOUNT/date
18146 }
18147 run_test 221 "make sure fault and truncate race to not cause OOM"
18148
18149 test_222a () {
18150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18151
18152         rm -rf $DIR/$tdir
18153         test_mkdir $DIR/$tdir
18154         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18155         createmany -o $DIR/$tdir/$tfile 10
18156         cancel_lru_locks mdc
18157         cancel_lru_locks osc
18158         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18159         $LCTL set_param fail_loc=0x31a
18160         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18161         $LCTL set_param fail_loc=0
18162         rm -r $DIR/$tdir
18163 }
18164 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18165
18166 test_222b () {
18167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18168
18169         rm -rf $DIR/$tdir
18170         test_mkdir $DIR/$tdir
18171         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18172         createmany -o $DIR/$tdir/$tfile 10
18173         cancel_lru_locks mdc
18174         cancel_lru_locks osc
18175         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18176         $LCTL set_param fail_loc=0x31a
18177         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18178         $LCTL set_param fail_loc=0
18179 }
18180 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18181
18182 test_223 () {
18183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18184
18185         rm -rf $DIR/$tdir
18186         test_mkdir $DIR/$tdir
18187         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18188         createmany -o $DIR/$tdir/$tfile 10
18189         cancel_lru_locks mdc
18190         cancel_lru_locks osc
18191         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18192         $LCTL set_param fail_loc=0x31b
18193         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18194         $LCTL set_param fail_loc=0
18195         rm -r $DIR/$tdir
18196 }
18197 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18198
18199 test_224a() { # LU-1039, MRP-303
18200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18201
18202         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18203         $LCTL set_param fail_loc=0x508
18204         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18205         $LCTL set_param fail_loc=0
18206         df $DIR
18207 }
18208 run_test 224a "Don't panic on bulk IO failure"
18209
18210 test_224b() { # LU-1039, MRP-303
18211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18212
18213         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18214         cancel_lru_locks osc
18215         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18216         $LCTL set_param fail_loc=0x515
18217         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18218         $LCTL set_param fail_loc=0
18219         df $DIR
18220 }
18221 run_test 224b "Don't panic on bulk IO failure"
18222
18223 test_224c() { # LU-6441
18224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18225         remote_mds_nodsh && skip "remote MDS with nodsh"
18226
18227         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18228         save_writethrough $p
18229         set_cache writethrough on
18230
18231         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18232         local at_max=$($LCTL get_param -n at_max)
18233         local timeout=$($LCTL get_param -n timeout)
18234         local test_at="at_max"
18235         local param_at="$FSNAME.sys.at_max"
18236         local test_timeout="timeout"
18237         local param_timeout="$FSNAME.sys.timeout"
18238
18239         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18240
18241         set_persistent_param_and_check client "$test_at" "$param_at" 0
18242         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18243
18244         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18245         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18246         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18247         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18248         sync
18249         do_facet ost1 "$LCTL set_param fail_loc=0"
18250
18251         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18252         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18253                 $timeout
18254
18255         $LCTL set_param -n $pages_per_rpc
18256         restore_lustre_params < $p
18257         rm -f $p
18258 }
18259 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18260
18261 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18262 test_225a () {
18263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18264         if [ -z ${MDSSURVEY} ]; then
18265                 skip_env "mds-survey not found"
18266         fi
18267         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18268                 skip "Need MDS version at least 2.2.51"
18269
18270         local mds=$(facet_host $SINGLEMDS)
18271         local target=$(do_nodes $mds 'lctl dl' |
18272                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18273
18274         local cmd1="file_count=1000 thrhi=4"
18275         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18276         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18277         local cmd="$cmd1 $cmd2 $cmd3"
18278
18279         rm -f ${TMP}/mds_survey*
18280         echo + $cmd
18281         eval $cmd || error "mds-survey with zero-stripe failed"
18282         cat ${TMP}/mds_survey*
18283         rm -f ${TMP}/mds_survey*
18284 }
18285 run_test 225a "Metadata survey sanity with zero-stripe"
18286
18287 test_225b () {
18288         if [ -z ${MDSSURVEY} ]; then
18289                 skip_env "mds-survey not found"
18290         fi
18291         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18292                 skip "Need MDS version at least 2.2.51"
18293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18294         remote_mds_nodsh && skip "remote MDS with nodsh"
18295         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18296                 skip_env "Need to mount OST to test"
18297         fi
18298
18299         local mds=$(facet_host $SINGLEMDS)
18300         local target=$(do_nodes $mds 'lctl dl' |
18301                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18302
18303         local cmd1="file_count=1000 thrhi=4"
18304         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18305         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18306         local cmd="$cmd1 $cmd2 $cmd3"
18307
18308         rm -f ${TMP}/mds_survey*
18309         echo + $cmd
18310         eval $cmd || error "mds-survey with stripe_count failed"
18311         cat ${TMP}/mds_survey*
18312         rm -f ${TMP}/mds_survey*
18313 }
18314 run_test 225b "Metadata survey sanity with stripe_count = 1"
18315
18316 mcreate_path2fid () {
18317         local mode=$1
18318         local major=$2
18319         local minor=$3
18320         local name=$4
18321         local desc=$5
18322         local path=$DIR/$tdir/$name
18323         local fid
18324         local rc
18325         local fid_path
18326
18327         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18328                 error "cannot create $desc"
18329
18330         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18331         rc=$?
18332         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18333
18334         fid_path=$($LFS fid2path $MOUNT $fid)
18335         rc=$?
18336         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18337
18338         [ "$path" == "$fid_path" ] ||
18339                 error "fid2path returned $fid_path, expected $path"
18340
18341         echo "pass with $path and $fid"
18342 }
18343
18344 test_226a () {
18345         rm -rf $DIR/$tdir
18346         mkdir -p $DIR/$tdir
18347
18348         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18349         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18350         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18351         mcreate_path2fid 0040666 0 0 dir "directory"
18352         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18353         mcreate_path2fid 0100666 0 0 file "regular file"
18354         mcreate_path2fid 0120666 0 0 link "symbolic link"
18355         mcreate_path2fid 0140666 0 0 sock "socket"
18356 }
18357 run_test 226a "call path2fid and fid2path on files of all type"
18358
18359 test_226b () {
18360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18361
18362         local MDTIDX=1
18363
18364         rm -rf $DIR/$tdir
18365         mkdir -p $DIR/$tdir
18366         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18367                 error "create remote directory failed"
18368         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18369         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18370                                 "character special file (null)"
18371         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18372                                 "character special file (no device)"
18373         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18374         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18375                                 "block special file (loop)"
18376         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18377         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18378         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18379 }
18380 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18381
18382 test_226c () {
18383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18384         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18385                 skip "Need MDS version at least 2.13.55"
18386
18387         local submnt=/mnt/submnt
18388         local srcfile=/etc/passwd
18389         local dstfile=$submnt/passwd
18390         local path
18391         local fid
18392
18393         rm -rf $DIR/$tdir
18394         rm -rf $submnt
18395         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18396                 error "create remote directory failed"
18397         mkdir -p $submnt || error "create $submnt failed"
18398         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18399                 error "mount $submnt failed"
18400         stack_trap "umount $submnt" EXIT
18401
18402         cp $srcfile $dstfile
18403         fid=$($LFS path2fid $dstfile)
18404         path=$($LFS fid2path $submnt "$fid")
18405         [ "$path" = "$dstfile" ] ||
18406                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18407 }
18408 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18409
18410 # LU-1299 Executing or running ldd on a truncated executable does not
18411 # cause an out-of-memory condition.
18412 test_227() {
18413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18414         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18415
18416         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18417         chmod +x $MOUNT/date
18418
18419         $MOUNT/date > /dev/null
18420         ldd $MOUNT/date > /dev/null
18421         rm -f $MOUNT/date
18422 }
18423 run_test 227 "running truncated executable does not cause OOM"
18424
18425 # LU-1512 try to reuse idle OI blocks
18426 test_228a() {
18427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18428         remote_mds_nodsh && skip "remote MDS with nodsh"
18429         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18430
18431         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18432         local myDIR=$DIR/$tdir
18433
18434         mkdir -p $myDIR
18435         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18436         $LCTL set_param fail_loc=0x80001002
18437         createmany -o $myDIR/t- 10000
18438         $LCTL set_param fail_loc=0
18439         # The guard is current the largest FID holder
18440         touch $myDIR/guard
18441         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18442                     tr -d '[')
18443         local IDX=$(($SEQ % 64))
18444
18445         do_facet $SINGLEMDS sync
18446         # Make sure journal flushed.
18447         sleep 6
18448         local blk1=$(do_facet $SINGLEMDS \
18449                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18450                      grep Blockcount | awk '{print $4}')
18451
18452         # Remove old files, some OI blocks will become idle.
18453         unlinkmany $myDIR/t- 10000
18454         # Create new files, idle OI blocks should be reused.
18455         createmany -o $myDIR/t- 2000
18456         do_facet $SINGLEMDS sync
18457         # Make sure journal flushed.
18458         sleep 6
18459         local blk2=$(do_facet $SINGLEMDS \
18460                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18461                      grep Blockcount | awk '{print $4}')
18462
18463         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18464 }
18465 run_test 228a "try to reuse idle OI blocks"
18466
18467 test_228b() {
18468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18469         remote_mds_nodsh && skip "remote MDS with nodsh"
18470         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18471
18472         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18473         local myDIR=$DIR/$tdir
18474
18475         mkdir -p $myDIR
18476         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18477         $LCTL set_param fail_loc=0x80001002
18478         createmany -o $myDIR/t- 10000
18479         $LCTL set_param fail_loc=0
18480         # The guard is current the largest FID holder
18481         touch $myDIR/guard
18482         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18483                     tr -d '[')
18484         local IDX=$(($SEQ % 64))
18485
18486         do_facet $SINGLEMDS sync
18487         # Make sure journal flushed.
18488         sleep 6
18489         local blk1=$(do_facet $SINGLEMDS \
18490                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18491                      grep Blockcount | awk '{print $4}')
18492
18493         # Remove old files, some OI blocks will become idle.
18494         unlinkmany $myDIR/t- 10000
18495
18496         # stop the MDT
18497         stop $SINGLEMDS || error "Fail to stop MDT."
18498         # remount the MDT
18499         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18500
18501         df $MOUNT || error "Fail to df."
18502         # Create new files, idle OI blocks should be reused.
18503         createmany -o $myDIR/t- 2000
18504         do_facet $SINGLEMDS sync
18505         # Make sure journal flushed.
18506         sleep 6
18507         local blk2=$(do_facet $SINGLEMDS \
18508                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18509                      grep Blockcount | awk '{print $4}')
18510
18511         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18512 }
18513 run_test 228b "idle OI blocks can be reused after MDT restart"
18514
18515 #LU-1881
18516 test_228c() {
18517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18518         remote_mds_nodsh && skip "remote MDS with nodsh"
18519         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18520
18521         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18522         local myDIR=$DIR/$tdir
18523
18524         mkdir -p $myDIR
18525         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18526         $LCTL set_param fail_loc=0x80001002
18527         # 20000 files can guarantee there are index nodes in the OI file
18528         createmany -o $myDIR/t- 20000
18529         $LCTL set_param fail_loc=0
18530         # The guard is current the largest FID holder
18531         touch $myDIR/guard
18532         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18533                     tr -d '[')
18534         local IDX=$(($SEQ % 64))
18535
18536         do_facet $SINGLEMDS sync
18537         # Make sure journal flushed.
18538         sleep 6
18539         local blk1=$(do_facet $SINGLEMDS \
18540                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18541                      grep Blockcount | awk '{print $4}')
18542
18543         # Remove old files, some OI blocks will become idle.
18544         unlinkmany $myDIR/t- 20000
18545         rm -f $myDIR/guard
18546         # The OI file should become empty now
18547
18548         # Create new files, idle OI blocks should be reused.
18549         createmany -o $myDIR/t- 2000
18550         do_facet $SINGLEMDS sync
18551         # Make sure journal flushed.
18552         sleep 6
18553         local blk2=$(do_facet $SINGLEMDS \
18554                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18555                      grep Blockcount | awk '{print $4}')
18556
18557         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18558 }
18559 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18560
18561 test_229() { # LU-2482, LU-3448
18562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18563         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18564         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18565                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18566
18567         rm -f $DIR/$tfile
18568
18569         # Create a file with a released layout and stripe count 2.
18570         $MULTIOP $DIR/$tfile H2c ||
18571                 error "failed to create file with released layout"
18572
18573         $LFS getstripe -v $DIR/$tfile
18574
18575         local pattern=$($LFS getstripe -L $DIR/$tfile)
18576         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18577
18578         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18579                 error "getstripe"
18580         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18581         stat $DIR/$tfile || error "failed to stat released file"
18582
18583         chown $RUNAS_ID $DIR/$tfile ||
18584                 error "chown $RUNAS_ID $DIR/$tfile failed"
18585
18586         chgrp $RUNAS_ID $DIR/$tfile ||
18587                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18588
18589         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18590         rm $DIR/$tfile || error "failed to remove released file"
18591 }
18592 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18593
18594 test_230a() {
18595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18597         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18598                 skip "Need MDS version at least 2.11.52"
18599
18600         local MDTIDX=1
18601
18602         test_mkdir $DIR/$tdir
18603         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18604         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18605         [ $mdt_idx -ne 0 ] &&
18606                 error "create local directory on wrong MDT $mdt_idx"
18607
18608         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18609                         error "create remote directory failed"
18610         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18611         [ $mdt_idx -ne $MDTIDX ] &&
18612                 error "create remote directory on wrong MDT $mdt_idx"
18613
18614         createmany -o $DIR/$tdir/test_230/t- 10 ||
18615                 error "create files on remote directory failed"
18616         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18617         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18618         rm -r $DIR/$tdir || error "unlink remote directory failed"
18619 }
18620 run_test 230a "Create remote directory and files under the remote directory"
18621
18622 test_230b() {
18623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18624         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18625         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18626                 skip "Need MDS version at least 2.11.52"
18627
18628         local MDTIDX=1
18629         local mdt_index
18630         local i
18631         local file
18632         local pid
18633         local stripe_count
18634         local migrate_dir=$DIR/$tdir/migrate_dir
18635         local other_dir=$DIR/$tdir/other_dir
18636
18637         test_mkdir $DIR/$tdir
18638         test_mkdir -i0 -c1 $migrate_dir
18639         test_mkdir -i0 -c1 $other_dir
18640         for ((i=0; i<10; i++)); do
18641                 mkdir -p $migrate_dir/dir_${i}
18642                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18643                         error "create files under remote dir failed $i"
18644         done
18645
18646         cp /etc/passwd $migrate_dir/$tfile
18647         cp /etc/passwd $other_dir/$tfile
18648         chattr +SAD $migrate_dir
18649         chattr +SAD $migrate_dir/$tfile
18650
18651         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18652         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18653         local old_dir_mode=$(stat -c%f $migrate_dir)
18654         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18655
18656         mkdir -p $migrate_dir/dir_default_stripe2
18657         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18658         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18659
18660         mkdir -p $other_dir
18661         ln $migrate_dir/$tfile $other_dir/luna
18662         ln $migrate_dir/$tfile $migrate_dir/sofia
18663         ln $other_dir/$tfile $migrate_dir/david
18664         ln -s $migrate_dir/$tfile $other_dir/zachary
18665         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18666         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18667
18668         local len
18669         local lnktgt
18670
18671         # inline symlink
18672         for len in 58 59 60; do
18673                 lnktgt=$(str_repeat 'l' $len)
18674                 touch $migrate_dir/$lnktgt
18675                 ln -s $lnktgt $migrate_dir/${len}char_ln
18676         done
18677
18678         # PATH_MAX
18679         for len in 4094 4095; do
18680                 lnktgt=$(str_repeat 'l' $len)
18681                 ln -s $lnktgt $migrate_dir/${len}char_ln
18682         done
18683
18684         # NAME_MAX
18685         for len in 254 255; do
18686                 touch $migrate_dir/$(str_repeat 'l' $len)
18687         done
18688
18689         $LFS migrate -m $MDTIDX $migrate_dir ||
18690                 error "fails on migrating remote dir to MDT1"
18691
18692         echo "migratate to MDT1, then checking.."
18693         for ((i = 0; i < 10; i++)); do
18694                 for file in $(find $migrate_dir/dir_${i}); do
18695                         mdt_index=$($LFS getstripe -m $file)
18696                         # broken symlink getstripe will fail
18697                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18698                                 error "$file is not on MDT${MDTIDX}"
18699                 done
18700         done
18701
18702         # the multiple link file should still in MDT0
18703         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18704         [ $mdt_index == 0 ] ||
18705                 error "$file is not on MDT${MDTIDX}"
18706
18707         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18708         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18709                 error " expect $old_dir_flag get $new_dir_flag"
18710
18711         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18712         [ "$old_file_flag" = "$new_file_flag" ] ||
18713                 error " expect $old_file_flag get $new_file_flag"
18714
18715         local new_dir_mode=$(stat -c%f $migrate_dir)
18716         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18717                 error "expect mode $old_dir_mode get $new_dir_mode"
18718
18719         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18720         [ "$old_file_mode" = "$new_file_mode" ] ||
18721                 error "expect mode $old_file_mode get $new_file_mode"
18722
18723         diff /etc/passwd $migrate_dir/$tfile ||
18724                 error "$tfile different after migration"
18725
18726         diff /etc/passwd $other_dir/luna ||
18727                 error "luna different after migration"
18728
18729         diff /etc/passwd $migrate_dir/sofia ||
18730                 error "sofia different after migration"
18731
18732         diff /etc/passwd $migrate_dir/david ||
18733                 error "david different after migration"
18734
18735         diff /etc/passwd $other_dir/zachary ||
18736                 error "zachary different after migration"
18737
18738         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18739                 error "${tfile}_ln different after migration"
18740
18741         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18742                 error "${tfile}_ln_other different after migration"
18743
18744         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18745         [ $stripe_count = 2 ] ||
18746                 error "dir strpe_count $d != 2 after migration."
18747
18748         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18749         [ $stripe_count = 2 ] ||
18750                 error "file strpe_count $d != 2 after migration."
18751
18752         #migrate back to MDT0
18753         MDTIDX=0
18754
18755         $LFS migrate -m $MDTIDX $migrate_dir ||
18756                 error "fails on migrating remote dir to MDT0"
18757
18758         echo "migrate back to MDT0, checking.."
18759         for file in $(find $migrate_dir); do
18760                 mdt_index=$($LFS getstripe -m $file)
18761                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18762                         error "$file is not on MDT${MDTIDX}"
18763         done
18764
18765         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18766         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18767                 error " expect $old_dir_flag get $new_dir_flag"
18768
18769         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18770         [ "$old_file_flag" = "$new_file_flag" ] ||
18771                 error " expect $old_file_flag get $new_file_flag"
18772
18773         local new_dir_mode=$(stat -c%f $migrate_dir)
18774         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18775                 error "expect mode $old_dir_mode get $new_dir_mode"
18776
18777         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18778         [ "$old_file_mode" = "$new_file_mode" ] ||
18779                 error "expect mode $old_file_mode get $new_file_mode"
18780
18781         diff /etc/passwd ${migrate_dir}/$tfile ||
18782                 error "$tfile different after migration"
18783
18784         diff /etc/passwd ${other_dir}/luna ||
18785                 error "luna different after migration"
18786
18787         diff /etc/passwd ${migrate_dir}/sofia ||
18788                 error "sofia different after migration"
18789
18790         diff /etc/passwd ${other_dir}/zachary ||
18791                 error "zachary different after migration"
18792
18793         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18794                 error "${tfile}_ln different after migration"
18795
18796         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18797                 error "${tfile}_ln_other different after migration"
18798
18799         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18800         [ $stripe_count = 2 ] ||
18801                 error "dir strpe_count $d != 2 after migration."
18802
18803         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18804         [ $stripe_count = 2 ] ||
18805                 error "file strpe_count $d != 2 after migration."
18806
18807         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18808 }
18809 run_test 230b "migrate directory"
18810
18811 test_230c() {
18812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18814         remote_mds_nodsh && skip "remote MDS with nodsh"
18815         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18816                 skip "Need MDS version at least 2.11.52"
18817
18818         local MDTIDX=1
18819         local total=3
18820         local mdt_index
18821         local file
18822         local migrate_dir=$DIR/$tdir/migrate_dir
18823
18824         #If migrating directory fails in the middle, all entries of
18825         #the directory is still accessiable.
18826         test_mkdir $DIR/$tdir
18827         test_mkdir -i0 -c1 $migrate_dir
18828         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18829         stat $migrate_dir
18830         createmany -o $migrate_dir/f $total ||
18831                 error "create files under ${migrate_dir} failed"
18832
18833         # fail after migrating top dir, and this will fail only once, so the
18834         # first sub file migration will fail (currently f3), others succeed.
18835         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18836         do_facet mds1 lctl set_param fail_loc=0x1801
18837         local t=$(ls $migrate_dir | wc -l)
18838         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18839                 error "migrate should fail"
18840         local u=$(ls $migrate_dir | wc -l)
18841         [ "$u" == "$t" ] || error "$u != $t during migration"
18842
18843         # add new dir/file should succeed
18844         mkdir $migrate_dir/dir ||
18845                 error "mkdir failed under migrating directory"
18846         touch $migrate_dir/file ||
18847                 error "create file failed under migrating directory"
18848
18849         # add file with existing name should fail
18850         for file in $migrate_dir/f*; do
18851                 stat $file > /dev/null || error "stat $file failed"
18852                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18853                         error "open(O_CREAT|O_EXCL) $file should fail"
18854                 $MULTIOP $file m && error "create $file should fail"
18855                 touch $DIR/$tdir/remote_dir/$tfile ||
18856                         error "touch $tfile failed"
18857                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18858                         error "link $file should fail"
18859                 mdt_index=$($LFS getstripe -m $file)
18860                 if [ $mdt_index == 0 ]; then
18861                         # file failed to migrate is not allowed to rename to
18862                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18863                                 error "rename to $file should fail"
18864                 else
18865                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18866                                 error "rename to $file failed"
18867                 fi
18868                 echo hello >> $file || error "write $file failed"
18869         done
18870
18871         # resume migration with different options should fail
18872         $LFS migrate -m 0 $migrate_dir &&
18873                 error "migrate -m 0 $migrate_dir should fail"
18874
18875         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18876                 error "migrate -c 2 $migrate_dir should fail"
18877
18878         # resume migration should succeed
18879         $LFS migrate -m $MDTIDX $migrate_dir ||
18880                 error "migrate $migrate_dir failed"
18881
18882         echo "Finish migration, then checking.."
18883         for file in $(find $migrate_dir); do
18884                 mdt_index=$($LFS getstripe -m $file)
18885                 [ $mdt_index == $MDTIDX ] ||
18886                         error "$file is not on MDT${MDTIDX}"
18887         done
18888
18889         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18890 }
18891 run_test 230c "check directory accessiblity if migration failed"
18892
18893 test_230d() {
18894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18895         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18896         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18897                 skip "Need MDS version at least 2.11.52"
18898         # LU-11235
18899         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18900
18901         local migrate_dir=$DIR/$tdir/migrate_dir
18902         local old_index
18903         local new_index
18904         local old_count
18905         local new_count
18906         local new_hash
18907         local mdt_index
18908         local i
18909         local j
18910
18911         old_index=$((RANDOM % MDSCOUNT))
18912         old_count=$((MDSCOUNT - old_index))
18913         new_index=$((RANDOM % MDSCOUNT))
18914         new_count=$((MDSCOUNT - new_index))
18915         new_hash=1 # for all_char
18916
18917         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18918         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18919
18920         test_mkdir $DIR/$tdir
18921         test_mkdir -i $old_index -c $old_count $migrate_dir
18922
18923         for ((i=0; i<100; i++)); do
18924                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18925                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18926                         error "create files under remote dir failed $i"
18927         done
18928
18929         echo -n "Migrate from MDT$old_index "
18930         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18931         echo -n "to MDT$new_index"
18932         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18933         echo
18934
18935         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18936         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18937                 error "migrate remote dir error"
18938
18939         echo "Finish migration, then checking.."
18940         for file in $(find $migrate_dir); do
18941                 mdt_index=$($LFS getstripe -m $file)
18942                 if [ $mdt_index -lt $new_index ] ||
18943                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18944                         error "$file is on MDT$mdt_index"
18945                 fi
18946         done
18947
18948         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18949 }
18950 run_test 230d "check migrate big directory"
18951
18952 test_230e() {
18953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18955         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18956                 skip "Need MDS version at least 2.11.52"
18957
18958         local i
18959         local j
18960         local a_fid
18961         local b_fid
18962
18963         mkdir -p $DIR/$tdir
18964         mkdir $DIR/$tdir/migrate_dir
18965         mkdir $DIR/$tdir/other_dir
18966         touch $DIR/$tdir/migrate_dir/a
18967         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18968         ls $DIR/$tdir/other_dir
18969
18970         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18971                 error "migrate dir fails"
18972
18973         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18974         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18975
18976         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18977         [ $mdt_index == 0 ] || error "a is not on MDT0"
18978
18979         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18980                 error "migrate dir fails"
18981
18982         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18983         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18984
18985         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18986         [ $mdt_index == 1 ] || error "a is not on MDT1"
18987
18988         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18989         [ $mdt_index == 1 ] || error "b is not on MDT1"
18990
18991         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18992         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18993
18994         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18995
18996         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18997 }
18998 run_test 230e "migrate mulitple local link files"
18999
19000 test_230f() {
19001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19003         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19004                 skip "Need MDS version at least 2.11.52"
19005
19006         local a_fid
19007         local ln_fid
19008
19009         mkdir -p $DIR/$tdir
19010         mkdir $DIR/$tdir/migrate_dir
19011         $LFS mkdir -i1 $DIR/$tdir/other_dir
19012         touch $DIR/$tdir/migrate_dir/a
19013         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19014         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19015         ls $DIR/$tdir/other_dir
19016
19017         # a should be migrated to MDT1, since no other links on MDT0
19018         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19019                 error "#1 migrate dir fails"
19020         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19021         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19022         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19023         [ $mdt_index == 1 ] || error "a is not on MDT1"
19024
19025         # a should stay on MDT1, because it is a mulitple link file
19026         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19027                 error "#2 migrate dir fails"
19028         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19029         [ $mdt_index == 1 ] || error "a is not on MDT1"
19030
19031         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19032                 error "#3 migrate dir fails"
19033
19034         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19035         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19036         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19037
19038         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19039         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19040
19041         # a should be migrated to MDT0, since no other links on MDT1
19042         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19043                 error "#4 migrate dir fails"
19044         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19045         [ $mdt_index == 0 ] || error "a is not on MDT0"
19046
19047         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19048 }
19049 run_test 230f "migrate mulitple remote link files"
19050
19051 test_230g() {
19052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19053         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19054         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19055                 skip "Need MDS version at least 2.11.52"
19056
19057         mkdir -p $DIR/$tdir/migrate_dir
19058
19059         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19060                 error "migrating dir to non-exist MDT succeeds"
19061         true
19062 }
19063 run_test 230g "migrate dir to non-exist MDT"
19064
19065 test_230h() {
19066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19068         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19069                 skip "Need MDS version at least 2.11.52"
19070
19071         local mdt_index
19072
19073         mkdir -p $DIR/$tdir/migrate_dir
19074
19075         $LFS migrate -m1 $DIR &&
19076                 error "migrating mountpoint1 should fail"
19077
19078         $LFS migrate -m1 $DIR/$tdir/.. &&
19079                 error "migrating mountpoint2 should fail"
19080
19081         # same as mv
19082         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19083                 error "migrating $tdir/migrate_dir/.. should fail"
19084
19085         true
19086 }
19087 run_test 230h "migrate .. and root"
19088
19089 test_230i() {
19090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19092         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19093                 skip "Need MDS version at least 2.11.52"
19094
19095         mkdir -p $DIR/$tdir/migrate_dir
19096
19097         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19098                 error "migration fails with a tailing slash"
19099
19100         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19101                 error "migration fails with two tailing slashes"
19102 }
19103 run_test 230i "lfs migrate -m tolerates trailing slashes"
19104
19105 test_230j() {
19106         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19107         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19108                 skip "Need MDS version at least 2.11.52"
19109
19110         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19111         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19112                 error "create $tfile failed"
19113         cat /etc/passwd > $DIR/$tdir/$tfile
19114
19115         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19116
19117         cmp /etc/passwd $DIR/$tdir/$tfile ||
19118                 error "DoM file mismatch after migration"
19119 }
19120 run_test 230j "DoM file data not changed after dir migration"
19121
19122 test_230k() {
19123         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19124         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19125                 skip "Need MDS version at least 2.11.56"
19126
19127         local total=20
19128         local files_on_starting_mdt=0
19129
19130         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19131         $LFS getdirstripe $DIR/$tdir
19132         for i in $(seq $total); do
19133                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19134                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19135                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19136         done
19137
19138         echo "$files_on_starting_mdt files on MDT0"
19139
19140         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19141         $LFS getdirstripe $DIR/$tdir
19142
19143         files_on_starting_mdt=0
19144         for i in $(seq $total); do
19145                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19146                         error "file $tfile.$i mismatch after migration"
19147                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19148                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19149         done
19150
19151         echo "$files_on_starting_mdt files on MDT1 after migration"
19152         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19153
19154         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19155         $LFS getdirstripe $DIR/$tdir
19156
19157         files_on_starting_mdt=0
19158         for i in $(seq $total); do
19159                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19160                         error "file $tfile.$i mismatch after 2nd migration"
19161                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19162                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19163         done
19164
19165         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19166         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19167
19168         true
19169 }
19170 run_test 230k "file data not changed after dir migration"
19171
19172 test_230l() {
19173         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19174         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19175                 skip "Need MDS version at least 2.11.56"
19176
19177         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19178         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19179                 error "create files under remote dir failed $i"
19180         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19181 }
19182 run_test 230l "readdir between MDTs won't crash"
19183
19184 test_230m() {
19185         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19186         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19187                 skip "Need MDS version at least 2.11.56"
19188
19189         local MDTIDX=1
19190         local mig_dir=$DIR/$tdir/migrate_dir
19191         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19192         local shortstr="b"
19193         local val
19194
19195         echo "Creating files and dirs with xattrs"
19196         test_mkdir $DIR/$tdir
19197         test_mkdir -i0 -c1 $mig_dir
19198         mkdir $mig_dir/dir
19199         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19200                 error "cannot set xattr attr1 on dir"
19201         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19202                 error "cannot set xattr attr2 on dir"
19203         touch $mig_dir/dir/f0
19204         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19205                 error "cannot set xattr attr1 on file"
19206         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19207                 error "cannot set xattr attr2 on file"
19208         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19209         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19210         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19211         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19212         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19213         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19214         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19215         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19216         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19217
19218         echo "Migrating to MDT1"
19219         $LFS migrate -m $MDTIDX $mig_dir ||
19220                 error "fails on migrating dir to MDT1"
19221
19222         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19223         echo "Checking xattrs"
19224         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19225         [ "$val" = $longstr ] ||
19226                 error "expecting xattr1 $longstr on dir, found $val"
19227         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19228         [ "$val" = $shortstr ] ||
19229                 error "expecting xattr2 $shortstr on dir, found $val"
19230         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19231         [ "$val" = $longstr ] ||
19232                 error "expecting xattr1 $longstr on file, found $val"
19233         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19234         [ "$val" = $shortstr ] ||
19235                 error "expecting xattr2 $shortstr on file, found $val"
19236 }
19237 run_test 230m "xattrs not changed after dir migration"
19238
19239 test_230n() {
19240         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19241         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19242                 skip "Need MDS version at least 2.13.53"
19243
19244         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19245         cat /etc/hosts > $DIR/$tdir/$tfile
19246         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19247         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19248
19249         cmp /etc/hosts $DIR/$tdir/$tfile ||
19250                 error "File data mismatch after migration"
19251 }
19252 run_test 230n "Dir migration with mirrored file"
19253
19254 test_230o() {
19255         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19256         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19257                 skip "Need MDS version at least 2.13.52"
19258
19259         local mdts=$(comma_list $(mdts_nodes))
19260         local timeout=100
19261         local restripe_status
19262         local delta
19263         local i
19264
19265         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19266
19267         # in case "crush" hash type is not set
19268         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19269
19270         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19271                            mdt.*MDT0000.enable_dir_restripe)
19272         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19273         stack_trap "do_nodes $mdts $LCTL set_param \
19274                     mdt.*.enable_dir_restripe=$restripe_status"
19275
19276         mkdir $DIR/$tdir
19277         createmany -m $DIR/$tdir/f 100 ||
19278                 error "create files under remote dir failed $i"
19279         createmany -d $DIR/$tdir/d 100 ||
19280                 error "create dirs under remote dir failed $i"
19281
19282         for i in $(seq 2 $MDSCOUNT); do
19283                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19284                 $LFS setdirstripe -c $i $DIR/$tdir ||
19285                         error "split -c $i $tdir failed"
19286                 wait_update $HOSTNAME \
19287                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19288                         error "dir split not finished"
19289                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19290                         awk '/migrate/ {sum += $2} END { print sum }')
19291                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19292                 # delta is around total_files/stripe_count
19293                 (( $delta < 200 / (i - 1) + 4 )) ||
19294                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19295         done
19296 }
19297 run_test 230o "dir split"
19298
19299 test_230p() {
19300         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19301         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19302                 skip "Need MDS version at least 2.13.52"
19303
19304         local mdts=$(comma_list $(mdts_nodes))
19305         local timeout=100
19306         local restripe_status
19307         local delta
19308         local i
19309
19310         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19311
19312         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19313
19314         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19315                            mdt.*MDT0000.enable_dir_restripe)
19316         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19317         stack_trap "do_nodes $mdts $LCTL set_param \
19318                     mdt.*.enable_dir_restripe=$restripe_status"
19319
19320         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19321         createmany -m $DIR/$tdir/f 100 ||
19322                 error "create files under remote dir failed $i"
19323         createmany -d $DIR/$tdir/d 100 ||
19324                 error "create dirs under remote dir failed $i"
19325
19326         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19327                 local mdt_hash="crush"
19328
19329                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19330                 $LFS setdirstripe -c $i $DIR/$tdir ||
19331                         error "split -c $i $tdir failed"
19332                 [ $i -eq 1 ] && mdt_hash="none"
19333                 wait_update $HOSTNAME \
19334                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19335                         error "dir merge not finished"
19336                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19337                         awk '/migrate/ {sum += $2} END { print sum }')
19338                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19339                 # delta is around total_files/stripe_count
19340                 (( $delta < 200 / i + 4 )) ||
19341                         error "$delta files migrated >= $((200 / i + 4))"
19342         done
19343 }
19344 run_test 230p "dir merge"
19345
19346 test_230q() {
19347         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19348         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19349                 skip "Need MDS version at least 2.13.52"
19350
19351         local mdts=$(comma_list $(mdts_nodes))
19352         local saved_threshold=$(do_facet mds1 \
19353                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19354         local saved_delta=$(do_facet mds1 \
19355                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19356         local threshold=100
19357         local delta=2
19358         local total=0
19359         local stripe_count=0
19360         local stripe_index
19361         local nr_files
19362         local create
19363
19364         # test with fewer files on ZFS
19365         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19366
19367         stack_trap "do_nodes $mdts $LCTL set_param \
19368                     mdt.*.dir_split_count=$saved_threshold"
19369         stack_trap "do_nodes $mdts $LCTL set_param \
19370                     mdt.*.dir_split_delta=$saved_delta"
19371         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19372         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19373         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19374         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19375         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19376         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19377
19378         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19379         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19380
19381         create=$((threshold * 3 / 2))
19382         while [ $stripe_count -lt $MDSCOUNT ]; do
19383                 createmany -m $DIR/$tdir/f $total $create ||
19384                         error "create sub files failed"
19385                 stat $DIR/$tdir > /dev/null
19386                 total=$((total + create))
19387                 stripe_count=$((stripe_count + delta))
19388                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19389
19390                 wait_update $HOSTNAME \
19391                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19392                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19393
19394                 wait_update $HOSTNAME \
19395                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19396                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19397
19398                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19399                 echo "$nr_files/$total files on MDT$stripe_index after split"
19400                 # allow 10% margin of imbalance with crush hash
19401                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19402                         error "$nr_files files on MDT$stripe_index after split"
19403
19404                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19405                 [ $nr_files -eq $total ] ||
19406                         error "total sub files $nr_files != $total"
19407         done
19408 }
19409 run_test 230q "dir auto split"
19410
19411 test_230r() {
19412         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19413         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19414         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19415                 skip "Need MDS version at least 2.13.54"
19416
19417         # maximum amount of local locks:
19418         # parent striped dir - 2 locks
19419         # new stripe in parent to migrate to - 1 lock
19420         # source and target - 2 locks
19421         # Total 5 locks for regular file
19422         mkdir -p $DIR/$tdir
19423         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19424         touch $DIR/$tdir/dir1/eee
19425
19426         # create 4 hardlink for 4 more locks
19427         # Total: 9 locks > RS_MAX_LOCKS (8)
19428         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19429         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19430         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19431         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19432         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19433         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19434         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19435         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19436
19437         cancel_lru_locks mdc
19438
19439         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19440                 error "migrate dir fails"
19441
19442         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19443 }
19444 run_test 230r "migrate with too many local locks"
19445
19446 test_230s() {
19447         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19448                 skip "Need MDS version at least 2.13.57"
19449
19450         local mdts=$(comma_list $(mdts_nodes))
19451         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19452                                 mdt.*MDT0000.enable_dir_restripe)
19453
19454         stack_trap "do_nodes $mdts $LCTL set_param \
19455                     mdt.*.enable_dir_restripe=$restripe_status"
19456
19457         local st
19458         for st in 0 1; do
19459                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19460                 test_mkdir $DIR/$tdir
19461                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19462                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19463                 rmdir $DIR/$tdir
19464         done
19465 }
19466 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19467
19468 test_230t()
19469 {
19470         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19471         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19472                 skip "Need MDS version at least 2.14.50"
19473
19474         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19475         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19476         $LFS project -p 1 -s $DIR/$tdir ||
19477                 error "set $tdir project id failed"
19478         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19479                 error "set subdir project id failed"
19480         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19481 }
19482 run_test 230t "migrate directory with project ID set"
19483
19484 test_231a()
19485 {
19486         # For simplicity this test assumes that max_pages_per_rpc
19487         # is the same across all OSCs
19488         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19489         local bulk_size=$((max_pages * PAGE_SIZE))
19490         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19491                                        head -n 1)
19492
19493         mkdir -p $DIR/$tdir
19494         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19495                 error "failed to set stripe with -S ${brw_size}M option"
19496
19497         # clear the OSC stats
19498         $LCTL set_param osc.*.stats=0 &>/dev/null
19499         stop_writeback
19500
19501         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19502         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19503                 oflag=direct &>/dev/null || error "dd failed"
19504
19505         sync; sleep 1; sync # just to be safe
19506         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19507         if [ x$nrpcs != "x1" ]; then
19508                 $LCTL get_param osc.*.stats
19509                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19510         fi
19511
19512         start_writeback
19513         # Drop the OSC cache, otherwise we will read from it
19514         cancel_lru_locks osc
19515
19516         # clear the OSC stats
19517         $LCTL set_param osc.*.stats=0 &>/dev/null
19518
19519         # Client reads $bulk_size.
19520         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19521                 iflag=direct &>/dev/null || error "dd failed"
19522
19523         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19524         if [ x$nrpcs != "x1" ]; then
19525                 $LCTL get_param osc.*.stats
19526                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19527         fi
19528 }
19529 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19530
19531 test_231b() {
19532         mkdir -p $DIR/$tdir
19533         local i
19534         for i in {0..1023}; do
19535                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19536                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19537                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19538         done
19539         sync
19540 }
19541 run_test 231b "must not assert on fully utilized OST request buffer"
19542
19543 test_232a() {
19544         mkdir -p $DIR/$tdir
19545         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19546
19547         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19548         do_facet ost1 $LCTL set_param fail_loc=0x31c
19549
19550         # ignore dd failure
19551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19552
19553         do_facet ost1 $LCTL set_param fail_loc=0
19554         umount_client $MOUNT || error "umount failed"
19555         mount_client $MOUNT || error "mount failed"
19556         stop ost1 || error "cannot stop ost1"
19557         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19558 }
19559 run_test 232a "failed lock should not block umount"
19560
19561 test_232b() {
19562         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19563                 skip "Need MDS version at least 2.10.58"
19564
19565         mkdir -p $DIR/$tdir
19566         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19568         sync
19569         cancel_lru_locks osc
19570
19571         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19572         do_facet ost1 $LCTL set_param fail_loc=0x31c
19573
19574         # ignore failure
19575         $LFS data_version $DIR/$tdir/$tfile || true
19576
19577         do_facet ost1 $LCTL set_param fail_loc=0
19578         umount_client $MOUNT || error "umount failed"
19579         mount_client $MOUNT || error "mount failed"
19580         stop ost1 || error "cannot stop ost1"
19581         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19582 }
19583 run_test 232b "failed data version lock should not block umount"
19584
19585 test_233a() {
19586         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19587                 skip "Need MDS version at least 2.3.64"
19588         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19589
19590         local fid=$($LFS path2fid $MOUNT)
19591
19592         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19593                 error "cannot access $MOUNT using its FID '$fid'"
19594 }
19595 run_test 233a "checking that OBF of the FS root succeeds"
19596
19597 test_233b() {
19598         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19599                 skip "Need MDS version at least 2.5.90"
19600         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19601
19602         local fid=$($LFS path2fid $MOUNT/.lustre)
19603
19604         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19605                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19606
19607         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19608         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19609                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19610 }
19611 run_test 233b "checking that OBF of the FS .lustre succeeds"
19612
19613 test_234() {
19614         local p="$TMP/sanityN-$TESTNAME.parameters"
19615         save_lustre_params client "llite.*.xattr_cache" > $p
19616         lctl set_param llite.*.xattr_cache 1 ||
19617                 skip_env "xattr cache is not supported"
19618
19619         mkdir -p $DIR/$tdir || error "mkdir failed"
19620         touch $DIR/$tdir/$tfile || error "touch failed"
19621         # OBD_FAIL_LLITE_XATTR_ENOMEM
19622         $LCTL set_param fail_loc=0x1405
19623         getfattr -n user.attr $DIR/$tdir/$tfile &&
19624                 error "getfattr should have failed with ENOMEM"
19625         $LCTL set_param fail_loc=0x0
19626         rm -rf $DIR/$tdir
19627
19628         restore_lustre_params < $p
19629         rm -f $p
19630 }
19631 run_test 234 "xattr cache should not crash on ENOMEM"
19632
19633 test_235() {
19634         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19635                 skip "Need MDS version at least 2.4.52"
19636
19637         flock_deadlock $DIR/$tfile
19638         local RC=$?
19639         case $RC in
19640                 0)
19641                 ;;
19642                 124) error "process hangs on a deadlock"
19643                 ;;
19644                 *) error "error executing flock_deadlock $DIR/$tfile"
19645                 ;;
19646         esac
19647 }
19648 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19649
19650 #LU-2935
19651 test_236() {
19652         check_swap_layouts_support
19653
19654         local ref1=/etc/passwd
19655         local ref2=/etc/group
19656         local file1=$DIR/$tdir/f1
19657         local file2=$DIR/$tdir/f2
19658
19659         test_mkdir -c1 $DIR/$tdir
19660         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19661         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19662         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19663         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19664         local fd=$(free_fd)
19665         local cmd="exec $fd<>$file2"
19666         eval $cmd
19667         rm $file2
19668         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19669                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19670         cmd="exec $fd>&-"
19671         eval $cmd
19672         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19673
19674         #cleanup
19675         rm -rf $DIR/$tdir
19676 }
19677 run_test 236 "Layout swap on open unlinked file"
19678
19679 # LU-4659 linkea consistency
19680 test_238() {
19681         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19682                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19683                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19684                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19685
19686         touch $DIR/$tfile
19687         ln $DIR/$tfile $DIR/$tfile.lnk
19688         touch $DIR/$tfile.new
19689         mv $DIR/$tfile.new $DIR/$tfile
19690         local fid1=$($LFS path2fid $DIR/$tfile)
19691         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19692         local path1=$($LFS fid2path $FSNAME "$fid1")
19693         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19694         local path2=$($LFS fid2path $FSNAME "$fid2")
19695         [ $tfile.lnk == $path2 ] ||
19696                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19697         rm -f $DIR/$tfile*
19698 }
19699 run_test 238 "Verify linkea consistency"
19700
19701 test_239A() { # was test_239
19702         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19703                 skip "Need MDS version at least 2.5.60"
19704
19705         local list=$(comma_list $(mdts_nodes))
19706
19707         mkdir -p $DIR/$tdir
19708         createmany -o $DIR/$tdir/f- 5000
19709         unlinkmany $DIR/$tdir/f- 5000
19710         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19711                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19712         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19713                         osp.*MDT*.sync_in_flight" | calc_sum)
19714         [ "$changes" -eq 0 ] || error "$changes not synced"
19715 }
19716 run_test 239A "osp_sync test"
19717
19718 test_239a() { #LU-5297
19719         remote_mds_nodsh && skip "remote MDS with nodsh"
19720
19721         touch $DIR/$tfile
19722         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19723         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19724         chgrp $RUNAS_GID $DIR/$tfile
19725         wait_delete_completed
19726 }
19727 run_test 239a "process invalid osp sync record correctly"
19728
19729 test_239b() { #LU-5297
19730         remote_mds_nodsh && skip "remote MDS with nodsh"
19731
19732         touch $DIR/$tfile1
19733         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19734         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19735         chgrp $RUNAS_GID $DIR/$tfile1
19736         wait_delete_completed
19737         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19738         touch $DIR/$tfile2
19739         chgrp $RUNAS_GID $DIR/$tfile2
19740         wait_delete_completed
19741 }
19742 run_test 239b "process osp sync record with ENOMEM error correctly"
19743
19744 test_240() {
19745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19746         remote_mds_nodsh && skip "remote MDS with nodsh"
19747
19748         mkdir -p $DIR/$tdir
19749
19750         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19751                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19752         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19753                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19754
19755         umount_client $MOUNT || error "umount failed"
19756         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19757         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19758         mount_client $MOUNT || error "failed to mount client"
19759
19760         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19761         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19762 }
19763 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19764
19765 test_241_bio() {
19766         local count=$1
19767         local bsize=$2
19768
19769         for LOOP in $(seq $count); do
19770                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19771                 cancel_lru_locks $OSC || true
19772         done
19773 }
19774
19775 test_241_dio() {
19776         local count=$1
19777         local bsize=$2
19778
19779         for LOOP in $(seq $1); do
19780                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19781                         2>/dev/null
19782         done
19783 }
19784
19785 test_241a() { # was test_241
19786         local bsize=$PAGE_SIZE
19787
19788         (( bsize < 40960 )) && bsize=40960
19789         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19790         ls -la $DIR/$tfile
19791         cancel_lru_locks $OSC
19792         test_241_bio 1000 $bsize &
19793         PID=$!
19794         test_241_dio 1000 $bsize
19795         wait $PID
19796 }
19797 run_test 241a "bio vs dio"
19798
19799 test_241b() {
19800         local bsize=$PAGE_SIZE
19801
19802         (( bsize < 40960 )) && bsize=40960
19803         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19804         ls -la $DIR/$tfile
19805         test_241_dio 1000 $bsize &
19806         PID=$!
19807         test_241_dio 1000 $bsize
19808         wait $PID
19809 }
19810 run_test 241b "dio vs dio"
19811
19812 test_242() {
19813         remote_mds_nodsh && skip "remote MDS with nodsh"
19814
19815         mkdir -p $DIR/$tdir
19816         touch $DIR/$tdir/$tfile
19817
19818         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19819         do_facet mds1 lctl set_param fail_loc=0x105
19820         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19821
19822         do_facet mds1 lctl set_param fail_loc=0
19823         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19824 }
19825 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19826
19827 test_243()
19828 {
19829         test_mkdir $DIR/$tdir
19830         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19831 }
19832 run_test 243 "various group lock tests"
19833
19834 test_244a()
19835 {
19836         test_mkdir $DIR/$tdir
19837         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19838         sendfile_grouplock $DIR/$tdir/$tfile || \
19839                 error "sendfile+grouplock failed"
19840         rm -rf $DIR/$tdir
19841 }
19842 run_test 244a "sendfile with group lock tests"
19843
19844 test_244b()
19845 {
19846         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19847
19848         local threads=50
19849         local size=$((1024*1024))
19850
19851         test_mkdir $DIR/$tdir
19852         for i in $(seq 1 $threads); do
19853                 local file=$DIR/$tdir/file_$((i / 10))
19854                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19855                 local pids[$i]=$!
19856         done
19857         for i in $(seq 1 $threads); do
19858                 wait ${pids[$i]}
19859         done
19860 }
19861 run_test 244b "multi-threaded write with group lock"
19862
19863 test_245() {
19864         local flagname="multi_mod_rpcs"
19865         local connect_data_name="max_mod_rpcs"
19866         local out
19867
19868         # check if multiple modify RPCs flag is set
19869         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19870                 grep "connect_flags:")
19871         echo "$out"
19872
19873         echo "$out" | grep -qw $flagname
19874         if [ $? -ne 0 ]; then
19875                 echo "connect flag $flagname is not set"
19876                 return
19877         fi
19878
19879         # check if multiple modify RPCs data is set
19880         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19881         echo "$out"
19882
19883         echo "$out" | grep -qw $connect_data_name ||
19884                 error "import should have connect data $connect_data_name"
19885 }
19886 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19887
19888 cleanup_247() {
19889         local submount=$1
19890
19891         trap 0
19892         umount_client $submount
19893         rmdir $submount
19894 }
19895
19896 test_247a() {
19897         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19898                 grep -q subtree ||
19899                 skip_env "Fileset feature is not supported"
19900
19901         local submount=${MOUNT}_$tdir
19902
19903         mkdir $MOUNT/$tdir
19904         mkdir -p $submount || error "mkdir $submount failed"
19905         FILESET="$FILESET/$tdir" mount_client $submount ||
19906                 error "mount $submount failed"
19907         trap "cleanup_247 $submount" EXIT
19908         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19909         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19910                 error "read $MOUNT/$tdir/$tfile failed"
19911         cleanup_247 $submount
19912 }
19913 run_test 247a "mount subdir as fileset"
19914
19915 test_247b() {
19916         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19917                 skip_env "Fileset feature is not supported"
19918
19919         local submount=${MOUNT}_$tdir
19920
19921         rm -rf $MOUNT/$tdir
19922         mkdir -p $submount || error "mkdir $submount failed"
19923         SKIP_FILESET=1
19924         FILESET="$FILESET/$tdir" mount_client $submount &&
19925                 error "mount $submount should fail"
19926         rmdir $submount
19927 }
19928 run_test 247b "mount subdir that dose not exist"
19929
19930 test_247c() {
19931         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19932                 skip_env "Fileset feature is not supported"
19933
19934         local submount=${MOUNT}_$tdir
19935
19936         mkdir -p $MOUNT/$tdir/dir1
19937         mkdir -p $submount || error "mkdir $submount failed"
19938         trap "cleanup_247 $submount" EXIT
19939         FILESET="$FILESET/$tdir" mount_client $submount ||
19940                 error "mount $submount failed"
19941         local fid=$($LFS path2fid $MOUNT/)
19942         $LFS fid2path $submount $fid && error "fid2path should fail"
19943         cleanup_247 $submount
19944 }
19945 run_test 247c "running fid2path outside subdirectory root"
19946
19947 test_247d() {
19948         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19949                 skip "Fileset feature is not supported"
19950
19951         local submount=${MOUNT}_$tdir
19952
19953         mkdir -p $MOUNT/$tdir/dir1
19954         mkdir -p $submount || error "mkdir $submount failed"
19955         FILESET="$FILESET/$tdir" mount_client $submount ||
19956                 error "mount $submount failed"
19957         trap "cleanup_247 $submount" EXIT
19958
19959         local td=$submount/dir1
19960         local fid=$($LFS path2fid $td)
19961         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19962
19963         # check that we get the same pathname back
19964         local rootpath
19965         local found
19966         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19967                 echo "$rootpath $fid"
19968                 found=$($LFS fid2path $rootpath "$fid")
19969                 [ -n "found" ] || error "fid2path should succeed"
19970                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19971         done
19972         # check wrong root path format
19973         rootpath=$submount"_wrong"
19974         found=$($LFS fid2path $rootpath "$fid")
19975         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19976
19977         cleanup_247 $submount
19978 }
19979 run_test 247d "running fid2path inside subdirectory root"
19980
19981 # LU-8037
19982 test_247e() {
19983         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19984                 grep -q subtree ||
19985                 skip "Fileset feature is not supported"
19986
19987         local submount=${MOUNT}_$tdir
19988
19989         mkdir $MOUNT/$tdir
19990         mkdir -p $submount || error "mkdir $submount failed"
19991         FILESET="$FILESET/.." mount_client $submount &&
19992                 error "mount $submount should fail"
19993         rmdir $submount
19994 }
19995 run_test 247e "mount .. as fileset"
19996
19997 test_247f() {
19998         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19999         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20000                 skip "Need at least version 2.13.52"
20001         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20002                 skip "Need at least version 2.14.50"
20003         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20004                 grep -q subtree ||
20005                 skip "Fileset feature is not supported"
20006
20007         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20008         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20009                 error "mkdir remote failed"
20010         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20011         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20012                 error "mkdir striped failed"
20013         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20014
20015         local submount=${MOUNT}_$tdir
20016
20017         mkdir -p $submount || error "mkdir $submount failed"
20018         stack_trap "rmdir $submount"
20019
20020         local dir
20021         local stat
20022         local fileset=$FILESET
20023         local mdts=$(comma_list $(mdts_nodes))
20024
20025         stat=$(do_facet mds1 $LCTL get_param -n \
20026                 mdt.*MDT0000.enable_remote_subdir_mount)
20027         stack_trap "do_nodes $mdts $LCTL set_param \
20028                 mdt.*.enable_remote_subdir_mount=$stat"
20029
20030         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20031         stack_trap "umount_client $submount"
20032         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20033                 error "mount remote dir $dir should fail"
20034
20035         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20036                 $tdir/striped/. ; do
20037                 FILESET="$fileset/$dir" mount_client $submount ||
20038                         error "mount $dir failed"
20039                 umount_client $submount
20040         done
20041
20042         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20043         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20044                 error "mount $tdir/remote failed"
20045 }
20046 run_test 247f "mount striped or remote directory as fileset"
20047
20048 test_247g() {
20049         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20050         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20051                 skip "Need at least version 2.14.50"
20052
20053         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20054                 error "mkdir $tdir failed"
20055         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20056
20057         local submount=${MOUNT}_$tdir
20058
20059         mkdir -p $submount || error "mkdir $submount failed"
20060         stack_trap "rmdir $submount"
20061
20062         FILESET="$fileset/$tdir" mount_client $submount ||
20063                 error "mount $dir failed"
20064         stack_trap "umount $submount"
20065
20066         local mdts=$(comma_list $(mdts_nodes))
20067
20068         local nrpcs
20069
20070         stat $submount > /dev/null
20071         cancel_lru_locks $MDC
20072         stat $submount > /dev/null
20073         stat $submount/$tfile > /dev/null
20074         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20075         stat $submount/$tfile > /dev/null
20076         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20077                 awk '/getattr/ {sum += $2} END {print sum}')
20078
20079         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20080 }
20081 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20082
20083 test_248a() {
20084         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20085         [ -z "$fast_read_sav" ] && skip "no fast read support"
20086
20087         # create a large file for fast read verification
20088         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20089
20090         # make sure the file is created correctly
20091         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20092                 { rm -f $DIR/$tfile; skip "file creation error"; }
20093
20094         echo "Test 1: verify that fast read is 4 times faster on cache read"
20095
20096         # small read with fast read enabled
20097         $LCTL set_param -n llite.*.fast_read=1
20098         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20099                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20100                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20101         # small read with fast read disabled
20102         $LCTL set_param -n llite.*.fast_read=0
20103         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20104                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20105                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20106
20107         # verify that fast read is 4 times faster for cache read
20108         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20109                 error_not_in_vm "fast read was not 4 times faster: " \
20110                            "$t_fast vs $t_slow"
20111
20112         echo "Test 2: verify the performance between big and small read"
20113         $LCTL set_param -n llite.*.fast_read=1
20114
20115         # 1k non-cache read
20116         cancel_lru_locks osc
20117         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20118                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20119                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20120
20121         # 1M non-cache read
20122         cancel_lru_locks osc
20123         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20124                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20125                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20126
20127         # verify that big IO is not 4 times faster than small IO
20128         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20129                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20130
20131         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20132         rm -f $DIR/$tfile
20133 }
20134 run_test 248a "fast read verification"
20135
20136 test_248b() {
20137         # Default short_io_bytes=16384, try both smaller and larger sizes.
20138         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20139         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20140         echo "bs=53248 count=113 normal buffered write"
20141         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20142                 error "dd of initial data file failed"
20143         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20144
20145         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20146         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20147                 error "dd with sync normal writes failed"
20148         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20149
20150         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20151         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20152                 error "dd with sync small writes failed"
20153         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20154
20155         cancel_lru_locks osc
20156
20157         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20158         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20159         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20160         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20161                 iflag=direct || error "dd with O_DIRECT small read failed"
20162         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20163         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20164                 error "compare $TMP/$tfile.1 failed"
20165
20166         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20167         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20168
20169         # just to see what the maximum tunable value is, and test parsing
20170         echo "test invalid parameter 2MB"
20171         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20172                 error "too-large short_io_bytes allowed"
20173         echo "test maximum parameter 512KB"
20174         # if we can set a larger short_io_bytes, run test regardless of version
20175         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20176                 # older clients may not allow setting it this large, that's OK
20177                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20178                         skip "Need at least client version 2.13.50"
20179                 error "medium short_io_bytes failed"
20180         fi
20181         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20182         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20183
20184         echo "test large parameter 64KB"
20185         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20186         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20187
20188         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20189         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20190                 error "dd with sync large writes failed"
20191         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20192
20193         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20194         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20195         num=$((113 * 4096 / PAGE_SIZE))
20196         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20197         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20198                 error "dd with O_DIRECT large writes failed"
20199         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20200                 error "compare $DIR/$tfile.3 failed"
20201
20202         cancel_lru_locks osc
20203
20204         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20205         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20206                 error "dd with O_DIRECT large read failed"
20207         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20208                 error "compare $TMP/$tfile.2 failed"
20209
20210         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20211         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20212                 error "dd with O_DIRECT large read failed"
20213         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20214                 error "compare $TMP/$tfile.3 failed"
20215 }
20216 run_test 248b "test short_io read and write for both small and large sizes"
20217
20218 test_249() { # LU-7890
20219         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20220                 skip "Need at least version 2.8.54"
20221
20222         rm -f $DIR/$tfile
20223         $LFS setstripe -c 1 $DIR/$tfile
20224         # Offset 2T == 4k * 512M
20225         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20226                 error "dd to 2T offset failed"
20227 }
20228 run_test 249 "Write above 2T file size"
20229
20230 test_250() {
20231         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20232          && skip "no 16TB file size limit on ZFS"
20233
20234         $LFS setstripe -c 1 $DIR/$tfile
20235         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20236         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20237         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20238         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20239                 conv=notrunc,fsync && error "append succeeded"
20240         return 0
20241 }
20242 run_test 250 "Write above 16T limit"
20243
20244 test_251() {
20245         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20246
20247         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20248         #Skip once - writing the first stripe will succeed
20249         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20250         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20251                 error "short write happened"
20252
20253         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20254         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20255                 error "short read happened"
20256
20257         rm -f $DIR/$tfile
20258 }
20259 run_test 251 "Handling short read and write correctly"
20260
20261 test_252() {
20262         remote_mds_nodsh && skip "remote MDS with nodsh"
20263         remote_ost_nodsh && skip "remote OST with nodsh"
20264         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20265                 skip_env "ldiskfs only test"
20266         fi
20267
20268         local tgt
20269         local dev
20270         local out
20271         local uuid
20272         local num
20273         local gen
20274
20275         # check lr_reader on OST0000
20276         tgt=ost1
20277         dev=$(facet_device $tgt)
20278         out=$(do_facet $tgt $LR_READER $dev)
20279         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20280         echo "$out"
20281         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20282         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20283                 error "Invalid uuid returned by $LR_READER on target $tgt"
20284         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20285
20286         # check lr_reader -c on MDT0000
20287         tgt=mds1
20288         dev=$(facet_device $tgt)
20289         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20290                 skip "$LR_READER does not support additional options"
20291         fi
20292         out=$(do_facet $tgt $LR_READER -c $dev)
20293         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20294         echo "$out"
20295         num=$(echo "$out" | grep -c "mdtlov")
20296         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20297                 error "Invalid number of mdtlov clients returned by $LR_READER"
20298         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20299
20300         # check lr_reader -cr on MDT0000
20301         out=$(do_facet $tgt $LR_READER -cr $dev)
20302         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20303         echo "$out"
20304         echo "$out" | grep -q "^reply_data:$" ||
20305                 error "$LR_READER should have returned 'reply_data' section"
20306         num=$(echo "$out" | grep -c "client_generation")
20307         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20308 }
20309 run_test 252 "check lr_reader tool"
20310
20311 test_253() {
20312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20313         remote_mds_nodsh && skip "remote MDS with nodsh"
20314         remote_mgs_nodsh && skip "remote MGS with nodsh"
20315
20316         local ostidx=0
20317         local rc=0
20318         local ost_name=$(ostname_from_index $ostidx)
20319
20320         # on the mdt's osc
20321         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20322         do_facet $SINGLEMDS $LCTL get_param -n \
20323                 osp.$mdtosc_proc1.reserved_mb_high ||
20324                 skip  "remote MDS does not support reserved_mb_high"
20325
20326         rm -rf $DIR/$tdir
20327         wait_mds_ost_sync
20328         wait_delete_completed
20329         mkdir $DIR/$tdir
20330
20331         pool_add $TESTNAME || error "Pool creation failed"
20332         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20333
20334         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20335                 error "Setstripe failed"
20336
20337         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20338
20339         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20340                     grep "watermarks")
20341         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20342
20343         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20344                         osp.$mdtosc_proc1.prealloc_status)
20345         echo "prealloc_status $oa_status"
20346
20347         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20348                 error "File creation should fail"
20349
20350         #object allocation was stopped, but we still able to append files
20351         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20352                 oflag=append || error "Append failed"
20353
20354         rm -f $DIR/$tdir/$tfile.0
20355
20356         # For this test, we want to delete the files we created to go out of
20357         # space but leave the watermark, so we remain nearly out of space
20358         ost_watermarks_enospc_delete_files $tfile $ostidx
20359
20360         wait_delete_completed
20361
20362         sleep_maxage
20363
20364         for i in $(seq 10 12); do
20365                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20366                         2>/dev/null || error "File creation failed after rm"
20367         done
20368
20369         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20370                         osp.$mdtosc_proc1.prealloc_status)
20371         echo "prealloc_status $oa_status"
20372
20373         if (( oa_status != 0 )); then
20374                 error "Object allocation still disable after rm"
20375         fi
20376 }
20377 run_test 253 "Check object allocation limit"
20378
20379 test_254() {
20380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20381         remote_mds_nodsh && skip "remote MDS with nodsh"
20382         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20383                 skip "MDS does not support changelog_size"
20384
20385         local cl_user
20386         local MDT0=$(facet_svc $SINGLEMDS)
20387
20388         changelog_register || error "changelog_register failed"
20389
20390         changelog_clear 0 || error "changelog_clear failed"
20391
20392         local size1=$(do_facet $SINGLEMDS \
20393                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20394         echo "Changelog size $size1"
20395
20396         rm -rf $DIR/$tdir
20397         $LFS mkdir -i 0 $DIR/$tdir
20398         # change something
20399         mkdir -p $DIR/$tdir/pics/2008/zachy
20400         touch $DIR/$tdir/pics/2008/zachy/timestamp
20401         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20402         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20403         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20404         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20405         rm $DIR/$tdir/pics/desktop.jpg
20406
20407         local size2=$(do_facet $SINGLEMDS \
20408                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20409         echo "Changelog size after work $size2"
20410
20411         (( $size2 > $size1 )) ||
20412                 error "new Changelog size=$size2 less than old size=$size1"
20413 }
20414 run_test 254 "Check changelog size"
20415
20416 ladvise_no_type()
20417 {
20418         local type=$1
20419         local file=$2
20420
20421         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20422                 awk -F: '{print $2}' | grep $type > /dev/null
20423         if [ $? -ne 0 ]; then
20424                 return 0
20425         fi
20426         return 1
20427 }
20428
20429 ladvise_no_ioctl()
20430 {
20431         local file=$1
20432
20433         lfs ladvise -a willread $file > /dev/null 2>&1
20434         if [ $? -eq 0 ]; then
20435                 return 1
20436         fi
20437
20438         lfs ladvise -a willread $file 2>&1 |
20439                 grep "Inappropriate ioctl for device" > /dev/null
20440         if [ $? -eq 0 ]; then
20441                 return 0
20442         fi
20443         return 1
20444 }
20445
20446 percent() {
20447         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20448 }
20449
20450 # run a random read IO workload
20451 # usage: random_read_iops <filename> <filesize> <iosize>
20452 random_read_iops() {
20453         local file=$1
20454         local fsize=$2
20455         local iosize=${3:-4096}
20456
20457         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20458                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20459 }
20460
20461 drop_file_oss_cache() {
20462         local file="$1"
20463         local nodes="$2"
20464
20465         $LFS ladvise -a dontneed $file 2>/dev/null ||
20466                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20467 }
20468
20469 ladvise_willread_performance()
20470 {
20471         local repeat=10
20472         local average_origin=0
20473         local average_cache=0
20474         local average_ladvise=0
20475
20476         for ((i = 1; i <= $repeat; i++)); do
20477                 echo "Iter $i/$repeat: reading without willread hint"
20478                 cancel_lru_locks osc
20479                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20480                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20481                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20482                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20483
20484                 cancel_lru_locks osc
20485                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20486                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20487                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20488
20489                 cancel_lru_locks osc
20490                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20491                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20492                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20493                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20494                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20495         done
20496         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20497         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20498         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20499
20500         speedup_cache=$(percent $average_cache $average_origin)
20501         speedup_ladvise=$(percent $average_ladvise $average_origin)
20502
20503         echo "Average uncached read: $average_origin"
20504         echo "Average speedup with OSS cached read: " \
20505                 "$average_cache = +$speedup_cache%"
20506         echo "Average speedup with ladvise willread: " \
20507                 "$average_ladvise = +$speedup_ladvise%"
20508
20509         local lowest_speedup=20
20510         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20511                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20512                         "got $average_cache%. Skipping ladvise willread check."
20513                 return 0
20514         fi
20515
20516         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20517         # it is still good to run until then to exercise 'ladvise willread'
20518         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20519                 [ "$ost1_FSTYPE" = "zfs" ] &&
20520                 echo "osd-zfs does not support dontneed or drop_caches" &&
20521                 return 0
20522
20523         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20524         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20525                 error_not_in_vm "Speedup with willread is less than " \
20526                         "$lowest_speedup%, got $average_ladvise%"
20527 }
20528
20529 test_255a() {
20530         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20531                 skip "lustre < 2.8.54 does not support ladvise "
20532         remote_ost_nodsh && skip "remote OST with nodsh"
20533
20534         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20535
20536         ladvise_no_type willread $DIR/$tfile &&
20537                 skip "willread ladvise is not supported"
20538
20539         ladvise_no_ioctl $DIR/$tfile &&
20540                 skip "ladvise ioctl is not supported"
20541
20542         local size_mb=100
20543         local size=$((size_mb * 1048576))
20544         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20545                 error "dd to $DIR/$tfile failed"
20546
20547         lfs ladvise -a willread $DIR/$tfile ||
20548                 error "Ladvise failed with no range argument"
20549
20550         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20551                 error "Ladvise failed with no -l or -e argument"
20552
20553         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20554                 error "Ladvise failed with only -e argument"
20555
20556         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20557                 error "Ladvise failed with only -l argument"
20558
20559         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20560                 error "End offset should not be smaller than start offset"
20561
20562         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20563                 error "End offset should not be equal to start offset"
20564
20565         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20566                 error "Ladvise failed with overflowing -s argument"
20567
20568         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20569                 error "Ladvise failed with overflowing -e argument"
20570
20571         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20572                 error "Ladvise failed with overflowing -l argument"
20573
20574         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20575                 error "Ladvise succeeded with conflicting -l and -e arguments"
20576
20577         echo "Synchronous ladvise should wait"
20578         local delay=4
20579 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20580         do_nodes $(comma_list $(osts_nodes)) \
20581                 $LCTL set_param fail_val=$delay fail_loc=0x237
20582
20583         local start_ts=$SECONDS
20584         lfs ladvise -a willread $DIR/$tfile ||
20585                 error "Ladvise failed with no range argument"
20586         local end_ts=$SECONDS
20587         local inteval_ts=$((end_ts - start_ts))
20588
20589         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20590                 error "Synchronous advice didn't wait reply"
20591         fi
20592
20593         echo "Asynchronous ladvise shouldn't wait"
20594         local start_ts=$SECONDS
20595         lfs ladvise -a willread -b $DIR/$tfile ||
20596                 error "Ladvise failed with no range argument"
20597         local end_ts=$SECONDS
20598         local inteval_ts=$((end_ts - start_ts))
20599
20600         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20601                 error "Asynchronous advice blocked"
20602         fi
20603
20604         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20605         ladvise_willread_performance
20606 }
20607 run_test 255a "check 'lfs ladvise -a willread'"
20608
20609 facet_meminfo() {
20610         local facet=$1
20611         local info=$2
20612
20613         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20614 }
20615
20616 test_255b() {
20617         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20618                 skip "lustre < 2.8.54 does not support ladvise "
20619         remote_ost_nodsh && skip "remote OST with nodsh"
20620
20621         lfs setstripe -c 1 -i 0 $DIR/$tfile
20622
20623         ladvise_no_type dontneed $DIR/$tfile &&
20624                 skip "dontneed ladvise is not supported"
20625
20626         ladvise_no_ioctl $DIR/$tfile &&
20627                 skip "ladvise ioctl is not supported"
20628
20629         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20630                 [ "$ost1_FSTYPE" = "zfs" ] &&
20631                 skip "zfs-osd does not support 'ladvise dontneed'"
20632
20633         local size_mb=100
20634         local size=$((size_mb * 1048576))
20635         # In order to prevent disturbance of other processes, only check 3/4
20636         # of the memory usage
20637         local kibibytes=$((size_mb * 1024 * 3 / 4))
20638
20639         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20640                 error "dd to $DIR/$tfile failed"
20641
20642         #force write to complete before dropping OST cache & checking memory
20643         sync
20644
20645         local total=$(facet_meminfo ost1 MemTotal)
20646         echo "Total memory: $total KiB"
20647
20648         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20649         local before_read=$(facet_meminfo ost1 Cached)
20650         echo "Cache used before read: $before_read KiB"
20651
20652         lfs ladvise -a willread $DIR/$tfile ||
20653                 error "Ladvise willread failed"
20654         local after_read=$(facet_meminfo ost1 Cached)
20655         echo "Cache used after read: $after_read KiB"
20656
20657         lfs ladvise -a dontneed $DIR/$tfile ||
20658                 error "Ladvise dontneed again failed"
20659         local no_read=$(facet_meminfo ost1 Cached)
20660         echo "Cache used after dontneed ladvise: $no_read KiB"
20661
20662         if [ $total -lt $((before_read + kibibytes)) ]; then
20663                 echo "Memory is too small, abort checking"
20664                 return 0
20665         fi
20666
20667         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20668                 error "Ladvise willread should use more memory" \
20669                         "than $kibibytes KiB"
20670         fi
20671
20672         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20673                 error "Ladvise dontneed should release more memory" \
20674                         "than $kibibytes KiB"
20675         fi
20676 }
20677 run_test 255b "check 'lfs ladvise -a dontneed'"
20678
20679 test_255c() {
20680         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20681                 skip "lustre < 2.10.50 does not support lockahead"
20682
20683         local ost1_imp=$(get_osc_import_name client ost1)
20684         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20685                          cut -d'.' -f2)
20686         local count
20687         local new_count
20688         local difference
20689         local i
20690         local rc
20691
20692         test_mkdir -p $DIR/$tdir
20693         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20694
20695         #test 10 returns only success/failure
20696         i=10
20697         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20698         rc=$?
20699         if [ $rc -eq 255 ]; then
20700                 error "Ladvise test${i} failed, ${rc}"
20701         fi
20702
20703         #test 11 counts lock enqueue requests, all others count new locks
20704         i=11
20705         count=$(do_facet ost1 \
20706                 $LCTL get_param -n ost.OSS.ost.stats)
20707         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20708
20709         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20710         rc=$?
20711         if [ $rc -eq 255 ]; then
20712                 error "Ladvise test${i} failed, ${rc}"
20713         fi
20714
20715         new_count=$(do_facet ost1 \
20716                 $LCTL get_param -n ost.OSS.ost.stats)
20717         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20718                    awk '{ print $2 }')
20719
20720         difference="$((new_count - count))"
20721         if [ $difference -ne $rc ]; then
20722                 error "Ladvise test${i}, bad enqueue count, returned " \
20723                       "${rc}, actual ${difference}"
20724         fi
20725
20726         for i in $(seq 12 21); do
20727                 # If we do not do this, we run the risk of having too many
20728                 # locks and starting lock cancellation while we are checking
20729                 # lock counts.
20730                 cancel_lru_locks osc
20731
20732                 count=$($LCTL get_param -n \
20733                        ldlm.namespaces.$imp_name.lock_unused_count)
20734
20735                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20736                 rc=$?
20737                 if [ $rc -eq 255 ]; then
20738                         error "Ladvise test ${i} failed, ${rc}"
20739                 fi
20740
20741                 new_count=$($LCTL get_param -n \
20742                        ldlm.namespaces.$imp_name.lock_unused_count)
20743                 difference="$((new_count - count))"
20744
20745                 # Test 15 output is divided by 100 to map down to valid return
20746                 if [ $i -eq 15 ]; then
20747                         rc="$((rc * 100))"
20748                 fi
20749
20750                 if [ $difference -ne $rc ]; then
20751                         error "Ladvise test ${i}, bad lock count, returned " \
20752                               "${rc}, actual ${difference}"
20753                 fi
20754         done
20755
20756         #test 22 returns only success/failure
20757         i=22
20758         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20759         rc=$?
20760         if [ $rc -eq 255 ]; then
20761                 error "Ladvise test${i} failed, ${rc}"
20762         fi
20763 }
20764 run_test 255c "suite of ladvise lockahead tests"
20765
20766 test_256() {
20767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20768         remote_mds_nodsh && skip "remote MDS with nodsh"
20769         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20770         changelog_users $SINGLEMDS | grep "^cl" &&
20771                 skip "active changelog user"
20772
20773         local cl_user
20774         local cat_sl
20775         local mdt_dev
20776
20777         mdt_dev=$(mdsdevname 1)
20778         echo $mdt_dev
20779
20780         changelog_register || error "changelog_register failed"
20781
20782         rm -rf $DIR/$tdir
20783         mkdir -p $DIR/$tdir
20784
20785         changelog_clear 0 || error "changelog_clear failed"
20786
20787         # change something
20788         touch $DIR/$tdir/{1..10}
20789
20790         # stop the MDT
20791         stop $SINGLEMDS || error "Fail to stop MDT"
20792
20793         # remount the MDT
20794
20795         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20796
20797         #after mount new plainllog is used
20798         touch $DIR/$tdir/{11..19}
20799         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20800         stack_trap "rm -f $tmpfile"
20801         cat_sl=$(do_facet $SINGLEMDS "sync; \
20802                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20803                  llog_reader $tmpfile | grep -c type=1064553b")
20804         do_facet $SINGLEMDS llog_reader $tmpfile
20805
20806         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20807
20808         changelog_clear 0 || error "changelog_clear failed"
20809
20810         cat_sl=$(do_facet $SINGLEMDS "sync; \
20811                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20812                  llog_reader $tmpfile | grep -c type=1064553b")
20813
20814         if (( cat_sl == 2 )); then
20815                 error "Empty plain llog was not deleted from changelog catalog"
20816         elif (( cat_sl != 1 )); then
20817                 error "Active plain llog shouldn't be deleted from catalog"
20818         fi
20819 }
20820 run_test 256 "Check llog delete for empty and not full state"
20821
20822 test_257() {
20823         remote_mds_nodsh && skip "remote MDS with nodsh"
20824         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20825                 skip "Need MDS version at least 2.8.55"
20826
20827         test_mkdir $DIR/$tdir
20828
20829         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20830                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20831         stat $DIR/$tdir
20832
20833 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20834         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20835         local facet=mds$((mdtidx + 1))
20836         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20837         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20838
20839         stop $facet || error "stop MDS failed"
20840         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20841                 error "start MDS fail"
20842         wait_recovery_complete $facet
20843 }
20844 run_test 257 "xattr locks are not lost"
20845
20846 # Verify we take the i_mutex when security requires it
20847 test_258a() {
20848 #define OBD_FAIL_IMUTEX_SEC 0x141c
20849         $LCTL set_param fail_loc=0x141c
20850         touch $DIR/$tfile
20851         chmod u+s $DIR/$tfile
20852         chmod a+rwx $DIR/$tfile
20853         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20854         RC=$?
20855         if [ $RC -ne 0 ]; then
20856                 error "error, failed to take i_mutex, rc=$?"
20857         fi
20858         rm -f $DIR/$tfile
20859 }
20860 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20861
20862 # Verify we do NOT take the i_mutex in the normal case
20863 test_258b() {
20864 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20865         $LCTL set_param fail_loc=0x141d
20866         touch $DIR/$tfile
20867         chmod a+rwx $DIR
20868         chmod a+rw $DIR/$tfile
20869         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20870         RC=$?
20871         if [ $RC -ne 0 ]; then
20872                 error "error, took i_mutex unnecessarily, rc=$?"
20873         fi
20874         rm -f $DIR/$tfile
20875
20876 }
20877 run_test 258b "verify i_mutex security behavior"
20878
20879 test_259() {
20880         local file=$DIR/$tfile
20881         local before
20882         local after
20883
20884         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20885
20886         stack_trap "rm -f $file" EXIT
20887
20888         wait_delete_completed
20889         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20890         echo "before: $before"
20891
20892         $LFS setstripe -i 0 -c 1 $file
20893         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20894         sync_all_data
20895         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20896         echo "after write: $after"
20897
20898 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20899         do_facet ost1 $LCTL set_param fail_loc=0x2301
20900         $TRUNCATE $file 0
20901         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20902         echo "after truncate: $after"
20903
20904         stop ost1
20905         do_facet ost1 $LCTL set_param fail_loc=0
20906         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20907         sleep 2
20908         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20909         echo "after restart: $after"
20910         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20911                 error "missing truncate?"
20912
20913         return 0
20914 }
20915 run_test 259 "crash at delayed truncate"
20916
20917 test_260() {
20918 #define OBD_FAIL_MDC_CLOSE               0x806
20919         $LCTL set_param fail_loc=0x80000806
20920         touch $DIR/$tfile
20921
20922 }
20923 run_test 260 "Check mdc_close fail"
20924
20925 ### Data-on-MDT sanity tests ###
20926 test_270a() {
20927         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20928                 skip "Need MDS version at least 2.10.55 for DoM"
20929
20930         # create DoM file
20931         local dom=$DIR/$tdir/dom_file
20932         local tmp=$DIR/$tdir/tmp_file
20933
20934         mkdir -p $DIR/$tdir
20935
20936         # basic checks for DoM component creation
20937         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20938                 error "Can set MDT layout to non-first entry"
20939
20940         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20941                 error "Can define multiple entries as MDT layout"
20942
20943         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20944
20945         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20946         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20947         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20948
20949         local mdtidx=$($LFS getstripe -m $dom)
20950         local mdtname=MDT$(printf %04x $mdtidx)
20951         local facet=mds$((mdtidx + 1))
20952         local space_check=1
20953
20954         # Skip free space checks with ZFS
20955         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20956
20957         # write
20958         sync
20959         local size_tmp=$((65536 * 3))
20960         local mdtfree1=$(do_facet $facet \
20961                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20962
20963         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20964         # check also direct IO along write
20965         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20966         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20967         sync
20968         cmp $tmp $dom || error "file data is different"
20969         [ $(stat -c%s $dom) == $size_tmp ] ||
20970                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20971         if [ $space_check == 1 ]; then
20972                 local mdtfree2=$(do_facet $facet \
20973                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20974
20975                 # increase in usage from by $size_tmp
20976                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20977                         error "MDT free space wrong after write: " \
20978                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20979         fi
20980
20981         # truncate
20982         local size_dom=10000
20983
20984         $TRUNCATE $dom $size_dom
20985         [ $(stat -c%s $dom) == $size_dom ] ||
20986                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20987         if [ $space_check == 1 ]; then
20988                 mdtfree1=$(do_facet $facet \
20989                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20990                 # decrease in usage from $size_tmp to new $size_dom
20991                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20992                   $(((size_tmp - size_dom) / 1024)) ] ||
20993                         error "MDT free space is wrong after truncate: " \
20994                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20995         fi
20996
20997         # append
20998         cat $tmp >> $dom
20999         sync
21000         size_dom=$((size_dom + size_tmp))
21001         [ $(stat -c%s $dom) == $size_dom ] ||
21002                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21003         if [ $space_check == 1 ]; then
21004                 mdtfree2=$(do_facet $facet \
21005                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21006                 # increase in usage by $size_tmp from previous
21007                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21008                         error "MDT free space is wrong after append: " \
21009                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21010         fi
21011
21012         # delete
21013         rm $dom
21014         if [ $space_check == 1 ]; then
21015                 mdtfree1=$(do_facet $facet \
21016                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21017                 # decrease in usage by $size_dom from previous
21018                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21019                         error "MDT free space is wrong after removal: " \
21020                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21021         fi
21022
21023         # combined striping
21024         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21025                 error "Can't create DoM + OST striping"
21026
21027         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21028         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21029         # check also direct IO along write
21030         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21031         sync
21032         cmp $tmp $dom || error "file data is different"
21033         [ $(stat -c%s $dom) == $size_tmp ] ||
21034                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21035         rm $dom $tmp
21036
21037         return 0
21038 }
21039 run_test 270a "DoM: basic functionality tests"
21040
21041 test_270b() {
21042         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21043                 skip "Need MDS version at least 2.10.55"
21044
21045         local dom=$DIR/$tdir/dom_file
21046         local max_size=1048576
21047
21048         mkdir -p $DIR/$tdir
21049         $LFS setstripe -E $max_size -L mdt $dom
21050
21051         # truncate over the limit
21052         $TRUNCATE $dom $(($max_size + 1)) &&
21053                 error "successful truncate over the maximum size"
21054         # write over the limit
21055         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21056                 error "successful write over the maximum size"
21057         # append over the limit
21058         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21059         echo "12345" >> $dom && error "successful append over the maximum size"
21060         rm $dom
21061
21062         return 0
21063 }
21064 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21065
21066 test_270c() {
21067         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21068                 skip "Need MDS version at least 2.10.55"
21069
21070         mkdir -p $DIR/$tdir
21071         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21072
21073         # check files inherit DoM EA
21074         touch $DIR/$tdir/first
21075         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21076                 error "bad pattern"
21077         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21078                 error "bad stripe count"
21079         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21080                 error "bad stripe size"
21081
21082         # check directory inherits DoM EA and uses it as default
21083         mkdir $DIR/$tdir/subdir
21084         touch $DIR/$tdir/subdir/second
21085         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21086                 error "bad pattern in sub-directory"
21087         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21088                 error "bad stripe count in sub-directory"
21089         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21090                 error "bad stripe size in sub-directory"
21091         return 0
21092 }
21093 run_test 270c "DoM: DoM EA inheritance tests"
21094
21095 test_270d() {
21096         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21097                 skip "Need MDS version at least 2.10.55"
21098
21099         mkdir -p $DIR/$tdir
21100         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21101
21102         # inherit default DoM striping
21103         mkdir $DIR/$tdir/subdir
21104         touch $DIR/$tdir/subdir/f1
21105
21106         # change default directory striping
21107         $LFS setstripe -c 1 $DIR/$tdir/subdir
21108         touch $DIR/$tdir/subdir/f2
21109         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21110                 error "wrong default striping in file 2"
21111         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21112                 error "bad pattern in file 2"
21113         return 0
21114 }
21115 run_test 270d "DoM: change striping from DoM to RAID0"
21116
21117 test_270e() {
21118         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21119                 skip "Need MDS version at least 2.10.55"
21120
21121         mkdir -p $DIR/$tdir/dom
21122         mkdir -p $DIR/$tdir/norm
21123         DOMFILES=20
21124         NORMFILES=10
21125         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21126         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21127
21128         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21129         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21130
21131         # find DoM files by layout
21132         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21133         [ $NUM -eq  $DOMFILES ] ||
21134                 error "lfs find -L: found $NUM, expected $DOMFILES"
21135         echo "Test 1: lfs find 20 DOM files by layout: OK"
21136
21137         # there should be 1 dir with default DOM striping
21138         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21139         [ $NUM -eq  1 ] ||
21140                 error "lfs find -L: found $NUM, expected 1 dir"
21141         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21142
21143         # find DoM files by stripe size
21144         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21145         [ $NUM -eq  $DOMFILES ] ||
21146                 error "lfs find -S: found $NUM, expected $DOMFILES"
21147         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21148
21149         # find files by stripe offset except DoM files
21150         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21151         [ $NUM -eq  $NORMFILES ] ||
21152                 error "lfs find -i: found $NUM, expected $NORMFILES"
21153         echo "Test 5: lfs find no DOM files by stripe index: OK"
21154         return 0
21155 }
21156 run_test 270e "DoM: lfs find with DoM files test"
21157
21158 test_270f() {
21159         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21160                 skip "Need MDS version at least 2.10.55"
21161
21162         local mdtname=${FSNAME}-MDT0000-mdtlov
21163         local dom=$DIR/$tdir/dom_file
21164         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21165                                                 lod.$mdtname.dom_stripesize)
21166         local dom_limit=131072
21167
21168         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21169         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21170                                                 lod.$mdtname.dom_stripesize)
21171         [ ${dom_limit} -eq ${dom_current} ] ||
21172                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21173
21174         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21175         $LFS setstripe -d $DIR/$tdir
21176         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21177                 error "Can't set directory default striping"
21178
21179         # exceed maximum stripe size
21180         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21181                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21182         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21183                 error "Able to create DoM component size more than LOD limit"
21184
21185         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21186         dom_current=$(do_facet mds1 $LCTL get_param -n \
21187                                                 lod.$mdtname.dom_stripesize)
21188         [ 0 -eq ${dom_current} ] ||
21189                 error "Can't set zero DoM stripe limit"
21190         rm $dom
21191
21192         # attempt to create DoM file on server with disabled DoM should
21193         # remove DoM entry from layout and be succeed
21194         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21195                 error "Can't create DoM file (DoM is disabled)"
21196         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21197                 error "File has DoM component while DoM is disabled"
21198         rm $dom
21199
21200         # attempt to create DoM file with only DoM stripe should return error
21201         $LFS setstripe -E $dom_limit -L mdt $dom &&
21202                 error "Able to create DoM-only file while DoM is disabled"
21203
21204         # too low values to be aligned with smallest stripe size 64K
21205         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21206         dom_current=$(do_facet mds1 $LCTL get_param -n \
21207                                                 lod.$mdtname.dom_stripesize)
21208         [ 30000 -eq ${dom_current} ] &&
21209                 error "Can set too small DoM stripe limit"
21210
21211         # 64K is a minimal stripe size in Lustre, expect limit of that size
21212         [ 65536 -eq ${dom_current} ] ||
21213                 error "Limit is not set to 64K but ${dom_current}"
21214
21215         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21216         dom_current=$(do_facet mds1 $LCTL get_param -n \
21217                                                 lod.$mdtname.dom_stripesize)
21218         echo $dom_current
21219         [ 2147483648 -eq ${dom_current} ] &&
21220                 error "Can set too large DoM stripe limit"
21221
21222         do_facet mds1 $LCTL set_param -n \
21223                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21224         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21225                 error "Can't create DoM component size after limit change"
21226         do_facet mds1 $LCTL set_param -n \
21227                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21228         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21229                 error "Can't create DoM file after limit decrease"
21230         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21231                 error "Can create big DoM component after limit decrease"
21232         touch ${dom}_def ||
21233                 error "Can't create file with old default layout"
21234
21235         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21236         return 0
21237 }
21238 run_test 270f "DoM: maximum DoM stripe size checks"
21239
21240 test_270g() {
21241         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21242                 skip "Need MDS version at least 2.13.52"
21243         local dom=$DIR/$tdir/$tfile
21244
21245         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21246         local lodname=${FSNAME}-MDT0000-mdtlov
21247
21248         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21249         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21250         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21251         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21252
21253         local dom_limit=1024
21254         local dom_threshold="50%"
21255
21256         $LFS setstripe -d $DIR/$tdir
21257         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21258                 error "Can't set directory default striping"
21259
21260         do_facet mds1 $LCTL set_param -n \
21261                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21262         # set 0 threshold and create DOM file to change tunable stripesize
21263         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21264         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21265                 error "Failed to create $dom file"
21266         # now tunable dom_cur_stripesize should reach maximum
21267         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21268                                         lod.${lodname}.dom_stripesize_cur_kb)
21269         [[ $dom_current == $dom_limit ]] ||
21270                 error "Current DOM stripesize is not maximum"
21271         rm $dom
21272
21273         # set threshold for further tests
21274         do_facet mds1 $LCTL set_param -n \
21275                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21276         echo "DOM threshold is $dom_threshold free space"
21277         local dom_def
21278         local dom_set
21279         # Spoof bfree to exceed threshold
21280         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21281         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21282         for spfree in 40 20 0 15 30 55; do
21283                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21284                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21285                         error "Failed to create $dom file"
21286                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21287                                         lod.${lodname}.dom_stripesize_cur_kb)
21288                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21289                 [[ $dom_def != $dom_current ]] ||
21290                         error "Default stripe size was not changed"
21291                 if [[ $spfree > 0 ]] ; then
21292                         dom_set=$($LFS getstripe -S $dom)
21293                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21294                                 error "DOM component size is still old"
21295                 else
21296                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21297                                 error "DoM component is set with no free space"
21298                 fi
21299                 rm $dom
21300                 dom_current=$dom_def
21301         done
21302 }
21303 run_test 270g "DoM: default DoM stripe size depends on free space"
21304
21305 test_270h() {
21306         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21307                 skip "Need MDS version at least 2.13.53"
21308
21309         local mdtname=${FSNAME}-MDT0000-mdtlov
21310         local dom=$DIR/$tdir/$tfile
21311         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21312
21313         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21314         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21315
21316         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21317         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21318                 error "can't create OST file"
21319         # mirrored file with DOM entry in the second mirror
21320         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21321                 error "can't create mirror with DoM component"
21322
21323         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21324
21325         # DOM component in the middle and has other enries in the same mirror,
21326         # should succeed but lost DoM component
21327         $LFS setstripe --copy=${dom}_1 $dom ||
21328                 error "Can't create file from OST|DOM mirror layout"
21329         # check new file has no DoM layout after all
21330         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21331                 error "File has DoM component while DoM is disabled"
21332 }
21333 run_test 270h "DoM: DoM stripe removal when disabled on server"
21334
21335 test_271a() {
21336         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21337                 skip "Need MDS version at least 2.10.55"
21338
21339         local dom=$DIR/$tdir/dom
21340
21341         mkdir -p $DIR/$tdir
21342
21343         $LFS setstripe -E 1024K -L mdt $dom
21344
21345         lctl set_param -n mdc.*.stats=clear
21346         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21347         cat $dom > /dev/null
21348         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21349         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21350         ls $dom
21351         rm -f $dom
21352 }
21353 run_test 271a "DoM: data is cached for read after write"
21354
21355 test_271b() {
21356         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21357                 skip "Need MDS version at least 2.10.55"
21358
21359         local dom=$DIR/$tdir/dom
21360
21361         mkdir -p $DIR/$tdir
21362
21363         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21364
21365         lctl set_param -n mdc.*.stats=clear
21366         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21367         cancel_lru_locks mdc
21368         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21369         # second stat to check size is cached on client
21370         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21371         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21372         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21373         rm -f $dom
21374 }
21375 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21376
21377 test_271ba() {
21378         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21379                 skip "Need MDS version at least 2.10.55"
21380
21381         local dom=$DIR/$tdir/dom
21382
21383         mkdir -p $DIR/$tdir
21384
21385         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21386
21387         lctl set_param -n mdc.*.stats=clear
21388         lctl set_param -n osc.*.stats=clear
21389         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21390         cancel_lru_locks mdc
21391         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21392         # second stat to check size is cached on client
21393         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21394         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21395         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21396         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21397         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21398         rm -f $dom
21399 }
21400 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21401
21402
21403 get_mdc_stats() {
21404         local mdtidx=$1
21405         local param=$2
21406         local mdt=MDT$(printf %04x $mdtidx)
21407
21408         if [ -z $param ]; then
21409                 lctl get_param -n mdc.*$mdt*.stats
21410         else
21411                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21412         fi
21413 }
21414
21415 test_271c() {
21416         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21417                 skip "Need MDS version at least 2.10.55"
21418
21419         local dom=$DIR/$tdir/dom
21420
21421         mkdir -p $DIR/$tdir
21422
21423         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21424
21425         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21426         local facet=mds$((mdtidx + 1))
21427
21428         cancel_lru_locks mdc
21429         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21430         createmany -o $dom 1000
21431         lctl set_param -n mdc.*.stats=clear
21432         smalliomany -w $dom 1000 200
21433         get_mdc_stats $mdtidx
21434         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21435         # Each file has 1 open, 1 IO enqueues, total 2000
21436         # but now we have also +1 getxattr for security.capability, total 3000
21437         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21438         unlinkmany $dom 1000
21439
21440         cancel_lru_locks mdc
21441         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21442         createmany -o $dom 1000
21443         lctl set_param -n mdc.*.stats=clear
21444         smalliomany -w $dom 1000 200
21445         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21446         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21447         # for OPEN and IO lock.
21448         [ $((enq - enq_2)) -ge 1000 ] ||
21449                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21450         unlinkmany $dom 1000
21451         return 0
21452 }
21453 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21454
21455 cleanup_271def_tests() {
21456         trap 0
21457         rm -f $1
21458 }
21459
21460 test_271d() {
21461         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21462                 skip "Need MDS version at least 2.10.57"
21463
21464         local dom=$DIR/$tdir/dom
21465         local tmp=$TMP/$tfile
21466         trap "cleanup_271def_tests $tmp" EXIT
21467
21468         mkdir -p $DIR/$tdir
21469
21470         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21471
21472         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21473
21474         cancel_lru_locks mdc
21475         dd if=/dev/urandom of=$tmp bs=1000 count=1
21476         dd if=$tmp of=$dom bs=1000 count=1
21477         cancel_lru_locks mdc
21478
21479         cat /etc/hosts >> $tmp
21480         lctl set_param -n mdc.*.stats=clear
21481
21482         # append data to the same file it should update local page
21483         echo "Append to the same page"
21484         cat /etc/hosts >> $dom
21485         local num=$(get_mdc_stats $mdtidx ost_read)
21486         local ra=$(get_mdc_stats $mdtidx req_active)
21487         local rw=$(get_mdc_stats $mdtidx req_waittime)
21488
21489         [ -z $num ] || error "$num READ RPC occured"
21490         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21491         echo "... DONE"
21492
21493         # compare content
21494         cmp $tmp $dom || error "file miscompare"
21495
21496         cancel_lru_locks mdc
21497         lctl set_param -n mdc.*.stats=clear
21498
21499         echo "Open and read file"
21500         cat $dom > /dev/null
21501         local num=$(get_mdc_stats $mdtidx ost_read)
21502         local ra=$(get_mdc_stats $mdtidx req_active)
21503         local rw=$(get_mdc_stats $mdtidx req_waittime)
21504
21505         [ -z $num ] || error "$num READ RPC occured"
21506         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21507         echo "... DONE"
21508
21509         # compare content
21510         cmp $tmp $dom || error "file miscompare"
21511
21512         return 0
21513 }
21514 run_test 271d "DoM: read on open (1K file in reply buffer)"
21515
21516 test_271f() {
21517         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21518                 skip "Need MDS version at least 2.10.57"
21519
21520         local dom=$DIR/$tdir/dom
21521         local tmp=$TMP/$tfile
21522         trap "cleanup_271def_tests $tmp" EXIT
21523
21524         mkdir -p $DIR/$tdir
21525
21526         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21527
21528         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21529
21530         cancel_lru_locks mdc
21531         dd if=/dev/urandom of=$tmp bs=265000 count=1
21532         dd if=$tmp of=$dom bs=265000 count=1
21533         cancel_lru_locks mdc
21534         cat /etc/hosts >> $tmp
21535         lctl set_param -n mdc.*.stats=clear
21536
21537         echo "Append to the same page"
21538         cat /etc/hosts >> $dom
21539         local num=$(get_mdc_stats $mdtidx ost_read)
21540         local ra=$(get_mdc_stats $mdtidx req_active)
21541         local rw=$(get_mdc_stats $mdtidx req_waittime)
21542
21543         [ -z $num ] || error "$num READ RPC occured"
21544         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21545         echo "... DONE"
21546
21547         # compare content
21548         cmp $tmp $dom || error "file miscompare"
21549
21550         cancel_lru_locks mdc
21551         lctl set_param -n mdc.*.stats=clear
21552
21553         echo "Open and read file"
21554         cat $dom > /dev/null
21555         local num=$(get_mdc_stats $mdtidx ost_read)
21556         local ra=$(get_mdc_stats $mdtidx req_active)
21557         local rw=$(get_mdc_stats $mdtidx req_waittime)
21558
21559         [ -z $num ] && num=0
21560         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21561         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21562         echo "... DONE"
21563
21564         # compare content
21565         cmp $tmp $dom || error "file miscompare"
21566
21567         return 0
21568 }
21569 run_test 271f "DoM: read on open (200K file and read tail)"
21570
21571 test_271g() {
21572         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21573                 skip "Skipping due to old client or server version"
21574
21575         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21576         # to get layout
21577         $CHECKSTAT -t file $DIR1/$tfile
21578
21579         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21580         MULTIOP_PID=$!
21581         sleep 1
21582         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21583         $LCTL set_param fail_loc=0x80000314
21584         rm $DIR1/$tfile || error "Unlink fails"
21585         RC=$?
21586         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21587         [ $RC -eq 0 ] || error "Failed write to stale object"
21588 }
21589 run_test 271g "Discard DoM data vs client flush race"
21590
21591 test_272a() {
21592         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21593                 skip "Need MDS version at least 2.11.50"
21594
21595         local dom=$DIR/$tdir/dom
21596         mkdir -p $DIR/$tdir
21597
21598         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21599         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21600                 error "failed to write data into $dom"
21601         local old_md5=$(md5sum $dom)
21602
21603         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21604                 error "failed to migrate to the same DoM component"
21605
21606         local new_md5=$(md5sum $dom)
21607
21608         [ "$old_md5" == "$new_md5" ] ||
21609                 error "md5sum differ: $old_md5, $new_md5"
21610
21611         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21612                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21613 }
21614 run_test 272a "DoM migration: new layout with the same DOM component"
21615
21616 test_272b() {
21617         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21618                 skip "Need MDS version at least 2.11.50"
21619
21620         local dom=$DIR/$tdir/dom
21621         mkdir -p $DIR/$tdir
21622         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21623
21624         local mdtidx=$($LFS getstripe -m $dom)
21625         local mdtname=MDT$(printf %04x $mdtidx)
21626         local facet=mds$((mdtidx + 1))
21627
21628         local mdtfree1=$(do_facet $facet \
21629                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21630         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21631                 error "failed to write data into $dom"
21632         local old_md5=$(md5sum $dom)
21633         cancel_lru_locks mdc
21634         local mdtfree1=$(do_facet $facet \
21635                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21636
21637         $LFS migrate -c2 $dom ||
21638                 error "failed to migrate to the new composite layout"
21639         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21640                 error "MDT stripe was not removed"
21641
21642         cancel_lru_locks mdc
21643         local new_md5=$(md5sum $dom)
21644         [ "$old_md5" == "$new_md5" ] ||
21645                 error "$old_md5 != $new_md5"
21646
21647         # Skip free space checks with ZFS
21648         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21649                 local mdtfree2=$(do_facet $facet \
21650                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21651                 [ $mdtfree2 -gt $mdtfree1 ] ||
21652                         error "MDT space is not freed after migration"
21653         fi
21654         return 0
21655 }
21656 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21657
21658 test_272c() {
21659         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21660                 skip "Need MDS version at least 2.11.50"
21661
21662         local dom=$DIR/$tdir/$tfile
21663         mkdir -p $DIR/$tdir
21664         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21665
21666         local mdtidx=$($LFS getstripe -m $dom)
21667         local mdtname=MDT$(printf %04x $mdtidx)
21668         local facet=mds$((mdtidx + 1))
21669
21670         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21671                 error "failed to write data into $dom"
21672         local old_md5=$(md5sum $dom)
21673         cancel_lru_locks mdc
21674         local mdtfree1=$(do_facet $facet \
21675                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21676
21677         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21678                 error "failed to migrate to the new composite layout"
21679         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21680                 error "MDT stripe was not removed"
21681
21682         cancel_lru_locks mdc
21683         local new_md5=$(md5sum $dom)
21684         [ "$old_md5" == "$new_md5" ] ||
21685                 error "$old_md5 != $new_md5"
21686
21687         # Skip free space checks with ZFS
21688         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21689                 local mdtfree2=$(do_facet $facet \
21690                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21691                 [ $mdtfree2 -gt $mdtfree1 ] ||
21692                         error "MDS space is not freed after migration"
21693         fi
21694         return 0
21695 }
21696 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21697
21698 test_272d() {
21699         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21700                 skip "Need MDS version at least 2.12.55"
21701
21702         local dom=$DIR/$tdir/$tfile
21703         mkdir -p $DIR/$tdir
21704         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21705
21706         local mdtidx=$($LFS getstripe -m $dom)
21707         local mdtname=MDT$(printf %04x $mdtidx)
21708         local facet=mds$((mdtidx + 1))
21709
21710         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21711                 error "failed to write data into $dom"
21712         local old_md5=$(md5sum $dom)
21713         cancel_lru_locks mdc
21714         local mdtfree1=$(do_facet $facet \
21715                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21716
21717         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21718                 error "failed mirroring to the new composite layout"
21719         $LFS mirror resync $dom ||
21720                 error "failed mirror resync"
21721         $LFS mirror split --mirror-id 1 -d $dom ||
21722                 error "failed mirror split"
21723
21724         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21725                 error "MDT stripe was not removed"
21726
21727         cancel_lru_locks mdc
21728         local new_md5=$(md5sum $dom)
21729         [ "$old_md5" == "$new_md5" ] ||
21730                 error "$old_md5 != $new_md5"
21731
21732         # Skip free space checks with ZFS
21733         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21734                 local mdtfree2=$(do_facet $facet \
21735                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21736                 [ $mdtfree2 -gt $mdtfree1 ] ||
21737                         error "MDS space is not freed after DOM mirror deletion"
21738         fi
21739         return 0
21740 }
21741 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21742
21743 test_272e() {
21744         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21745                 skip "Need MDS version at least 2.12.55"
21746
21747         local dom=$DIR/$tdir/$tfile
21748         mkdir -p $DIR/$tdir
21749         $LFS setstripe -c 2 $dom
21750
21751         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21752                 error "failed to write data into $dom"
21753         local old_md5=$(md5sum $dom)
21754         cancel_lru_locks mdc
21755
21756         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21757                 error "failed mirroring to the DOM layout"
21758         $LFS mirror resync $dom ||
21759                 error "failed mirror resync"
21760         $LFS mirror split --mirror-id 1 -d $dom ||
21761                 error "failed mirror split"
21762
21763         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21764                 error "MDT stripe was not removed"
21765
21766         cancel_lru_locks mdc
21767         local new_md5=$(md5sum $dom)
21768         [ "$old_md5" == "$new_md5" ] ||
21769                 error "$old_md5 != $new_md5"
21770
21771         return 0
21772 }
21773 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21774
21775 test_272f() {
21776         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21777                 skip "Need MDS version at least 2.12.55"
21778
21779         local dom=$DIR/$tdir/$tfile
21780         mkdir -p $DIR/$tdir
21781         $LFS setstripe -c 2 $dom
21782
21783         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21784                 error "failed to write data into $dom"
21785         local old_md5=$(md5sum $dom)
21786         cancel_lru_locks mdc
21787
21788         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21789                 error "failed migrating to the DOM file"
21790
21791         cancel_lru_locks mdc
21792         local new_md5=$(md5sum $dom)
21793         [ "$old_md5" != "$new_md5" ] &&
21794                 error "$old_md5 != $new_md5"
21795
21796         return 0
21797 }
21798 run_test 272f "DoM migration: OST-striped file to DOM file"
21799
21800 test_273a() {
21801         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21802                 skip "Need MDS version at least 2.11.50"
21803
21804         # Layout swap cannot be done if either file has DOM component,
21805         # this will never be supported, migration should be used instead
21806
21807         local dom=$DIR/$tdir/$tfile
21808         mkdir -p $DIR/$tdir
21809
21810         $LFS setstripe -c2 ${dom}_plain
21811         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21812         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21813                 error "can swap layout with DoM component"
21814         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21815                 error "can swap layout with DoM component"
21816
21817         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21818         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21819                 error "can swap layout with DoM component"
21820         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21821                 error "can swap layout with DoM component"
21822         return 0
21823 }
21824 run_test 273a "DoM: layout swapping should fail with DOM"
21825
21826 test_273b() {
21827         mkdir -p $DIR/$tdir
21828         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21829
21830 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21831         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21832
21833         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21834 }
21835 run_test 273b "DoM: race writeback and object destroy"
21836
21837 test_275() {
21838         remote_ost_nodsh && skip "remote OST with nodsh"
21839         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21840                 skip "Need OST version >= 2.10.57"
21841
21842         local file=$DIR/$tfile
21843         local oss
21844
21845         oss=$(comma_list $(osts_nodes))
21846
21847         dd if=/dev/urandom of=$file bs=1M count=2 ||
21848                 error "failed to create a file"
21849         cancel_lru_locks osc
21850
21851         #lock 1
21852         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21853                 error "failed to read a file"
21854
21855 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21856         $LCTL set_param fail_loc=0x8000031f
21857
21858         cancel_lru_locks osc &
21859         sleep 1
21860
21861 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21862         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21863         #IO takes another lock, but matches the PENDING one
21864         #and places it to the IO RPC
21865         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21866                 error "failed to read a file with PENDING lock"
21867 }
21868 run_test 275 "Read on a canceled duplicate lock"
21869
21870 test_276() {
21871         remote_ost_nodsh && skip "remote OST with nodsh"
21872         local pid
21873
21874         do_facet ost1 "(while true; do \
21875                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21876                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21877         pid=$!
21878
21879         for LOOP in $(seq 20); do
21880                 stop ost1
21881                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21882         done
21883         kill -9 $pid
21884         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21885                 rm $TMP/sanity_276_pid"
21886 }
21887 run_test 276 "Race between mount and obd_statfs"
21888
21889 test_277() {
21890         $LCTL set_param ldlm.namespaces.*.lru_size=0
21891         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21892         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21893                         grep ^used_mb | awk '{print $2}')
21894         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21895         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21896                 oflag=direct conv=notrunc
21897         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21898                         grep ^used_mb | awk '{print $2}')
21899         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21900 }
21901 run_test 277 "Direct IO shall drop page cache"
21902
21903 test_278() {
21904         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21905         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21906         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21907                 skip "needs the same host for mdt1 mdt2" && return
21908
21909         local pid1
21910         local pid2
21911
21912 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21913         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21914         stop mds2 &
21915         pid2=$!
21916
21917         stop mds1
21918
21919         echo "Starting MDTs"
21920         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21921         wait $pid2
21922 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21923 #will return NULL
21924         do_facet mds2 $LCTL set_param fail_loc=0
21925
21926         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21927         wait_recovery_complete mds2
21928 }
21929 run_test 278 "Race starting MDS between MDTs stop/start"
21930
21931 test_280() {
21932         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21933                 skip "Need MGS version at least 2.13.52"
21934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21935         combined_mgs_mds || skip "needs combined MGS/MDT"
21936
21937         umount_client $MOUNT
21938 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21939         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21940
21941         mount_client $MOUNT &
21942         sleep 1
21943         stop mgs || error "stop mgs failed"
21944         #for a race mgs would crash
21945         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21946         # make sure we unmount client before remounting
21947         wait
21948         umount_client $MOUNT
21949         mount_client $MOUNT || error "mount client failed"
21950 }
21951 run_test 280 "Race between MGS umount and client llog processing"
21952
21953 cleanup_test_300() {
21954         trap 0
21955         umask $SAVE_UMASK
21956 }
21957 test_striped_dir() {
21958         local mdt_index=$1
21959         local stripe_count
21960         local stripe_index
21961
21962         mkdir -p $DIR/$tdir
21963
21964         SAVE_UMASK=$(umask)
21965         trap cleanup_test_300 RETURN EXIT
21966
21967         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21968                                                 $DIR/$tdir/striped_dir ||
21969                 error "set striped dir error"
21970
21971         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21972         [ "$mode" = "755" ] || error "expect 755 got $mode"
21973
21974         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21975                 error "getdirstripe failed"
21976         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21977         if [ "$stripe_count" != "2" ]; then
21978                 error "1:stripe_count is $stripe_count, expect 2"
21979         fi
21980         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21981         if [ "$stripe_count" != "2" ]; then
21982                 error "2:stripe_count is $stripe_count, expect 2"
21983         fi
21984
21985         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21986         if [ "$stripe_index" != "$mdt_index" ]; then
21987                 error "stripe_index is $stripe_index, expect $mdt_index"
21988         fi
21989
21990         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21991                 error "nlink error after create striped dir"
21992
21993         mkdir $DIR/$tdir/striped_dir/a
21994         mkdir $DIR/$tdir/striped_dir/b
21995
21996         stat $DIR/$tdir/striped_dir/a ||
21997                 error "create dir under striped dir failed"
21998         stat $DIR/$tdir/striped_dir/b ||
21999                 error "create dir under striped dir failed"
22000
22001         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22002                 error "nlink error after mkdir"
22003
22004         rmdir $DIR/$tdir/striped_dir/a
22005         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22006                 error "nlink error after rmdir"
22007
22008         rmdir $DIR/$tdir/striped_dir/b
22009         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22010                 error "nlink error after rmdir"
22011
22012         chattr +i $DIR/$tdir/striped_dir
22013         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22014                 error "immutable flags not working under striped dir!"
22015         chattr -i $DIR/$tdir/striped_dir
22016
22017         rmdir $DIR/$tdir/striped_dir ||
22018                 error "rmdir striped dir error"
22019
22020         cleanup_test_300
22021
22022         true
22023 }
22024
22025 test_300a() {
22026         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22027                 skip "skipped for lustre < 2.7.0"
22028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22029         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22030
22031         test_striped_dir 0 || error "failed on striped dir on MDT0"
22032         test_striped_dir 1 || error "failed on striped dir on MDT0"
22033 }
22034 run_test 300a "basic striped dir sanity test"
22035
22036 test_300b() {
22037         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22038                 skip "skipped for lustre < 2.7.0"
22039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22040         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22041
22042         local i
22043         local mtime1
22044         local mtime2
22045         local mtime3
22046
22047         test_mkdir $DIR/$tdir || error "mkdir fail"
22048         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22049                 error "set striped dir error"
22050         for i in {0..9}; do
22051                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22052                 sleep 1
22053                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22054                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22055                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22056                 sleep 1
22057                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22058                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22059                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22060         done
22061         true
22062 }
22063 run_test 300b "check ctime/mtime for striped dir"
22064
22065 test_300c() {
22066         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22067                 skip "skipped for lustre < 2.7.0"
22068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22070
22071         local file_count
22072
22073         mkdir -p $DIR/$tdir
22074         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22075                 error "set striped dir error"
22076
22077         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22078                 error "chown striped dir failed"
22079
22080         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22081                 error "create 5k files failed"
22082
22083         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22084
22085         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22086
22087         rm -rf $DIR/$tdir
22088 }
22089 run_test 300c "chown && check ls under striped directory"
22090
22091 test_300d() {
22092         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22093                 skip "skipped for lustre < 2.7.0"
22094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22095         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22096
22097         local stripe_count
22098         local file
22099
22100         mkdir -p $DIR/$tdir
22101         $LFS setstripe -c 2 $DIR/$tdir
22102
22103         #local striped directory
22104         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22105                 error "set striped dir error"
22106         #look at the directories for debug purposes
22107         ls -l $DIR/$tdir
22108         $LFS getdirstripe $DIR/$tdir
22109         ls -l $DIR/$tdir/striped_dir
22110         $LFS getdirstripe $DIR/$tdir/striped_dir
22111         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22112                 error "create 10 files failed"
22113
22114         #remote striped directory
22115         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22116                 error "set striped dir error"
22117         #look at the directories for debug purposes
22118         ls -l $DIR/$tdir
22119         $LFS getdirstripe $DIR/$tdir
22120         ls -l $DIR/$tdir/remote_striped_dir
22121         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22122         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22123                 error "create 10 files failed"
22124
22125         for file in $(find $DIR/$tdir); do
22126                 stripe_count=$($LFS getstripe -c $file)
22127                 [ $stripe_count -eq 2 ] ||
22128                         error "wrong stripe $stripe_count for $file"
22129         done
22130
22131         rm -rf $DIR/$tdir
22132 }
22133 run_test 300d "check default stripe under striped directory"
22134
22135 test_300e() {
22136         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22137                 skip "Need MDS version at least 2.7.55"
22138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22140
22141         local stripe_count
22142         local file
22143
22144         mkdir -p $DIR/$tdir
22145
22146         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22147                 error "set striped dir error"
22148
22149         touch $DIR/$tdir/striped_dir/a
22150         touch $DIR/$tdir/striped_dir/b
22151         touch $DIR/$tdir/striped_dir/c
22152
22153         mkdir $DIR/$tdir/striped_dir/dir_a
22154         mkdir $DIR/$tdir/striped_dir/dir_b
22155         mkdir $DIR/$tdir/striped_dir/dir_c
22156
22157         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22158                 error "set striped adir under striped dir error"
22159
22160         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22161                 error "set striped bdir under striped dir error"
22162
22163         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22164                 error "set striped cdir under striped dir error"
22165
22166         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22167                 error "rename dir under striped dir fails"
22168
22169         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22170                 error "rename dir under different stripes fails"
22171
22172         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22173                 error "rename file under striped dir should succeed"
22174
22175         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22176                 error "rename dir under striped dir should succeed"
22177
22178         rm -rf $DIR/$tdir
22179 }
22180 run_test 300e "check rename under striped directory"
22181
22182 test_300f() {
22183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22184         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22185         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22186                 skip "Need MDS version at least 2.7.55"
22187
22188         local stripe_count
22189         local file
22190
22191         rm -rf $DIR/$tdir
22192         mkdir -p $DIR/$tdir
22193
22194         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22195                 error "set striped dir error"
22196
22197         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22198                 error "set striped dir error"
22199
22200         touch $DIR/$tdir/striped_dir/a
22201         mkdir $DIR/$tdir/striped_dir/dir_a
22202         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22203                 error "create striped dir under striped dir fails"
22204
22205         touch $DIR/$tdir/striped_dir1/b
22206         mkdir $DIR/$tdir/striped_dir1/dir_b
22207         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22208                 error "create striped dir under striped dir fails"
22209
22210         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22211                 error "rename dir under different striped dir should fail"
22212
22213         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22214                 error "rename striped dir under diff striped dir should fail"
22215
22216         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22217                 error "rename file under diff striped dirs fails"
22218
22219         rm -rf $DIR/$tdir
22220 }
22221 run_test 300f "check rename cross striped directory"
22222
22223 test_300_check_default_striped_dir()
22224 {
22225         local dirname=$1
22226         local default_count=$2
22227         local default_index=$3
22228         local stripe_count
22229         local stripe_index
22230         local dir_stripe_index
22231         local dir
22232
22233         echo "checking $dirname $default_count $default_index"
22234         $LFS setdirstripe -D -c $default_count -i $default_index \
22235                                 -H all_char $DIR/$tdir/$dirname ||
22236                 error "set default stripe on striped dir error"
22237         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22238         [ $stripe_count -eq $default_count ] ||
22239                 error "expect $default_count get $stripe_count for $dirname"
22240
22241         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22242         [ $stripe_index -eq $default_index ] ||
22243                 error "expect $default_index get $stripe_index for $dirname"
22244
22245         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22246                                                 error "create dirs failed"
22247
22248         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22249         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22250         for dir in $(find $DIR/$tdir/$dirname/*); do
22251                 stripe_count=$($LFS getdirstripe -c $dir)
22252                 (( $stripe_count == $default_count )) ||
22253                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22254                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22255                 error "stripe count $default_count != $stripe_count for $dir"
22256
22257                 stripe_index=$($LFS getdirstripe -i $dir)
22258                 [ $default_index -eq -1 ] ||
22259                         [ $stripe_index -eq $default_index ] ||
22260                         error "$stripe_index != $default_index for $dir"
22261
22262                 #check default stripe
22263                 stripe_count=$($LFS getdirstripe -D -c $dir)
22264                 [ $stripe_count -eq $default_count ] ||
22265                 error "default count $default_count != $stripe_count for $dir"
22266
22267                 stripe_index=$($LFS getdirstripe -D -i $dir)
22268                 [ $stripe_index -eq $default_index ] ||
22269                 error "default index $default_index != $stripe_index for $dir"
22270         done
22271         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22272 }
22273
22274 test_300g() {
22275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22276         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22277                 skip "Need MDS version at least 2.7.55"
22278
22279         local dir
22280         local stripe_count
22281         local stripe_index
22282
22283         mkdir $DIR/$tdir
22284         mkdir $DIR/$tdir/normal_dir
22285
22286         #Checking when client cache stripe index
22287         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22288         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22289                 error "create striped_dir failed"
22290
22291         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22292                 error "create dir0 fails"
22293         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22294         [ $stripe_index -eq 0 ] ||
22295                 error "dir0 expect index 0 got $stripe_index"
22296
22297         mkdir $DIR/$tdir/striped_dir/dir1 ||
22298                 error "create dir1 fails"
22299         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22300         [ $stripe_index -eq 1 ] ||
22301                 error "dir1 expect index 1 got $stripe_index"
22302
22303         #check default stripe count/stripe index
22304         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22305         test_300_check_default_striped_dir normal_dir 1 0
22306         test_300_check_default_striped_dir normal_dir -1 1
22307         test_300_check_default_striped_dir normal_dir 2 -1
22308
22309         #delete default stripe information
22310         echo "delete default stripeEA"
22311         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22312                 error "set default stripe on striped dir error"
22313
22314         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22315         for dir in $(find $DIR/$tdir/normal_dir/*); do
22316                 stripe_count=$($LFS getdirstripe -c $dir)
22317                 [ $stripe_count -eq 0 ] ||
22318                         error "expect 1 get $stripe_count for $dir"
22319                 stripe_index=$($LFS getdirstripe -i $dir)
22320                 [ $stripe_index -eq 0 ] ||
22321                         error "expect 0 get $stripe_index for $dir"
22322         done
22323 }
22324 run_test 300g "check default striped directory for normal directory"
22325
22326 test_300h() {
22327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22328         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22329                 skip "Need MDS version at least 2.7.55"
22330
22331         local dir
22332         local stripe_count
22333
22334         mkdir $DIR/$tdir
22335         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22336                 error "set striped dir error"
22337
22338         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22339         test_300_check_default_striped_dir striped_dir 1 0
22340         test_300_check_default_striped_dir striped_dir -1 1
22341         test_300_check_default_striped_dir striped_dir 2 -1
22342
22343         #delete default stripe information
22344         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22345                 error "set default stripe on striped dir error"
22346
22347         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22348         for dir in $(find $DIR/$tdir/striped_dir/*); do
22349                 stripe_count=$($LFS getdirstripe -c $dir)
22350                 [ $stripe_count -eq 0 ] ||
22351                         error "expect 1 get $stripe_count for $dir"
22352         done
22353 }
22354 run_test 300h "check default striped directory for striped directory"
22355
22356 test_300i() {
22357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22359         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22360                 skip "Need MDS version at least 2.7.55"
22361
22362         local stripe_count
22363         local file
22364
22365         mkdir $DIR/$tdir
22366
22367         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22368                 error "set striped dir error"
22369
22370         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22371                 error "create files under striped dir failed"
22372
22373         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22374                 error "set striped hashdir error"
22375
22376         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22377                 error "create dir0 under hash dir failed"
22378         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22379                 error "create dir1 under hash dir failed"
22380         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22381                 error "create dir2 under hash dir failed"
22382
22383         # unfortunately, we need to umount to clear dir layout cache for now
22384         # once we fully implement dir layout, we can drop this
22385         umount_client $MOUNT || error "umount failed"
22386         mount_client $MOUNT || error "mount failed"
22387
22388         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22389         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22390         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22391
22392         #set the stripe to be unknown hash type
22393         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22394         $LCTL set_param fail_loc=0x1901
22395         for ((i = 0; i < 10; i++)); do
22396                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22397                         error "stat f-$i failed"
22398                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22399         done
22400
22401         touch $DIR/$tdir/striped_dir/f0 &&
22402                 error "create under striped dir with unknown hash should fail"
22403
22404         $LCTL set_param fail_loc=0
22405
22406         umount_client $MOUNT || error "umount failed"
22407         mount_client $MOUNT || error "mount failed"
22408
22409         return 0
22410 }
22411 run_test 300i "client handle unknown hash type striped directory"
22412
22413 test_300j() {
22414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22416         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22417                 skip "Need MDS version at least 2.7.55"
22418
22419         local stripe_count
22420         local file
22421
22422         mkdir $DIR/$tdir
22423
22424         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22425         $LCTL set_param fail_loc=0x1702
22426         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22427                 error "set striped dir error"
22428
22429         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22430                 error "create files under striped dir failed"
22431
22432         $LCTL set_param fail_loc=0
22433
22434         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22435
22436         return 0
22437 }
22438 run_test 300j "test large update record"
22439
22440 test_300k() {
22441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22443         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22444                 skip "Need MDS version at least 2.7.55"
22445
22446         # this test needs a huge transaction
22447         local kb
22448         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22449              osd*.$FSNAME-MDT0000.kbytestotal")
22450         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22451
22452         local stripe_count
22453         local file
22454
22455         mkdir $DIR/$tdir
22456
22457         #define OBD_FAIL_LARGE_STRIPE   0x1703
22458         $LCTL set_param fail_loc=0x1703
22459         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22460                 error "set striped dir error"
22461         $LCTL set_param fail_loc=0
22462
22463         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22464                 error "getstripeddir fails"
22465         rm -rf $DIR/$tdir/striped_dir ||
22466                 error "unlink striped dir fails"
22467
22468         return 0
22469 }
22470 run_test 300k "test large striped directory"
22471
22472 test_300l() {
22473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22475         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22476                 skip "Need MDS version at least 2.7.55"
22477
22478         local stripe_index
22479
22480         test_mkdir -p $DIR/$tdir/striped_dir
22481         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22482                         error "chown $RUNAS_ID failed"
22483         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22484                 error "set default striped dir failed"
22485
22486         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22487         $LCTL set_param fail_loc=0x80000158
22488         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22489
22490         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22491         [ $stripe_index -eq 1 ] ||
22492                 error "expect 1 get $stripe_index for $dir"
22493 }
22494 run_test 300l "non-root user to create dir under striped dir with stale layout"
22495
22496 test_300m() {
22497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22498         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22499         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22500                 skip "Need MDS version at least 2.7.55"
22501
22502         mkdir -p $DIR/$tdir/striped_dir
22503         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22504                 error "set default stripes dir error"
22505
22506         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22507
22508         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22509         [ $stripe_count -eq 0 ] ||
22510                         error "expect 0 get $stripe_count for a"
22511
22512         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22513                 error "set default stripes dir error"
22514
22515         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22516
22517         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22518         [ $stripe_count -eq 0 ] ||
22519                         error "expect 0 get $stripe_count for b"
22520
22521         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22522                 error "set default stripes dir error"
22523
22524         mkdir $DIR/$tdir/striped_dir/c &&
22525                 error "default stripe_index is invalid, mkdir c should fails"
22526
22527         rm -rf $DIR/$tdir || error "rmdir fails"
22528 }
22529 run_test 300m "setstriped directory on single MDT FS"
22530
22531 cleanup_300n() {
22532         local list=$(comma_list $(mdts_nodes))
22533
22534         trap 0
22535         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22536 }
22537
22538 test_300n() {
22539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22541         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22542                 skip "Need MDS version at least 2.7.55"
22543         remote_mds_nodsh && skip "remote MDS with nodsh"
22544
22545         local stripe_index
22546         local list=$(comma_list $(mdts_nodes))
22547
22548         trap cleanup_300n RETURN EXIT
22549         mkdir -p $DIR/$tdir
22550         chmod 777 $DIR/$tdir
22551         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22552                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22553                 error "create striped dir succeeds with gid=0"
22554
22555         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22556         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22557                 error "create striped dir fails with gid=-1"
22558
22559         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22560         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22561                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22562                 error "set default striped dir succeeds with gid=0"
22563
22564
22565         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22566         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22567                 error "set default striped dir fails with gid=-1"
22568
22569
22570         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22571         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22572                                         error "create test_dir fails"
22573         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22574                                         error "create test_dir1 fails"
22575         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22576                                         error "create test_dir2 fails"
22577         cleanup_300n
22578 }
22579 run_test 300n "non-root user to create dir under striped dir with default EA"
22580
22581 test_300o() {
22582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22583         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22584         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22585                 skip "Need MDS version at least 2.7.55"
22586
22587         local numfree1
22588         local numfree2
22589
22590         mkdir -p $DIR/$tdir
22591
22592         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22593         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22594         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22595                 skip "not enough free inodes $numfree1 $numfree2"
22596         fi
22597
22598         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22599         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22600         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22601                 skip "not enough free space $numfree1 $numfree2"
22602         fi
22603
22604         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22605                 error "setdirstripe fails"
22606
22607         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22608                 error "create dirs fails"
22609
22610         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22611         ls $DIR/$tdir/striped_dir > /dev/null ||
22612                 error "ls striped dir fails"
22613         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22614                 error "unlink big striped dir fails"
22615 }
22616 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22617
22618 test_300p() {
22619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22621         remote_mds_nodsh && skip "remote MDS with nodsh"
22622
22623         mkdir -p $DIR/$tdir
22624
22625         #define OBD_FAIL_OUT_ENOSPC     0x1704
22626         do_facet mds2 lctl set_param fail_loc=0x80001704
22627         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22628                  && error "create striped directory should fail"
22629
22630         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22631
22632         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22633         true
22634 }
22635 run_test 300p "create striped directory without space"
22636
22637 test_300q() {
22638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22639         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22640
22641         local fd=$(free_fd)
22642         local cmd="exec $fd<$tdir"
22643         cd $DIR
22644         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22645         eval $cmd
22646         cmd="exec $fd<&-"
22647         trap "eval $cmd" EXIT
22648         cd $tdir || error "cd $tdir fails"
22649         rmdir  ../$tdir || error "rmdir $tdir fails"
22650         mkdir local_dir && error "create dir succeeds"
22651         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22652         eval $cmd
22653         return 0
22654 }
22655 run_test 300q "create remote directory under orphan directory"
22656
22657 test_300r() {
22658         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22659                 skip "Need MDS version at least 2.7.55" && return
22660         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22661
22662         mkdir $DIR/$tdir
22663
22664         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22665                 error "set striped dir error"
22666
22667         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22668                 error "getstripeddir fails"
22669
22670         local stripe_count
22671         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22672                       awk '/lmv_stripe_count:/ { print $2 }')
22673
22674         [ $MDSCOUNT -ne $stripe_count ] &&
22675                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22676
22677         rm -rf $DIR/$tdir/striped_dir ||
22678                 error "unlink striped dir fails"
22679 }
22680 run_test 300r "test -1 striped directory"
22681
22682 test_300s_helper() {
22683         local count=$1
22684
22685         local stripe_dir=$DIR/$tdir/striped_dir.$count
22686
22687         $LFS mkdir -c $count $stripe_dir ||
22688                 error "lfs mkdir -c error"
22689
22690         $LFS getdirstripe $stripe_dir ||
22691                 error "lfs getdirstripe fails"
22692
22693         local stripe_count
22694         stripe_count=$($LFS getdirstripe $stripe_dir |
22695                       awk '/lmv_stripe_count:/ { print $2 }')
22696
22697         [ $count -ne $stripe_count ] &&
22698                 error_noexit "bad stripe count $stripe_count expected $count"
22699
22700         local dupe_stripes
22701         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22702                 awk '/0x/ {count[$1] += 1}; END {
22703                         for (idx in count) {
22704                                 if (count[idx]>1) {
22705                                         print "index " idx " count " count[idx]
22706                                 }
22707                         }
22708                 }')
22709
22710         if [[ -n "$dupe_stripes" ]] ; then
22711                 lfs getdirstripe $stripe_dir
22712                 error_noexit "Dupe MDT above: $dupe_stripes "
22713         fi
22714
22715         rm -rf $stripe_dir ||
22716                 error_noexit "unlink $stripe_dir fails"
22717 }
22718
22719 test_300s() {
22720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22721                 skip "Need MDS version at least 2.7.55" && return
22722         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22723
22724         mkdir $DIR/$tdir
22725         for count in $(seq 2 $MDSCOUNT); do
22726                 test_300s_helper $count
22727         done
22728 }
22729 run_test 300s "test lfs mkdir -c without -i"
22730
22731
22732 prepare_remote_file() {
22733         mkdir $DIR/$tdir/src_dir ||
22734                 error "create remote source failed"
22735
22736         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22737                  error "cp to remote source failed"
22738         touch $DIR/$tdir/src_dir/a
22739
22740         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22741                 error "create remote target dir failed"
22742
22743         touch $DIR/$tdir/tgt_dir/b
22744
22745         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22746                 error "rename dir cross MDT failed!"
22747
22748         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22749                 error "src_child still exists after rename"
22750
22751         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22752                 error "missing file(a) after rename"
22753
22754         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22755                 error "diff after rename"
22756 }
22757
22758 test_310a() {
22759         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22761
22762         local remote_file=$DIR/$tdir/tgt_dir/b
22763
22764         mkdir -p $DIR/$tdir
22765
22766         prepare_remote_file || error "prepare remote file failed"
22767
22768         #open-unlink file
22769         $OPENUNLINK $remote_file $remote_file ||
22770                 error "openunlink $remote_file failed"
22771         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22772 }
22773 run_test 310a "open unlink remote file"
22774
22775 test_310b() {
22776         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22778
22779         local remote_file=$DIR/$tdir/tgt_dir/b
22780
22781         mkdir -p $DIR/$tdir
22782
22783         prepare_remote_file || error "prepare remote file failed"
22784
22785         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22786         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22787         $CHECKSTAT -t file $remote_file || error "check file failed"
22788 }
22789 run_test 310b "unlink remote file with multiple links while open"
22790
22791 test_310c() {
22792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22793         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22794
22795         local remote_file=$DIR/$tdir/tgt_dir/b
22796
22797         mkdir -p $DIR/$tdir
22798
22799         prepare_remote_file || error "prepare remote file failed"
22800
22801         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22802         multiop_bg_pause $remote_file O_uc ||
22803                         error "mulitop failed for remote file"
22804         MULTIPID=$!
22805         $MULTIOP $DIR/$tfile Ouc
22806         kill -USR1 $MULTIPID
22807         wait $MULTIPID
22808 }
22809 run_test 310c "open-unlink remote file with multiple links"
22810
22811 #LU-4825
22812 test_311() {
22813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22814         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22815         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22816                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22817         remote_mds_nodsh && skip "remote MDS with nodsh"
22818
22819         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22820         local mdts=$(comma_list $(mdts_nodes))
22821
22822         mkdir -p $DIR/$tdir
22823         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22824         createmany -o $DIR/$tdir/$tfile. 1000
22825
22826         # statfs data is not real time, let's just calculate it
22827         old_iused=$((old_iused + 1000))
22828
22829         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22830                         osp.*OST0000*MDT0000.create_count")
22831         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22832                                 osp.*OST0000*MDT0000.max_create_count")
22833         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22834
22835         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22836         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22837         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22838
22839         unlinkmany $DIR/$tdir/$tfile. 1000
22840
22841         do_nodes $mdts "$LCTL set_param -n \
22842                         osp.*OST0000*.max_create_count=$max_count"
22843         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22844                 do_nodes $mdts "$LCTL set_param -n \
22845                                 osp.*OST0000*.create_count=$count"
22846         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22847                         grep "=0" && error "create_count is zero"
22848
22849         local new_iused
22850         for i in $(seq 120); do
22851                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22852                 # system may be too busy to destroy all objs in time, use
22853                 # a somewhat small value to not fail autotest
22854                 [ $((old_iused - new_iused)) -gt 400 ] && break
22855                 sleep 1
22856         done
22857
22858         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22859         [ $((old_iused - new_iused)) -gt 400 ] ||
22860                 error "objs not destroyed after unlink"
22861 }
22862 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22863
22864 zfs_oid_to_objid()
22865 {
22866         local ost=$1
22867         local objid=$2
22868
22869         local vdevdir=$(dirname $(facet_vdevice $ost))
22870         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22871         local zfs_zapid=$(do_facet $ost $cmd |
22872                           grep -w "/O/0/d$((objid%32))" -C 5 |
22873                           awk '/Object/{getline; print $1}')
22874         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22875                           awk "/$objid = /"'{printf $3}')
22876
22877         echo $zfs_objid
22878 }
22879
22880 zfs_object_blksz() {
22881         local ost=$1
22882         local objid=$2
22883
22884         local vdevdir=$(dirname $(facet_vdevice $ost))
22885         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22886         local blksz=$(do_facet $ost $cmd $objid |
22887                       awk '/dblk/{getline; printf $4}')
22888
22889         case "${blksz: -1}" in
22890                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22891                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22892                 *) ;;
22893         esac
22894
22895         echo $blksz
22896 }
22897
22898 test_312() { # LU-4856
22899         remote_ost_nodsh && skip "remote OST with nodsh"
22900         [ "$ost1_FSTYPE" = "zfs" ] ||
22901                 skip_env "the test only applies to zfs"
22902
22903         local max_blksz=$(do_facet ost1 \
22904                           $ZFS get -p recordsize $(facet_device ost1) |
22905                           awk '!/VALUE/{print $3}')
22906
22907         # to make life a little bit easier
22908         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22909         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22910
22911         local tf=$DIR/$tdir/$tfile
22912         touch $tf
22913         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22914
22915         # Get ZFS object id
22916         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22917         # block size change by sequential overwrite
22918         local bs
22919
22920         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22921                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22922
22923                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22924                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22925         done
22926         rm -f $tf
22927
22928         # block size change by sequential append write
22929         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22930         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22931         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22932         local count
22933
22934         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22935                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22936                         oflag=sync conv=notrunc
22937
22938                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22939                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22940                         error "blksz error, actual $blksz, " \
22941                                 "expected: 2 * $count * $PAGE_SIZE"
22942         done
22943         rm -f $tf
22944
22945         # random write
22946         touch $tf
22947         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22948         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22949
22950         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22951         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22952         [ $blksz -eq $PAGE_SIZE ] ||
22953                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22954
22955         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22956         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22957         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22958
22959         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22960         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22961         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22962 }
22963 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22964
22965 test_313() {
22966         remote_ost_nodsh && skip "remote OST with nodsh"
22967
22968         local file=$DIR/$tfile
22969
22970         rm -f $file
22971         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22972
22973         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22974         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22975         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22976                 error "write should failed"
22977         do_facet ost1 "$LCTL set_param fail_loc=0"
22978         rm -f $file
22979 }
22980 run_test 313 "io should fail after last_rcvd update fail"
22981
22982 test_314() {
22983         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22984
22985         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22986         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22987         rm -f $DIR/$tfile
22988         wait_delete_completed
22989         do_facet ost1 "$LCTL set_param fail_loc=0"
22990 }
22991 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22992
22993 test_315() { # LU-618
22994         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22995
22996         local file=$DIR/$tfile
22997         rm -f $file
22998
22999         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23000                 error "multiop file write failed"
23001         $MULTIOP $file oO_RDONLY:r4063232_c &
23002         PID=$!
23003
23004         sleep 2
23005
23006         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23007         kill -USR1 $PID
23008
23009         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23010         rm -f $file
23011 }
23012 run_test 315 "read should be accounted"
23013
23014 test_316() {
23015         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23016         large_xattr_enabled || skip_env "ea_inode feature disabled"
23017
23018         rm -rf $DIR/$tdir/d
23019         mkdir -p $DIR/$tdir/d
23020         chown nobody $DIR/$tdir/d
23021         touch $DIR/$tdir/d/file
23022
23023         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23024 }
23025 run_test 316 "lfs mv"
23026
23027 test_317() {
23028         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23029                 skip "Need MDS version at least 2.11.53"
23030         if [ "$ost1_FSTYPE" == "zfs" ]; then
23031                 skip "LU-10370: no implementation for ZFS"
23032         fi
23033
23034         local trunc_sz
23035         local grant_blk_size
23036
23037         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23038                         awk '/grant_block_size:/ { print $2; exit; }')
23039         #
23040         # Create File of size 5M. Truncate it to below size's and verify
23041         # blocks count.
23042         #
23043         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23044                 error "Create file $DIR/$tfile failed"
23045         stack_trap "rm -f $DIR/$tfile" EXIT
23046
23047         for trunc_sz in 2097152 4097 4000 509 0; do
23048                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23049                         error "truncate $tfile to $trunc_sz failed"
23050                 local sz=$(stat --format=%s $DIR/$tfile)
23051                 local blk=$(stat --format=%b $DIR/$tfile)
23052                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23053                                      grant_blk_size) * 8))
23054
23055                 if [[ $blk -ne $trunc_blk ]]; then
23056                         $(which stat) $DIR/$tfile
23057                         error "Expected Block $trunc_blk got $blk for $tfile"
23058                 fi
23059
23060                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23061                         error "Expected Size $trunc_sz got $sz for $tfile"
23062         done
23063
23064         #
23065         # sparse file test
23066         # Create file with a hole and write actual two blocks. Block count
23067         # must be 16.
23068         #
23069         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23070                 conv=fsync || error "Create file : $DIR/$tfile"
23071
23072         # Calculate the final truncate size.
23073         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23074
23075         #
23076         # truncate to size $trunc_sz bytes. Strip the last block
23077         # The block count must drop to 8
23078         #
23079         $TRUNCATE $DIR/$tfile $trunc_sz ||
23080                 error "truncate $tfile to $trunc_sz failed"
23081
23082         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23083         sz=$(stat --format=%s $DIR/$tfile)
23084         blk=$(stat --format=%b $DIR/$tfile)
23085
23086         if [[ $blk -ne $trunc_bsz ]]; then
23087                 $(which stat) $DIR/$tfile
23088                 error "Expected Block $trunc_bsz got $blk for $tfile"
23089         fi
23090
23091         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23092                 error "Expected Size $trunc_sz got $sz for $tfile"
23093 }
23094 run_test 317 "Verify blocks get correctly update after truncate"
23095
23096 test_318() {
23097         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23098         local old_max_active=$($LCTL get_param -n \
23099                             ${llite_name}.max_read_ahead_async_active \
23100                             2>/dev/null)
23101
23102         $LCTL set_param llite.*.max_read_ahead_async_active=256
23103         local max_active=$($LCTL get_param -n \
23104                            ${llite_name}.max_read_ahead_async_active \
23105                            2>/dev/null)
23106         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23107
23108         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23109                 error "set max_read_ahead_async_active should succeed"
23110
23111         $LCTL set_param llite.*.max_read_ahead_async_active=512
23112         max_active=$($LCTL get_param -n \
23113                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23114         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23115
23116         # restore @max_active
23117         [ $old_max_active -ne 0 ] && $LCTL set_param \
23118                 llite.*.max_read_ahead_async_active=$old_max_active
23119
23120         local old_threshold=$($LCTL get_param -n \
23121                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23122         local max_per_file_mb=$($LCTL get_param -n \
23123                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23124
23125         local invalid=$(($max_per_file_mb + 1))
23126         $LCTL set_param \
23127                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23128                         && error "set $invalid should fail"
23129
23130         local valid=$(($invalid - 1))
23131         $LCTL set_param \
23132                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23133                         error "set $valid should succeed"
23134         local threshold=$($LCTL get_param -n \
23135                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23136         [ $threshold -eq $valid ] || error \
23137                 "expect threshold $valid got $threshold"
23138         $LCTL set_param \
23139                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23140 }
23141 run_test 318 "Verify async readahead tunables"
23142
23143 test_319() {
23144         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23145
23146         local before=$(date +%s)
23147         local evict
23148         local mdir=$DIR/$tdir
23149         local file=$mdir/xxx
23150
23151         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23152         touch $file
23153
23154 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23155         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23156         $LFS mv -m1 $file &
23157
23158         sleep 1
23159         dd if=$file of=/dev/null
23160         wait
23161         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23162           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23163
23164         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23165 }
23166 run_test 319 "lost lease lock on migrate error"
23167
23168 test_398a() { # LU-4198
23169         local ost1_imp=$(get_osc_import_name client ost1)
23170         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23171                          cut -d'.' -f2)
23172
23173         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23174         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23175
23176         # request a new lock on client
23177         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23178
23179         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23180         local lock_count=$($LCTL get_param -n \
23181                            ldlm.namespaces.$imp_name.lru_size)
23182         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23183
23184         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23185
23186         # no lock cached, should use lockless IO and not enqueue new lock
23187         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23188         lock_count=$($LCTL get_param -n \
23189                      ldlm.namespaces.$imp_name.lru_size)
23190         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23191 }
23192 run_test 398a "direct IO should cancel lock otherwise lockless"
23193
23194 test_398b() { # LU-4198
23195         which fio || skip_env "no fio installed"
23196         $LFS setstripe -c -1 $DIR/$tfile
23197
23198         local size=12
23199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23200
23201         local njobs=4
23202         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23203         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23204                 --numjobs=$njobs --fallocate=none \
23205                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23206                 --filename=$DIR/$tfile &
23207         bg_pid=$!
23208
23209         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23210         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23211                 --numjobs=$njobs --fallocate=none \
23212                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23213                 --filename=$DIR/$tfile || true
23214         wait $bg_pid
23215
23216         rm -f $DIR/$tfile
23217 }
23218 run_test 398b "DIO and buffer IO race"
23219
23220 test_398c() { # LU-4198
23221         local ost1_imp=$(get_osc_import_name client ost1)
23222         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23223                          cut -d'.' -f2)
23224
23225         which fio || skip_env "no fio installed"
23226
23227         saved_debug=$($LCTL get_param -n debug)
23228         $LCTL set_param debug=0
23229
23230         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23231         ((size /= 1024)) # by megabytes
23232         ((size /= 2)) # write half of the OST at most
23233         [ $size -gt 40 ] && size=40 #reduce test time anyway
23234
23235         $LFS setstripe -c 1 $DIR/$tfile
23236
23237         # it seems like ldiskfs reserves more space than necessary if the
23238         # writing blocks are not mapped, so it extends the file firstly
23239         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23240         cancel_lru_locks osc
23241
23242         # clear and verify rpc_stats later
23243         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23244
23245         local njobs=4
23246         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23247         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23248                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23249                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23250                 --filename=$DIR/$tfile
23251         [ $? -eq 0 ] || error "fio write error"
23252
23253         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23254                 error "Locks were requested while doing AIO"
23255
23256         # get the percentage of 1-page I/O
23257         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23258                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23259                 awk '{print $7}')
23260         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23261
23262         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23263         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23264                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23265                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23266                 --filename=$DIR/$tfile
23267         [ $? -eq 0 ] || error "fio mixed read write error"
23268
23269         echo "AIO with large block size ${size}M"
23270         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23271                 --numjobs=1 --fallocate=none --ioengine=libaio \
23272                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23273                 --filename=$DIR/$tfile
23274         [ $? -eq 0 ] || error "fio large block size failed"
23275
23276         rm -f $DIR/$tfile
23277         $LCTL set_param debug="$saved_debug"
23278 }
23279 run_test 398c "run fio to test AIO"
23280
23281 test_398d() { #  LU-13846
23282         which aiocp || skip_env "no aiocp installed"
23283         local aio_file=$DIR/$tfile.aio
23284
23285         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23286
23287         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23288         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23289         stack_trap "rm -f $DIR/$tfile $aio_file"
23290
23291         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23292
23293         # make sure we don't crash and fail properly
23294         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23295                 error "aio not aligned with PAGE SIZE should fail"
23296
23297         rm -f $DIR/$tfile $aio_file
23298 }
23299 run_test 398d "run aiocp to verify block size > stripe size"
23300
23301 test_398e() {
23302         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23303         touch $DIR/$tfile.new
23304         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23305 }
23306 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23307
23308 test_398f() { #  LU-14687
23309         which aiocp || skip_env "no aiocp installed"
23310         local aio_file=$DIR/$tfile.aio
23311
23312         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23313
23314         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23315         stack_trap "rm -f $DIR/$tfile $aio_file"
23316
23317         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23318         $LCTL set_param fail_loc=0x1418
23319         # make sure we don't crash and fail properly
23320         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23321                 error "aio with page allocation failure succeeded"
23322         $LCTL set_param fail_loc=0
23323         diff $DIR/$tfile $aio_file
23324         [[ $? != 0 ]] || error "no diff after failed aiocp"
23325 }
23326 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23327
23328 test_fake_rw() {
23329         local read_write=$1
23330         if [ "$read_write" = "write" ]; then
23331                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23332         elif [ "$read_write" = "read" ]; then
23333                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23334         else
23335                 error "argument error"
23336         fi
23337
23338         # turn off debug for performance testing
23339         local saved_debug=$($LCTL get_param -n debug)
23340         $LCTL set_param debug=0
23341
23342         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23343
23344         # get ost1 size - $FSNAME-OST0000
23345         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23346         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23347         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23348
23349         if [ "$read_write" = "read" ]; then
23350                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23351         fi
23352
23353         local start_time=$(date +%s.%N)
23354         $dd_cmd bs=1M count=$blocks oflag=sync ||
23355                 error "real dd $read_write error"
23356         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23357
23358         if [ "$read_write" = "write" ]; then
23359                 rm -f $DIR/$tfile
23360         fi
23361
23362         # define OBD_FAIL_OST_FAKE_RW           0x238
23363         do_facet ost1 $LCTL set_param fail_loc=0x238
23364
23365         local start_time=$(date +%s.%N)
23366         $dd_cmd bs=1M count=$blocks oflag=sync ||
23367                 error "fake dd $read_write error"
23368         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23369
23370         if [ "$read_write" = "write" ]; then
23371                 # verify file size
23372                 cancel_lru_locks osc
23373                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23374                         error "$tfile size not $blocks MB"
23375         fi
23376         do_facet ost1 $LCTL set_param fail_loc=0
23377
23378         echo "fake $read_write $duration_fake vs. normal $read_write" \
23379                 "$duration in seconds"
23380         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23381                 error_not_in_vm "fake write is slower"
23382
23383         $LCTL set_param -n debug="$saved_debug"
23384         rm -f $DIR/$tfile
23385 }
23386 test_399a() { # LU-7655 for OST fake write
23387         remote_ost_nodsh && skip "remote OST with nodsh"
23388
23389         test_fake_rw write
23390 }
23391 run_test 399a "fake write should not be slower than normal write"
23392
23393 test_399b() { # LU-8726 for OST fake read
23394         remote_ost_nodsh && skip "remote OST with nodsh"
23395         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23396                 skip_env "ldiskfs only test"
23397         fi
23398
23399         test_fake_rw read
23400 }
23401 run_test 399b "fake read should not be slower than normal read"
23402
23403 test_400a() { # LU-1606, was conf-sanity test_74
23404         if ! which $CC > /dev/null 2>&1; then
23405                 skip_env "$CC is not installed"
23406         fi
23407
23408         local extra_flags=''
23409         local out=$TMP/$tfile
23410         local prefix=/usr/include/lustre
23411         local prog
23412
23413         # Oleg removes c files in his test rig so test if any c files exist
23414         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23415                 skip_env "Needed c test files are missing"
23416
23417         if ! [[ -d $prefix ]]; then
23418                 # Assume we're running in tree and fixup the include path.
23419                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23420                 extra_flags+=" -L$LUSTRE/utils/.lib"
23421         fi
23422
23423         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23424                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23425                         error "client api broken"
23426         done
23427         rm -f $out
23428 }
23429 run_test 400a "Lustre client api program can compile and link"
23430
23431 test_400b() { # LU-1606, LU-5011
23432         local header
23433         local out=$TMP/$tfile
23434         local prefix=/usr/include/linux/lustre
23435
23436         # We use a hard coded prefix so that this test will not fail
23437         # when run in tree. There are headers in lustre/include/lustre/
23438         # that are not packaged (like lustre_idl.h) and have more
23439         # complicated include dependencies (like config.h and lnet/types.h).
23440         # Since this test about correct packaging we just skip them when
23441         # they don't exist (see below) rather than try to fixup cppflags.
23442
23443         if ! which $CC > /dev/null 2>&1; then
23444                 skip_env "$CC is not installed"
23445         fi
23446
23447         for header in $prefix/*.h; do
23448                 if ! [[ -f "$header" ]]; then
23449                         continue
23450                 fi
23451
23452                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23453                         continue # lustre_ioctl.h is internal header
23454                 fi
23455
23456                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23457                         error "cannot compile '$header'"
23458         done
23459         rm -f $out
23460 }
23461 run_test 400b "packaged headers can be compiled"
23462
23463 test_401a() { #LU-7437
23464         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23465         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23466
23467         #count the number of parameters by "list_param -R"
23468         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23469         #count the number of parameters by listing proc files
23470         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23471         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23472         echo "proc_dirs='$proc_dirs'"
23473         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23474         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23475                       sort -u | wc -l)
23476
23477         [ $params -eq $procs ] ||
23478                 error "found $params parameters vs. $procs proc files"
23479
23480         # test the list_param -D option only returns directories
23481         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23482         #count the number of parameters by listing proc directories
23483         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23484                 sort -u | wc -l)
23485
23486         [ $params -eq $procs ] ||
23487                 error "found $params parameters vs. $procs proc files"
23488 }
23489 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23490
23491 test_401b() {
23492         # jobid_var may not allow arbitrary values, so use jobid_name
23493         # if available
23494         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23495                 local testname=jobid_name tmp='testing%p'
23496         else
23497                 local testname=jobid_var tmp=testing
23498         fi
23499
23500         local save=$($LCTL get_param -n $testname)
23501
23502         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23503                 error "no error returned when setting bad parameters"
23504
23505         local jobid_new=$($LCTL get_param -n foe $testname baz)
23506         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23507
23508         $LCTL set_param -n fog=bam $testname=$save bat=fog
23509         local jobid_old=$($LCTL get_param -n foe $testname bag)
23510         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23511 }
23512 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23513
23514 test_401c() {
23515         # jobid_var may not allow arbitrary values, so use jobid_name
23516         # if available
23517         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23518                 local testname=jobid_name
23519         else
23520                 local testname=jobid_var
23521         fi
23522
23523         local jobid_var_old=$($LCTL get_param -n $testname)
23524         local jobid_var_new
23525
23526         $LCTL set_param $testname= &&
23527                 error "no error returned for 'set_param a='"
23528
23529         jobid_var_new=$($LCTL get_param -n $testname)
23530         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23531                 error "$testname was changed by setting without value"
23532
23533         $LCTL set_param $testname &&
23534                 error "no error returned for 'set_param a'"
23535
23536         jobid_var_new=$($LCTL get_param -n $testname)
23537         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23538                 error "$testname was changed by setting without value"
23539 }
23540 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23541
23542 test_401d() {
23543         # jobid_var may not allow arbitrary values, so use jobid_name
23544         # if available
23545         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23546                 local testname=jobid_name new_value='foo=bar%p'
23547         else
23548                 local testname=jobid_var new_valuie=foo=bar
23549         fi
23550
23551         local jobid_var_old=$($LCTL get_param -n $testname)
23552         local jobid_var_new
23553
23554         $LCTL set_param $testname=$new_value ||
23555                 error "'set_param a=b' did not accept a value containing '='"
23556
23557         jobid_var_new=$($LCTL get_param -n $testname)
23558         [[ "$jobid_var_new" == "$new_value" ]] ||
23559                 error "'set_param a=b' failed on a value containing '='"
23560
23561         # Reset the $testname to test the other format
23562         $LCTL set_param $testname=$jobid_var_old
23563         jobid_var_new=$($LCTL get_param -n $testname)
23564         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23565                 error "failed to reset $testname"
23566
23567         $LCTL set_param $testname $new_value ||
23568                 error "'set_param a b' did not accept a value containing '='"
23569
23570         jobid_var_new=$($LCTL get_param -n $testname)
23571         [[ "$jobid_var_new" == "$new_value" ]] ||
23572                 error "'set_param a b' failed on a value containing '='"
23573
23574         $LCTL set_param $testname $jobid_var_old
23575         jobid_var_new=$($LCTL get_param -n $testname)
23576         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23577                 error "failed to reset $testname"
23578 }
23579 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23580
23581 test_402() {
23582         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23583         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23584                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23585         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23586                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23587                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23588         remote_mds_nodsh && skip "remote MDS with nodsh"
23589
23590         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23591 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23592         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23593         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23594                 echo "Touch failed - OK"
23595 }
23596 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23597
23598 test_403() {
23599         local file1=$DIR/$tfile.1
23600         local file2=$DIR/$tfile.2
23601         local tfile=$TMP/$tfile
23602
23603         rm -f $file1 $file2 $tfile
23604
23605         touch $file1
23606         ln $file1 $file2
23607
23608         # 30 sec OBD_TIMEOUT in ll_getattr()
23609         # right before populating st_nlink
23610         $LCTL set_param fail_loc=0x80001409
23611         stat -c %h $file1 > $tfile &
23612
23613         # create an alias, drop all locks and reclaim the dentry
23614         < $file2
23615         cancel_lru_locks mdc
23616         cancel_lru_locks osc
23617         sysctl -w vm.drop_caches=2
23618
23619         wait
23620
23621         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23622
23623         rm -f $tfile $file1 $file2
23624 }
23625 run_test 403 "i_nlink should not drop to zero due to aliasing"
23626
23627 test_404() { # LU-6601
23628         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23629                 skip "Need server version newer than 2.8.52"
23630         remote_mds_nodsh && skip "remote MDS with nodsh"
23631
23632         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23633                 awk '/osp .*-osc-MDT/ { print $4}')
23634
23635         local osp
23636         for osp in $mosps; do
23637                 echo "Deactivate: " $osp
23638                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23639                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23640                         awk -vp=$osp '$4 == p { print $2 }')
23641                 [ $stat = IN ] || {
23642                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23643                         error "deactivate error"
23644                 }
23645                 echo "Activate: " $osp
23646                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23647                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23648                         awk -vp=$osp '$4 == p { print $2 }')
23649                 [ $stat = UP ] || {
23650                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23651                         error "activate error"
23652                 }
23653         done
23654 }
23655 run_test 404 "validate manual {de}activated works properly for OSPs"
23656
23657 test_405() {
23658         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23659         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23660                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23661                         skip "Layout swap lock is not supported"
23662
23663         check_swap_layouts_support
23664         check_swap_layout_no_dom $DIR
23665
23666         test_mkdir $DIR/$tdir
23667         swap_lock_test -d $DIR/$tdir ||
23668                 error "One layout swap locked test failed"
23669 }
23670 run_test 405 "Various layout swap lock tests"
23671
23672 test_406() {
23673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23674         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23675         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23677         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23678                 skip "Need MDS version at least 2.8.50"
23679
23680         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23681         local test_pool=$TESTNAME
23682
23683         pool_add $test_pool || error "pool_add failed"
23684         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23685                 error "pool_add_targets failed"
23686
23687         save_layout_restore_at_exit $MOUNT
23688
23689         # parent set default stripe count only, child will stripe from both
23690         # parent and fs default
23691         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23692                 error "setstripe $MOUNT failed"
23693         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23694         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23695         for i in $(seq 10); do
23696                 local f=$DIR/$tdir/$tfile.$i
23697                 touch $f || error "touch failed"
23698                 local count=$($LFS getstripe -c $f)
23699                 [ $count -eq $OSTCOUNT ] ||
23700                         error "$f stripe count $count != $OSTCOUNT"
23701                 local offset=$($LFS getstripe -i $f)
23702                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23703                 local size=$($LFS getstripe -S $f)
23704                 [ $size -eq $((def_stripe_size * 2)) ] ||
23705                         error "$f stripe size $size != $((def_stripe_size * 2))"
23706                 local pool=$($LFS getstripe -p $f)
23707                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23708         done
23709
23710         # change fs default striping, delete parent default striping, now child
23711         # will stripe from new fs default striping only
23712         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23713                 error "change $MOUNT default stripe failed"
23714         $LFS setstripe -c 0 $DIR/$tdir ||
23715                 error "delete $tdir default stripe failed"
23716         for i in $(seq 11 20); do
23717                 local f=$DIR/$tdir/$tfile.$i
23718                 touch $f || error "touch $f failed"
23719                 local count=$($LFS getstripe -c $f)
23720                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23721                 local offset=$($LFS getstripe -i $f)
23722                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23723                 local size=$($LFS getstripe -S $f)
23724                 [ $size -eq $def_stripe_size ] ||
23725                         error "$f stripe size $size != $def_stripe_size"
23726                 local pool=$($LFS getstripe -p $f)
23727                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23728         done
23729
23730         unlinkmany $DIR/$tdir/$tfile. 1 20
23731
23732         local f=$DIR/$tdir/$tfile
23733         pool_remove_all_targets $test_pool $f
23734         pool_remove $test_pool $f
23735 }
23736 run_test 406 "DNE support fs default striping"
23737
23738 test_407() {
23739         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23740         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23741                 skip "Need MDS version at least 2.8.55"
23742         remote_mds_nodsh && skip "remote MDS with nodsh"
23743
23744         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23745                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23746         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23747                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23748         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23749
23750         #define OBD_FAIL_DT_TXN_STOP    0x2019
23751         for idx in $(seq $MDSCOUNT); do
23752                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23753         done
23754         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23755         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23756                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23757         true
23758 }
23759 run_test 407 "transaction fail should cause operation fail"
23760
23761 test_408() {
23762         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23763
23764         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23765         lctl set_param fail_loc=0x8000040a
23766         # let ll_prepare_partial_page() fail
23767         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23768
23769         rm -f $DIR/$tfile
23770
23771         # create at least 100 unused inodes so that
23772         # shrink_icache_memory(0) should not return 0
23773         touch $DIR/$tfile-{0..100}
23774         rm -f $DIR/$tfile-{0..100}
23775         sync
23776
23777         echo 2 > /proc/sys/vm/drop_caches
23778 }
23779 run_test 408 "drop_caches should not hang due to page leaks"
23780
23781 test_409()
23782 {
23783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23784
23785         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23786         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23787         touch $DIR/$tdir/guard || error "(2) Fail to create"
23788
23789         local PREFIX=$(str_repeat 'A' 128)
23790         echo "Create 1K hard links start at $(date)"
23791         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23792                 error "(3) Fail to hard link"
23793
23794         echo "Links count should be right although linkEA overflow"
23795         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23796         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23797         [ $linkcount -eq 1001 ] ||
23798                 error "(5) Unexpected hard links count: $linkcount"
23799
23800         echo "List all links start at $(date)"
23801         ls -l $DIR/$tdir/foo > /dev/null ||
23802                 error "(6) Fail to list $DIR/$tdir/foo"
23803
23804         echo "Unlink hard links start at $(date)"
23805         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23806                 error "(7) Fail to unlink"
23807         echo "Unlink hard links finished at $(date)"
23808 }
23809 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23810
23811 test_410()
23812 {
23813         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23814                 skip "Need client version at least 2.9.59"
23815         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23816                 skip "Need MODULES build"
23817
23818         # Create a file, and stat it from the kernel
23819         local testfile=$DIR/$tfile
23820         touch $testfile
23821
23822         local run_id=$RANDOM
23823         local my_ino=$(stat --format "%i" $testfile)
23824
23825         # Try to insert the module. This will always fail as the
23826         # module is designed to not be inserted.
23827         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23828             &> /dev/null
23829
23830         # Anything but success is a test failure
23831         dmesg | grep -q \
23832             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23833             error "no inode match"
23834 }
23835 run_test 410 "Test inode number returned from kernel thread"
23836
23837 cleanup_test411_cgroup() {
23838         trap 0
23839         rmdir "$1"
23840 }
23841
23842 test_411() {
23843         local cg_basedir=/sys/fs/cgroup/memory
23844         # LU-9966
23845         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23846                 skip "no setup for cgroup"
23847
23848         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23849                 error "test file creation failed"
23850         cancel_lru_locks osc
23851
23852         # Create a very small memory cgroup to force a slab allocation error
23853         local cgdir=$cg_basedir/osc_slab_alloc
23854         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23855         trap "cleanup_test411_cgroup $cgdir" EXIT
23856         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23857         echo 1M > $cgdir/memory.limit_in_bytes
23858
23859         # Should not LBUG, just be killed by oom-killer
23860         # dd will return 0 even allocation failure in some environment.
23861         # So don't check return value
23862         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23863         cleanup_test411_cgroup $cgdir
23864
23865         return 0
23866 }
23867 run_test 411 "Slab allocation error with cgroup does not LBUG"
23868
23869 test_412() {
23870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23871         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23872                 skip "Need server version at least 2.10.55"
23873         fi
23874
23875         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23876                 error "mkdir failed"
23877         $LFS getdirstripe $DIR/$tdir
23878         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23879         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23880                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23881         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23882         [ $stripe_count -eq 2 ] ||
23883                 error "expect 2 get $stripe_count"
23884 }
23885 run_test 412 "mkdir on specific MDTs"
23886
23887 test_qos_mkdir() {
23888         local mkdir_cmd=$1
23889         local stripe_count=$2
23890         local mdts=$(comma_list $(mdts_nodes))
23891
23892         local testdir
23893         local lmv_qos_prio_free
23894         local lmv_qos_threshold_rr
23895         local lmv_qos_maxage
23896         local lod_qos_prio_free
23897         local lod_qos_threshold_rr
23898         local lod_qos_maxage
23899         local count
23900         local i
23901
23902         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23903         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23904         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23905                 head -n1)
23906         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23907         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23908         stack_trap "$LCTL set_param \
23909                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23910         stack_trap "$LCTL set_param \
23911                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23912         stack_trap "$LCTL set_param \
23913                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23914
23915         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23916                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23917         lod_qos_prio_free=${lod_qos_prio_free%%%}
23918         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23919                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23920         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23921         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23922                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23923         stack_trap "do_nodes $mdts $LCTL set_param \
23924                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23925         stack_trap "do_nodes $mdts $LCTL set_param \
23926                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23927                 EXIT
23928         stack_trap "do_nodes $mdts $LCTL set_param \
23929                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23930
23931         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23932         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23933
23934         testdir=$DIR/$tdir-s$stripe_count/rr
23935
23936         local stripe_index=$($LFS getstripe -m $testdir)
23937         local test_mkdir_rr=true
23938
23939         getfattr -d -m dmv $testdir | grep dmv
23940         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
23941                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
23942
23943                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
23944         fi
23945
23946         echo
23947         $test_mkdir_rr &&
23948                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
23949                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
23950
23951         for i in $(seq $((100 * MDSCOUNT))); do
23952                 eval $mkdir_cmd $testdir/subdir$i ||
23953                         error "$mkdir_cmd subdir$i failed"
23954         done
23955
23956         for i in $(seq $MDSCOUNT); do
23957                 count=$($LFS getdirstripe -i $testdir/* |
23958                                 grep ^$((i - 1))$ | wc -l)
23959                 echo "$count directories created on MDT$((i - 1))"
23960                 if $test_mkdir_rr; then
23961                         (( $count == 100 )) ||
23962                                 error "subdirs are not evenly distributed"
23963                 elif [ $((i - 1)) -eq $stripe_index ]; then
23964                         (( $count == 100 * MDSCOUNT )) ||
23965                                 error "$count subdirs created on MDT$((i - 1))"
23966                 else
23967                         (( $count == 0 )) ||
23968                                 error "$count subdirs created on MDT$((i - 1))"
23969                 fi
23970
23971                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
23972                         count=$($LFS getdirstripe $testdir/* |
23973                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23974                         echo "$count stripes created on MDT$((i - 1))"
23975                         # deviation should < 5% of average
23976                         (( $count < 95 * stripe_count )) ||
23977                         (( $count > 105 * stripe_count)) &&
23978                                 error "stripes are not evenly distributed"
23979                 fi
23980         done
23981
23982         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23983         do_nodes $mdts $LCTL set_param \
23984                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23985
23986         echo
23987         echo "Check for uneven MDTs: "
23988
23989         local ffree
23990         local bavail
23991         local max
23992         local min
23993         local max_index
23994         local min_index
23995         local tmp
23996
23997         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23998         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23999         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24000
24001         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24002         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24003         max_index=0
24004         min_index=0
24005         for ((i = 1; i < ${#ffree[@]}; i++)); do
24006                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24007                 if [ $tmp -gt $max ]; then
24008                         max=$tmp
24009                         max_index=$i
24010                 fi
24011                 if [ $tmp -lt $min ]; then
24012                         min=$tmp
24013                         min_index=$i
24014                 fi
24015         done
24016
24017         (( ${ffree[min_index]} == 0 )) &&
24018                 skip "no free files in MDT$min_index"
24019         (( ${ffree[min_index]} > 100000000 )) &&
24020                 skip "too many free files in MDT$min_index"
24021
24022         # Check if we need to generate uneven MDTs
24023         local threshold=50
24024         local diff=$(((max - min) * 100 / min))
24025         local value="$(generate_string 1024)"
24026
24027         while [ $diff -lt $threshold ]; do
24028                 # generate uneven MDTs, create till $threshold% diff
24029                 echo -n "weight diff=$diff% must be > $threshold% ..."
24030                 count=$((${ffree[min_index]} / 10))
24031                 # 50 sec per 10000 files in vm
24032                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24033                         skip "$count files to create"
24034                 echo "Fill MDT$min_index with $count files"
24035                 [ -d $DIR/$tdir-MDT$min_index ] ||
24036                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24037                         error "mkdir $tdir-MDT$min_index failed"
24038                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24039                         error "create d$count failed"
24040
24041                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24042                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24043                 max=$(((${ffree[max_index]} >> 8) * \
24044                         (${bavail[max_index]} * bsize >> 16)))
24045                 min=$(((${ffree[min_index]} >> 8) * \
24046                         (${bavail[min_index]} * bsize >> 16)))
24047                 diff=$(((max - min) * 100 / min))
24048         done
24049
24050         echo "MDT filesfree available: ${ffree[@]}"
24051         echo "MDT blocks available: ${bavail[@]}"
24052         echo "weight diff=$diff%"
24053
24054         echo
24055         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24056
24057         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24058         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24059         # decrease statfs age, so that it can be updated in time
24060         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24061         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24062
24063         sleep 1
24064
24065         testdir=$DIR/$tdir-s$stripe_count/qos
24066
24067         for i in $(seq $((100 * MDSCOUNT))); do
24068                 eval $mkdir_cmd $testdir/subdir$i ||
24069                         error "$mkdir_cmd subdir$i failed"
24070         done
24071
24072         for i in $(seq $MDSCOUNT); do
24073                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24074                         wc -l)
24075                 echo "$count directories created on MDT$((i - 1))"
24076
24077                 if [ $stripe_count -gt 1 ]; then
24078                         count=$($LFS getdirstripe $testdir/* |
24079                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24080                         echo "$count stripes created on MDT$((i - 1))"
24081                 fi
24082         done
24083
24084         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24085         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24086
24087         # D-value should > 10% of averge
24088         (( $max - $min < 10 )) &&
24089                 error "subdirs shouldn't be evenly distributed"
24090
24091         # ditto
24092         if [ $stripe_count -gt 1 ]; then
24093                 max=$($LFS getdirstripe $testdir/* |
24094                         grep -P "^\s+$max_index\t" | wc -l)
24095                 min=$($LFS getdirstripe $testdir/* |
24096                         grep -P "^\s+$min_index\t" | wc -l)
24097                 (( $max - $min < 10 * $stripe_count )) &&
24098                         error "stripes shouldn't be evenly distributed"|| true
24099         fi
24100 }
24101
24102 test_413a() {
24103         [ $MDSCOUNT -lt 2 ] &&
24104                 skip "We need at least 2 MDTs for this test"
24105
24106         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24107                 skip "Need server version at least 2.12.52"
24108
24109         local stripe_count
24110
24111         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24112                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24113                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24114                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24115                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24116         done
24117 }
24118 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24119
24120 test_413b() {
24121         [ $MDSCOUNT -lt 2 ] &&
24122                 skip "We need at least 2 MDTs for this test"
24123
24124         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24125                 skip "Need server version at least 2.12.52"
24126
24127         local testdir
24128         local stripe_count
24129
24130         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24131                 testdir=$DIR/$tdir-s$stripe_count
24132                 mkdir $testdir || error "mkdir $testdir failed"
24133                 mkdir $testdir/rr || error "mkdir rr failed"
24134                 mkdir $testdir/qos || error "mkdir qos failed"
24135                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24136                         $testdir/rr || error "setdirstripe rr failed"
24137                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24138                         error "setdirstripe failed"
24139                 test_qos_mkdir "mkdir" $stripe_count
24140         done
24141 }
24142 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24143
24144 test_413c() {
24145         [ $MDSCOUNT -ge 2 ] ||
24146                 skip "We need at least 2 MDTs for this test"
24147
24148         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24149                 skip "Need server version at least 2.14.50"
24150
24151         local testdir
24152         local inherit
24153         local inherit_rr
24154
24155         testdir=$DIR/${tdir}-s1
24156         mkdir $testdir || error "mkdir $testdir failed"
24157         mkdir $testdir/rr || error "mkdir rr failed"
24158         mkdir $testdir/qos || error "mkdir qos failed"
24159         # default max_inherit is -1, default max_inherit_rr is 0
24160         $LFS setdirstripe -D -c 1 $testdir/rr ||
24161                 error "setdirstripe rr failed"
24162         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24163                 error "setdirstripe qos failed"
24164         test_qos_mkdir "mkdir" 1
24165
24166         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24167         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24168         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24169         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24170         (( $inherit_rr == 0 )) ||
24171                 error "rr/level1 inherit-rr $inherit_rr != 0"
24172
24173         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24174         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24175         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24176         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24177         (( $inherit_rr == 0 )) ||
24178                 error "qos/level1 inherit-rr $inherit_rr !=0"
24179         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24180         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24181                 error "level2 shouldn't have default LMV" || true
24182 }
24183 run_test 413c "mkdir with default LMV max inherit rr"
24184
24185 test_414() {
24186 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24187         $LCTL set_param fail_loc=0x80000521
24188         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24189         rm -f $DIR/$tfile
24190 }
24191 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24192
24193 test_415() {
24194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24195         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24196                 skip "Need server version at least 2.11.52"
24197
24198         # LU-11102
24199         local total
24200         local setattr_pid
24201         local start_time
24202         local end_time
24203         local duration
24204
24205         total=500
24206         # this test may be slow on ZFS
24207         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24208
24209         # though this test is designed for striped directory, let's test normal
24210         # directory too since lock is always saved as CoS lock.
24211         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24212         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24213
24214         (
24215                 while true; do
24216                         touch $DIR/$tdir
24217                 done
24218         ) &
24219         setattr_pid=$!
24220
24221         start_time=$(date +%s)
24222         for i in $(seq $total); do
24223                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24224                         > /dev/null
24225         done
24226         end_time=$(date +%s)
24227         duration=$((end_time - start_time))
24228
24229         kill -9 $setattr_pid
24230
24231         echo "rename $total files took $duration sec"
24232         [ $duration -lt 100 ] || error "rename took $duration sec"
24233 }
24234 run_test 415 "lock revoke is not missing"
24235
24236 test_416() {
24237         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24238                 skip "Need server version at least 2.11.55"
24239
24240         # define OBD_FAIL_OSD_TXN_START    0x19a
24241         do_facet mds1 lctl set_param fail_loc=0x19a
24242
24243         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24244
24245         true
24246 }
24247 run_test 416 "transaction start failure won't cause system hung"
24248
24249 cleanup_417() {
24250         trap 0
24251         do_nodes $(comma_list $(mdts_nodes)) \
24252                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24253         do_nodes $(comma_list $(mdts_nodes)) \
24254                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24255         do_nodes $(comma_list $(mdts_nodes)) \
24256                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24257 }
24258
24259 test_417() {
24260         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24261         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24262                 skip "Need MDS version at least 2.11.56"
24263
24264         trap cleanup_417 RETURN EXIT
24265
24266         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24267         do_nodes $(comma_list $(mdts_nodes)) \
24268                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24269         $LFS migrate -m 0 $DIR/$tdir.1 &&
24270                 error "migrate dir $tdir.1 should fail"
24271
24272         do_nodes $(comma_list $(mdts_nodes)) \
24273                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24274         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24275                 error "create remote dir $tdir.2 should fail"
24276
24277         do_nodes $(comma_list $(mdts_nodes)) \
24278                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24279         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24280                 error "create striped dir $tdir.3 should fail"
24281         true
24282 }
24283 run_test 417 "disable remote dir, striped dir and dir migration"
24284
24285 # Checks that the outputs of df [-i] and lfs df [-i] match
24286 #
24287 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24288 check_lfs_df() {
24289         local dir=$2
24290         local inodes
24291         local df_out
24292         local lfs_df_out
24293         local count
24294         local passed=false
24295
24296         # blocks or inodes
24297         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24298
24299         for count in {1..100}; do
24300                 cancel_lru_locks
24301                 sync; sleep 0.2
24302
24303                 # read the lines of interest
24304                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24305                         error "df $inodes $dir | tail -n +2 failed"
24306                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24307                         error "lfs df $inodes $dir | grep summary: failed"
24308
24309                 # skip first substrings of each output as they are different
24310                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24311                 # compare the two outputs
24312                 passed=true
24313                 for i in {1..5}; do
24314                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24315                 done
24316                 $passed && break
24317         done
24318
24319         if ! $passed; then
24320                 df -P $inodes $dir
24321                 echo
24322                 lfs df $inodes $dir
24323                 error "df and lfs df $1 output mismatch: "      \
24324                       "df ${inodes}: ${df_out[*]}, "            \
24325                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24326         fi
24327 }
24328
24329 test_418() {
24330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24331
24332         local dir=$DIR/$tdir
24333         local numfiles=$((RANDOM % 4096 + 2))
24334         local numblocks=$((RANDOM % 256 + 1))
24335
24336         wait_delete_completed
24337         test_mkdir $dir
24338
24339         # check block output
24340         check_lfs_df blocks $dir
24341         # check inode output
24342         check_lfs_df inodes $dir
24343
24344         # create a single file and retest
24345         echo "Creating a single file and testing"
24346         createmany -o $dir/$tfile- 1 &>/dev/null ||
24347                 error "creating 1 file in $dir failed"
24348         check_lfs_df blocks $dir
24349         check_lfs_df inodes $dir
24350
24351         # create a random number of files
24352         echo "Creating $((numfiles - 1)) files and testing"
24353         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24354                 error "creating $((numfiles - 1)) files in $dir failed"
24355
24356         # write a random number of blocks to the first test file
24357         echo "Writing $numblocks 4K blocks and testing"
24358         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24359                 count=$numblocks &>/dev/null ||
24360                 error "dd to $dir/${tfile}-0 failed"
24361
24362         # retest
24363         check_lfs_df blocks $dir
24364         check_lfs_df inodes $dir
24365
24366         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24367                 error "unlinking $numfiles files in $dir failed"
24368 }
24369 run_test 418 "df and lfs df outputs match"
24370
24371 test_419()
24372 {
24373         local dir=$DIR/$tdir
24374
24375         mkdir -p $dir
24376         touch $dir/file
24377
24378         cancel_lru_locks mdc
24379
24380         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24381         $LCTL set_param fail_loc=0x1410
24382         cat $dir/file
24383         $LCTL set_param fail_loc=0
24384         rm -rf $dir
24385 }
24386 run_test 419 "Verify open file by name doesn't crash kernel"
24387
24388 test_420()
24389 {
24390         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24391                 skip "Need MDS version at least 2.12.53"
24392
24393         local SAVE_UMASK=$(umask)
24394         local dir=$DIR/$tdir
24395         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24396
24397         mkdir -p $dir
24398         umask 0000
24399         mkdir -m03777 $dir/testdir
24400         ls -dn $dir/testdir
24401         # Need to remove trailing '.' when SELinux is enabled
24402         local dirperms=$(ls -dn $dir/testdir |
24403                          awk '{ sub(/\.$/, "", $1); print $1}')
24404         [ $dirperms == "drwxrwsrwt" ] ||
24405                 error "incorrect perms on $dir/testdir"
24406
24407         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24408                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24409         ls -n $dir/testdir/testfile
24410         local fileperms=$(ls -n $dir/testdir/testfile |
24411                           awk '{ sub(/\.$/, "", $1); print $1}')
24412         [ $fileperms == "-rwxr-xr-x" ] ||
24413                 error "incorrect perms on $dir/testdir/testfile"
24414
24415         umask $SAVE_UMASK
24416 }
24417 run_test 420 "clear SGID bit on non-directories for non-members"
24418
24419 test_421a() {
24420         local cnt
24421         local fid1
24422         local fid2
24423
24424         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24425                 skip "Need MDS version at least 2.12.54"
24426
24427         test_mkdir $DIR/$tdir
24428         createmany -o $DIR/$tdir/f 3
24429         cnt=$(ls -1 $DIR/$tdir | wc -l)
24430         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24431
24432         fid1=$(lfs path2fid $DIR/$tdir/f1)
24433         fid2=$(lfs path2fid $DIR/$tdir/f2)
24434         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24435
24436         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24437         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24438
24439         cnt=$(ls -1 $DIR/$tdir | wc -l)
24440         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24441
24442         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24443         createmany -o $DIR/$tdir/f 3
24444         cnt=$(ls -1 $DIR/$tdir | wc -l)
24445         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24446
24447         fid1=$(lfs path2fid $DIR/$tdir/f1)
24448         fid2=$(lfs path2fid $DIR/$tdir/f2)
24449         echo "remove using fsname $FSNAME"
24450         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24451
24452         cnt=$(ls -1 $DIR/$tdir | wc -l)
24453         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24454 }
24455 run_test 421a "simple rm by fid"
24456
24457 test_421b() {
24458         local cnt
24459         local FID1
24460         local FID2
24461
24462         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24463                 skip "Need MDS version at least 2.12.54"
24464
24465         test_mkdir $DIR/$tdir
24466         createmany -o $DIR/$tdir/f 3
24467         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24468         MULTIPID=$!
24469
24470         FID1=$(lfs path2fid $DIR/$tdir/f1)
24471         FID2=$(lfs path2fid $DIR/$tdir/f2)
24472         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24473
24474         kill -USR1 $MULTIPID
24475         wait
24476
24477         cnt=$(ls $DIR/$tdir | wc -l)
24478         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24479 }
24480 run_test 421b "rm by fid on open file"
24481
24482 test_421c() {
24483         local cnt
24484         local FIDS
24485
24486         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24487                 skip "Need MDS version at least 2.12.54"
24488
24489         test_mkdir $DIR/$tdir
24490         createmany -o $DIR/$tdir/f 3
24491         touch $DIR/$tdir/$tfile
24492         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24493         cnt=$(ls -1 $DIR/$tdir | wc -l)
24494         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24495
24496         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24497         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24498
24499         cnt=$(ls $DIR/$tdir | wc -l)
24500         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24501 }
24502 run_test 421c "rm by fid against hardlinked files"
24503
24504 test_421d() {
24505         local cnt
24506         local FIDS
24507
24508         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24509                 skip "Need MDS version at least 2.12.54"
24510
24511         test_mkdir $DIR/$tdir
24512         createmany -o $DIR/$tdir/f 4097
24513         cnt=$(ls -1 $DIR/$tdir | wc -l)
24514         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24515
24516         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24517         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24518
24519         cnt=$(ls $DIR/$tdir | wc -l)
24520         rm -rf $DIR/$tdir
24521         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24522 }
24523 run_test 421d "rmfid en masse"
24524
24525 test_421e() {
24526         local cnt
24527         local FID
24528
24529         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24530         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24531                 skip "Need MDS version at least 2.12.54"
24532
24533         mkdir -p $DIR/$tdir
24534         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24535         createmany -o $DIR/$tdir/striped_dir/f 512
24536         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24537         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24538
24539         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24540                 sed "s/[/][^:]*://g")
24541         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24542
24543         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24544         rm -rf $DIR/$tdir
24545         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24546 }
24547 run_test 421e "rmfid in DNE"
24548
24549 test_421f() {
24550         local cnt
24551         local FID
24552
24553         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24554                 skip "Need MDS version at least 2.12.54"
24555
24556         test_mkdir $DIR/$tdir
24557         touch $DIR/$tdir/f
24558         cnt=$(ls -1 $DIR/$tdir | wc -l)
24559         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24560
24561         FID=$(lfs path2fid $DIR/$tdir/f)
24562         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24563         # rmfid should fail
24564         cnt=$(ls -1 $DIR/$tdir | wc -l)
24565         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24566
24567         chmod a+rw $DIR/$tdir
24568         ls -la $DIR/$tdir
24569         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24570         # rmfid should fail
24571         cnt=$(ls -1 $DIR/$tdir | wc -l)
24572         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24573
24574         rm -f $DIR/$tdir/f
24575         $RUNAS touch $DIR/$tdir/f
24576         FID=$(lfs path2fid $DIR/$tdir/f)
24577         echo "rmfid as root"
24578         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24579         cnt=$(ls -1 $DIR/$tdir | wc -l)
24580         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24581
24582         rm -f $DIR/$tdir/f
24583         $RUNAS touch $DIR/$tdir/f
24584         cnt=$(ls -1 $DIR/$tdir | wc -l)
24585         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24586         FID=$(lfs path2fid $DIR/$tdir/f)
24587         # rmfid w/o user_fid2path mount option should fail
24588         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24589         cnt=$(ls -1 $DIR/$tdir | wc -l)
24590         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24591
24592         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24593         stack_trap "rmdir $tmpdir"
24594         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24595                 error "failed to mount client'"
24596         stack_trap "umount_client $tmpdir"
24597
24598         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24599         # rmfid should succeed
24600         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24601         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24602
24603         # rmfid shouldn't allow to remove files due to dir's permission
24604         chmod a+rwx $tmpdir/$tdir
24605         touch $tmpdir/$tdir/f
24606         ls -la $tmpdir/$tdir
24607         FID=$(lfs path2fid $tmpdir/$tdir/f)
24608         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24609         return 0
24610 }
24611 run_test 421f "rmfid checks permissions"
24612
24613 test_421g() {
24614         local cnt
24615         local FIDS
24616
24617         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24618         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24619                 skip "Need MDS version at least 2.12.54"
24620
24621         mkdir -p $DIR/$tdir
24622         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24623         createmany -o $DIR/$tdir/striped_dir/f 512
24624         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24625         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24626
24627         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24628                 sed "s/[/][^:]*://g")
24629
24630         rm -f $DIR/$tdir/striped_dir/f1*
24631         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24632         removed=$((512 - cnt))
24633
24634         # few files have been just removed, so we expect
24635         # rmfid to fail on their fids
24636         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24637         [ $removed != $errors ] && error "$errors != $removed"
24638
24639         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24640         rm -rf $DIR/$tdir
24641         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24642 }
24643 run_test 421g "rmfid to return errors properly"
24644
24645 test_422() {
24646         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24647         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24648         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24649         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24650         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24651
24652         local amc=$(at_max_get client)
24653         local amo=$(at_max_get mds1)
24654         local timeout=`lctl get_param -n timeout`
24655
24656         at_max_set 0 client
24657         at_max_set 0 mds1
24658
24659 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24660         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24661                         fail_val=$(((2*timeout + 10)*1000))
24662         touch $DIR/$tdir/d3/file &
24663         sleep 2
24664 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24665         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24666                         fail_val=$((2*timeout + 5))
24667         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24668         local pid=$!
24669         sleep 1
24670         kill -9 $pid
24671         sleep $((2 * timeout))
24672         echo kill $pid
24673         kill -9 $pid
24674         lctl mark touch
24675         touch $DIR/$tdir/d2/file3
24676         touch $DIR/$tdir/d2/file4
24677         touch $DIR/$tdir/d2/file5
24678
24679         wait
24680         at_max_set $amc client
24681         at_max_set $amo mds1
24682
24683         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24684         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24685                 error "Watchdog is always throttled"
24686 }
24687 run_test 422 "kill a process with RPC in progress"
24688
24689 stat_test() {
24690     df -h $MOUNT &
24691     df -h $MOUNT &
24692     df -h $MOUNT &
24693     df -h $MOUNT &
24694     df -h $MOUNT &
24695     df -h $MOUNT &
24696 }
24697
24698 test_423() {
24699     local _stats
24700     # ensure statfs cache is expired
24701     sleep 2;
24702
24703     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24704     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24705
24706     return 0
24707 }
24708 run_test 423 "statfs should return a right data"
24709
24710 test_424() {
24711 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24712         $LCTL set_param fail_loc=0x80000522
24713         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24714         rm -f $DIR/$tfile
24715 }
24716 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24717
24718 test_425() {
24719         test_mkdir -c -1 $DIR/$tdir
24720         $LFS setstripe -c -1 $DIR/$tdir
24721
24722         lru_resize_disable "" 100
24723         stack_trap "lru_resize_enable" EXIT
24724
24725         sleep 5
24726
24727         for i in $(seq $((MDSCOUNT * 125))); do
24728                 local t=$DIR/$tdir/$tfile_$i
24729
24730                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24731                         error_noexit "Create file $t"
24732         done
24733         stack_trap "rm -rf $DIR/$tdir" EXIT
24734
24735         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24736                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24737                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24738
24739                 [ $lock_count -le $lru_size ] ||
24740                         error "osc lock count $lock_count > lru size $lru_size"
24741         done
24742
24743         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24744                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24745                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24746
24747                 [ $lock_count -le $lru_size ] ||
24748                         error "mdc lock count $lock_count > lru size $lru_size"
24749         done
24750 }
24751 run_test 425 "lock count should not exceed lru size"
24752
24753 test_426() {
24754         splice-test -r $DIR/$tfile
24755         splice-test -rd $DIR/$tfile
24756         splice-test $DIR/$tfile
24757         splice-test -d $DIR/$tfile
24758 }
24759 run_test 426 "splice test on Lustre"
24760
24761 test_427() {
24762         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24763         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24764                 skip "Need MDS version at least 2.12.4"
24765         local log
24766
24767         mkdir $DIR/$tdir
24768         mkdir $DIR/$tdir/1
24769         mkdir $DIR/$tdir/2
24770         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24771         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24772
24773         $LFS getdirstripe $DIR/$tdir/1/dir
24774
24775         #first setfattr for creating updatelog
24776         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24777
24778 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24779         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24780         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24781         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24782
24783         sleep 2
24784         fail mds2
24785         wait_recovery_complete mds2 $((2*TIMEOUT))
24786
24787         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24788         echo $log | grep "get update log failed" &&
24789                 error "update log corruption is detected" || true
24790 }
24791 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24792
24793 test_428() {
24794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24795         local cache_limit=$CACHE_MAX
24796
24797         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24798         $LCTL set_param -n llite.*.max_cached_mb=64
24799
24800         mkdir $DIR/$tdir
24801         $LFS setstripe -c 1 $DIR/$tdir
24802         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24803         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24804         #test write
24805         for f in $(seq 4); do
24806                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24807         done
24808         wait
24809
24810         cancel_lru_locks osc
24811         # Test read
24812         for f in $(seq 4); do
24813                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24814         done
24815         wait
24816 }
24817 run_test 428 "large block size IO should not hang"
24818
24819 test_429() { # LU-7915 / LU-10948
24820         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24821         local testfile=$DIR/$tfile
24822         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24823         local new_flag=1
24824         local first_rpc
24825         local second_rpc
24826         local third_rpc
24827
24828         $LCTL get_param $ll_opencache_threshold_count ||
24829                 skip "client does not have opencache parameter"
24830
24831         set_opencache $new_flag
24832         stack_trap "restore_opencache"
24833         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
24834                 error "enable opencache failed"
24835         touch $testfile
24836         # drop MDC DLM locks
24837         cancel_lru_locks mdc
24838         # clear MDC RPC stats counters
24839         $LCTL set_param $mdc_rpcstats=clear
24840
24841         # According to the current implementation, we need to run 3 times
24842         # open & close file to verify if opencache is enabled correctly.
24843         # 1st, RPCs are sent for lookup/open and open handle is released on
24844         #      close finally.
24845         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
24846         #      so open handle won't be released thereafter.
24847         # 3rd, No RPC is sent out.
24848         $MULTIOP $testfile oc || error "multiop failed"
24849         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24850         echo "1st: $first_rpc RPCs in flight"
24851
24852         $MULTIOP $testfile oc || error "multiop failed"
24853         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24854         echo "2nd: $second_rpc RPCs in flight"
24855
24856         $MULTIOP $testfile oc || error "multiop failed"
24857         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24858         echo "3rd: $third_rpc RPCs in flight"
24859
24860         #verify no MDC RPC is sent
24861         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
24862 }
24863 run_test 429 "verify if opencache flag on client side does work"
24864
24865 lseek_test_430() {
24866         local offset
24867         local file=$1
24868
24869         # data at [200K, 400K)
24870         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24871                 error "256K->512K dd fails"
24872         # data at [2M, 3M)
24873         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24874                 error "2M->3M dd fails"
24875         # data at [4M, 5M)
24876         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24877                 error "4M->5M dd fails"
24878         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24879         # start at first component hole #1
24880         printf "Seeking hole from 1000 ... "
24881         offset=$(lseek_test -l 1000 $file)
24882         echo $offset
24883         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24884         printf "Seeking data from 1000 ... "
24885         offset=$(lseek_test -d 1000 $file)
24886         echo $offset
24887         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24888
24889         # start at first component data block
24890         printf "Seeking hole from 300000 ... "
24891         offset=$(lseek_test -l 300000 $file)
24892         echo $offset
24893         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24894         printf "Seeking data from 300000 ... "
24895         offset=$(lseek_test -d 300000 $file)
24896         echo $offset
24897         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24898
24899         # start at the first component but beyond end of object size
24900         printf "Seeking hole from 1000000 ... "
24901         offset=$(lseek_test -l 1000000 $file)
24902         echo $offset
24903         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24904         printf "Seeking data from 1000000 ... "
24905         offset=$(lseek_test -d 1000000 $file)
24906         echo $offset
24907         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24908
24909         # start at second component stripe 2 (empty file)
24910         printf "Seeking hole from 1500000 ... "
24911         offset=$(lseek_test -l 1500000 $file)
24912         echo $offset
24913         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24914         printf "Seeking data from 1500000 ... "
24915         offset=$(lseek_test -d 1500000 $file)
24916         echo $offset
24917         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24918
24919         # start at second component stripe 1 (all data)
24920         printf "Seeking hole from 3000000 ... "
24921         offset=$(lseek_test -l 3000000 $file)
24922         echo $offset
24923         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24924         printf "Seeking data from 3000000 ... "
24925         offset=$(lseek_test -d 3000000 $file)
24926         echo $offset
24927         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24928
24929         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24930                 error "2nd dd fails"
24931         echo "Add data block at 640K...1280K"
24932
24933         # start at before new data block, in hole
24934         printf "Seeking hole from 600000 ... "
24935         offset=$(lseek_test -l 600000 $file)
24936         echo $offset
24937         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24938         printf "Seeking data from 600000 ... "
24939         offset=$(lseek_test -d 600000 $file)
24940         echo $offset
24941         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24942
24943         # start at the first component new data block
24944         printf "Seeking hole from 1000000 ... "
24945         offset=$(lseek_test -l 1000000 $file)
24946         echo $offset
24947         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24948         printf "Seeking data from 1000000 ... "
24949         offset=$(lseek_test -d 1000000 $file)
24950         echo $offset
24951         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24952
24953         # start at second component stripe 2, new data
24954         printf "Seeking hole from 1200000 ... "
24955         offset=$(lseek_test -l 1200000 $file)
24956         echo $offset
24957         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24958         printf "Seeking data from 1200000 ... "
24959         offset=$(lseek_test -d 1200000 $file)
24960         echo $offset
24961         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24962
24963         # start beyond file end
24964         printf "Using offset > filesize ... "
24965         lseek_test -l 4000000 $file && error "lseek should fail"
24966         printf "Using offset > filesize ... "
24967         lseek_test -d 4000000 $file && error "lseek should fail"
24968
24969         printf "Done\n\n"
24970 }
24971
24972 test_430a() {
24973         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24974                 skip "MDT does not support SEEK_HOLE"
24975
24976         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24977                 skip "OST does not support SEEK_HOLE"
24978
24979         local file=$DIR/$tdir/$tfile
24980
24981         mkdir -p $DIR/$tdir
24982
24983         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24984         # OST stripe #1 will have continuous data at [1M, 3M)
24985         # OST stripe #2 is empty
24986         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24987         lseek_test_430 $file
24988         rm $file
24989         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24990         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24991         lseek_test_430 $file
24992         rm $file
24993         $LFS setstripe -c2 -S 512K $file
24994         echo "Two stripes, stripe size 512K"
24995         lseek_test_430 $file
24996         rm $file
24997         # FLR with stale mirror
24998         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24999                        -N -c2 -S 1M $file
25000         echo "Mirrored file:"
25001         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25002         echo "Plain 2 stripes 1M"
25003         lseek_test_430 $file
25004         rm $file
25005 }
25006 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25007
25008 test_430b() {
25009         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25010                 skip "OST does not support SEEK_HOLE"
25011
25012         local offset
25013         local file=$DIR/$tdir/$tfile
25014
25015         mkdir -p $DIR/$tdir
25016         # Empty layout lseek should fail
25017         $MCREATE $file
25018         # seek from 0
25019         printf "Seeking hole from 0 ... "
25020         lseek_test -l 0 $file && error "lseek should fail"
25021         printf "Seeking data from 0 ... "
25022         lseek_test -d 0 $file && error "lseek should fail"
25023         rm $file
25024
25025         # 1M-hole file
25026         $LFS setstripe -E 1M -c2 -E eof $file
25027         $TRUNCATE $file 1048576
25028         printf "Seeking hole from 1000000 ... "
25029         offset=$(lseek_test -l 1000000 $file)
25030         echo $offset
25031         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25032         printf "Seeking data from 1000000 ... "
25033         lseek_test -d 1000000 $file && error "lseek should fail"
25034         rm $file
25035
25036         # full component followed by non-inited one
25037         $LFS setstripe -E 1M -c2 -E eof $file
25038         dd if=/dev/urandom of=$file bs=1M count=1
25039         printf "Seeking hole from 1000000 ... "
25040         offset=$(lseek_test -l 1000000 $file)
25041         echo $offset
25042         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25043         printf "Seeking hole from 1048576 ... "
25044         lseek_test -l 1048576 $file && error "lseek should fail"
25045         # init second component and truncate back
25046         echo "123" >> $file
25047         $TRUNCATE $file 1048576
25048         printf "Seeking hole from 1000000 ... "
25049         offset=$(lseek_test -l 1000000 $file)
25050         echo $offset
25051         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25052         printf "Seeking hole from 1048576 ... "
25053         lseek_test -l 1048576 $file && error "lseek should fail"
25054         # boundary checks for big values
25055         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25056         offset=$(lseek_test -d 0 $file.10g)
25057         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25058         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25059         offset=$(lseek_test -d 0 $file.100g)
25060         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25061         return 0
25062 }
25063 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25064
25065 test_430c() {
25066         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25067                 skip "OST does not support SEEK_HOLE"
25068
25069         local file=$DIR/$tdir/$tfile
25070         local start
25071
25072         mkdir -p $DIR/$tdir
25073         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25074
25075         # cp version 8.33+ prefers lseek over fiemap
25076         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25077                 start=$SECONDS
25078                 time cp $file /dev/null
25079                 (( SECONDS - start < 5 )) ||
25080                         error "cp: too long runtime $((SECONDS - start))"
25081
25082         fi
25083         # tar version 1.29+ supports SEEK_HOLE/DATA
25084         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25085                 start=$SECONDS
25086                 time tar cS $file - | cat > /dev/null
25087                 (( SECONDS - start < 5 )) ||
25088                         error "tar: too long runtime $((SECONDS - start))"
25089         fi
25090 }
25091 run_test 430c "lseek: external tools check"
25092
25093 test_431() { # LU-14187
25094         local file=$DIR/$tdir/$tfile
25095
25096         mkdir -p $DIR/$tdir
25097         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25098         dd if=/dev/urandom of=$file bs=4k count=1
25099         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25100         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25101         #define OBD_FAIL_OST_RESTART_IO 0x251
25102         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25103         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25104         cp $file $file.0
25105         cancel_lru_locks
25106         sync_all_data
25107         echo 3 > /proc/sys/vm/drop_caches
25108         diff  $file $file.0 || error "data diff"
25109 }
25110 run_test 431 "Restart transaction for IO"
25111
25112 prep_801() {
25113         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25114         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25115                 skip "Need server version at least 2.9.55"
25116
25117         start_full_debug_logging
25118 }
25119
25120 post_801() {
25121         stop_full_debug_logging
25122 }
25123
25124 barrier_stat() {
25125         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25126                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25127                            awk '/The barrier for/ { print $7 }')
25128                 echo $st
25129         else
25130                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25131                 echo \'$st\'
25132         fi
25133 }
25134
25135 barrier_expired() {
25136         local expired
25137
25138         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25139                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25140                           awk '/will be expired/ { print $7 }')
25141         else
25142                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25143         fi
25144
25145         echo $expired
25146 }
25147
25148 test_801a() {
25149         prep_801
25150
25151         echo "Start barrier_freeze at: $(date)"
25152         #define OBD_FAIL_BARRIER_DELAY          0x2202
25153         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25154         # Do not reduce barrier time - See LU-11873
25155         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25156
25157         sleep 2
25158         local b_status=$(barrier_stat)
25159         echo "Got barrier status at: $(date)"
25160         [ "$b_status" = "'freezing_p1'" ] ||
25161                 error "(1) unexpected barrier status $b_status"
25162
25163         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25164         wait
25165         b_status=$(barrier_stat)
25166         [ "$b_status" = "'frozen'" ] ||
25167                 error "(2) unexpected barrier status $b_status"
25168
25169         local expired=$(barrier_expired)
25170         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25171         sleep $((expired + 3))
25172
25173         b_status=$(barrier_stat)
25174         [ "$b_status" = "'expired'" ] ||
25175                 error "(3) unexpected barrier status $b_status"
25176
25177         # Do not reduce barrier time - See LU-11873
25178         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25179                 error "(4) fail to freeze barrier"
25180
25181         b_status=$(barrier_stat)
25182         [ "$b_status" = "'frozen'" ] ||
25183                 error "(5) unexpected barrier status $b_status"
25184
25185         echo "Start barrier_thaw at: $(date)"
25186         #define OBD_FAIL_BARRIER_DELAY          0x2202
25187         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25188         do_facet mgs $LCTL barrier_thaw $FSNAME &
25189
25190         sleep 2
25191         b_status=$(barrier_stat)
25192         echo "Got barrier status at: $(date)"
25193         [ "$b_status" = "'thawing'" ] ||
25194                 error "(6) unexpected barrier status $b_status"
25195
25196         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25197         wait
25198         b_status=$(barrier_stat)
25199         [ "$b_status" = "'thawed'" ] ||
25200                 error "(7) unexpected barrier status $b_status"
25201
25202         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25203         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25204         do_facet mgs $LCTL barrier_freeze $FSNAME
25205
25206         b_status=$(barrier_stat)
25207         [ "$b_status" = "'failed'" ] ||
25208                 error "(8) unexpected barrier status $b_status"
25209
25210         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25211         do_facet mgs $LCTL barrier_thaw $FSNAME
25212
25213         post_801
25214 }
25215 run_test 801a "write barrier user interfaces and stat machine"
25216
25217 test_801b() {
25218         prep_801
25219
25220         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25221         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25222         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25223         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25224         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25225
25226         cancel_lru_locks mdc
25227
25228         # 180 seconds should be long enough
25229         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25230
25231         local b_status=$(barrier_stat)
25232         [ "$b_status" = "'frozen'" ] ||
25233                 error "(6) unexpected barrier status $b_status"
25234
25235         mkdir $DIR/$tdir/d0/d10 &
25236         mkdir_pid=$!
25237
25238         touch $DIR/$tdir/d1/f13 &
25239         touch_pid=$!
25240
25241         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25242         ln_pid=$!
25243
25244         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25245         mv_pid=$!
25246
25247         rm -f $DIR/$tdir/d4/f12 &
25248         rm_pid=$!
25249
25250         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25251
25252         # To guarantee taht the 'stat' is not blocked
25253         b_status=$(barrier_stat)
25254         [ "$b_status" = "'frozen'" ] ||
25255                 error "(8) unexpected barrier status $b_status"
25256
25257         # let above commands to run at background
25258         sleep 5
25259
25260         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25261         ps -p $touch_pid || error "(10) touch should be blocked"
25262         ps -p $ln_pid || error "(11) link should be blocked"
25263         ps -p $mv_pid || error "(12) rename should be blocked"
25264         ps -p $rm_pid || error "(13) unlink should be blocked"
25265
25266         b_status=$(barrier_stat)
25267         [ "$b_status" = "'frozen'" ] ||
25268                 error "(14) unexpected barrier status $b_status"
25269
25270         do_facet mgs $LCTL barrier_thaw $FSNAME
25271         b_status=$(barrier_stat)
25272         [ "$b_status" = "'thawed'" ] ||
25273                 error "(15) unexpected barrier status $b_status"
25274
25275         wait $mkdir_pid || error "(16) mkdir should succeed"
25276         wait $touch_pid || error "(17) touch should succeed"
25277         wait $ln_pid || error "(18) link should succeed"
25278         wait $mv_pid || error "(19) rename should succeed"
25279         wait $rm_pid || error "(20) unlink should succeed"
25280
25281         post_801
25282 }
25283 run_test 801b "modification will be blocked by write barrier"
25284
25285 test_801c() {
25286         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25287
25288         prep_801
25289
25290         stop mds2 || error "(1) Fail to stop mds2"
25291
25292         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25293
25294         local b_status=$(barrier_stat)
25295         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25296                 do_facet mgs $LCTL barrier_thaw $FSNAME
25297                 error "(2) unexpected barrier status $b_status"
25298         }
25299
25300         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25301                 error "(3) Fail to rescan barrier bitmap"
25302
25303         # Do not reduce barrier time - See LU-11873
25304         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25305
25306         b_status=$(barrier_stat)
25307         [ "$b_status" = "'frozen'" ] ||
25308                 error "(4) unexpected barrier status $b_status"
25309
25310         do_facet mgs $LCTL barrier_thaw $FSNAME
25311         b_status=$(barrier_stat)
25312         [ "$b_status" = "'thawed'" ] ||
25313                 error "(5) unexpected barrier status $b_status"
25314
25315         local devname=$(mdsdevname 2)
25316
25317         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25318
25319         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25320                 error "(7) Fail to rescan barrier bitmap"
25321
25322         post_801
25323 }
25324 run_test 801c "rescan barrier bitmap"
25325
25326 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25327 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25328 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25329 saved_MOUNT_OPTS=$MOUNT_OPTS
25330
25331 cleanup_802a() {
25332         trap 0
25333
25334         stopall
25335         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25336         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25337         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25338         MOUNT_OPTS=$saved_MOUNT_OPTS
25339         setupall
25340 }
25341
25342 test_802a() {
25343         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25344         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25345         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25346                 skip "Need server version at least 2.9.55"
25347
25348         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25349
25350         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25351
25352         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25353                 error "(2) Fail to copy"
25354
25355         trap cleanup_802a EXIT
25356
25357         # sync by force before remount as readonly
25358         sync; sync_all_data; sleep 3; sync_all_data
25359
25360         stopall
25361
25362         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25363         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25364         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25365
25366         echo "Mount the server as read only"
25367         setupall server_only || error "(3) Fail to start servers"
25368
25369         echo "Mount client without ro should fail"
25370         mount_client $MOUNT &&
25371                 error "(4) Mount client without 'ro' should fail"
25372
25373         echo "Mount client with ro should succeed"
25374         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25375         mount_client $MOUNT ||
25376                 error "(5) Mount client with 'ro' should succeed"
25377
25378         echo "Modify should be refused"
25379         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25380
25381         echo "Read should be allowed"
25382         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25383                 error "(7) Read should succeed under ro mode"
25384
25385         cleanup_802a
25386 }
25387 run_test 802a "simulate readonly device"
25388
25389 test_802b() {
25390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25391         remote_mds_nodsh && skip "remote MDS with nodsh"
25392
25393         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25394                 skip "readonly option not available"
25395
25396         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25397
25398         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25399                 error "(2) Fail to copy"
25400
25401         # write back all cached data before setting MDT to readonly
25402         cancel_lru_locks
25403         sync_all_data
25404
25405         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25406         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25407
25408         echo "Modify should be refused"
25409         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25410
25411         echo "Read should be allowed"
25412         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25413                 error "(7) Read should succeed under ro mode"
25414
25415         # disable readonly
25416         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25417 }
25418 run_test 802b "be able to set MDTs to readonly"
25419
25420 test_803a() {
25421         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25422         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25423                 skip "MDS needs to be newer than 2.10.54"
25424
25425         mkdir -p $DIR/$tdir
25426         # Create some objects on all MDTs to trigger related logs objects
25427         for idx in $(seq $MDSCOUNT); do
25428                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25429                         $DIR/$tdir/dir${idx} ||
25430                         error "Fail to create $DIR/$tdir/dir${idx}"
25431         done
25432
25433         sync; sleep 3
25434         wait_delete_completed # ensure old test cleanups are finished
25435         echo "before create:"
25436         $LFS df -i $MOUNT
25437         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25438
25439         for i in {1..10}; do
25440                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25441                         error "Fail to create $DIR/$tdir/foo$i"
25442         done
25443
25444         sync; sleep 3
25445         echo "after create:"
25446         $LFS df -i $MOUNT
25447         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25448
25449         # allow for an llog to be cleaned up during the test
25450         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25451                 error "before ($before_used) + 10 > after ($after_used)"
25452
25453         for i in {1..10}; do
25454                 rm -rf $DIR/$tdir/foo$i ||
25455                         error "Fail to remove $DIR/$tdir/foo$i"
25456         done
25457
25458         sleep 3 # avoid MDT return cached statfs
25459         wait_delete_completed
25460         echo "after unlink:"
25461         $LFS df -i $MOUNT
25462         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25463
25464         # allow for an llog to be created during the test
25465         [ $after_used -le $((before_used + 1)) ] ||
25466                 error "after ($after_used) > before ($before_used) + 1"
25467 }
25468 run_test 803a "verify agent object for remote object"
25469
25470 test_803b() {
25471         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25472         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25473                 skip "MDS needs to be newer than 2.13.56"
25474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25475
25476         for i in $(seq 0 $((MDSCOUNT - 1))); do
25477                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25478         done
25479
25480         local before=0
25481         local after=0
25482
25483         local tmp
25484
25485         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25486         for i in $(seq 0 $((MDSCOUNT - 1))); do
25487                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25488                         awk '/getattr/ { print $2 }')
25489                 before=$((before + tmp))
25490         done
25491         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25492         for i in $(seq 0 $((MDSCOUNT - 1))); do
25493                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25494                         awk '/getattr/ { print $2 }')
25495                 after=$((after + tmp))
25496         done
25497
25498         [ $before -eq $after ] || error "getattr count $before != $after"
25499 }
25500 run_test 803b "remote object can getattr from cache"
25501
25502 test_804() {
25503         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25504         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25505                 skip "MDS needs to be newer than 2.10.54"
25506         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25507
25508         mkdir -p $DIR/$tdir
25509         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25510                 error "Fail to create $DIR/$tdir/dir0"
25511
25512         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25513         local dev=$(mdsdevname 2)
25514
25515         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25516                 grep ${fid} || error "NOT found agent entry for dir0"
25517
25518         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25519                 error "Fail to create $DIR/$tdir/dir1"
25520
25521         touch $DIR/$tdir/dir1/foo0 ||
25522                 error "Fail to create $DIR/$tdir/dir1/foo0"
25523         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25524         local rc=0
25525
25526         for idx in $(seq $MDSCOUNT); do
25527                 dev=$(mdsdevname $idx)
25528                 do_facet mds${idx} \
25529                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25530                         grep ${fid} && rc=$idx
25531         done
25532
25533         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25534                 error "Fail to rename foo0 to foo1"
25535         if [ $rc -eq 0 ]; then
25536                 for idx in $(seq $MDSCOUNT); do
25537                         dev=$(mdsdevname $idx)
25538                         do_facet mds${idx} \
25539                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25540                         grep ${fid} && rc=$idx
25541                 done
25542         fi
25543
25544         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25545                 error "Fail to rename foo1 to foo2"
25546         if [ $rc -eq 0 ]; then
25547                 for idx in $(seq $MDSCOUNT); do
25548                         dev=$(mdsdevname $idx)
25549                         do_facet mds${idx} \
25550                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25551                         grep ${fid} && rc=$idx
25552                 done
25553         fi
25554
25555         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25556
25557         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25558                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25559         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25560                 error "Fail to rename foo2 to foo0"
25561         unlink $DIR/$tdir/dir1/foo0 ||
25562                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25563         rm -rf $DIR/$tdir/dir0 ||
25564                 error "Fail to rm $DIR/$tdir/dir0"
25565
25566         for idx in $(seq $MDSCOUNT); do
25567                 dev=$(mdsdevname $idx)
25568                 rc=0
25569
25570                 stop mds${idx}
25571                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25572                         rc=$?
25573                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25574                         error "mount mds$idx failed"
25575                 df $MOUNT > /dev/null 2>&1
25576
25577                 # e2fsck should not return error
25578                 [ $rc -eq 0 ] ||
25579                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25580         done
25581 }
25582 run_test 804 "verify agent entry for remote entry"
25583
25584 cleanup_805() {
25585         do_facet $SINGLEMDS zfs set quota=$old $fsset
25586         unlinkmany $DIR/$tdir/f- 1000000
25587         trap 0
25588 }
25589
25590 test_805() {
25591         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25592         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25593         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25594                 skip "netfree not implemented before 0.7"
25595         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25596                 skip "Need MDS version at least 2.10.57"
25597
25598         local fsset
25599         local freekb
25600         local usedkb
25601         local old
25602         local quota
25603         local pref="osd-zfs.$FSNAME-MDT0000."
25604
25605         # limit available space on MDS dataset to meet nospace issue
25606         # quickly. then ZFS 0.7.2 can use reserved space if asked
25607         # properly (using netfree flag in osd_declare_destroy()
25608         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25609         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25610                 gawk '{print $3}')
25611         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25612         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25613         let "usedkb=usedkb-freekb"
25614         let "freekb=freekb/2"
25615         if let "freekb > 5000"; then
25616                 let "freekb=5000"
25617         fi
25618         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25619         trap cleanup_805 EXIT
25620         mkdir $DIR/$tdir
25621         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25622                 error "Can't set PFL layout"
25623         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25624         rm -rf $DIR/$tdir || error "not able to remove"
25625         do_facet $SINGLEMDS zfs set quota=$old $fsset
25626         trap 0
25627 }
25628 run_test 805 "ZFS can remove from full fs"
25629
25630 # Size-on-MDS test
25631 check_lsom_data()
25632 {
25633         local file=$1
25634         local expect=$(stat -c %s $file)
25635
25636         check_lsom_size $1 $expect
25637
25638         local blocks=$($LFS getsom -b $file)
25639         expect=$(stat -c %b $file)
25640         [[ $blocks == $expect ]] ||
25641                 error "$file expected blocks: $expect, got: $blocks"
25642 }
25643
25644 check_lsom_size()
25645 {
25646         local size
25647         local expect=$2
25648
25649         cancel_lru_locks mdc
25650
25651         size=$($LFS getsom -s $1)
25652         [[ $size == $expect ]] ||
25653                 error "$file expected size: $expect, got: $size"
25654 }
25655
25656 test_806() {
25657         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25658                 skip "Need MDS version at least 2.11.52"
25659
25660         local bs=1048576
25661
25662         touch $DIR/$tfile || error "touch $tfile failed"
25663
25664         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25665         save_lustre_params client "llite.*.xattr_cache" > $save
25666         lctl set_param llite.*.xattr_cache=0
25667         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25668
25669         # single-threaded write
25670         echo "Test SOM for single-threaded write"
25671         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25672                 error "write $tfile failed"
25673         check_lsom_size $DIR/$tfile $bs
25674
25675         local num=32
25676         local size=$(($num * $bs))
25677         local offset=0
25678         local i
25679
25680         echo "Test SOM for single client multi-threaded($num) write"
25681         $TRUNCATE $DIR/$tfile 0
25682         for ((i = 0; i < $num; i++)); do
25683                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25684                 local pids[$i]=$!
25685                 offset=$((offset + $bs))
25686         done
25687         for (( i=0; i < $num; i++ )); do
25688                 wait ${pids[$i]}
25689         done
25690         check_lsom_size $DIR/$tfile $size
25691
25692         $TRUNCATE $DIR/$tfile 0
25693         for ((i = 0; i < $num; i++)); do
25694                 offset=$((offset - $bs))
25695                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25696                 local pids[$i]=$!
25697         done
25698         for (( i=0; i < $num; i++ )); do
25699                 wait ${pids[$i]}
25700         done
25701         check_lsom_size $DIR/$tfile $size
25702
25703         # multi-client writes
25704         num=$(get_node_count ${CLIENTS//,/ })
25705         size=$(($num * $bs))
25706         offset=0
25707         i=0
25708
25709         echo "Test SOM for multi-client ($num) writes"
25710         $TRUNCATE $DIR/$tfile 0
25711         for client in ${CLIENTS//,/ }; do
25712                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25713                 local pids[$i]=$!
25714                 i=$((i + 1))
25715                 offset=$((offset + $bs))
25716         done
25717         for (( i=0; i < $num; i++ )); do
25718                 wait ${pids[$i]}
25719         done
25720         check_lsom_size $DIR/$tfile $offset
25721
25722         i=0
25723         $TRUNCATE $DIR/$tfile 0
25724         for client in ${CLIENTS//,/ }; do
25725                 offset=$((offset - $bs))
25726                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25727                 local pids[$i]=$!
25728                 i=$((i + 1))
25729         done
25730         for (( i=0; i < $num; i++ )); do
25731                 wait ${pids[$i]}
25732         done
25733         check_lsom_size $DIR/$tfile $size
25734
25735         # verify truncate
25736         echo "Test SOM for truncate"
25737         $TRUNCATE $DIR/$tfile 1048576
25738         check_lsom_size $DIR/$tfile 1048576
25739         $TRUNCATE $DIR/$tfile 1234
25740         check_lsom_size $DIR/$tfile 1234
25741
25742         # verify SOM blocks count
25743         echo "Verify SOM block count"
25744         $TRUNCATE $DIR/$tfile 0
25745         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25746                 error "failed to write file $tfile"
25747         check_lsom_data $DIR/$tfile
25748 }
25749 run_test 806 "Verify Lazy Size on MDS"
25750
25751 test_807() {
25752         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25753         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25754                 skip "Need MDS version at least 2.11.52"
25755
25756         # Registration step
25757         changelog_register || error "changelog_register failed"
25758         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25759         changelog_users $SINGLEMDS | grep -q $cl_user ||
25760                 error "User $cl_user not found in changelog_users"
25761
25762         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25763         save_lustre_params client "llite.*.xattr_cache" > $save
25764         lctl set_param llite.*.xattr_cache=0
25765         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25766
25767         rm -rf $DIR/$tdir || error "rm $tdir failed"
25768         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25769         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25770         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25771         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25772                 error "truncate $tdir/trunc failed"
25773
25774         local bs=1048576
25775         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25776                 error "write $tfile failed"
25777
25778         # multi-client wirtes
25779         local num=$(get_node_count ${CLIENTS//,/ })
25780         local offset=0
25781         local i=0
25782
25783         echo "Test SOM for multi-client ($num) writes"
25784         touch $DIR/$tfile || error "touch $tfile failed"
25785         $TRUNCATE $DIR/$tfile 0
25786         for client in ${CLIENTS//,/ }; do
25787                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25788                 local pids[$i]=$!
25789                 i=$((i + 1))
25790                 offset=$((offset + $bs))
25791         done
25792         for (( i=0; i < $num; i++ )); do
25793                 wait ${pids[$i]}
25794         done
25795
25796         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25797         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25798         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25799         check_lsom_data $DIR/$tdir/trunc
25800         check_lsom_data $DIR/$tdir/single_dd
25801         check_lsom_data $DIR/$tfile
25802
25803         rm -rf $DIR/$tdir
25804         # Deregistration step
25805         changelog_deregister || error "changelog_deregister failed"
25806 }
25807 run_test 807 "verify LSOM syncing tool"
25808
25809 check_som_nologged()
25810 {
25811         local lines=$($LFS changelog $FSNAME-MDT0000 |
25812                 grep 'x=trusted.som' | wc -l)
25813         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25814 }
25815
25816 test_808() {
25817         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25818                 skip "Need MDS version at least 2.11.55"
25819
25820         # Registration step
25821         changelog_register || error "changelog_register failed"
25822
25823         touch $DIR/$tfile || error "touch $tfile failed"
25824         check_som_nologged
25825
25826         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25827                 error "write $tfile failed"
25828         check_som_nologged
25829
25830         $TRUNCATE $DIR/$tfile 1234
25831         check_som_nologged
25832
25833         $TRUNCATE $DIR/$tfile 1048576
25834         check_som_nologged
25835
25836         # Deregistration step
25837         changelog_deregister || error "changelog_deregister failed"
25838 }
25839 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25840
25841 check_som_nodata()
25842 {
25843         $LFS getsom $1
25844         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25845 }
25846
25847 test_809() {
25848         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25849                 skip "Need MDS version at least 2.11.56"
25850
25851         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25852                 error "failed to create DoM-only file $DIR/$tfile"
25853         touch $DIR/$tfile || error "touch $tfile failed"
25854         check_som_nodata $DIR/$tfile
25855
25856         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25857                 error "write $tfile failed"
25858         check_som_nodata $DIR/$tfile
25859
25860         $TRUNCATE $DIR/$tfile 1234
25861         check_som_nodata $DIR/$tfile
25862
25863         $TRUNCATE $DIR/$tfile 4097
25864         check_som_nodata $DIR/$file
25865 }
25866 run_test 809 "Verify no SOM xattr store for DoM-only files"
25867
25868 test_810() {
25869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25870         $GSS && skip_env "could not run with gss"
25871         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25872                 skip "OST < 2.12.58 doesn't align checksum"
25873
25874         set_checksums 1
25875         stack_trap "set_checksums $ORIG_CSUM" EXIT
25876         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25877
25878         local csum
25879         local before
25880         local after
25881         for csum in $CKSUM_TYPES; do
25882                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25883                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25884                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25885                         eval set -- $i
25886                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25887                         before=$(md5sum $DIR/$tfile)
25888                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25889                         after=$(md5sum $DIR/$tfile)
25890                         [ "$before" == "$after" ] ||
25891                                 error "$csum: $before != $after bs=$1 seek=$2"
25892                 done
25893         done
25894 }
25895 run_test 810 "partial page writes on ZFS (LU-11663)"
25896
25897 test_812a() {
25898         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25899                 skip "OST < 2.12.51 doesn't support this fail_loc"
25900
25901         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25902         # ensure ost1 is connected
25903         stat $DIR/$tfile >/dev/null || error "can't stat"
25904         wait_osc_import_state client ost1 FULL
25905         # no locks, no reqs to let the connection idle
25906         cancel_lru_locks osc
25907
25908         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25909 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25910         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25911         wait_osc_import_state client ost1 CONNECTING
25912         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25913
25914         stat $DIR/$tfile >/dev/null || error "can't stat file"
25915 }
25916 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25917
25918 test_812b() { # LU-12378
25919         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25920                 skip "OST < 2.12.51 doesn't support this fail_loc"
25921
25922         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25923         # ensure ost1 is connected
25924         stat $DIR/$tfile >/dev/null || error "can't stat"
25925         wait_osc_import_state client ost1 FULL
25926         # no locks, no reqs to let the connection idle
25927         cancel_lru_locks osc
25928
25929         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25930 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25931         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25932         wait_osc_import_state client ost1 CONNECTING
25933         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25934
25935         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25936         wait_osc_import_state client ost1 IDLE
25937 }
25938 run_test 812b "do not drop no resend request for idle connect"
25939
25940 test_812c() {
25941         local old
25942
25943         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
25944
25945         $LFS setstripe -c 1 -o 0 $DIR/$tfile
25946         $LFS getstripe $DIR/$tfile
25947         $LCTL set_param osc.*.idle_timeout=10
25948         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
25949         # ensure ost1 is connected
25950         stat $DIR/$tfile >/dev/null || error "can't stat"
25951         wait_osc_import_state client ost1 FULL
25952         # no locks, no reqs to let the connection idle
25953         cancel_lru_locks osc
25954
25955 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
25956         $LCTL set_param fail_loc=0x80000533
25957         sleep 15
25958         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
25959 }
25960 run_test 812c "idle import vs lock enqueue race"
25961
25962 test_813() {
25963         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25964         [ -z "$file_heat_sav" ] && skip "no file heat support"
25965
25966         local readsample
25967         local writesample
25968         local readbyte
25969         local writebyte
25970         local readsample1
25971         local writesample1
25972         local readbyte1
25973         local writebyte1
25974
25975         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25976         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25977
25978         $LCTL set_param -n llite.*.file_heat=1
25979         echo "Turn on file heat"
25980         echo "Period second: $period_second, Decay percentage: $decay_pct"
25981
25982         echo "QQQQ" > $DIR/$tfile
25983         echo "QQQQ" > $DIR/$tfile
25984         echo "QQQQ" > $DIR/$tfile
25985         cat $DIR/$tfile > /dev/null
25986         cat $DIR/$tfile > /dev/null
25987         cat $DIR/$tfile > /dev/null
25988         cat $DIR/$tfile > /dev/null
25989
25990         local out=$($LFS heat_get $DIR/$tfile)
25991
25992         $LFS heat_get $DIR/$tfile
25993         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25994         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25995         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25996         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25997
25998         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25999         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26000         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26001         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26002
26003         sleep $((period_second + 3))
26004         echo "Sleep $((period_second + 3)) seconds..."
26005         # The recursion formula to calculate the heat of the file f is as
26006         # follow:
26007         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26008         # Where Hi is the heat value in the period between time points i*I and
26009         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26010         # to the weight of Ci.
26011         out=$($LFS heat_get $DIR/$tfile)
26012         $LFS heat_get $DIR/$tfile
26013         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26014         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26015         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26016         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26017
26018         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26019                 error "read sample ($readsample) is wrong"
26020         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26021                 error "write sample ($writesample) is wrong"
26022         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26023                 error "read bytes ($readbyte) is wrong"
26024         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26025                 error "write bytes ($writebyte) is wrong"
26026
26027         echo "QQQQ" > $DIR/$tfile
26028         echo "QQQQ" > $DIR/$tfile
26029         echo "QQQQ" > $DIR/$tfile
26030         cat $DIR/$tfile > /dev/null
26031         cat $DIR/$tfile > /dev/null
26032         cat $DIR/$tfile > /dev/null
26033         cat $DIR/$tfile > /dev/null
26034
26035         sleep $((period_second + 3))
26036         echo "Sleep $((period_second + 3)) seconds..."
26037
26038         out=$($LFS heat_get $DIR/$tfile)
26039         $LFS heat_get $DIR/$tfile
26040         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26041         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26042         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26043         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26044
26045         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26046                 4 * $decay_pct) / 100") -eq 1 ] ||
26047                 error "read sample ($readsample1) is wrong"
26048         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26049                 3 * $decay_pct) / 100") -eq 1 ] ||
26050                 error "write sample ($writesample1) is wrong"
26051         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26052                 20 * $decay_pct) / 100") -eq 1 ] ||
26053                 error "read bytes ($readbyte1) is wrong"
26054         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26055                 15 * $decay_pct) / 100") -eq 1 ] ||
26056                 error "write bytes ($writebyte1) is wrong"
26057
26058         echo "Turn off file heat for the file $DIR/$tfile"
26059         $LFS heat_set -o $DIR/$tfile
26060
26061         echo "QQQQ" > $DIR/$tfile
26062         echo "QQQQ" > $DIR/$tfile
26063         echo "QQQQ" > $DIR/$tfile
26064         cat $DIR/$tfile > /dev/null
26065         cat $DIR/$tfile > /dev/null
26066         cat $DIR/$tfile > /dev/null
26067         cat $DIR/$tfile > /dev/null
26068
26069         out=$($LFS heat_get $DIR/$tfile)
26070         $LFS heat_get $DIR/$tfile
26071         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26072         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26073         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26074         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26075
26076         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26077         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26078         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26079         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26080
26081         echo "Trun on file heat for the file $DIR/$tfile"
26082         $LFS heat_set -O $DIR/$tfile
26083
26084         echo "QQQQ" > $DIR/$tfile
26085         echo "QQQQ" > $DIR/$tfile
26086         echo "QQQQ" > $DIR/$tfile
26087         cat $DIR/$tfile > /dev/null
26088         cat $DIR/$tfile > /dev/null
26089         cat $DIR/$tfile > /dev/null
26090         cat $DIR/$tfile > /dev/null
26091
26092         out=$($LFS heat_get $DIR/$tfile)
26093         $LFS heat_get $DIR/$tfile
26094         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26095         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26096         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26097         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26098
26099         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26100         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26101         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26102         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26103
26104         $LFS heat_set -c $DIR/$tfile
26105         $LCTL set_param -n llite.*.file_heat=0
26106         echo "Turn off file heat support for the Lustre filesystem"
26107
26108         echo "QQQQ" > $DIR/$tfile
26109         echo "QQQQ" > $DIR/$tfile
26110         echo "QQQQ" > $DIR/$tfile
26111         cat $DIR/$tfile > /dev/null
26112         cat $DIR/$tfile > /dev/null
26113         cat $DIR/$tfile > /dev/null
26114         cat $DIR/$tfile > /dev/null
26115
26116         out=$($LFS heat_get $DIR/$tfile)
26117         $LFS heat_get $DIR/$tfile
26118         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26119         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26120         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26121         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26122
26123         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26124         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26125         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26126         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26127
26128         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26129         rm -f $DIR/$tfile
26130 }
26131 run_test 813 "File heat verfication"
26132
26133 test_814()
26134 {
26135         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26136         echo -n y >> $DIR/$tfile
26137         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26138         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26139 }
26140 run_test 814 "sparse cp works as expected (LU-12361)"
26141
26142 test_815()
26143 {
26144         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26145         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26146 }
26147 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26148
26149 test_816() {
26150         local ost1_imp=$(get_osc_import_name client ost1)
26151         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26152                          cut -d'.' -f2)
26153
26154         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26155         # ensure ost1 is connected
26156
26157         stat $DIR/$tfile >/dev/null || error "can't stat"
26158         wait_osc_import_state client ost1 FULL
26159         # no locks, no reqs to let the connection idle
26160         cancel_lru_locks osc
26161         lru_resize_disable osc
26162         local before
26163         local now
26164         before=$($LCTL get_param -n \
26165                  ldlm.namespaces.$imp_name.lru_size)
26166
26167         wait_osc_import_state client ost1 IDLE
26168         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26169         now=$($LCTL get_param -n \
26170               ldlm.namespaces.$imp_name.lru_size)
26171         [ $before == $now ] || error "lru_size changed $before != $now"
26172 }
26173 run_test 816 "do not reset lru_resize on idle reconnect"
26174
26175 cleanup_817() {
26176         umount $tmpdir
26177         exportfs -u localhost:$DIR/nfsexp
26178         rm -rf $DIR/nfsexp
26179 }
26180
26181 test_817() {
26182         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26183
26184         mkdir -p $DIR/nfsexp
26185         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26186                 error "failed to export nfs"
26187
26188         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26189         stack_trap cleanup_817 EXIT
26190
26191         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26192                 error "failed to mount nfs to $tmpdir"
26193
26194         cp /bin/true $tmpdir
26195         $DIR/nfsexp/true || error "failed to execute 'true' command"
26196 }
26197 run_test 817 "nfsd won't cache write lock for exec file"
26198
26199 test_818() {
26200         mkdir $DIR/$tdir
26201         $LFS setstripe -c1 -i0 $DIR/$tfile
26202         $LFS setstripe -c1 -i1 $DIR/$tfile
26203         stop $SINGLEMDS
26204         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26205         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26206         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26207                 error "start $SINGLEMDS failed"
26208         rm -rf $DIR/$tdir
26209 }
26210 run_test 818 "unlink with failed llog"
26211
26212 test_819a() {
26213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26214         cancel_lru_locks osc
26215         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26216         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26217         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26218         rm -f $TDIR/$tfile
26219 }
26220 run_test 819a "too big niobuf in read"
26221
26222 test_819b() {
26223         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26224         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26225         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26226         cancel_lru_locks osc
26227         sleep 1
26228         rm -f $TDIR/$tfile
26229 }
26230 run_test 819b "too big niobuf in write"
26231
26232
26233 function test_820_start_ost() {
26234         sleep 5
26235
26236         for num in $(seq $OSTCOUNT); do
26237                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26238         done
26239 }
26240
26241 test_820() {
26242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26243
26244         mkdir $DIR/$tdir
26245         umount_client $MOUNT || error "umount failed"
26246         for num in $(seq $OSTCOUNT); do
26247                 stop ost$num
26248         done
26249
26250         # mount client with no active OSTs
26251         # so that the client can't initialize max LOV EA size
26252         # from OSC notifications
26253         mount_client $MOUNT || error "mount failed"
26254         # delay OST starting to keep this 0 max EA size for a while
26255         test_820_start_ost &
26256
26257         # create a directory on MDS2
26258         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26259                 error "Failed to create directory"
26260         # open intent should update default EA size
26261         # see mdc_update_max_ea_from_body()
26262         # notice this is the very first RPC to MDS2
26263         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26264         ret=$?
26265         echo $out
26266         # With SSK, this situation can lead to -EPERM being returned.
26267         # In that case, simply retry.
26268         if [ $ret -ne 0 ] && $SHARED_KEY; then
26269                 if echo "$out" | grep -q "not permitted"; then
26270                         cp /etc/services $DIR/$tdir/mds2
26271                         ret=$?
26272                 fi
26273         fi
26274         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26275 }
26276 run_test 820 "update max EA from open intent"
26277
26278 test_822() {
26279         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26280
26281         save_lustre_params mds1 \
26282                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26283         do_facet $SINGLEMDS "$LCTL set_param -n \
26284                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26285         do_facet $SINGLEMDS "$LCTL set_param -n \
26286                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26287
26288         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26289         local maxage=$(do_facet mds1 $LCTL get_param -n \
26290                        osp.$FSNAME-OST0000*MDT0000.maxage)
26291         sleep $((maxage + 1))
26292
26293         #define OBD_FAIL_NET_ERROR_RPC          0x532
26294         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26295
26296         stack_trap "restore_lustre_params < $p; rm $p"
26297
26298         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26299                       osp.$FSNAME-OST0000*MDT0000.create_count")
26300         for i in $(seq 1 $count); do
26301                 touch $DIR/$tfile.${i} || error "touch failed"
26302         done
26303 }
26304 run_test 822 "test precreate failure"
26305
26306 #
26307 # tests that do cleanup/setup should be run at the end
26308 #
26309
26310 test_900() {
26311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26312         local ls
26313
26314         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26315         $LCTL set_param fail_loc=0x903
26316
26317         cancel_lru_locks MGC
26318
26319         FAIL_ON_ERROR=true cleanup
26320         FAIL_ON_ERROR=true setup
26321 }
26322 run_test 900 "umount should not race with any mgc requeue thread"
26323
26324 # LUS-6253/LU-11185
26325 test_901() {
26326         local oldc
26327         local newc
26328         local olds
26329         local news
26330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26331
26332         # some get_param have a bug to handle dot in param name
26333         cancel_lru_locks MGC
26334         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26335         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26336         umount_client $MOUNT || error "umount failed"
26337         mount_client $MOUNT || error "mount failed"
26338         cancel_lru_locks MGC
26339         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26340         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26341
26342         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26343         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26344
26345         return 0
26346 }
26347 run_test 901 "don't leak a mgc lock on client umount"
26348
26349 # LU-13377
26350 test_902() {
26351         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26352                 skip "client does not have LU-13377 fix"
26353         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26354         $LCTL set_param fail_loc=0x1415
26355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26356         cancel_lru_locks osc
26357         rm -f $DIR/$tfile
26358 }
26359 run_test 902 "test short write doesn't hang lustre"
26360
26361 complete $SECONDS
26362 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26363 check_and_cleanup_lustre
26364 if [ "$I_MOUNTED" != "yes" ]; then
26365         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26366 fi
26367 exit_status