Whamcloud - gitweb
LU-14565 ofd: Do not rely on tgd_blockbit
[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 # createtest also checks that device nodes are created and
3323 # then visible correctly (#2091)
3324 test_28() { # bug 2091
3325         test_mkdir $DIR/d28
3326         $CREATETEST $DIR/d28/ct || error "createtest failed"
3327 }
3328 run_test 28 "create/mknod/mkdir with bad file types ============"
3329
3330 test_29() {
3331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3332
3333         sync; sleep 1; sync # flush out any dirty pages from previous tests
3334         cancel_lru_locks
3335         test_mkdir $DIR/d29
3336         touch $DIR/d29/foo
3337         log 'first d29'
3338         ls -l $DIR/d29
3339
3340         declare -i LOCKCOUNTORIG=0
3341         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3342                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3343         done
3344         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3345
3346         declare -i LOCKUNUSEDCOUNTORIG=0
3347         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3348                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3349         done
3350
3351         log 'second d29'
3352         ls -l $DIR/d29
3353         log 'done'
3354
3355         declare -i LOCKCOUNTCURRENT=0
3356         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3357                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3358         done
3359
3360         declare -i LOCKUNUSEDCOUNTCURRENT=0
3361         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3362                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3363         done
3364
3365         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3366                 $LCTL set_param -n ldlm.dump_namespaces ""
3367                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3368                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3369                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3370                 return 2
3371         fi
3372         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3373                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3374                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3375                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3376                 return 3
3377         fi
3378 }
3379 run_test 29 "IT_GETATTR regression  ============================"
3380
3381 test_30a() { # was test_30
3382         cp $(which ls) $DIR || cp /bin/ls $DIR
3383         $DIR/ls / || error "Can't execute binary from lustre"
3384         rm $DIR/ls
3385 }
3386 run_test 30a "execute binary from Lustre (execve) =============="
3387
3388 test_30b() {
3389         cp `which ls` $DIR || cp /bin/ls $DIR
3390         chmod go+rx $DIR/ls
3391         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3392         rm $DIR/ls
3393 }
3394 run_test 30b "execute binary from Lustre as non-root ==========="
3395
3396 test_30c() { # b=22376
3397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3398
3399         cp $(which ls) $DIR || cp /bin/ls $DIR
3400         chmod a-rw $DIR/ls
3401         cancel_lru_locks mdc
3402         cancel_lru_locks osc
3403         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3404         rm -f $DIR/ls
3405 }
3406 run_test 30c "execute binary from Lustre without read perms ===="
3407
3408 test_30d() {
3409         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3410
3411         for i in {1..10}; do
3412                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3413                 local PID=$!
3414                 sleep 1
3415                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3416                 wait $PID || error "executing dd from Lustre failed"
3417                 rm -f $DIR/$tfile
3418         done
3419
3420         rm -f $DIR/dd
3421 }
3422 run_test 30d "execute binary from Lustre while clear locks"
3423
3424 test_31a() {
3425         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3426         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3427 }
3428 run_test 31a "open-unlink file =================================="
3429
3430 test_31b() {
3431         touch $DIR/f31 || error "touch $DIR/f31 failed"
3432         ln $DIR/f31 $DIR/f31b || error "ln failed"
3433         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3434         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3435 }
3436 run_test 31b "unlink file with multiple links while open ======="
3437
3438 test_31c() {
3439         touch $DIR/f31 || error "touch $DIR/f31 failed"
3440         ln $DIR/f31 $DIR/f31c || error "ln failed"
3441         multiop_bg_pause $DIR/f31 O_uc ||
3442                 error "multiop_bg_pause for $DIR/f31 failed"
3443         MULTIPID=$!
3444         $MULTIOP $DIR/f31c Ouc
3445         kill -USR1 $MULTIPID
3446         wait $MULTIPID
3447 }
3448 run_test 31c "open-unlink file with multiple links ============="
3449
3450 test_31d() {
3451         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3452         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3453 }
3454 run_test 31d "remove of open directory ========================="
3455
3456 test_31e() { # bug 2904
3457         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3458 }
3459 run_test 31e "remove of open non-empty directory ==============="
3460
3461 test_31f() { # bug 4554
3462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3463
3464         set -vx
3465         test_mkdir $DIR/d31f
3466         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3467         cp /etc/hosts $DIR/d31f
3468         ls -l $DIR/d31f
3469         $LFS getstripe $DIR/d31f/hosts
3470         multiop_bg_pause $DIR/d31f D_c || return 1
3471         MULTIPID=$!
3472
3473         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3474         test_mkdir $DIR/d31f
3475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3476         cp /etc/hosts $DIR/d31f
3477         ls -l $DIR/d31f
3478         $LFS getstripe $DIR/d31f/hosts
3479         multiop_bg_pause $DIR/d31f D_c || return 1
3480         MULTIPID2=$!
3481
3482         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3483         wait $MULTIPID || error "first opendir $MULTIPID failed"
3484
3485         sleep 6
3486
3487         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3488         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3489         set +vx
3490 }
3491 run_test 31f "remove of open directory with open-unlink file ==="
3492
3493 test_31g() {
3494         echo "-- cross directory link --"
3495         test_mkdir -c1 $DIR/${tdir}ga
3496         test_mkdir -c1 $DIR/${tdir}gb
3497         touch $DIR/${tdir}ga/f
3498         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3499         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3500         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3501         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3502         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3503 }
3504 run_test 31g "cross directory link==============="
3505
3506 test_31h() {
3507         echo "-- cross directory link --"
3508         test_mkdir -c1 $DIR/${tdir}
3509         test_mkdir -c1 $DIR/${tdir}/dir
3510         touch $DIR/${tdir}/f
3511         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3512         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3513         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3514         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3515         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3516 }
3517 run_test 31h "cross directory link under child==============="
3518
3519 test_31i() {
3520         echo "-- cross directory link --"
3521         test_mkdir -c1 $DIR/$tdir
3522         test_mkdir -c1 $DIR/$tdir/dir
3523         touch $DIR/$tdir/dir/f
3524         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3525         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3526         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3527         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3528         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3529 }
3530 run_test 31i "cross directory link under parent==============="
3531
3532 test_31j() {
3533         test_mkdir -c1 -p $DIR/$tdir
3534         test_mkdir -c1 -p $DIR/$tdir/dir1
3535         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3536         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3537         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3538         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3539         return 0
3540 }
3541 run_test 31j "link for directory==============="
3542
3543 test_31k() {
3544         test_mkdir -c1 -p $DIR/$tdir
3545         touch $DIR/$tdir/s
3546         touch $DIR/$tdir/exist
3547         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3548         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3549         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3550         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3551         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3552         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3553         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3554         return 0
3555 }
3556 run_test 31k "link to file: the same, non-existing, dir==============="
3557
3558 test_31m() {
3559         mkdir $DIR/d31m
3560         touch $DIR/d31m/s
3561         mkdir $DIR/d31m2
3562         touch $DIR/d31m2/exist
3563         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3564         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3565         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3566         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3567         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3568         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3569         return 0
3570 }
3571 run_test 31m "link to file: the same, non-existing, dir==============="
3572
3573 test_31n() {
3574         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3575         nlink=$(stat --format=%h $DIR/$tfile)
3576         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3577         local fd=$(free_fd)
3578         local cmd="exec $fd<$DIR/$tfile"
3579         eval $cmd
3580         cmd="exec $fd<&-"
3581         trap "eval $cmd" EXIT
3582         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3583         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3584         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3585         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3586         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3587         eval $cmd
3588 }
3589 run_test 31n "check link count of unlinked file"
3590
3591 link_one() {
3592         local tempfile=$(mktemp $1_XXXXXX)
3593         mlink $tempfile $1 2> /dev/null &&
3594                 echo "$BASHPID: link $tempfile to $1 succeeded"
3595         munlink $tempfile
3596 }
3597
3598 test_31o() { # LU-2901
3599         test_mkdir $DIR/$tdir
3600         for LOOP in $(seq 100); do
3601                 rm -f $DIR/$tdir/$tfile*
3602                 for THREAD in $(seq 8); do
3603                         link_one $DIR/$tdir/$tfile.$LOOP &
3604                 done
3605                 wait
3606                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3607                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3608                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3609                         break || true
3610         done
3611 }
3612 run_test 31o "duplicate hard links with same filename"
3613
3614 test_31p() {
3615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3616
3617         test_mkdir $DIR/$tdir
3618         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3619         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3620
3621         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3622                 error "open unlink test1 failed"
3623         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3624                 error "open unlink test2 failed"
3625
3626         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3627                 error "test1 still exists"
3628         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3629                 error "test2 still exists"
3630 }
3631 run_test 31p "remove of open striped directory"
3632
3633 test_31q() {
3634         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3635
3636         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3637         index=$($LFS getdirstripe -i $DIR/$tdir)
3638         [ $index -eq 3 ] || error "first stripe index $index != 3"
3639         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3640         [ $index -eq 1 ] || error "second stripe index $index != 1"
3641
3642         # when "-c <stripe_count>" is set, the number of MDTs specified after
3643         # "-i" should equal to the stripe count
3644         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3645 }
3646 run_test 31q "create striped directory on specific MDTs"
3647
3648 cleanup_test32_mount() {
3649         local rc=0
3650         trap 0
3651         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3652         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3653         losetup -d $loopdev || true
3654         rm -rf $DIR/$tdir
3655         return $rc
3656 }
3657
3658 test_32a() {
3659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3660
3661         echo "== more mountpoints and symlinks ================="
3662         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3663         trap cleanup_test32_mount EXIT
3664         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3665         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3666                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3667         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3668                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3669         cleanup_test32_mount
3670 }
3671 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3672
3673 test_32b() {
3674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3675
3676         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3677         trap cleanup_test32_mount EXIT
3678         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3679         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3680                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3681         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3682                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3683         cleanup_test32_mount
3684 }
3685 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3686
3687 test_32c() {
3688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3689
3690         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3691         trap cleanup_test32_mount EXIT
3692         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3693         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3694                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3695         test_mkdir -p $DIR/$tdir/d2/test_dir
3696         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3697                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3698         cleanup_test32_mount
3699 }
3700 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3701
3702 test_32d() {
3703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3704
3705         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3706         trap cleanup_test32_mount EXIT
3707         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3708         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3709                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3710         test_mkdir -p $DIR/$tdir/d2/test_dir
3711         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3712                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3713         cleanup_test32_mount
3714 }
3715 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3716
3717 test_32e() {
3718         rm -fr $DIR/$tdir
3719         test_mkdir -p $DIR/$tdir/tmp
3720         local tmp_dir=$DIR/$tdir/tmp
3721         ln -s $DIR/$tdir $tmp_dir/symlink11
3722         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3723         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3724         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3725 }
3726 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3727
3728 test_32f() {
3729         rm -fr $DIR/$tdir
3730         test_mkdir -p $DIR/$tdir/tmp
3731         local tmp_dir=$DIR/$tdir/tmp
3732         ln -s $DIR/$tdir $tmp_dir/symlink11
3733         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3734         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3735         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3736 }
3737 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3738
3739 test_32g() {
3740         local tmp_dir=$DIR/$tdir/tmp
3741         test_mkdir -p $tmp_dir
3742         test_mkdir $DIR/${tdir}2
3743         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3744         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3745         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3746         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3747         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3748         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3749 }
3750 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3751
3752 test_32h() {
3753         rm -fr $DIR/$tdir $DIR/${tdir}2
3754         tmp_dir=$DIR/$tdir/tmp
3755         test_mkdir -p $tmp_dir
3756         test_mkdir $DIR/${tdir}2
3757         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3758         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3759         ls $tmp_dir/symlink12 || error "listing symlink12"
3760         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3761 }
3762 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3763
3764 test_32i() {
3765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3766
3767         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3768         trap cleanup_test32_mount EXIT
3769         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3770         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3771                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3772         touch $DIR/$tdir/test_file
3773         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3774                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3775         cleanup_test32_mount
3776 }
3777 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3778
3779 test_32j() {
3780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3781
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         touch $DIR/$tdir/test_file
3788         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3789                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3790         cleanup_test32_mount
3791 }
3792 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3793
3794 test_32k() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         rm -fr $DIR/$tdir
3798         trap cleanup_test32_mount EXIT
3799         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3800         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3801                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3802         test_mkdir -p $DIR/$tdir/d2
3803         touch $DIR/$tdir/d2/test_file || error "touch failed"
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3809
3810 test_32l() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         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         test_mkdir -p $DIR/$tdir/d2
3819         touch $DIR/$tdir/d2/test_file || error "touch failed"
3820         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3825
3826 test_32m() {
3827         rm -fr $DIR/d32m
3828         test_mkdir -p $DIR/d32m/tmp
3829         TMP_DIR=$DIR/d32m/tmp
3830         ln -s $DIR $TMP_DIR/symlink11
3831         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3832         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3833                 error "symlink11 not a link"
3834         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3835                 error "symlink01 not a link"
3836 }
3837 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3838
3839 test_32n() {
3840         rm -fr $DIR/d32n
3841         test_mkdir -p $DIR/d32n/tmp
3842         TMP_DIR=$DIR/d32n/tmp
3843         ln -s $DIR $TMP_DIR/symlink11
3844         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3845         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3846         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3847 }
3848 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3849
3850 test_32o() {
3851         touch $DIR/$tfile
3852         test_mkdir -p $DIR/d32o/tmp
3853         TMP_DIR=$DIR/d32o/tmp
3854         ln -s $DIR/$tfile $TMP_DIR/symlink12
3855         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3856         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3857                 error "symlink12 not a link"
3858         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3859         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3860                 error "$DIR/d32o/tmp/symlink12 not file type"
3861         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3862                 error "$DIR/d32o/symlink02 not file type"
3863 }
3864 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3865
3866 test_32p() {
3867         log 32p_1
3868         rm -fr $DIR/d32p
3869         log 32p_2
3870         rm -f $DIR/$tfile
3871         log 32p_3
3872         touch $DIR/$tfile
3873         log 32p_4
3874         test_mkdir -p $DIR/d32p/tmp
3875         log 32p_5
3876         TMP_DIR=$DIR/d32p/tmp
3877         log 32p_6
3878         ln -s $DIR/$tfile $TMP_DIR/symlink12
3879         log 32p_7
3880         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3881         log 32p_8
3882         cat $DIR/d32p/tmp/symlink12 ||
3883                 error "Can't open $DIR/d32p/tmp/symlink12"
3884         log 32p_9
3885         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3886         log 32p_10
3887 }
3888 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3889
3890 test_32q() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3894         trap cleanup_test32_mount EXIT
3895         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3896         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3900         cleanup_test32_mount
3901 }
3902 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3903
3904 test_32r() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3908         trap cleanup_test32_mount EXIT
3909         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3910         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3914         cleanup_test32_mount
3915 }
3916 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3917
3918 test_33aa() {
3919         rm -f $DIR/$tfile
3920         touch $DIR/$tfile
3921         chmod 444 $DIR/$tfile
3922         chown $RUNAS_ID $DIR/$tfile
3923         log 33_1
3924         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3925         log 33_2
3926 }
3927 run_test 33aa "write file with mode 444 (should return error)"
3928
3929 test_33a() {
3930         rm -fr $DIR/$tdir
3931         test_mkdir $DIR/$tdir
3932         chown $RUNAS_ID $DIR/$tdir
3933         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3934                 error "$RUNAS create $tdir/$tfile failed"
3935         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3936                 error "open RDWR" || true
3937 }
3938 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3939
3940 test_33b() {
3941         rm -fr $DIR/$tdir
3942         test_mkdir $DIR/$tdir
3943         chown $RUNAS_ID $DIR/$tdir
3944         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3945 }
3946 run_test 33b "test open file with malformed flags (No panic)"
3947
3948 test_33c() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950         remote_ost_nodsh && skip "remote OST with nodsh"
3951
3952         local ostnum
3953         local ostname
3954         local write_bytes
3955         local all_zeros
3956
3957         all_zeros=true
3958         test_mkdir $DIR/$tdir
3959         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3960
3961         sync
3962         for ostnum in $(seq $OSTCOUNT); do
3963                 # test-framework's OST numbering is one-based, while Lustre's
3964                 # is zero-based
3965                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3966                 # check if at least some write_bytes stats are counted
3967                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3968                               obdfilter.$ostname.stats |
3969                               awk '/^write_bytes/ {print $7}' )
3970                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
3971                 if (( ${write_bytes:-0} > 0 )); then
3972                         all_zeros=false
3973                         break
3974                 fi
3975         done
3976
3977         $all_zeros || return 0
3978
3979         # Write four bytes
3980         echo foo > $DIR/$tdir/bar
3981         # Really write them
3982         sync
3983
3984         # Total up write_bytes after writing.  We'd better find non-zeros.
3985         for ostnum in $(seq $OSTCOUNT); do
3986                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3987                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3988                               obdfilter/$ostname/stats |
3989                               awk '/^write_bytes/ {print $7}' )
3990                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
3991                 if (( ${write_bytes:-0} > 0 )); then
3992                         all_zeros=false
3993                         break
3994                 fi
3995         done
3996
3997         if $all_zeros; then
3998                 for ostnum in $(seq $OSTCOUNT); do
3999                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4000                         echo "Check write_bytes is in obdfilter.*.stats:"
4001                         do_facet ost$ostnum lctl get_param -n \
4002                                 obdfilter.$ostname.stats
4003                 done
4004                 error "OST not keeping write_bytes stats (b=22312)"
4005         fi
4006 }
4007 run_test 33c "test write_bytes stats"
4008
4009 test_33d() {
4010         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         local MDTIDX=1
4014         local remote_dir=$DIR/$tdir/remote_dir
4015
4016         test_mkdir $DIR/$tdir
4017         $LFS mkdir -i $MDTIDX $remote_dir ||
4018                 error "create remote directory failed"
4019
4020         touch $remote_dir/$tfile
4021         chmod 444 $remote_dir/$tfile
4022         chown $RUNAS_ID $remote_dir/$tfile
4023
4024         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4025
4026         chown $RUNAS_ID $remote_dir
4027         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4028                                         error "create" || true
4029         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4030                                     error "open RDWR" || true
4031         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4032 }
4033 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4034
4035 test_33e() {
4036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4037
4038         mkdir $DIR/$tdir
4039
4040         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4041         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4042         mkdir $DIR/$tdir/local_dir
4043
4044         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4045         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4046         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4047
4048         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4049                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4050
4051         rmdir $DIR/$tdir/* || error "rmdir failed"
4052
4053         umask 777
4054         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4055         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4056         mkdir $DIR/$tdir/local_dir
4057
4058         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4059         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4060         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4061
4062         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4063                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4064
4065         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4066
4067         umask 000
4068         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4069         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4070         mkdir $DIR/$tdir/local_dir
4071
4072         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4073         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4074         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4075
4076         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4077                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4078 }
4079 run_test 33e "mkdir and striped directory should have same mode"
4080
4081 cleanup_33f() {
4082         trap 0
4083         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4084 }
4085
4086 test_33f() {
4087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4088         remote_mds_nodsh && skip "remote MDS with nodsh"
4089
4090         mkdir $DIR/$tdir
4091         chmod go+rwx $DIR/$tdir
4092         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4093         trap cleanup_33f EXIT
4094
4095         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4096                 error "cannot create striped directory"
4097
4098         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4099                 error "cannot create files in striped directory"
4100
4101         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4102                 error "cannot remove files in striped directory"
4103
4104         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4105                 error "cannot remove striped directory"
4106
4107         cleanup_33f
4108 }
4109 run_test 33f "nonroot user can create, access, and remove a striped directory"
4110
4111 test_33g() {
4112         mkdir -p $DIR/$tdir/dir2
4113
4114         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4115         echo $err
4116         [[ $err =~ "exists" ]] || error "Not exists error"
4117 }
4118 run_test 33g "nonroot user create already existing root created file"
4119
4120 test_33h() {
4121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4122         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4123                 skip "Need MDS version at least 2.13.50"
4124
4125         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4126                 error "mkdir $tdir failed"
4127         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4128
4129         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4130         local index2
4131
4132         for fname in $DIR/$tdir/$tfile.bak \
4133                      $DIR/$tdir/$tfile.SAV \
4134                      $DIR/$tdir/$tfile.orig \
4135                      $DIR/$tdir/$tfile~; do
4136                 touch $fname  || error "touch $fname failed"
4137                 index2=$($LFS getstripe -m $fname)
4138                 [ $index -eq $index2 ] ||
4139                         error "$fname MDT index mismatch $index != $index2"
4140         done
4141
4142         local failed=0
4143         for i in {1..250}; do
4144                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4145                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4146                         touch $fname  || error "touch $fname failed"
4147                         index2=$($LFS getstripe -m $fname)
4148                         if [[ $index != $index2 ]]; then
4149                                 failed=$((failed + 1))
4150                                 echo "$fname MDT index mismatch $index != $index2"
4151                         fi
4152                 done
4153         done
4154         echo "$failed MDT index mismatches"
4155         (( failed < 20 )) || error "MDT index mismatch $failed times"
4156
4157 }
4158 run_test 33h "temp file is located on the same MDT as target"
4159
4160 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4161 test_34a() {
4162         rm -f $DIR/f34
4163         $MCREATE $DIR/f34 || error "mcreate failed"
4164         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4165                 error "getstripe failed"
4166         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4167         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4168                 error "getstripe failed"
4169         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4170                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4171 }
4172 run_test 34a "truncate file that has not been opened ==========="
4173
4174 test_34b() {
4175         [ ! -f $DIR/f34 ] && test_34a
4176         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4177                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4178         $OPENFILE -f O_RDONLY $DIR/f34
4179         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4180                 error "getstripe failed"
4181         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4182                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4183 }
4184 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4185
4186 test_34c() {
4187         [ ! -f $DIR/f34 ] && test_34a
4188         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4189                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4190         $OPENFILE -f O_RDWR $DIR/f34
4191         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4192                 error "$LFS getstripe failed"
4193         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4194                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4195 }
4196 run_test 34c "O_RDWR opening file-with-size works =============="
4197
4198 test_34d() {
4199         [ ! -f $DIR/f34 ] && test_34a
4200         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4201                 error "dd failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204         rm $DIR/f34
4205 }
4206 run_test 34d "write to sparse file ============================="
4207
4208 test_34e() {
4209         rm -f $DIR/f34e
4210         $MCREATE $DIR/f34e || error "mcreate failed"
4211         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4212         $CHECKSTAT -s 1000 $DIR/f34e ||
4213                 error "Size of $DIR/f34e not equal to 1000 bytes"
4214         $OPENFILE -f O_RDWR $DIR/f34e
4215         $CHECKSTAT -s 1000 $DIR/f34e ||
4216                 error "Size of $DIR/f34e not equal to 1000 bytes"
4217 }
4218 run_test 34e "create objects, some with size and some without =="
4219
4220 test_34f() { # bug 6242, 6243
4221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4222
4223         SIZE34F=48000
4224         rm -f $DIR/f34f
4225         $MCREATE $DIR/f34f || error "mcreate failed"
4226         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4227         dd if=$DIR/f34f of=$TMP/f34f
4228         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4229         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4230         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4231         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4232         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4233 }
4234 run_test 34f "read from a file with no objects until EOF ======="
4235
4236 test_34g() {
4237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4238
4239         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4240                 error "dd failed"
4241         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4242         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4243                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4244         cancel_lru_locks osc
4245         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4246                 error "wrong size after lock cancel"
4247
4248         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4249         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4250                 error "expanding truncate failed"
4251         cancel_lru_locks osc
4252         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4253                 error "wrong expanded size after lock cancel"
4254 }
4255 run_test 34g "truncate long file ==============================="
4256
4257 test_34h() {
4258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4259
4260         local gid=10
4261         local sz=1000
4262
4263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4264         sync # Flush the cache so that multiop below does not block on cache
4265              # flush when getting the group lock
4266         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4267         MULTIPID=$!
4268
4269         # Since just timed wait is not good enough, let's do a sync write
4270         # that way we are sure enough time for a roundtrip + processing
4271         # passed + 2 seconds of extra margin.
4272         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4273         rm $DIR/${tfile}-1
4274         sleep 2
4275
4276         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4277                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4278                 kill -9 $MULTIPID
4279         fi
4280         wait $MULTIPID
4281         local nsz=`stat -c %s $DIR/$tfile`
4282         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4283 }
4284 run_test 34h "ftruncate file under grouplock should not block"
4285
4286 test_35a() {
4287         cp /bin/sh $DIR/f35a
4288         chmod 444 $DIR/f35a
4289         chown $RUNAS_ID $DIR/f35a
4290         $RUNAS $DIR/f35a && error || true
4291         rm $DIR/f35a
4292 }
4293 run_test 35a "exec file with mode 444 (should return and not leak)"
4294
4295 test_36a() {
4296         rm -f $DIR/f36
4297         utime $DIR/f36 || error "utime failed for MDS"
4298 }
4299 run_test 36a "MDS utime check (mknod, utime)"
4300
4301 test_36b() {
4302         echo "" > $DIR/f36
4303         utime $DIR/f36 || error "utime failed for OST"
4304 }
4305 run_test 36b "OST utime check (open, utime)"
4306
4307 test_36c() {
4308         rm -f $DIR/d36/f36
4309         test_mkdir $DIR/d36
4310         chown $RUNAS_ID $DIR/d36
4311         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4312 }
4313 run_test 36c "non-root MDS utime check (mknod, utime)"
4314
4315 test_36d() {
4316         [ ! -d $DIR/d36 ] && test_36c
4317         echo "" > $DIR/d36/f36
4318         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4319 }
4320 run_test 36d "non-root OST utime check (open, utime)"
4321
4322 test_36e() {
4323         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4324
4325         test_mkdir $DIR/$tdir
4326         touch $DIR/$tdir/$tfile
4327         $RUNAS utime $DIR/$tdir/$tfile &&
4328                 error "utime worked, expected failure" || true
4329 }
4330 run_test 36e "utime on non-owned file (should return error)"
4331
4332 subr_36fh() {
4333         local fl="$1"
4334         local LANG_SAVE=$LANG
4335         local LC_LANG_SAVE=$LC_LANG
4336         export LANG=C LC_LANG=C # for date language
4337
4338         DATESTR="Dec 20  2000"
4339         test_mkdir $DIR/$tdir
4340         lctl set_param fail_loc=$fl
4341         date; date +%s
4342         cp /etc/hosts $DIR/$tdir/$tfile
4343         sync & # write RPC generated with "current" inode timestamp, but delayed
4344         sleep 1
4345         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4346         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4347         cancel_lru_locks $OSC
4348         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4349         date; date +%s
4350         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4351                 echo "BEFORE: $LS_BEFORE" && \
4352                 echo "AFTER : $LS_AFTER" && \
4353                 echo "WANT  : $DATESTR" && \
4354                 error "$DIR/$tdir/$tfile timestamps changed" || true
4355
4356         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4357 }
4358
4359 test_36f() {
4360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4361
4362         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4363         subr_36fh "0x80000214"
4364 }
4365 run_test 36f "utime on file racing with OST BRW write =========="
4366
4367 test_36g() {
4368         remote_ost_nodsh && skip "remote OST with nodsh"
4369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4370         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4371                 skip "Need MDS version at least 2.12.51"
4372
4373         local fmd_max_age
4374         local fmd
4375         local facet="ost1"
4376         local tgt="obdfilter"
4377
4378         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4379
4380         test_mkdir $DIR/$tdir
4381         fmd_max_age=$(do_facet $facet \
4382                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4383                 head -n 1")
4384
4385         echo "FMD max age: ${fmd_max_age}s"
4386         touch $DIR/$tdir/$tfile
4387         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4388                 gawk '{cnt=cnt+$1}  END{print cnt}')
4389         echo "FMD before: $fmd"
4390         [[ $fmd == 0 ]] &&
4391                 error "FMD wasn't create by touch"
4392         sleep $((fmd_max_age + 12))
4393         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4394                 gawk '{cnt=cnt+$1}  END{print cnt}')
4395         echo "FMD after: $fmd"
4396         [[ $fmd == 0 ]] ||
4397                 error "FMD wasn't expired by ping"
4398 }
4399 run_test 36g "FMD cache expiry ====================="
4400
4401 test_36h() {
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403
4404         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4405         subr_36fh "0x80000227"
4406 }
4407 run_test 36h "utime on file racing with OST BRW write =========="
4408
4409 test_36i() {
4410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4411
4412         test_mkdir $DIR/$tdir
4413         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4414
4415         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4416         local new_mtime=$((mtime + 200))
4417
4418         #change Modify time of striped dir
4419         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4420                         error "change mtime failed"
4421
4422         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4423
4424         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4425 }
4426 run_test 36i "change mtime on striped directory"
4427
4428 # test_37 - duplicate with tests 32q 32r
4429
4430 test_38() {
4431         local file=$DIR/$tfile
4432         touch $file
4433         openfile -f O_DIRECTORY $file
4434         local RC=$?
4435         local ENOTDIR=20
4436         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4437         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4438 }
4439 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4440
4441 test_39a() { # was test_39
4442         touch $DIR/$tfile
4443         touch $DIR/${tfile}2
4444 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4445 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4446 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4447         sleep 2
4448         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4449         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4450                 echo "mtime"
4451                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4452                 echo "atime"
4453                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4454                 echo "ctime"
4455                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4456                 error "O_TRUNC didn't change timestamps"
4457         fi
4458 }
4459 run_test 39a "mtime changed on create"
4460
4461 test_39b() {
4462         test_mkdir -c1 $DIR/$tdir
4463         cp -p /etc/passwd $DIR/$tdir/fopen
4464         cp -p /etc/passwd $DIR/$tdir/flink
4465         cp -p /etc/passwd $DIR/$tdir/funlink
4466         cp -p /etc/passwd $DIR/$tdir/frename
4467         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4468
4469         sleep 1
4470         echo "aaaaaa" >> $DIR/$tdir/fopen
4471         echo "aaaaaa" >> $DIR/$tdir/flink
4472         echo "aaaaaa" >> $DIR/$tdir/funlink
4473         echo "aaaaaa" >> $DIR/$tdir/frename
4474
4475         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4476         local link_new=`stat -c %Y $DIR/$tdir/flink`
4477         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4478         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4479
4480         cat $DIR/$tdir/fopen > /dev/null
4481         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4482         rm -f $DIR/$tdir/funlink2
4483         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4487                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4488                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4489                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4490
4491                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4492                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4493                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4494                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4495
4496                 cancel_lru_locks $OSC
4497                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4498         done
4499 }
4500 run_test 39b "mtime change on open, link, unlink, rename  ======"
4501
4502 # this should be set to past
4503 TEST_39_MTIME=`date -d "1 year ago" +%s`
4504
4505 # bug 11063
4506 test_39c() {
4507         touch $DIR1/$tfile
4508         sleep 2
4509         local mtime0=`stat -c %Y $DIR1/$tfile`
4510
4511         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4512         local mtime1=`stat -c %Y $DIR1/$tfile`
4513         [ "$mtime1" = $TEST_39_MTIME ] || \
4514                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4515
4516         local d1=`date +%s`
4517         echo hello >> $DIR1/$tfile
4518         local d2=`date +%s`
4519         local mtime2=`stat -c %Y $DIR1/$tfile`
4520         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4521                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4522
4523         mv $DIR1/$tfile $DIR1/$tfile-1
4524
4525         for (( i=0; i < 2; i++ )) ; do
4526                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4527                 [ "$mtime2" = "$mtime3" ] || \
4528                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4529
4530                 cancel_lru_locks $OSC
4531                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4532         done
4533 }
4534 run_test 39c "mtime change on rename ==========================="
4535
4536 # bug 21114
4537 test_39d() {
4538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4539
4540         touch $DIR1/$tfile
4541         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4542
4543         for (( i=0; i < 2; i++ )) ; do
4544                 local mtime=`stat -c %Y $DIR1/$tfile`
4545                 [ $mtime = $TEST_39_MTIME ] || \
4546                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4547
4548                 cancel_lru_locks $OSC
4549                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4550         done
4551 }
4552 run_test 39d "create, utime, stat =============================="
4553
4554 # bug 21114
4555 test_39e() {
4556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4557
4558         touch $DIR1/$tfile
4559         local mtime1=`stat -c %Y $DIR1/$tfile`
4560
4561         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4562
4563         for (( i=0; i < 2; i++ )) ; do
4564                 local mtime2=`stat -c %Y $DIR1/$tfile`
4565                 [ $mtime2 = $TEST_39_MTIME ] || \
4566                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4567
4568                 cancel_lru_locks $OSC
4569                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4570         done
4571 }
4572 run_test 39e "create, stat, utime, stat ========================"
4573
4574 # bug 21114
4575 test_39f() {
4576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4577
4578         touch $DIR1/$tfile
4579         mtime1=`stat -c %Y $DIR1/$tfile`
4580
4581         sleep 2
4582         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4583
4584         for (( i=0; i < 2; i++ )) ; do
4585                 local mtime2=`stat -c %Y $DIR1/$tfile`
4586                 [ $mtime2 = $TEST_39_MTIME ] || \
4587                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4588
4589                 cancel_lru_locks $OSC
4590                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4591         done
4592 }
4593 run_test 39f "create, stat, sleep, utime, stat ================="
4594
4595 # bug 11063
4596 test_39g() {
4597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4598
4599         echo hello >> $DIR1/$tfile
4600         local mtime1=`stat -c %Y $DIR1/$tfile`
4601
4602         sleep 2
4603         chmod o+r $DIR1/$tfile
4604
4605         for (( i=0; i < 2; i++ )) ; do
4606                 local mtime2=`stat -c %Y $DIR1/$tfile`
4607                 [ "$mtime1" = "$mtime2" ] || \
4608                         error "lost mtime: $mtime2, should be $mtime1"
4609
4610                 cancel_lru_locks $OSC
4611                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4612         done
4613 }
4614 run_test 39g "write, chmod, stat ==============================="
4615
4616 # bug 11063
4617 test_39h() {
4618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4619
4620         touch $DIR1/$tfile
4621         sleep 1
4622
4623         local d1=`date`
4624         echo hello >> $DIR1/$tfile
4625         local mtime1=`stat -c %Y $DIR1/$tfile`
4626
4627         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4628         local d2=`date`
4629         if [ "$d1" != "$d2" ]; then
4630                 echo "write and touch not within one second"
4631         else
4632                 for (( i=0; i < 2; i++ )) ; do
4633                         local mtime2=`stat -c %Y $DIR1/$tfile`
4634                         [ "$mtime2" = $TEST_39_MTIME ] || \
4635                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4636
4637                         cancel_lru_locks $OSC
4638                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4639                 done
4640         fi
4641 }
4642 run_test 39h "write, utime within one second, stat ============="
4643
4644 test_39i() {
4645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4646
4647         touch $DIR1/$tfile
4648         sleep 1
4649
4650         echo hello >> $DIR1/$tfile
4651         local mtime1=`stat -c %Y $DIR1/$tfile`
4652
4653         mv $DIR1/$tfile $DIR1/$tfile-1
4654
4655         for (( i=0; i < 2; i++ )) ; do
4656                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4657
4658                 [ "$mtime1" = "$mtime2" ] || \
4659                         error "lost mtime: $mtime2, should be $mtime1"
4660
4661                 cancel_lru_locks $OSC
4662                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4663         done
4664 }
4665 run_test 39i "write, rename, stat =============================="
4666
4667 test_39j() {
4668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4669
4670         start_full_debug_logging
4671         touch $DIR1/$tfile
4672         sleep 1
4673
4674         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4675         lctl set_param fail_loc=0x80000412
4676         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4677                 error "multiop failed"
4678         local multipid=$!
4679         local mtime1=`stat -c %Y $DIR1/$tfile`
4680
4681         mv $DIR1/$tfile $DIR1/$tfile-1
4682
4683         kill -USR1 $multipid
4684         wait $multipid || error "multiop close failed"
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4688                 [ "$mtime1" = "$mtime2" ] ||
4689                         error "mtime is lost on close: $mtime2, " \
4690                               "should be $mtime1"
4691
4692                 cancel_lru_locks
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695         lctl set_param fail_loc=0
4696         stop_full_debug_logging
4697 }
4698 run_test 39j "write, rename, close, stat ======================="
4699
4700 test_39k() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         sleep 1
4705
4706         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4707         local multipid=$!
4708         local mtime1=`stat -c %Y $DIR1/$tfile`
4709
4710         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4711
4712         kill -USR1 $multipid
4713         wait $multipid || error "multiop close failed"
4714
4715         for (( i=0; i < 2; i++ )) ; do
4716                 local mtime2=`stat -c %Y $DIR1/$tfile`
4717
4718                 [ "$mtime2" = $TEST_39_MTIME ] || \
4719                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4720
4721                 cancel_lru_locks
4722                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4723         done
4724 }
4725 run_test 39k "write, utime, close, stat ========================"
4726
4727 # this should be set to future
4728 TEST_39_ATIME=`date -d "1 year" +%s`
4729
4730 test_39l() {
4731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4732         remote_mds_nodsh && skip "remote MDS with nodsh"
4733
4734         local atime_diff=$(do_facet $SINGLEMDS \
4735                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4736         rm -rf $DIR/$tdir
4737         mkdir -p $DIR/$tdir
4738
4739         # test setting directory atime to future
4740         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4741         local atime=$(stat -c %X $DIR/$tdir)
4742         [ "$atime" = $TEST_39_ATIME ] ||
4743                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4744
4745         # test setting directory atime from future to now
4746         local now=$(date +%s)
4747         touch -a -d @$now $DIR/$tdir
4748
4749         atime=$(stat -c %X $DIR/$tdir)
4750         [ "$atime" -eq "$now"  ] ||
4751                 error "atime is not updated from future: $atime, $now"
4752
4753         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4754         sleep 3
4755
4756         # test setting directory atime when now > dir atime + atime_diff
4757         local d1=$(date +%s)
4758         ls $DIR/$tdir
4759         local d2=$(date +%s)
4760         cancel_lru_locks mdc
4761         atime=$(stat -c %X $DIR/$tdir)
4762         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4763                 error "atime is not updated  : $atime, should be $d2"
4764
4765         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4766         sleep 3
4767
4768         # test not setting directory atime when now < dir atime + atime_diff
4769         ls $DIR/$tdir
4770         cancel_lru_locks mdc
4771         atime=$(stat -c %X $DIR/$tdir)
4772         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4773                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4774
4775         do_facet $SINGLEMDS \
4776                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4777 }
4778 run_test 39l "directory atime update ==========================="
4779
4780 test_39m() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         touch $DIR1/$tfile
4784         sleep 2
4785         local far_past_mtime=$(date -d "May 29 1953" +%s)
4786         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4787
4788         touch -m -d @$far_past_mtime $DIR1/$tfile
4789         touch -a -d @$far_past_atime $DIR1/$tfile
4790
4791         for (( i=0; i < 2; i++ )) ; do
4792                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4793                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4794                         error "atime or mtime set incorrectly"
4795
4796                 cancel_lru_locks $OSC
4797                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4798         done
4799 }
4800 run_test 39m "test atime and mtime before 1970"
4801
4802 test_39n() { # LU-3832
4803         remote_mds_nodsh && skip "remote MDS with nodsh"
4804
4805         local atime_diff=$(do_facet $SINGLEMDS \
4806                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4807         local atime0
4808         local atime1
4809         local atime2
4810
4811         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4812
4813         rm -rf $DIR/$tfile
4814         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4815         atime0=$(stat -c %X $DIR/$tfile)
4816
4817         sleep 5
4818         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4819         atime1=$(stat -c %X $DIR/$tfile)
4820
4821         sleep 5
4822         cancel_lru_locks mdc
4823         cancel_lru_locks osc
4824         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4825         atime2=$(stat -c %X $DIR/$tfile)
4826
4827         do_facet $SINGLEMDS \
4828                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4829
4830         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4831         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4832 }
4833 run_test 39n "check that O_NOATIME is honored"
4834
4835 test_39o() {
4836         TESTDIR=$DIR/$tdir/$tfile
4837         [ -e $TESTDIR ] && rm -rf $TESTDIR
4838         mkdir -p $TESTDIR
4839         cd $TESTDIR
4840         links1=2
4841         ls
4842         mkdir a b
4843         ls
4844         links2=$(stat -c %h .)
4845         [ $(($links1 + 2)) != $links2 ] &&
4846                 error "wrong links count $(($links1 + 2)) != $links2"
4847         rmdir b
4848         links3=$(stat -c %h .)
4849         [ $(($links1 + 1)) != $links3 ] &&
4850                 error "wrong links count $links1 != $links3"
4851         return 0
4852 }
4853 run_test 39o "directory cached attributes updated after create"
4854
4855 test_39p() {
4856         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4857
4858         local MDTIDX=1
4859         TESTDIR=$DIR/$tdir/$tdir
4860         [ -e $TESTDIR ] && rm -rf $TESTDIR
4861         test_mkdir -p $TESTDIR
4862         cd $TESTDIR
4863         links1=2
4864         ls
4865         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4866         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4867         ls
4868         links2=$(stat -c %h .)
4869         [ $(($links1 + 2)) != $links2 ] &&
4870                 error "wrong links count $(($links1 + 2)) != $links2"
4871         rmdir remote_dir2
4872         links3=$(stat -c %h .)
4873         [ $(($links1 + 1)) != $links3 ] &&
4874                 error "wrong links count $links1 != $links3"
4875         return 0
4876 }
4877 run_test 39p "remote directory cached attributes updated after create ========"
4878
4879 test_39r() {
4880         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4881                 skip "no atime update on old OST"
4882         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4883                 skip_env "ldiskfs only test"
4884         fi
4885
4886         local saved_adiff
4887         saved_adiff=$(do_facet ost1 \
4888                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4889         stack_trap "do_facet ost1 \
4890                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4891
4892         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4893
4894         $LFS setstripe -i 0 $DIR/$tfile
4895         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4896                 error "can't write initial file"
4897         cancel_lru_locks osc
4898
4899         # exceed atime_diff and access file
4900         sleep 6
4901         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4902                 error "can't udpate atime"
4903
4904         local atime_cli=$(stat -c %X $DIR/$tfile)
4905         echo "client atime: $atime_cli"
4906         # allow atime update to be written to device
4907         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4908         sleep 5
4909
4910         local ostdev=$(ostdevname 1)
4911         local fid=($(lfs getstripe -y $DIR/$tfile |
4912                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4913         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4914         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4915
4916         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4917         local atime_ost=$(do_facet ost1 "$cmd" |&
4918                           awk -F'[: ]' '/atime:/ { print $4 }')
4919         (( atime_cli == atime_ost )) ||
4920                 error "atime on client $atime_cli != ost $atime_ost"
4921 }
4922 run_test 39r "lazy atime update on OST"
4923
4924 test_39q() { # LU-8041
4925         local testdir=$DIR/$tdir
4926         mkdir -p $testdir
4927         multiop_bg_pause $testdir D_c || error "multiop failed"
4928         local multipid=$!
4929         cancel_lru_locks mdc
4930         kill -USR1 $multipid
4931         local atime=$(stat -c %X $testdir)
4932         [ "$atime" -ne 0 ] || error "atime is zero"
4933 }
4934 run_test 39q "close won't zero out atime"
4935
4936 test_40() {
4937         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4938         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4939                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4940         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4941                 error "$tfile is not 4096 bytes in size"
4942 }
4943 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4944
4945 test_41() {
4946         # bug 1553
4947         small_write $DIR/f41 18
4948 }
4949 run_test 41 "test small file write + fstat ====================="
4950
4951 count_ost_writes() {
4952         lctl get_param -n ${OSC}.*.stats |
4953                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4954                         END { printf("%0.0f", writes) }'
4955 }
4956
4957 # decent default
4958 WRITEBACK_SAVE=500
4959 DIRTY_RATIO_SAVE=40
4960 MAX_DIRTY_RATIO=50
4961 BG_DIRTY_RATIO_SAVE=10
4962 MAX_BG_DIRTY_RATIO=25
4963
4964 start_writeback() {
4965         trap 0
4966         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4967         # dirty_ratio, dirty_background_ratio
4968         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4969                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4970                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4971                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4972         else
4973                 # if file not here, we are a 2.4 kernel
4974                 kill -CONT `pidof kupdated`
4975         fi
4976 }
4977
4978 stop_writeback() {
4979         # setup the trap first, so someone cannot exit the test at the
4980         # exact wrong time and mess up a machine
4981         trap start_writeback EXIT
4982         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4983         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4984                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4985                 sysctl -w vm.dirty_writeback_centisecs=0
4986                 sysctl -w vm.dirty_writeback_centisecs=0
4987                 # save and increase /proc/sys/vm/dirty_ratio
4988                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4989                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4990                 # save and increase /proc/sys/vm/dirty_background_ratio
4991                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4992                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4993         else
4994                 # if file not here, we are a 2.4 kernel
4995                 kill -STOP `pidof kupdated`
4996         fi
4997 }
4998
4999 # ensure that all stripes have some grant before we test client-side cache
5000 setup_test42() {
5001         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5002                 dd if=/dev/zero of=$i bs=4k count=1
5003                 rm $i
5004         done
5005 }
5006
5007 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5008 # file truncation, and file removal.
5009 test_42a() {
5010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5011
5012         setup_test42
5013         cancel_lru_locks $OSC
5014         stop_writeback
5015         sync; sleep 1; sync # just to be safe
5016         BEFOREWRITES=`count_ost_writes`
5017         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5018         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5019         AFTERWRITES=`count_ost_writes`
5020         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5021                 error "$BEFOREWRITES < $AFTERWRITES"
5022         start_writeback
5023 }
5024 run_test 42a "ensure that we don't flush on close"
5025
5026 test_42b() {
5027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5028
5029         setup_test42
5030         cancel_lru_locks $OSC
5031         stop_writeback
5032         sync
5033         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5034         BEFOREWRITES=$(count_ost_writes)
5035         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5036         AFTERWRITES=$(count_ost_writes)
5037         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5038                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5039         fi
5040         BEFOREWRITES=$(count_ost_writes)
5041         sync || error "sync: $?"
5042         AFTERWRITES=$(count_ost_writes)
5043         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5044                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5045         fi
5046         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5047         start_writeback
5048         return 0
5049 }
5050 run_test 42b "test destroy of file with cached dirty data ======"
5051
5052 # if these tests just want to test the effect of truncation,
5053 # they have to be very careful.  consider:
5054 # - the first open gets a {0,EOF}PR lock
5055 # - the first write conflicts and gets a {0, count-1}PW
5056 # - the rest of the writes are under {count,EOF}PW
5057 # - the open for truncate tries to match a {0,EOF}PR
5058 #   for the filesize and cancels the PWs.
5059 # any number of fixes (don't get {0,EOF} on open, match
5060 # composite locks, do smarter file size management) fix
5061 # this, but for now we want these tests to verify that
5062 # the cancellation with truncate intent works, so we
5063 # start the file with a full-file pw lock to match against
5064 # until the truncate.
5065 trunc_test() {
5066         test=$1
5067         file=$DIR/$test
5068         offset=$2
5069         cancel_lru_locks $OSC
5070         stop_writeback
5071         # prime the file with 0,EOF PW to match
5072         touch $file
5073         $TRUNCATE $file 0
5074         sync; sync
5075         # now the real test..
5076         dd if=/dev/zero of=$file bs=1024 count=100
5077         BEFOREWRITES=`count_ost_writes`
5078         $TRUNCATE $file $offset
5079         cancel_lru_locks $OSC
5080         AFTERWRITES=`count_ost_writes`
5081         start_writeback
5082 }
5083
5084 test_42c() {
5085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5086
5087         trunc_test 42c 1024
5088         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5089                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5090         rm $file
5091 }
5092 run_test 42c "test partial truncate of file with cached dirty data"
5093
5094 test_42d() {
5095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5096
5097         trunc_test 42d 0
5098         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5099                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5100         rm $file
5101 }
5102 run_test 42d "test complete truncate of file with cached dirty data"
5103
5104 test_42e() { # bug22074
5105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5106
5107         local TDIR=$DIR/${tdir}e
5108         local pages=16 # hardcoded 16 pages, don't change it.
5109         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5110         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5111         local max_dirty_mb
5112         local warmup_files
5113
5114         test_mkdir $DIR/${tdir}e
5115         $LFS setstripe -c 1 $TDIR
5116         createmany -o $TDIR/f $files
5117
5118         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5119
5120         # we assume that with $OSTCOUNT files, at least one of them will
5121         # be allocated on OST0.
5122         warmup_files=$((OSTCOUNT * max_dirty_mb))
5123         createmany -o $TDIR/w $warmup_files
5124
5125         # write a large amount of data into one file and sync, to get good
5126         # avail_grant number from OST.
5127         for ((i=0; i<$warmup_files; i++)); do
5128                 idx=$($LFS getstripe -i $TDIR/w$i)
5129                 [ $idx -ne 0 ] && continue
5130                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5131                 break
5132         done
5133         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5134         sync
5135         $LCTL get_param $proc_osc0/cur_dirty_bytes
5136         $LCTL get_param $proc_osc0/cur_grant_bytes
5137
5138         # create as much dirty pages as we can while not to trigger the actual
5139         # RPCs directly. but depends on the env, VFS may trigger flush during this
5140         # period, hopefully we are good.
5141         for ((i=0; i<$warmup_files; i++)); do
5142                 idx=$($LFS getstripe -i $TDIR/w$i)
5143                 [ $idx -ne 0 ] && continue
5144                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5145         done
5146         $LCTL get_param $proc_osc0/cur_dirty_bytes
5147         $LCTL get_param $proc_osc0/cur_grant_bytes
5148
5149         # perform the real test
5150         $LCTL set_param $proc_osc0/rpc_stats 0
5151         for ((;i<$files; i++)); do
5152                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5153                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5154         done
5155         sync
5156         $LCTL get_param $proc_osc0/rpc_stats
5157
5158         local percent=0
5159         local have_ppr=false
5160         $LCTL get_param $proc_osc0/rpc_stats |
5161                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5162                         # skip lines until we are at the RPC histogram data
5163                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5164                         $have_ppr || continue
5165
5166                         # we only want the percent stat for < 16 pages
5167                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5168
5169                         percent=$((percent + WPCT))
5170                         if [[ $percent -gt 15 ]]; then
5171                                 error "less than 16-pages write RPCs" \
5172                                       "$percent% > 15%"
5173                                 break
5174                         fi
5175                 done
5176         rm -rf $TDIR
5177 }
5178 run_test 42e "verify sub-RPC writes are not done synchronously"
5179
5180 test_43A() { # was test_43
5181         test_mkdir $DIR/$tdir
5182         cp -p /bin/ls $DIR/$tdir/$tfile
5183         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5184         pid=$!
5185         # give multiop a chance to open
5186         sleep 1
5187
5188         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5189         kill -USR1 $pid
5190         # Wait for multiop to exit
5191         wait $pid
5192 }
5193 run_test 43A "execution of file opened for write should return -ETXTBSY"
5194
5195 test_43a() {
5196         test_mkdir $DIR/$tdir
5197         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5198         $DIR/$tdir/sleep 60 &
5199         SLEEP_PID=$!
5200         # Make sure exec of $tdir/sleep wins race with truncate
5201         sleep 1
5202         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5203         kill $SLEEP_PID
5204 }
5205 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5206
5207 test_43b() {
5208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5209
5210         test_mkdir $DIR/$tdir
5211         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5212         $DIR/$tdir/sleep 60 &
5213         SLEEP_PID=$!
5214         # Make sure exec of $tdir/sleep wins race with truncate
5215         sleep 1
5216         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5217         kill $SLEEP_PID
5218 }
5219 run_test 43b "truncate of file being executed should return -ETXTBSY"
5220
5221 test_43c() {
5222         local testdir="$DIR/$tdir"
5223         test_mkdir $testdir
5224         cp $SHELL $testdir/
5225         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5226                 ( cd $testdir && md5sum -c )
5227 }
5228 run_test 43c "md5sum of copy into lustre"
5229
5230 test_44A() { # was test_44
5231         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5232
5233         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5234         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5235 }
5236 run_test 44A "zero length read from a sparse stripe"
5237
5238 test_44a() {
5239         local nstripe=$($LFS getstripe -c -d $DIR)
5240         [ -z "$nstripe" ] && skip "can't get stripe info"
5241         [[ $nstripe -gt $OSTCOUNT ]] &&
5242                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5243
5244         local stride=$($LFS getstripe -S -d $DIR)
5245         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5246                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5247         fi
5248
5249         OFFSETS="0 $((stride/2)) $((stride-1))"
5250         for offset in $OFFSETS; do
5251                 for i in $(seq 0 $((nstripe-1))); do
5252                         local GLOBALOFFSETS=""
5253                         # size in Bytes
5254                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5255                         local myfn=$DIR/d44a-$size
5256                         echo "--------writing $myfn at $size"
5257                         ll_sparseness_write $myfn $size ||
5258                                 error "ll_sparseness_write"
5259                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5260                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5261                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5262
5263                         for j in $(seq 0 $((nstripe-1))); do
5264                                 # size in Bytes
5265                                 size=$((((j + $nstripe )*$stride + $offset)))
5266                                 ll_sparseness_write $myfn $size ||
5267                                         error "ll_sparseness_write"
5268                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5269                         done
5270                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5271                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5272                         rm -f $myfn
5273                 done
5274         done
5275 }
5276 run_test 44a "test sparse pwrite ==============================="
5277
5278 dirty_osc_total() {
5279         tot=0
5280         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5281                 tot=$(($tot + $d))
5282         done
5283         echo $tot
5284 }
5285 do_dirty_record() {
5286         before=`dirty_osc_total`
5287         echo executing "\"$*\""
5288         eval $*
5289         after=`dirty_osc_total`
5290         echo before $before, after $after
5291 }
5292 test_45() {
5293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5294
5295         f="$DIR/f45"
5296         # Obtain grants from OST if it supports it
5297         echo blah > ${f}_grant
5298         stop_writeback
5299         sync
5300         do_dirty_record "echo blah > $f"
5301         [[ $before -eq $after ]] && error "write wasn't cached"
5302         do_dirty_record "> $f"
5303         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5304         do_dirty_record "echo blah > $f"
5305         [[ $before -eq $after ]] && error "write wasn't cached"
5306         do_dirty_record "sync"
5307         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5308         do_dirty_record "echo blah > $f"
5309         [[ $before -eq $after ]] && error "write wasn't cached"
5310         do_dirty_record "cancel_lru_locks osc"
5311         [[ $before -gt $after ]] ||
5312                 error "lock cancellation didn't lower dirty count"
5313         start_writeback
5314 }
5315 run_test 45 "osc io page accounting ============================"
5316
5317 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5318 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5319 # objects offset and an assert hit when an rpc was built with 1023's mapped
5320 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5321 test_46() {
5322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5323
5324         f="$DIR/f46"
5325         stop_writeback
5326         sync
5327         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5328         sync
5329         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5330         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5331         sync
5332         start_writeback
5333 }
5334 run_test 46 "dirtying a previously written page ================"
5335
5336 # test_47 is removed "Device nodes check" is moved to test_28
5337
5338 test_48a() { # bug 2399
5339         [ "$mds1_FSTYPE" = "zfs" ] &&
5340         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5341                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5342
5343         test_mkdir $DIR/$tdir
5344         cd $DIR/$tdir
5345         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5346         test_mkdir $DIR/$tdir
5347         touch foo || error "'touch foo' failed after recreating cwd"
5348         test_mkdir bar
5349         touch .foo || error "'touch .foo' failed after recreating cwd"
5350         test_mkdir .bar
5351         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5352         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5353         cd . || error "'cd .' failed after recreating cwd"
5354         mkdir . && error "'mkdir .' worked after recreating cwd"
5355         rmdir . && error "'rmdir .' worked after recreating cwd"
5356         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5357         cd .. || error "'cd ..' failed after recreating cwd"
5358 }
5359 run_test 48a "Access renamed working dir (should return errors)="
5360
5361 test_48b() { # bug 2399
5362         rm -rf $DIR/$tdir
5363         test_mkdir $DIR/$tdir
5364         cd $DIR/$tdir
5365         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5366         touch foo && error "'touch foo' worked after removing cwd"
5367         mkdir foo && error "'mkdir foo' worked after removing cwd"
5368         touch .foo && error "'touch .foo' worked after removing cwd"
5369         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5370         ls . > /dev/null && error "'ls .' worked after removing cwd"
5371         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5372         mkdir . && error "'mkdir .' worked after removing cwd"
5373         rmdir . && error "'rmdir .' worked after removing cwd"
5374         ln -s . foo && error "'ln -s .' worked after removing cwd"
5375         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5376 }
5377 run_test 48b "Access removed working dir (should return errors)="
5378
5379 test_48c() { # bug 2350
5380         #lctl set_param debug=-1
5381         #set -vx
5382         rm -rf $DIR/$tdir
5383         test_mkdir -p $DIR/$tdir/dir
5384         cd $DIR/$tdir/dir
5385         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5386         $TRACE touch foo && error "touch foo worked after removing cwd"
5387         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5388         touch .foo && error "touch .foo worked after removing cwd"
5389         mkdir .foo && error "mkdir .foo worked after removing cwd"
5390         $TRACE ls . && error "'ls .' worked after removing cwd"
5391         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5392         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5393         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5394         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5395         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5396 }
5397 run_test 48c "Access removed working subdir (should return errors)"
5398
5399 test_48d() { # bug 2350
5400         #lctl set_param debug=-1
5401         #set -vx
5402         rm -rf $DIR/$tdir
5403         test_mkdir -p $DIR/$tdir/dir
5404         cd $DIR/$tdir/dir
5405         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5406         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5407         $TRACE touch foo && error "'touch foo' worked after removing parent"
5408         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5409         touch .foo && error "'touch .foo' worked after removing parent"
5410         mkdir .foo && error "mkdir .foo worked after removing parent"
5411         $TRACE ls . && error "'ls .' worked after removing parent"
5412         $TRACE ls .. && error "'ls ..' worked after removing parent"
5413         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5414         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5415         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5416         true
5417 }
5418 run_test 48d "Access removed parent subdir (should return errors)"
5419
5420 test_48e() { # bug 4134
5421         #lctl set_param debug=-1
5422         #set -vx
5423         rm -rf $DIR/$tdir
5424         test_mkdir -p $DIR/$tdir/dir
5425         cd $DIR/$tdir/dir
5426         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5427         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5428         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5429         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5430         # On a buggy kernel addition of "touch foo" after cd .. will
5431         # produce kernel oops in lookup_hash_it
5432         touch ../foo && error "'cd ..' worked after recreate parent"
5433         cd $DIR
5434         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5435 }
5436 run_test 48e "Access to recreated parent subdir (should return errors)"
5437
5438 test_48f() {
5439         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5440                 skip "need MDS >= 2.13.55"
5441         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5442         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5443                 skip "needs different host for mdt1 mdt2"
5444         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5445
5446         $LFS mkdir -i0 $DIR/$tdir
5447         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5448
5449         for d in sub1 sub2 sub3; do
5450                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5451                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5452                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5453         done
5454
5455         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5456 }
5457 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5458
5459 test_49() { # LU-1030
5460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5461         remote_ost_nodsh && skip "remote OST with nodsh"
5462
5463         # get ost1 size - $FSNAME-OST0000
5464         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5465                 awk '{ print $4 }')
5466         # write 800M at maximum
5467         [[ $ost1_size -lt 2 ]] && ost1_size=2
5468         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5469
5470         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5471         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5472         local dd_pid=$!
5473
5474         # change max_pages_per_rpc while writing the file
5475         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5476         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5477         # loop until dd process exits
5478         while ps ax -opid | grep -wq $dd_pid; do
5479                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5480                 sleep $((RANDOM % 5 + 1))
5481         done
5482         # restore original max_pages_per_rpc
5483         $LCTL set_param $osc1_mppc=$orig_mppc
5484         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5485 }
5486 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5487
5488 test_50() {
5489         # bug 1485
5490         test_mkdir $DIR/$tdir
5491         cd $DIR/$tdir
5492         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5493 }
5494 run_test 50 "special situations: /proc symlinks  ==============="
5495
5496 test_51a() {    # was test_51
5497         # bug 1516 - create an empty entry right after ".." then split dir
5498         test_mkdir -c1 $DIR/$tdir
5499         touch $DIR/$tdir/foo
5500         $MCREATE $DIR/$tdir/bar
5501         rm $DIR/$tdir/foo
5502         createmany -m $DIR/$tdir/longfile 201
5503         FNUM=202
5504         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5505                 $MCREATE $DIR/$tdir/longfile$FNUM
5506                 FNUM=$(($FNUM + 1))
5507                 echo -n "+"
5508         done
5509         echo
5510         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5511 }
5512 run_test 51a "special situations: split htree with empty entry =="
5513
5514 cleanup_print_lfs_df () {
5515         trap 0
5516         $LFS df
5517         $LFS df -i
5518 }
5519
5520 test_51b() {
5521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5522
5523         local dir=$DIR/$tdir
5524         local nrdirs=$((65536 + 100))
5525
5526         # cleanup the directory
5527         rm -fr $dir
5528
5529         test_mkdir -c1 $dir
5530
5531         $LFS df
5532         $LFS df -i
5533         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5534         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5535         [[ $numfree -lt $nrdirs ]] &&
5536                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5537
5538         # need to check free space for the directories as well
5539         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5540         numfree=$(( blkfree / $(fs_inode_ksize) ))
5541         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5542
5543         trap cleanup_print_lfs_df EXIT
5544
5545         # create files
5546         createmany -d $dir/d $nrdirs || {
5547                 unlinkmany $dir/d $nrdirs
5548                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5549         }
5550
5551         # really created :
5552         nrdirs=$(ls -U $dir | wc -l)
5553
5554         # unlink all but 100 subdirectories, then check it still works
5555         local left=100
5556         local delete=$((nrdirs - left))
5557
5558         $LFS df
5559         $LFS df -i
5560
5561         # for ldiskfs the nlink count should be 1, but this is OSD specific
5562         # and so this is listed for informational purposes only
5563         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5564         unlinkmany -d $dir/d $delete ||
5565                 error "unlink of first $delete subdirs failed"
5566
5567         echo "nlink between: $(stat -c %h $dir)"
5568         local found=$(ls -U $dir | wc -l)
5569         [ $found -ne $left ] &&
5570                 error "can't find subdirs: found only $found, expected $left"
5571
5572         unlinkmany -d $dir/d $delete $left ||
5573                 error "unlink of second $left subdirs failed"
5574         # regardless of whether the backing filesystem tracks nlink accurately
5575         # or not, the nlink count shouldn't be more than "." and ".." here
5576         local after=$(stat -c %h $dir)
5577         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5578                 echo "nlink after: $after"
5579
5580         cleanup_print_lfs_df
5581 }
5582 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5583
5584 test_51d() {
5585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5586         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5587
5588         test_mkdir $DIR/$tdir
5589         createmany -o $DIR/$tdir/t- 1000
5590         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5591         for N in $(seq 0 $((OSTCOUNT - 1))); do
5592                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5593                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5594                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5595                         '($1 == '$N') { objs += 1 } \
5596                         END { printf("%0.0f", objs) }')
5597                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5598         done
5599         unlinkmany $DIR/$tdir/t- 1000
5600
5601         NLAST=0
5602         for N in $(seq 1 $((OSTCOUNT - 1))); do
5603                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5604                         error "OST $N has less objects vs OST $NLAST" \
5605                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5606                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5607                         error "OST $N has less objects vs OST $NLAST" \
5608                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5609
5610                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5611                         error "OST $N has less #0 objects vs OST $NLAST" \
5612                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5613                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5614                         error "OST $N has less #0 objects vs OST $NLAST" \
5615                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5616                 NLAST=$N
5617         done
5618         rm -f $TMP/$tfile
5619 }
5620 run_test 51d "check object distribution"
5621
5622 test_51e() {
5623         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5624                 skip_env "ldiskfs only test"
5625         fi
5626
5627         test_mkdir -c1 $DIR/$tdir
5628         test_mkdir -c1 $DIR/$tdir/d0
5629
5630         touch $DIR/$tdir/d0/foo
5631         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5632                 error "file exceed 65000 nlink limit!"
5633         unlinkmany $DIR/$tdir/d0/f- 65001
5634         return 0
5635 }
5636 run_test 51e "check file nlink limit"
5637
5638 test_51f() {
5639         test_mkdir $DIR/$tdir
5640
5641         local max=100000
5642         local ulimit_old=$(ulimit -n)
5643         local spare=20 # number of spare fd's for scripts/libraries, etc.
5644         local mdt=$($LFS getstripe -m $DIR/$tdir)
5645         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5646
5647         echo "MDT$mdt numfree=$numfree, max=$max"
5648         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5649         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5650                 while ! ulimit -n $((numfree + spare)); do
5651                         numfree=$((numfree * 3 / 4))
5652                 done
5653                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5654         else
5655                 echo "left ulimit at $ulimit_old"
5656         fi
5657
5658         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5659                 unlinkmany $DIR/$tdir/f $numfree
5660                 error "create+open $numfree files in $DIR/$tdir failed"
5661         }
5662         ulimit -n $ulimit_old
5663
5664         # if createmany exits at 120s there will be fewer than $numfree files
5665         unlinkmany $DIR/$tdir/f $numfree || true
5666 }
5667 run_test 51f "check many open files limit"
5668
5669 test_52a() {
5670         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5671         test_mkdir $DIR/$tdir
5672         touch $DIR/$tdir/foo
5673         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5674         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5675         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5676         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5677         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5678                                         error "link worked"
5679         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5680         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5681         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5682                                                      error "lsattr"
5683         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5684         cp -r $DIR/$tdir $TMP/
5685         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5686 }
5687 run_test 52a "append-only flag test (should return errors)"
5688
5689 test_52b() {
5690         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5691         test_mkdir $DIR/$tdir
5692         touch $DIR/$tdir/foo
5693         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5694         cat test > $DIR/$tdir/foo && error "cat test worked"
5695         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5696         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5697         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5698                                         error "link worked"
5699         echo foo >> $DIR/$tdir/foo && error "echo worked"
5700         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5701         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5702         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5703         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5704                                                         error "lsattr"
5705         chattr -i $DIR/$tdir/foo || error "chattr failed"
5706
5707         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5708 }
5709 run_test 52b "immutable flag test (should return errors) ======="
5710
5711 test_53() {
5712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5713         remote_mds_nodsh && skip "remote MDS with nodsh"
5714         remote_ost_nodsh && skip "remote OST with nodsh"
5715
5716         local param
5717         local param_seq
5718         local ostname
5719         local mds_last
5720         local mds_last_seq
5721         local ost_last
5722         local ost_last_seq
5723         local ost_last_id
5724         local ostnum
5725         local node
5726         local found=false
5727         local support_last_seq=true
5728
5729         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5730                 support_last_seq=false
5731
5732         # only test MDT0000
5733         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5734         local value
5735         for value in $(do_facet $SINGLEMDS \
5736                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5737                 param=$(echo ${value[0]} | cut -d "=" -f1)
5738                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5739
5740                 if $support_last_seq; then
5741                         param_seq=$(echo $param |
5742                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5743                         mds_last_seq=$(do_facet $SINGLEMDS \
5744                                        $LCTL get_param -n $param_seq)
5745                 fi
5746                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5747
5748                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5749                 node=$(facet_active_host ost$((ostnum+1)))
5750                 param="obdfilter.$ostname.last_id"
5751                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5752                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5753                         ost_last_id=$ost_last
5754
5755                         if $support_last_seq; then
5756                                 ost_last_id=$(echo $ost_last |
5757                                               awk -F':' '{print $2}' |
5758                                               sed -e "s/^0x//g")
5759                                 ost_last_seq=$(echo $ost_last |
5760                                                awk -F':' '{print $1}')
5761                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5762                         fi
5763
5764                         if [[ $ost_last_id != $mds_last ]]; then
5765                                 error "$ost_last_id != $mds_last"
5766                         else
5767                                 found=true
5768                                 break
5769                         fi
5770                 done
5771         done
5772         $found || error "can not match last_seq/last_id for $mdtosc"
5773         return 0
5774 }
5775 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5776
5777 test_54a() {
5778         perl -MSocket -e ';' || skip "no Socket perl module installed"
5779
5780         $SOCKETSERVER $DIR/socket ||
5781                 error "$SOCKETSERVER $DIR/socket failed: $?"
5782         $SOCKETCLIENT $DIR/socket ||
5783                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5784         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5785 }
5786 run_test 54a "unix domain socket test =========================="
5787
5788 test_54b() {
5789         f="$DIR/f54b"
5790         mknod $f c 1 3
5791         chmod 0666 $f
5792         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5793 }
5794 run_test 54b "char device works in lustre ======================"
5795
5796 find_loop_dev() {
5797         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5798         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5799         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5800
5801         for i in $(seq 3 7); do
5802                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5803                 LOOPDEV=$LOOPBASE$i
5804                 LOOPNUM=$i
5805                 break
5806         done
5807 }
5808
5809 cleanup_54c() {
5810         local rc=0
5811         loopdev="$DIR/loop54c"
5812
5813         trap 0
5814         $UMOUNT $DIR/$tdir || rc=$?
5815         losetup -d $loopdev || true
5816         losetup -d $LOOPDEV || true
5817         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5818         return $rc
5819 }
5820
5821 test_54c() {
5822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5823
5824         loopdev="$DIR/loop54c"
5825
5826         find_loop_dev
5827         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5828         trap cleanup_54c EXIT
5829         mknod $loopdev b 7 $LOOPNUM
5830         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5831         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5832         losetup $loopdev $DIR/$tfile ||
5833                 error "can't set up $loopdev for $DIR/$tfile"
5834         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5835         test_mkdir $DIR/$tdir
5836         mount -t ext2 $loopdev $DIR/$tdir ||
5837                 error "error mounting $loopdev on $DIR/$tdir"
5838         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5839                 error "dd write"
5840         df $DIR/$tdir
5841         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5842                 error "dd read"
5843         cleanup_54c
5844 }
5845 run_test 54c "block device works in lustre ====================="
5846
5847 test_54d() {
5848         f="$DIR/f54d"
5849         string="aaaaaa"
5850         mknod $f p
5851         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5852 }
5853 run_test 54d "fifo device works in lustre ======================"
5854
5855 test_54e() {
5856         f="$DIR/f54e"
5857         string="aaaaaa"
5858         cp -aL /dev/console $f
5859         echo $string > $f || error "echo $string to $f failed"
5860 }
5861 run_test 54e "console/tty device works in lustre ======================"
5862
5863 test_56a() {
5864         local numfiles=3
5865         local dir=$DIR/$tdir
5866
5867         rm -rf $dir
5868         test_mkdir -p $dir/dir
5869         for i in $(seq $numfiles); do
5870                 touch $dir/file$i
5871                 touch $dir/dir/file$i
5872         done
5873
5874         local numcomp=$($LFS getstripe --component-count $dir)
5875
5876         [[ $numcomp == 0 ]] && numcomp=1
5877
5878         # test lfs getstripe with --recursive
5879         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5880
5881         [[ $filenum -eq $((numfiles * 2)) ]] ||
5882                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5883         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5884         [[ $filenum -eq $numfiles ]] ||
5885                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5886         echo "$LFS getstripe showed obdidx or l_ost_idx"
5887
5888         # test lfs getstripe with file instead of dir
5889         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5890         [[ $filenum -eq 1 ]] ||
5891                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5892         echo "$LFS getstripe file1 passed"
5893
5894         #test lfs getstripe with --verbose
5895         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5896         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5897                 error "$LFS getstripe --verbose $dir: "\
5898                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5899         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5900                 error "$LFS getstripe $dir: showed lmm_magic"
5901
5902         #test lfs getstripe with -v prints lmm_fid
5903         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5904         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5905                 error "$LFS getstripe -v $dir: "\
5906                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5907         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5908                 error "$LFS getstripe $dir: showed lmm_fid by default"
5909         echo "$LFS getstripe --verbose passed"
5910
5911         #check for FID information
5912         local fid1=$($LFS getstripe --fid $dir/file1)
5913         local fid2=$($LFS getstripe --verbose $dir/file1 |
5914                      awk '/lmm_fid: / { print $2; exit; }')
5915         local fid3=$($LFS path2fid $dir/file1)
5916
5917         [ "$fid1" != "$fid2" ] &&
5918                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5919         [ "$fid1" != "$fid3" ] &&
5920                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5921         echo "$LFS getstripe --fid passed"
5922
5923         #test lfs getstripe with --obd
5924         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5925                 error "$LFS getstripe --obd wrong_uuid: should return error"
5926
5927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5928
5929         local ostidx=1
5930         local obduuid=$(ostuuid_from_index $ostidx)
5931         local found=$($LFS getstripe -r --obd $obduuid $dir |
5932                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5933
5934         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5935         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5936                 ((filenum--))
5937         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5938                 ((filenum--))
5939
5940         [[ $found -eq $filenum ]] ||
5941                 error "$LFS getstripe --obd: found $found expect $filenum"
5942         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5943                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5944                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5945                 error "$LFS getstripe --obd: should not show file on other obd"
5946         echo "$LFS getstripe --obd passed"
5947 }
5948 run_test 56a "check $LFS getstripe"
5949
5950 test_56b() {
5951         local dir=$DIR/$tdir
5952         local numdirs=3
5953
5954         test_mkdir $dir
5955         for i in $(seq $numdirs); do
5956                 test_mkdir $dir/dir$i
5957         done
5958
5959         # test lfs getdirstripe default mode is non-recursion, which is
5960         # different from lfs getstripe
5961         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5962
5963         [[ $dircnt -eq 1 ]] ||
5964                 error "$LFS getdirstripe: found $dircnt, not 1"
5965         dircnt=$($LFS getdirstripe --recursive $dir |
5966                 grep -c lmv_stripe_count)
5967         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5968                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5969 }
5970 run_test 56b "check $LFS getdirstripe"
5971
5972 test_56c() {
5973         remote_ost_nodsh && skip "remote OST with nodsh"
5974
5975         local ost_idx=0
5976         local ost_name=$(ostname_from_index $ost_idx)
5977         local old_status=$(ost_dev_status $ost_idx)
5978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5979
5980         [[ -z "$old_status" ]] ||
5981                 skip_env "OST $ost_name is in $old_status status"
5982
5983         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5984         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5985                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5986         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5987                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5988                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5989         fi
5990
5991         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5992                 error "$LFS df -v showing inactive devices"
5993         sleep_maxage
5994
5995         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5996
5997         [[ "$new_status" =~ "D" ]] ||
5998                 error "$ost_name status is '$new_status', missing 'D'"
5999         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6000                 [[ "$new_status" =~ "N" ]] ||
6001                         error "$ost_name status is '$new_status', missing 'N'"
6002         fi
6003         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6004                 [[ "$new_status" =~ "f" ]] ||
6005                         error "$ost_name status is '$new_status', missing 'f'"
6006         fi
6007
6008         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6009         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6010                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6011         [[ -z "$p" ]] && restore_lustre_params < $p || true
6012         sleep_maxage
6013
6014         new_status=$(ost_dev_status $ost_idx)
6015         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6016                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6017         # can't check 'f' as devices may actually be on flash
6018 }
6019 run_test 56c "check 'lfs df' showing device status"
6020
6021 test_56d() {
6022         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6023         local osts=$($LFS df -v $MOUNT | grep -c OST)
6024
6025         $LFS df $MOUNT
6026
6027         (( mdts == MDSCOUNT )) ||
6028                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6029         (( osts == OSTCOUNT )) ||
6030                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6031 }
6032 run_test 56d "'lfs df -v' prints only configured devices"
6033
6034 NUMFILES=3
6035 NUMDIRS=3
6036 setup_56() {
6037         local local_tdir="$1"
6038         local local_numfiles="$2"
6039         local local_numdirs="$3"
6040         local dir_params="$4"
6041         local dir_stripe_params="$5"
6042
6043         if [ ! -d "$local_tdir" ] ; then
6044                 test_mkdir -p $dir_stripe_params $local_tdir
6045                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6046                 for i in $(seq $local_numfiles) ; do
6047                         touch $local_tdir/file$i
6048                 done
6049                 for i in $(seq $local_numdirs) ; do
6050                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6051                         for j in $(seq $local_numfiles) ; do
6052                                 touch $local_tdir/dir$i/file$j
6053                         done
6054                 done
6055         fi
6056 }
6057
6058 setup_56_special() {
6059         local local_tdir=$1
6060         local local_numfiles=$2
6061         local local_numdirs=$3
6062
6063         setup_56 $local_tdir $local_numfiles $local_numdirs
6064
6065         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6066                 for i in $(seq $local_numfiles) ; do
6067                         mknod $local_tdir/loop${i}b b 7 $i
6068                         mknod $local_tdir/null${i}c c 1 3
6069                         ln -s $local_tdir/file1 $local_tdir/link${i}
6070                 done
6071                 for i in $(seq $local_numdirs) ; do
6072                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6073                         mknod $local_tdir/dir$i/null${i}c c 1 3
6074                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6075                 done
6076         fi
6077 }
6078
6079 test_56g() {
6080         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6081         local expected=$(($NUMDIRS + 2))
6082
6083         setup_56 $dir $NUMFILES $NUMDIRS
6084
6085         # test lfs find with -name
6086         for i in $(seq $NUMFILES) ; do
6087                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6088
6089                 [ $nums -eq $expected ] ||
6090                         error "lfs find -name '*$i' $dir wrong: "\
6091                               "found $nums, expected $expected"
6092         done
6093 }
6094 run_test 56g "check lfs find -name"
6095
6096 test_56h() {
6097         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6098         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6099
6100         setup_56 $dir $NUMFILES $NUMDIRS
6101
6102         # test lfs find with ! -name
6103         for i in $(seq $NUMFILES) ; do
6104                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6105
6106                 [ $nums -eq $expected ] ||
6107                         error "lfs find ! -name '*$i' $dir wrong: "\
6108                               "found $nums, expected $expected"
6109         done
6110 }
6111 run_test 56h "check lfs find ! -name"
6112
6113 test_56i() {
6114         local dir=$DIR/$tdir
6115
6116         test_mkdir $dir
6117
6118         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6119         local out=$($cmd)
6120
6121         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6122 }
6123 run_test 56i "check 'lfs find -ost UUID' skips directories"
6124
6125 test_56j() {
6126         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6127
6128         setup_56_special $dir $NUMFILES $NUMDIRS
6129
6130         local expected=$((NUMDIRS + 1))
6131         local cmd="$LFS find -type d $dir"
6132         local nums=$($cmd | wc -l)
6133
6134         [ $nums -eq $expected ] ||
6135                 error "'$cmd' wrong: found $nums, expected $expected"
6136 }
6137 run_test 56j "check lfs find -type d"
6138
6139 test_56k() {
6140         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6141
6142         setup_56_special $dir $NUMFILES $NUMDIRS
6143
6144         local expected=$(((NUMDIRS + 1) * NUMFILES))
6145         local cmd="$LFS find -type f $dir"
6146         local nums=$($cmd | wc -l)
6147
6148         [ $nums -eq $expected ] ||
6149                 error "'$cmd' wrong: found $nums, expected $expected"
6150 }
6151 run_test 56k "check lfs find -type f"
6152
6153 test_56l() {
6154         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6155
6156         setup_56_special $dir $NUMFILES $NUMDIRS
6157
6158         local expected=$((NUMDIRS + NUMFILES))
6159         local cmd="$LFS find -type b $dir"
6160         local nums=$($cmd | wc -l)
6161
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164 }
6165 run_test 56l "check lfs find -type b"
6166
6167 test_56m() {
6168         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6169
6170         setup_56_special $dir $NUMFILES $NUMDIRS
6171
6172         local expected=$((NUMDIRS + NUMFILES))
6173         local cmd="$LFS find -type c $dir"
6174         local nums=$($cmd | wc -l)
6175         [ $nums -eq $expected ] ||
6176                 error "'$cmd' wrong: found $nums, expected $expected"
6177 }
6178 run_test 56m "check lfs find -type c"
6179
6180 test_56n() {
6181         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6182         setup_56_special $dir $NUMFILES $NUMDIRS
6183
6184         local expected=$((NUMDIRS + NUMFILES))
6185         local cmd="$LFS find -type l $dir"
6186         local nums=$($cmd | wc -l)
6187
6188         [ $nums -eq $expected ] ||
6189                 error "'$cmd' wrong: found $nums, expected $expected"
6190 }
6191 run_test 56n "check lfs find -type l"
6192
6193 test_56o() {
6194         local dir=$DIR/$tdir
6195
6196         setup_56 $dir $NUMFILES $NUMDIRS
6197         utime $dir/file1 > /dev/null || error "utime (1)"
6198         utime $dir/file2 > /dev/null || error "utime (2)"
6199         utime $dir/dir1 > /dev/null || error "utime (3)"
6200         utime $dir/dir2 > /dev/null || error "utime (4)"
6201         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6202         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6203
6204         local expected=4
6205         local nums=$($LFS find -mtime +0 $dir | wc -l)
6206
6207         [ $nums -eq $expected ] ||
6208                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6209
6210         expected=12
6211         cmd="$LFS find -mtime 0 $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] ||
6214                 error "'$cmd' wrong: found $nums, expected $expected"
6215 }
6216 run_test 56o "check lfs find -mtime for old files"
6217
6218 test_56ob() {
6219         local dir=$DIR/$tdir
6220         local expected=1
6221         local count=0
6222
6223         # just to make sure there is something that won't be found
6224         test_mkdir $dir
6225         touch $dir/$tfile.now
6226
6227         for age in year week day hour min; do
6228                 count=$((count + 1))
6229
6230                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6231                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6232                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6233
6234                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6235                 local nums=$($cmd | wc -l)
6236                 [ $nums -eq $expected ] ||
6237                         error "'$cmd' wrong: found $nums, expected $expected"
6238
6239                 cmd="$LFS find $dir -atime $count${age:0:1}"
6240                 nums=$($cmd | wc -l)
6241                 [ $nums -eq $expected ] ||
6242                         error "'$cmd' wrong: found $nums, expected $expected"
6243         done
6244
6245         sleep 2
6246         cmd="$LFS find $dir -ctime +1s -type f"
6247         nums=$($cmd | wc -l)
6248         (( $nums == $count * 2 + 1)) ||
6249                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6250 }
6251 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6252
6253 test_newerXY_base() {
6254         local x=$1
6255         local y=$2
6256         local dir=$DIR/$tdir
6257         local ref
6258         local negref
6259
6260         if [ $y == "t" ]; then
6261                 if [ $x == "b" ]; then
6262                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6263                 else
6264                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6265                 fi
6266         else
6267                 ref=$DIR/$tfile.newer.$x$y
6268                 touch $ref || error "touch $ref failed"
6269         fi
6270
6271         echo "before = $ref"
6272         sleep 2
6273         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6274         sleep 2
6275         if [ $y == "t" ]; then
6276                 if [ $x == "b" ]; then
6277                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6278                 else
6279                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6280                 fi
6281         else
6282                 negref=$DIR/$tfile.negnewer.$x$y
6283                 touch $negref || error "touch $negref failed"
6284         fi
6285
6286         echo "after = $negref"
6287         local cmd="$LFS find $dir -newer$x$y $ref"
6288         local nums=$(eval $cmd | wc -l)
6289         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6290
6291         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6292                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6293
6294         cmd="$LFS find $dir ! -newer$x$y $negref"
6295         nums=$(eval $cmd | wc -l)
6296         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6297                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6298
6299         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6300         nums=$(eval $cmd | wc -l)
6301         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6302                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6303
6304         rm -rf $DIR/*
6305 }
6306
6307 test_56oc() {
6308         test_newerXY_base "a" "a"
6309         test_newerXY_base "a" "m"
6310         test_newerXY_base "a" "c"
6311         test_newerXY_base "m" "a"
6312         test_newerXY_base "m" "m"
6313         test_newerXY_base "m" "c"
6314         test_newerXY_base "c" "a"
6315         test_newerXY_base "c" "m"
6316         test_newerXY_base "c" "c"
6317
6318         [[ -n "$sles_version" ]] &&
6319                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6320
6321         test_newerXY_base "a" "t"
6322         test_newerXY_base "m" "t"
6323         test_newerXY_base "c" "t"
6324
6325         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6326            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6327                 ! btime_supported && echo "btime unsupported" && return 0
6328
6329         test_newerXY_base "b" "b"
6330         test_newerXY_base "b" "t"
6331 }
6332 run_test 56oc "check lfs find -newerXY work"
6333
6334 btime_supported() {
6335         local dir=$DIR/$tdir
6336         local rc
6337
6338         mkdir -p $dir
6339         touch $dir/$tfile
6340         $LFS find $dir -btime -1d -type f
6341         rc=$?
6342         rm -rf $dir
6343         return $rc
6344 }
6345
6346 test_56od() {
6347         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6348                 ! btime_supported && skip "btime unsupported on MDS"
6349
6350         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6351                 ! btime_supported && skip "btime unsupported on clients"
6352
6353         local dir=$DIR/$tdir
6354         local ref=$DIR/$tfile.ref
6355         local negref=$DIR/$tfile.negref
6356
6357         mkdir $dir || error "mkdir $dir failed"
6358         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6359         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6360         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6361         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6362         touch $ref || error "touch $ref failed"
6363         # sleep 3 seconds at least
6364         sleep 3
6365
6366         local before=$(do_facet mds1 date +%s)
6367         local skew=$(($(date +%s) - before + 1))
6368
6369         if (( skew < 0 && skew > -5 )); then
6370                 sleep $((0 - skew + 1))
6371                 skew=0
6372         fi
6373
6374         # Set the dir stripe params to limit files all on MDT0,
6375         # otherwise we need to calc the max clock skew between
6376         # the client and MDTs.
6377         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6378         sleep 2
6379         touch $negref || error "touch $negref failed"
6380
6381         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6382         local nums=$($cmd | wc -l)
6383         local expected=$(((NUMFILES + 1) * NUMDIRS))
6384
6385         [ $nums -eq $expected ] ||
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387
6388         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6389         nums=$($cmd | wc -l)
6390         expected=$((NUMFILES + 1))
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         [ $skew -lt 0 ] && return
6395
6396         local after=$(do_facet mds1 date +%s)
6397         local age=$((after - before + 1 + skew))
6398
6399         cmd="$LFS find $dir -btime -${age}s -type f"
6400         nums=$($cmd | wc -l)
6401         expected=$(((NUMFILES + 1) * NUMDIRS))
6402
6403         echo "Clock skew between client and server: $skew, age:$age"
6404         [ $nums -eq $expected ] ||
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406
6407         expected=$(($NUMDIRS + 1))
6408         cmd="$LFS find $dir -btime -${age}s -type d"
6409         nums=$($cmd | wc -l)
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         rm -f $ref $negref || error "Failed to remove $ref $negref"
6413 }
6414 run_test 56od "check lfs find -btime with units"
6415
6416 test_56p() {
6417         [ $RUNAS_ID -eq $UID ] &&
6418                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6419
6420         local dir=$DIR/$tdir
6421
6422         setup_56 $dir $NUMFILES $NUMDIRS
6423         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6424
6425         local expected=$NUMFILES
6426         local cmd="$LFS find -uid $RUNAS_ID $dir"
6427         local nums=$($cmd | wc -l)
6428
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6433         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437 }
6438 run_test 56p "check lfs find -uid and ! -uid"
6439
6440 test_56q() {
6441         [ $RUNAS_ID -eq $UID ] &&
6442                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6443
6444         local dir=$DIR/$tdir
6445
6446         setup_56 $dir $NUMFILES $NUMDIRS
6447         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6448
6449         local expected=$NUMFILES
6450         local cmd="$LFS find -gid $RUNAS_GID $dir"
6451         local nums=$($cmd | wc -l)
6452
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6457         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6458         nums=$($cmd | wc -l)
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461 }
6462 run_test 56q "check lfs find -gid and ! -gid"
6463
6464 test_56r() {
6465         local dir=$DIR/$tdir
6466
6467         setup_56 $dir $NUMFILES $NUMDIRS
6468
6469         local expected=12
6470         local cmd="$LFS find -size 0 -type f -lazy $dir"
6471         local nums=$($cmd | wc -l)
6472
6473         [ $nums -eq $expected ] ||
6474                 error "'$cmd' wrong: found $nums, expected $expected"
6475         cmd="$LFS find -size 0 -type f $dir"
6476         nums=$($cmd | wc -l)
6477         [ $nums -eq $expected ] ||
6478                 error "'$cmd' wrong: found $nums, expected $expected"
6479
6480         expected=0
6481         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485         cmd="$LFS find ! -size 0 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         echo "test" > $dir/$tfile
6491         echo "test2" > $dir/$tfile.2 && sync
6492         expected=1
6493         cmd="$LFS find -size 5 -type f -lazy $dir"
6494         nums=$($cmd | wc -l)
6495         [ $nums -eq $expected ] ||
6496                 error "'$cmd' wrong: found $nums, expected $expected"
6497         cmd="$LFS find -size 5 -type f $dir"
6498         nums=$($cmd | wc -l)
6499         [ $nums -eq $expected ] ||
6500                 error "'$cmd' wrong: found $nums, expected $expected"
6501
6502         expected=1
6503         cmd="$LFS find -size +5 -type f -lazy $dir"
6504         nums=$($cmd | wc -l)
6505         [ $nums -eq $expected ] ||
6506                 error "'$cmd' wrong: found $nums, expected $expected"
6507         cmd="$LFS find -size +5 -type f $dir"
6508         nums=$($cmd | wc -l)
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511
6512         expected=2
6513         cmd="$LFS find -size +0 -type f -lazy $dir"
6514         nums=$($cmd | wc -l)
6515         [ $nums -eq $expected ] ||
6516                 error "'$cmd' wrong: found $nums, expected $expected"
6517         cmd="$LFS find -size +0 -type f $dir"
6518         nums=$($cmd | wc -l)
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521
6522         expected=2
6523         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6524         nums=$($cmd | wc -l)
6525         [ $nums -eq $expected ] ||
6526                 error "'$cmd' wrong: found $nums, expected $expected"
6527         cmd="$LFS find ! -size -5 -type f $dir"
6528         nums=$($cmd | wc -l)
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         expected=12
6533         cmd="$LFS find -size -5 -type f -lazy $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537         cmd="$LFS find -size -5 -type f $dir"
6538         nums=$($cmd | wc -l)
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541 }
6542 run_test 56r "check lfs find -size works"
6543
6544 test_56ra_sub() {
6545         local expected=$1
6546         local glimpses=$2
6547         local cmd="$3"
6548
6549         cancel_lru_locks $OSC
6550
6551         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6552         local nums=$($cmd | wc -l)
6553
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6558
6559         if (( rpcs_before + glimpses != rpcs_after )); then
6560                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6561                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6562
6563                 if [[ $glimpses == 0 ]]; then
6564                         error "'$cmd' should not send glimpse RPCs to OST"
6565                 else
6566                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6567                 fi
6568         fi
6569 }
6570
6571 test_56ra() {
6572         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6573                 skip "MDS < 2.12.58 doesn't return LSOM data"
6574         local dir=$DIR/$tdir
6575         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6576
6577         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6578
6579         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6580         $LCTL set_param -n llite.*.statahead_agl=0
6581         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6582
6583         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6584         # open and close all files to ensure LSOM is updated
6585         cancel_lru_locks $OSC
6586         find $dir -type f | xargs cat > /dev/null
6587
6588         #   expect_found  glimpse_rpcs  command_to_run
6589         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6590         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6591         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6592         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6593
6594         echo "test" > $dir/$tfile
6595         echo "test2" > $dir/$tfile.2 && sync
6596         cancel_lru_locks $OSC
6597         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6598
6599         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6600         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6601         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6602         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6603
6604         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6605         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6606         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6607         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6608         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6609         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6610 }
6611 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6612
6613 test_56rb() {
6614         local dir=$DIR/$tdir
6615         local tmp=$TMP/$tfile.log
6616         local mdt_idx;
6617
6618         test_mkdir -p $dir || error "failed to mkdir $dir"
6619         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6620                 error "failed to setstripe $dir/$tfile"
6621         mdt_idx=$($LFS getdirstripe -i $dir)
6622         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6623
6624         stack_trap "rm -f $tmp" EXIT
6625         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6626         ! grep -q obd_uuid $tmp ||
6627                 error "failed to find --size +100K --ost 0 $dir"
6628         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6629         ! grep -q obd_uuid $tmp ||
6630                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6631 }
6632 run_test 56rb "check lfs find --size --ost/--mdt works"
6633
6634 test_56s() { # LU-611 #LU-9369
6635         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6636
6637         local dir=$DIR/$tdir
6638         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6639
6640         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6641         for i in $(seq $NUMDIRS); do
6642                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6643         done
6644
6645         local expected=$NUMDIRS
6646         local cmd="$LFS find -c $OSTCOUNT $dir"
6647         local nums=$($cmd | wc -l)
6648
6649         [ $nums -eq $expected ] || {
6650                 $LFS getstripe -R $dir
6651                 error "'$cmd' wrong: found $nums, expected $expected"
6652         }
6653
6654         expected=$((NUMDIRS + onestripe))
6655         cmd="$LFS find -stripe-count +0 -type f $dir"
6656         nums=$($cmd | wc -l)
6657         [ $nums -eq $expected ] || {
6658                 $LFS getstripe -R $dir
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660         }
6661
6662         expected=$onestripe
6663         cmd="$LFS find -stripe-count 1 -type f $dir"
6664         nums=$($cmd | wc -l)
6665         [ $nums -eq $expected ] || {
6666                 $LFS getstripe -R $dir
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668         }
6669
6670         cmd="$LFS find -stripe-count -2 -type f $dir"
6671         nums=$($cmd | wc -l)
6672         [ $nums -eq $expected ] || {
6673                 $LFS getstripe -R $dir
6674                 error "'$cmd' wrong: found $nums, expected $expected"
6675         }
6676
6677         expected=0
6678         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6679         nums=$($cmd | wc -l)
6680         [ $nums -eq $expected ] || {
6681                 $LFS getstripe -R $dir
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683         }
6684 }
6685 run_test 56s "check lfs find -stripe-count works"
6686
6687 test_56t() { # LU-611 #LU-9369
6688         local dir=$DIR/$tdir
6689
6690         setup_56 $dir 0 $NUMDIRS
6691         for i in $(seq $NUMDIRS); do
6692                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6693         done
6694
6695         local expected=$NUMDIRS
6696         local cmd="$LFS find -S 8M $dir"
6697         local nums=$($cmd | wc -l)
6698
6699         [ $nums -eq $expected ] || {
6700                 $LFS getstripe -R $dir
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         }
6703         rm -rf $dir
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6706
6707         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6708
6709         expected=$(((NUMDIRS + 1) * NUMFILES))
6710         cmd="$LFS find -stripe-size 512k -type f $dir"
6711         nums=$($cmd | wc -l)
6712         [ $nums -eq $expected ] ||
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714
6715         cmd="$LFS find -stripe-size +320k -type f $dir"
6716         nums=$($cmd | wc -l)
6717         [ $nums -eq $expected ] ||
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719
6720         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6721         cmd="$LFS find -stripe-size +200k -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         cmd="$LFS find -stripe-size -640k -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730
6731         expected=4
6732         cmd="$LFS find -stripe-size 256k -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         cmd="$LFS find -stripe-size -320k -type f $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741
6742         expected=0
6743         cmd="$LFS find -stripe-size 1024k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56t "check lfs find -stripe-size works"
6749
6750 test_56u() { # LU-611
6751         local dir=$DIR/$tdir
6752
6753         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6754
6755         if [[ $OSTCOUNT -gt 1 ]]; then
6756                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6757                 onestripe=4
6758         else
6759                 onestripe=0
6760         fi
6761
6762         local expected=$(((NUMDIRS + 1) * NUMFILES))
6763         local cmd="$LFS find -stripe-index 0 -type f $dir"
6764         local nums=$($cmd | wc -l)
6765
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768
6769         expected=$onestripe
6770         cmd="$LFS find -stripe-index 1 -type f $dir"
6771         nums=$($cmd | wc -l)
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         expected=0
6781         # This should produce an error and not return any files
6782         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6783         nums=$($cmd 2>/dev/null | wc -l)
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786
6787         if [[ $OSTCOUNT -gt 1 ]]; then
6788                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6789                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6790                 nums=$($cmd | wc -l)
6791                 [ $nums -eq $expected ] ||
6792                         error "'$cmd' wrong: found $nums, expected $expected"
6793         fi
6794 }
6795 run_test 56u "check lfs find -stripe-index works"
6796
6797 test_56v() {
6798         local mdt_idx=0
6799         local dir=$DIR/$tdir
6800
6801         setup_56 $dir $NUMFILES $NUMDIRS
6802
6803         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6804         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6805
6806         for file in $($LFS find -m $UUID $dir); do
6807                 file_midx=$($LFS getstripe -m $file)
6808                 [ $file_midx -eq $mdt_idx ] ||
6809                         error "lfs find -m $UUID != getstripe -m $file_midx"
6810         done
6811 }
6812 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6813
6814 test_56w() {
6815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6817
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6821
6822         local stripe_size=$($LFS getstripe -S -d $dir) ||
6823                 error "$LFS getstripe -S -d $dir failed"
6824         stripe_size=${stripe_size%% *}
6825
6826         local file_size=$((stripe_size * OSTCOUNT))
6827         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6828         local required_space=$((file_num * file_size))
6829         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6830                            head -n1)
6831         [[ $free_space -le $((required_space / 1024)) ]] &&
6832                 skip_env "need $required_space, have $free_space kbytes"
6833
6834         local dd_bs=65536
6835         local dd_count=$((file_size / dd_bs))
6836
6837         # write data into the files
6838         local i
6839         local j
6840         local file
6841
6842         for i in $(seq $NUMFILES); do
6843                 file=$dir/file$i
6844                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6845                         error "write data into $file failed"
6846         done
6847         for i in $(seq $NUMDIRS); do
6848                 for j in $(seq $NUMFILES); do
6849                         file=$dir/dir$i/file$j
6850                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6851                                 error "write data into $file failed"
6852                 done
6853         done
6854
6855         # $LFS_MIGRATE will fail if hard link migration is unsupported
6856         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6857                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6858                         error "creating links to $dir/dir1/file1 failed"
6859         fi
6860
6861         local expected=-1
6862
6863         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6864
6865         # lfs_migrate file
6866         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6867
6868         echo "$cmd"
6869         eval $cmd || error "$cmd failed"
6870
6871         check_stripe_count $dir/file1 $expected
6872
6873         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6874         then
6875                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6876                 # OST 1 if it is on OST 0. This file is small enough to
6877                 # be on only one stripe.
6878                 file=$dir/migr_1_ost
6879                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6880                         error "write data into $file failed"
6881                 local obdidx=$($LFS getstripe -i $file)
6882                 local oldmd5=$(md5sum $file)
6883                 local newobdidx=0
6884
6885                 [[ $obdidx -eq 0 ]] && newobdidx=1
6886                 cmd="$LFS migrate -i $newobdidx $file"
6887                 echo $cmd
6888                 eval $cmd || error "$cmd failed"
6889
6890                 local realobdix=$($LFS getstripe -i $file)
6891                 local newmd5=$(md5sum $file)
6892
6893                 [[ $newobdidx -ne $realobdix ]] &&
6894                         error "new OST is different (was=$obdidx, "\
6895                               "wanted=$newobdidx, got=$realobdix)"
6896                 [[ "$oldmd5" != "$newmd5" ]] &&
6897                         error "md5sum differ: $oldmd5, $newmd5"
6898         fi
6899
6900         # lfs_migrate dir
6901         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6902         echo "$cmd"
6903         eval $cmd || error "$cmd failed"
6904
6905         for j in $(seq $NUMFILES); do
6906                 check_stripe_count $dir/dir1/file$j $expected
6907         done
6908
6909         # lfs_migrate works with lfs find
6910         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6911              $LFS_MIGRATE -y -c $expected"
6912         echo "$cmd"
6913         eval $cmd || error "$cmd failed"
6914
6915         for i in $(seq 2 $NUMFILES); do
6916                 check_stripe_count $dir/file$i $expected
6917         done
6918         for i in $(seq 2 $NUMDIRS); do
6919                 for j in $(seq $NUMFILES); do
6920                 check_stripe_count $dir/dir$i/file$j $expected
6921                 done
6922         done
6923 }
6924 run_test 56w "check lfs_migrate -c stripe_count works"
6925
6926 test_56wb() {
6927         local file1=$DIR/$tdir/file1
6928         local create_pool=false
6929         local initial_pool=$($LFS getstripe -p $DIR)
6930         local pool_list=()
6931         local pool=""
6932
6933         echo -n "Creating test dir..."
6934         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6935         echo "done."
6936
6937         echo -n "Creating test file..."
6938         touch $file1 || error "cannot create file"
6939         echo "done."
6940
6941         echo -n "Detecting existing pools..."
6942         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6943
6944         if [ ${#pool_list[@]} -gt 0 ]; then
6945                 echo "${pool_list[@]}"
6946                 for thispool in "${pool_list[@]}"; do
6947                         if [[ -z "$initial_pool" ||
6948                               "$initial_pool" != "$thispool" ]]; then
6949                                 pool="$thispool"
6950                                 echo "Using existing pool '$pool'"
6951                                 break
6952                         fi
6953                 done
6954         else
6955                 echo "none detected."
6956         fi
6957         if [ -z "$pool" ]; then
6958                 pool=${POOL:-testpool}
6959                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6960                 echo -n "Creating pool '$pool'..."
6961                 create_pool=true
6962                 pool_add $pool &> /dev/null ||
6963                         error "pool_add failed"
6964                 echo "done."
6965
6966                 echo -n "Adding target to pool..."
6967                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6968                         error "pool_add_targets failed"
6969                 echo "done."
6970         fi
6971
6972         echo -n "Setting pool using -p option..."
6973         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6974                 error "migrate failed rc = $?"
6975         echo "done."
6976
6977         echo -n "Verifying test file is in pool after migrating..."
6978         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6979                 error "file was not migrated to pool $pool"
6980         echo "done."
6981
6982         echo -n "Removing test file from pool '$pool'..."
6983         # "lfs migrate $file" won't remove the file from the pool
6984         # until some striping information is changed.
6985         $LFS migrate -c 1 $file1 &> /dev/null ||
6986                 error "cannot remove from pool"
6987         [ "$($LFS getstripe -p $file1)" ] &&
6988                 error "pool still set"
6989         echo "done."
6990
6991         echo -n "Setting pool using --pool option..."
6992         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6993                 error "migrate failed rc = $?"
6994         echo "done."
6995
6996         # Clean up
6997         rm -f $file1
6998         if $create_pool; then
6999                 destroy_test_pools 2> /dev/null ||
7000                         error "destroy test pools failed"
7001         fi
7002 }
7003 run_test 56wb "check lfs_migrate pool support"
7004
7005 test_56wc() {
7006         local file1="$DIR/$tdir/file1"
7007         local parent_ssize
7008         local parent_scount
7009         local cur_ssize
7010         local cur_scount
7011         local orig_ssize
7012
7013         echo -n "Creating test dir..."
7014         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7015         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7016                 error "cannot set stripe by '-S 1M -c 1'"
7017         echo "done"
7018
7019         echo -n "Setting initial stripe for test file..."
7020         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7021                 error "cannot set stripe"
7022         cur_ssize=$($LFS getstripe -S "$file1")
7023         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7024         echo "done."
7025
7026         # File currently set to -S 512K -c 1
7027
7028         # Ensure -c and -S options are rejected when -R is set
7029         echo -n "Verifying incompatible options are detected..."
7030         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7031                 error "incompatible -c and -R options not detected"
7032         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7033                 error "incompatible -S and -R options not detected"
7034         echo "done."
7035
7036         # Ensure unrecognized options are passed through to 'lfs migrate'
7037         echo -n "Verifying -S option is passed through to lfs migrate..."
7038         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7039                 error "migration failed"
7040         cur_ssize=$($LFS getstripe -S "$file1")
7041         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7042         echo "done."
7043
7044         # File currently set to -S 1M -c 1
7045
7046         # Ensure long options are supported
7047         echo -n "Verifying long options supported..."
7048         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7049                 error "long option without argument not supported"
7050         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7051                 error "long option with argument not supported"
7052         cur_ssize=$($LFS getstripe -S "$file1")
7053         [ $cur_ssize -eq 524288 ] ||
7054                 error "migrate --stripe-size $cur_ssize != 524288"
7055         echo "done."
7056
7057         # File currently set to -S 512K -c 1
7058
7059         if [ "$OSTCOUNT" -gt 1 ]; then
7060                 echo -n "Verifying explicit stripe count can be set..."
7061                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7062                         error "migrate failed"
7063                 cur_scount=$($LFS getstripe -c "$file1")
7064                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7065                 echo "done."
7066         fi
7067
7068         # File currently set to -S 512K -c 1 or -S 512K -c 2
7069
7070         # Ensure parent striping is used if -R is set, and no stripe
7071         # count or size is specified
7072         echo -n "Setting stripe for parent directory..."
7073         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7074                 error "cannot set stripe '-S 2M -c 1'"
7075         echo "done."
7076
7077         echo -n "Verifying restripe option uses parent stripe settings..."
7078         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7079         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7080         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7081                 error "migrate failed"
7082         cur_ssize=$($LFS getstripe -S "$file1")
7083         [ $cur_ssize -eq $parent_ssize ] ||
7084                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7085         cur_scount=$($LFS getstripe -c "$file1")
7086         [ $cur_scount -eq $parent_scount ] ||
7087                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7088         echo "done."
7089
7090         # File currently set to -S 1M -c 1
7091
7092         # Ensure striping is preserved if -R is not set, and no stripe
7093         # count or size is specified
7094         echo -n "Verifying striping size preserved when not specified..."
7095         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7096         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7097                 error "cannot set stripe on parent directory"
7098         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7099                 error "migrate failed"
7100         cur_ssize=$($LFS getstripe -S "$file1")
7101         [ $cur_ssize -eq $orig_ssize ] ||
7102                 error "migrate by default $cur_ssize != $orig_ssize"
7103         echo "done."
7104
7105         # Ensure file name properly detected when final option has no argument
7106         echo -n "Verifying file name properly detected..."
7107         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7108                 error "file name interpreted as option argument"
7109         echo "done."
7110
7111         # Clean up
7112         rm -f "$file1"
7113 }
7114 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7115
7116 test_56wd() {
7117         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7118
7119         local file1=$DIR/$tdir/file1
7120
7121         echo -n "Creating test dir..."
7122         test_mkdir $DIR/$tdir || error "cannot create dir"
7123         echo "done."
7124
7125         echo -n "Creating test file..."
7126         touch $file1
7127         echo "done."
7128
7129         # Ensure 'lfs migrate' will fail by using a non-existent option,
7130         # and make sure rsync is not called to recover
7131         echo -n "Make sure --no-rsync option works..."
7132         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7133                 grep -q 'refusing to fall back to rsync' ||
7134                 error "rsync was called with --no-rsync set"
7135         echo "done."
7136
7137         # Ensure rsync is called without trying 'lfs migrate' first
7138         echo -n "Make sure --rsync option works..."
7139         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7140                 grep -q 'falling back to rsync' &&
7141                 error "lfs migrate was called with --rsync set"
7142         echo "done."
7143
7144         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7145         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7146                 grep -q 'at the same time' ||
7147                 error "--rsync and --no-rsync accepted concurrently"
7148         echo "done."
7149
7150         # Clean up
7151         rm -f $file1
7152 }
7153 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7154
7155 test_56we() {
7156         local td=$DIR/$tdir
7157         local tf=$td/$tfile
7158
7159         test_mkdir $td || error "cannot create $td"
7160         touch $tf || error "cannot touch $tf"
7161
7162         echo -n "Make sure --non-direct|-D works..."
7163         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7164                 grep -q "lfs migrate --non-direct" ||
7165                 error "--non-direct option cannot work correctly"
7166         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7167                 grep -q "lfs migrate -D" ||
7168                 error "-D option cannot work correctly"
7169         echo "done."
7170 }
7171 run_test 56we "check lfs_migrate --non-direct|-D support"
7172
7173 test_56x() {
7174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7175         check_swap_layouts_support
7176
7177         local dir=$DIR/$tdir
7178         local ref1=/etc/passwd
7179         local file1=$dir/file1
7180
7181         test_mkdir $dir || error "creating dir $dir"
7182         $LFS setstripe -c 2 $file1
7183         cp $ref1 $file1
7184         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7185         stripe=$($LFS getstripe -c $file1)
7186         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7187         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7188
7189         # clean up
7190         rm -f $file1
7191 }
7192 run_test 56x "lfs migration support"
7193
7194 test_56xa() {
7195         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7196         check_swap_layouts_support
7197
7198         local dir=$DIR/$tdir/$testnum
7199
7200         test_mkdir -p $dir
7201
7202         local ref1=/etc/passwd
7203         local file1=$dir/file1
7204
7205         $LFS setstripe -c 2 $file1
7206         cp $ref1 $file1
7207         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7208
7209         local stripe=$($LFS getstripe -c $file1)
7210
7211         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7212         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7213
7214         # clean up
7215         rm -f $file1
7216 }
7217 run_test 56xa "lfs migration --block support"
7218
7219 check_migrate_links() {
7220         local dir="$1"
7221         local file1="$dir/file1"
7222         local begin="$2"
7223         local count="$3"
7224         local runas="$4"
7225         local total_count=$(($begin + $count - 1))
7226         local symlink_count=10
7227         local uniq_count=10
7228
7229         if [ ! -f "$file1" ]; then
7230                 echo -n "creating initial file..."
7231                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7232                         error "cannot setstripe initial file"
7233                 echo "done"
7234
7235                 echo -n "creating symlinks..."
7236                 for s in $(seq 1 $symlink_count); do
7237                         ln -s "$file1" "$dir/slink$s" ||
7238                                 error "cannot create symlinks"
7239                 done
7240                 echo "done"
7241
7242                 echo -n "creating nonlinked files..."
7243                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7244                         error "cannot create nonlinked files"
7245                 echo "done"
7246         fi
7247
7248         # create hard links
7249         if [ ! -f "$dir/file$total_count" ]; then
7250                 echo -n "creating hard links $begin:$total_count..."
7251                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7252                         /dev/null || error "cannot create hard links"
7253                 echo "done"
7254         fi
7255
7256         echo -n "checking number of hard links listed in xattrs..."
7257         local fid=$($LFS getstripe -F "$file1")
7258         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7259
7260         echo "${#paths[*]}"
7261         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7262                         skip "hard link list has unexpected size, skipping test"
7263         fi
7264         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7265                         error "link names should exceed xattrs size"
7266         fi
7267
7268         echo -n "migrating files..."
7269         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7270         local rc=$?
7271         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7272         echo "done"
7273
7274         # make sure all links have been properly migrated
7275         echo -n "verifying files..."
7276         fid=$($LFS getstripe -F "$file1") ||
7277                 error "cannot get fid for file $file1"
7278         for i in $(seq 2 $total_count); do
7279                 local fid2=$($LFS getstripe -F $dir/file$i)
7280
7281                 [ "$fid2" == "$fid" ] ||
7282                         error "migrated hard link has mismatched FID"
7283         done
7284
7285         # make sure hard links were properly detected, and migration was
7286         # performed only once for the entire link set; nonlinked files should
7287         # also be migrated
7288         local actual=$(grep -c 'done' <<< "$migrate_out")
7289         local expected=$(($uniq_count + 1))
7290
7291         [ "$actual" -eq  "$expected" ] ||
7292                 error "hard links individually migrated ($actual != $expected)"
7293
7294         # make sure the correct number of hard links are present
7295         local hardlinks=$(stat -c '%h' "$file1")
7296
7297         [ $hardlinks -eq $total_count ] ||
7298                 error "num hard links $hardlinks != $total_count"
7299         echo "done"
7300
7301         return 0
7302 }
7303
7304 test_56xb() {
7305         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7306                 skip "Need MDS version at least 2.10.55"
7307
7308         local dir="$DIR/$tdir"
7309
7310         test_mkdir "$dir" || error "cannot create dir $dir"
7311
7312         echo "testing lfs migrate mode when all links fit within xattrs"
7313         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7314
7315         echo "testing rsync mode when all links fit within xattrs"
7316         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7317
7318         echo "testing lfs migrate mode when all links do not fit within xattrs"
7319         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7320
7321         echo "testing rsync mode when all links do not fit within xattrs"
7322         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7323
7324         chown -R $RUNAS_ID $dir
7325         echo "testing non-root lfs migrate mode when not all links are in xattr"
7326         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7327
7328         # clean up
7329         rm -rf $dir
7330 }
7331 run_test 56xb "lfs migration hard link support"
7332
7333 test_56xc() {
7334         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7335
7336         local dir="$DIR/$tdir"
7337
7338         test_mkdir "$dir" || error "cannot create dir $dir"
7339
7340         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7341         echo -n "Setting initial stripe for 20MB test file..."
7342         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7343                 error "cannot setstripe 20MB file"
7344         echo "done"
7345         echo -n "Sizing 20MB test file..."
7346         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7347         echo "done"
7348         echo -n "Verifying small file autostripe count is 1..."
7349         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7350                 error "cannot migrate 20MB file"
7351         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7352                 error "cannot get stripe for $dir/20mb"
7353         [ $stripe_count -eq 1 ] ||
7354                 error "unexpected stripe count $stripe_count for 20MB file"
7355         rm -f "$dir/20mb"
7356         echo "done"
7357
7358         # Test 2: File is small enough to fit within the available space on
7359         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7360         # have at least an additional 1KB for each desired stripe for test 3
7361         echo -n "Setting stripe for 1GB test file..."
7362         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7363         echo "done"
7364         echo -n "Sizing 1GB test file..."
7365         # File size is 1GB + 3KB
7366         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7367         echo "done"
7368
7369         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7370         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7371         if (( avail > 524288 * OSTCOUNT )); then
7372                 echo -n "Migrating 1GB file..."
7373                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7374                         error "cannot migrate 1GB file"
7375                 echo "done"
7376                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7377                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7378                         error "cannot getstripe for 1GB file"
7379                 [ $stripe_count -eq 2 ] ||
7380                         error "unexpected stripe count $stripe_count != 2"
7381                 echo "done"
7382         fi
7383
7384         # Test 3: File is too large to fit within the available space on
7385         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7386         if [ $OSTCOUNT -ge 3 ]; then
7387                 # The required available space is calculated as
7388                 # file size (1GB + 3KB) / OST count (3).
7389                 local kb_per_ost=349526
7390
7391                 echo -n "Migrating 1GB file with limit..."
7392                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7393                         error "cannot migrate 1GB file with limit"
7394                 echo "done"
7395
7396                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7397                 echo -n "Verifying 1GB autostripe count with limited space..."
7398                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7399                         error "unexpected stripe count $stripe_count (min 3)"
7400                 echo "done"
7401         fi
7402
7403         # clean up
7404         rm -rf $dir
7405 }
7406 run_test 56xc "lfs migration autostripe"
7407
7408 test_56xd() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410
7411         local dir=$DIR/$tdir
7412         local f_mgrt=$dir/$tfile.mgrt
7413         local f_yaml=$dir/$tfile.yaml
7414         local f_copy=$dir/$tfile.copy
7415         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7416         local layout_copy="-c 2 -S 2M -i 1"
7417         local yamlfile=$dir/yamlfile
7418         local layout_before;
7419         local layout_after;
7420
7421         test_mkdir "$dir" || error "cannot create dir $dir"
7422         $LFS setstripe $layout_yaml $f_yaml ||
7423                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7424         $LFS getstripe --yaml $f_yaml > $yamlfile
7425         $LFS setstripe $layout_copy $f_copy ||
7426                 error "cannot setstripe $f_copy with layout $layout_copy"
7427         touch $f_mgrt
7428         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7429
7430         # 1. test option --yaml
7431         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7432                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7433         layout_before=$(get_layout_param $f_yaml)
7434         layout_after=$(get_layout_param $f_mgrt)
7435         [ "$layout_after" == "$layout_before" ] ||
7436                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7437
7438         # 2. test option --copy
7439         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7440                 error "cannot migrate $f_mgrt with --copy $f_copy"
7441         layout_before=$(get_layout_param $f_copy)
7442         layout_after=$(get_layout_param $f_mgrt)
7443         [ "$layout_after" == "$layout_before" ] ||
7444                 error "lfs_migrate --copy: $layout_after != $layout_before"
7445 }
7446 run_test 56xd "check lfs_migrate --yaml and --copy support"
7447
7448 test_56xe() {
7449         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7450
7451         local dir=$DIR/$tdir
7452         local f_comp=$dir/$tfile
7453         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7454         local layout_before=""
7455         local layout_after=""
7456
7457         test_mkdir "$dir" || error "cannot create dir $dir"
7458         $LFS setstripe $layout $f_comp ||
7459                 error "cannot setstripe $f_comp with layout $layout"
7460         layout_before=$(get_layout_param $f_comp)
7461         dd if=/dev/zero of=$f_comp bs=1M count=4
7462
7463         # 1. migrate a comp layout file by lfs_migrate
7464         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7465         layout_after=$(get_layout_param $f_comp)
7466         [ "$layout_before" == "$layout_after" ] ||
7467                 error "lfs_migrate: $layout_before != $layout_after"
7468
7469         # 2. migrate a comp layout file by lfs migrate
7470         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7471         layout_after=$(get_layout_param $f_comp)
7472         [ "$layout_before" == "$layout_after" ] ||
7473                 error "lfs migrate: $layout_before != $layout_after"
7474 }
7475 run_test 56xe "migrate a composite layout file"
7476
7477 test_56xf() {
7478         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7479
7480         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7481                 skip "Need server version at least 2.13.53"
7482
7483         local dir=$DIR/$tdir
7484         local f_comp=$dir/$tfile
7485         local layout="-E 1M -c1 -E -1 -c2"
7486         local fid_before=""
7487         local fid_after=""
7488
7489         test_mkdir "$dir" || error "cannot create dir $dir"
7490         $LFS setstripe $layout $f_comp ||
7491                 error "cannot setstripe $f_comp with layout $layout"
7492         fid_before=$($LFS getstripe --fid $f_comp)
7493         dd if=/dev/zero of=$f_comp bs=1M count=4
7494
7495         # 1. migrate a comp layout file to a comp layout
7496         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7497         fid_after=$($LFS getstripe --fid $f_comp)
7498         [ "$fid_before" == "$fid_after" ] ||
7499                 error "comp-to-comp migrate: $fid_before != $fid_after"
7500
7501         # 2. migrate a comp layout file to a plain layout
7502         $LFS migrate -c2 $f_comp ||
7503                 error "cannot migrate $f_comp by lfs migrate"
7504         fid_after=$($LFS getstripe --fid $f_comp)
7505         [ "$fid_before" == "$fid_after" ] ||
7506                 error "comp-to-plain migrate: $fid_before != $fid_after"
7507
7508         # 3. migrate a plain layout file to a comp layout
7509         $LFS migrate $layout $f_comp ||
7510                 error "cannot migrate $f_comp by lfs migrate"
7511         fid_after=$($LFS getstripe --fid $f_comp)
7512         [ "$fid_before" == "$fid_after" ] ||
7513                 error "plain-to-comp migrate: $fid_before != $fid_after"
7514 }
7515 run_test 56xf "FID is not lost during migration of a composite layout file"
7516
7517 test_56y() {
7518         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7519                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7520
7521         local res=""
7522         local dir=$DIR/$tdir
7523         local f1=$dir/file1
7524         local f2=$dir/file2
7525
7526         test_mkdir -p $dir || error "creating dir $dir"
7527         touch $f1 || error "creating std file $f1"
7528         $MULTIOP $f2 H2c || error "creating released file $f2"
7529
7530         # a directory can be raid0, so ask only for files
7531         res=$($LFS find $dir -L raid0 -type f | wc -l)
7532         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7533
7534         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7535         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7536
7537         # only files can be released, so no need to force file search
7538         res=$($LFS find $dir -L released)
7539         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7540
7541         res=$($LFS find $dir -type f \! -L released)
7542         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7543 }
7544 run_test 56y "lfs find -L raid0|released"
7545
7546 test_56z() { # LU-4824
7547         # This checks to make sure 'lfs find' continues after errors
7548         # There are two classes of errors that should be caught:
7549         # - If multiple paths are provided, all should be searched even if one
7550         #   errors out
7551         # - If errors are encountered during the search, it should not terminate
7552         #   early
7553         local dir=$DIR/$tdir
7554         local i
7555
7556         test_mkdir $dir
7557         for i in d{0..9}; do
7558                 test_mkdir $dir/$i
7559                 touch $dir/$i/$tfile
7560         done
7561         $LFS find $DIR/non_existent_dir $dir &&
7562                 error "$LFS find did not return an error"
7563         # Make a directory unsearchable. This should NOT be the last entry in
7564         # directory order.  Arbitrarily pick the 6th entry
7565         chmod 700 $($LFS find $dir -type d | sed '6!d')
7566
7567         $RUNAS $LFS find $DIR/non_existent $dir
7568         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7569
7570         # The user should be able to see 10 directories and 9 files
7571         (( count == 19 )) ||
7572                 error "$LFS find found $count != 19 entries after error"
7573 }
7574 run_test 56z "lfs find should continue after an error"
7575
7576 test_56aa() { # LU-5937
7577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7578
7579         local dir=$DIR/$tdir
7580
7581         mkdir $dir
7582         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7583
7584         createmany -o $dir/striped_dir/${tfile}- 1024
7585         local dirs=$($LFS find --size +8k $dir/)
7586
7587         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7588 }
7589 run_test 56aa "lfs find --size under striped dir"
7590
7591 test_56ab() { # LU-10705
7592         test_mkdir $DIR/$tdir
7593         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7594         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7595         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7596         # Flush writes to ensure valid blocks.  Need to be more thorough for
7597         # ZFS, since blocks are not allocated/returned to client immediately.
7598         sync_all_data
7599         wait_zfs_commit ost1 2
7600         cancel_lru_locks osc
7601         ls -ls $DIR/$tdir
7602
7603         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7604
7605         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7606
7607         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7608         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7609
7610         rm -f $DIR/$tdir/$tfile.[123]
7611 }
7612 run_test 56ab "lfs find --blocks"
7613
7614 test_56ba() {
7615         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7616                 skip "Need MDS version at least 2.10.50"
7617
7618         # Create composite files with one component
7619         local dir=$DIR/$tdir
7620
7621         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7622         # Create composite files with three components
7623         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7624         # Create non-composite files
7625         createmany -o $dir/${tfile}- 10
7626
7627         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7628
7629         [[ $nfiles == 10 ]] ||
7630                 error "lfs find -E 1M found $nfiles != 10 files"
7631
7632         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7633         [[ $nfiles == 25 ]] ||
7634                 error "lfs find ! -E 1M found $nfiles != 25 files"
7635
7636         # All files have a component that starts at 0
7637         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7638         [[ $nfiles == 35 ]] ||
7639                 error "lfs find --component-start 0 - $nfiles != 35 files"
7640
7641         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7642         [[ $nfiles == 15 ]] ||
7643                 error "lfs find --component-start 2M - $nfiles != 15 files"
7644
7645         # All files created here have a componenet that does not starts at 2M
7646         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7647         [[ $nfiles == 35 ]] ||
7648                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7649
7650         # Find files with a specified number of components
7651         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7652         [[ $nfiles == 15 ]] ||
7653                 error "lfs find --component-count 3 - $nfiles != 15 files"
7654
7655         # Remember non-composite files have a component count of zero
7656         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7657         [[ $nfiles == 10 ]] ||
7658                 error "lfs find --component-count 0 - $nfiles != 10 files"
7659
7660         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7661         [[ $nfiles == 20 ]] ||
7662                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7663
7664         # All files have a flag called "init"
7665         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7666         [[ $nfiles == 35 ]] ||
7667                 error "lfs find --component-flags init - $nfiles != 35 files"
7668
7669         # Multi-component files will have a component not initialized
7670         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7671         [[ $nfiles == 15 ]] ||
7672                 error "lfs find !--component-flags init - $nfiles != 15 files"
7673
7674         rm -rf $dir
7675
7676 }
7677 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7678
7679 test_56ca() {
7680         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7681                 skip "Need MDS version at least 2.10.57"
7682
7683         local td=$DIR/$tdir
7684         local tf=$td/$tfile
7685         local dir
7686         local nfiles
7687         local cmd
7688         local i
7689         local j
7690
7691         # create mirrored directories and mirrored files
7692         mkdir $td || error "mkdir $td failed"
7693         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7694         createmany -o $tf- 10 || error "create $tf- failed"
7695
7696         for i in $(seq 2); do
7697                 dir=$td/dir$i
7698                 mkdir $dir || error "mkdir $dir failed"
7699                 $LFS mirror create -N$((3 + i)) $dir ||
7700                         error "create mirrored dir $dir failed"
7701                 createmany -o $dir/$tfile- 10 ||
7702                         error "create $dir/$tfile- failed"
7703         done
7704
7705         # change the states of some mirrored files
7706         echo foo > $tf-6
7707         for i in $(seq 2); do
7708                 dir=$td/dir$i
7709                 for j in $(seq 4 9); do
7710                         echo foo > $dir/$tfile-$j
7711                 done
7712         done
7713
7714         # find mirrored files with specific mirror count
7715         cmd="$LFS find --mirror-count 3 --type f $td"
7716         nfiles=$($cmd | wc -l)
7717         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7718
7719         cmd="$LFS find ! --mirror-count 3 --type f $td"
7720         nfiles=$($cmd | wc -l)
7721         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7722
7723         cmd="$LFS find --mirror-count +2 --type f $td"
7724         nfiles=$($cmd | wc -l)
7725         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7726
7727         cmd="$LFS find --mirror-count -6 --type f $td"
7728         nfiles=$($cmd | wc -l)
7729         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7730
7731         # find mirrored files with specific file state
7732         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7733         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7734
7735         cmd="$LFS find --mirror-state=ro --type f $td"
7736         nfiles=$($cmd | wc -l)
7737         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7738
7739         cmd="$LFS find ! --mirror-state=ro --type f $td"
7740         nfiles=$($cmd | wc -l)
7741         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7742
7743         cmd="$LFS find --mirror-state=wp --type f $td"
7744         nfiles=$($cmd | wc -l)
7745         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7746
7747         cmd="$LFS find ! --mirror-state=sp --type f $td"
7748         nfiles=$($cmd | wc -l)
7749         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7750 }
7751 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7752
7753 test_56da() { # LU-14179
7754         local path=$DIR/$tdir
7755
7756         test_mkdir $path
7757         cd $path
7758
7759         local longdir=$(str_repeat 'a' 255)
7760
7761         for i in {1..15}; do
7762                 path=$path/$longdir
7763                 test_mkdir $longdir
7764                 cd $longdir
7765         done
7766
7767         local len=${#path}
7768         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7769
7770         test_mkdir $lastdir
7771         cd $lastdir
7772         # PATH_MAX-1
7773         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7774
7775         # NAME_MAX
7776         touch $(str_repeat 'f' 255)
7777
7778         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7779                 error "lfs find reported an error"
7780
7781         rm -rf $DIR/$tdir
7782 }
7783 run_test 56da "test lfs find with long paths"
7784
7785 test_57a() {
7786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7787         # note test will not do anything if MDS is not local
7788         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7789                 skip_env "ldiskfs only test"
7790         fi
7791         remote_mds_nodsh && skip "remote MDS with nodsh"
7792
7793         local MNTDEV="osd*.*MDT*.mntdev"
7794         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7795         [ -z "$DEV" ] && error "can't access $MNTDEV"
7796         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7797                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7798                         error "can't access $DEV"
7799                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7800                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7801                 rm $TMP/t57a.dump
7802         done
7803 }
7804 run_test 57a "verify MDS filesystem created with large inodes =="
7805
7806 test_57b() {
7807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7808         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7809                 skip_env "ldiskfs only test"
7810         fi
7811         remote_mds_nodsh && skip "remote MDS with nodsh"
7812
7813         local dir=$DIR/$tdir
7814         local filecount=100
7815         local file1=$dir/f1
7816         local fileN=$dir/f$filecount
7817
7818         rm -rf $dir || error "removing $dir"
7819         test_mkdir -c1 $dir
7820         local mdtidx=$($LFS getstripe -m $dir)
7821         local mdtname=MDT$(printf %04x $mdtidx)
7822         local facet=mds$((mdtidx + 1))
7823
7824         echo "mcreating $filecount files"
7825         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7826
7827         # verify that files do not have EAs yet
7828         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7829                 error "$file1 has an EA"
7830         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7831                 error "$fileN has an EA"
7832
7833         sync
7834         sleep 1
7835         df $dir  #make sure we get new statfs data
7836         local mdsfree=$(do_facet $facet \
7837                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7838         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7839         local file
7840
7841         echo "opening files to create objects/EAs"
7842         for file in $(seq -f $dir/f%g 1 $filecount); do
7843                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7844                         error "opening $file"
7845         done
7846
7847         # verify that files have EAs now
7848         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7849         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7850
7851         sleep 1  #make sure we get new statfs data
7852         df $dir
7853         local mdsfree2=$(do_facet $facet \
7854                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7855         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7856
7857         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7858                 if [ "$mdsfree" != "$mdsfree2" ]; then
7859                         error "MDC before $mdcfree != after $mdcfree2"
7860                 else
7861                         echo "MDC before $mdcfree != after $mdcfree2"
7862                         echo "unable to confirm if MDS has large inodes"
7863                 fi
7864         fi
7865         rm -rf $dir
7866 }
7867 run_test 57b "default LOV EAs are stored inside large inodes ==="
7868
7869 test_58() {
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871         [ -z "$(which wiretest 2>/dev/null)" ] &&
7872                         skip_env "could not find wiretest"
7873
7874         wiretest
7875 }
7876 run_test 58 "verify cross-platform wire constants =============="
7877
7878 test_59() {
7879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7880
7881         echo "touch 130 files"
7882         createmany -o $DIR/f59- 130
7883         echo "rm 130 files"
7884         unlinkmany $DIR/f59- 130
7885         sync
7886         # wait for commitment of removal
7887         wait_delete_completed
7888 }
7889 run_test 59 "verify cancellation of llog records async ========="
7890
7891 TEST60_HEAD="test_60 run $RANDOM"
7892 test_60a() {
7893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7894         remote_mgs_nodsh && skip "remote MGS with nodsh"
7895         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7896                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7897                         skip_env "missing subtest run-llog.sh"
7898
7899         log "$TEST60_HEAD - from kernel mode"
7900         do_facet mgs "$LCTL dk > /dev/null"
7901         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7902         do_facet mgs $LCTL dk > $TMP/$tfile
7903
7904         # LU-6388: test llog_reader
7905         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7906         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7907         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7908                         skip_env "missing llog_reader"
7909         local fstype=$(facet_fstype mgs)
7910         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7911                 skip_env "Only for ldiskfs or zfs type mgs"
7912
7913         local mntpt=$(facet_mntpt mgs)
7914         local mgsdev=$(mgsdevname 1)
7915         local fid_list
7916         local fid
7917         local rec_list
7918         local rec
7919         local rec_type
7920         local obj_file
7921         local path
7922         local seq
7923         local oid
7924         local pass=true
7925
7926         #get fid and record list
7927         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7928                 tail -n 4))
7929         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7930                 tail -n 4))
7931         #remount mgs as ldiskfs or zfs type
7932         stop mgs || error "stop mgs failed"
7933         mount_fstype mgs || error "remount mgs failed"
7934         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7935                 fid=${fid_list[i]}
7936                 rec=${rec_list[i]}
7937                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7938                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7939                 oid=$((16#$oid))
7940
7941                 case $fstype in
7942                         ldiskfs )
7943                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7944                         zfs )
7945                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7946                 esac
7947                 echo "obj_file is $obj_file"
7948                 do_facet mgs $llog_reader $obj_file
7949
7950                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7951                         awk '{ print $3 }' | sed -e "s/^type=//g")
7952                 if [ $rec_type != $rec ]; then
7953                         echo "FAILED test_60a wrong record type $rec_type," \
7954                               "should be $rec"
7955                         pass=false
7956                         break
7957                 fi
7958
7959                 #check obj path if record type is LLOG_LOGID_MAGIC
7960                 if [ "$rec" == "1064553b" ]; then
7961                         path=$(do_facet mgs $llog_reader $obj_file |
7962                                 grep "path=" | awk '{ print $NF }' |
7963                                 sed -e "s/^path=//g")
7964                         if [ $obj_file != $mntpt/$path ]; then
7965                                 echo "FAILED test_60a wrong obj path" \
7966                                       "$montpt/$path, should be $obj_file"
7967                                 pass=false
7968                                 break
7969                         fi
7970                 fi
7971         done
7972         rm -f $TMP/$tfile
7973         #restart mgs before "error", otherwise it will block the next test
7974         stop mgs || error "stop mgs failed"
7975         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7976         $pass || error "test failed, see FAILED test_60a messages for specifics"
7977 }
7978 run_test 60a "llog_test run from kernel module and test llog_reader"
7979
7980 test_60b() { # bug 6411
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982
7983         dmesg > $DIR/$tfile
7984         LLOG_COUNT=$(do_facet mgs dmesg |
7985                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7986                           /llog_[a-z]*.c:[0-9]/ {
7987                                 if (marker)
7988                                         from_marker++
7989                                 from_begin++
7990                           }
7991                           END {
7992                                 if (marker)
7993                                         print from_marker
7994                                 else
7995                                         print from_begin
7996                           }")
7997
7998         [[ $LLOG_COUNT -gt 120 ]] &&
7999                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8000 }
8001 run_test 60b "limit repeated messages from CERROR/CWARN"
8002
8003 test_60c() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005
8006         echo "create 5000 files"
8007         createmany -o $DIR/f60c- 5000
8008 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8009         lctl set_param fail_loc=0x80000137
8010         unlinkmany $DIR/f60c- 5000
8011         lctl set_param fail_loc=0
8012 }
8013 run_test 60c "unlink file when mds full"
8014
8015 test_60d() {
8016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8017
8018         SAVEPRINTK=$(lctl get_param -n printk)
8019         # verify "lctl mark" is even working"
8020         MESSAGE="test message ID $RANDOM $$"
8021         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8022         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8023
8024         lctl set_param printk=0 || error "set lnet.printk failed"
8025         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8026         MESSAGE="new test message ID $RANDOM $$"
8027         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8028         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8029         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8030
8031         lctl set_param -n printk="$SAVEPRINTK"
8032 }
8033 run_test 60d "test printk console message masking"
8034
8035 test_60e() {
8036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8037         remote_mds_nodsh && skip "remote MDS with nodsh"
8038
8039         touch $DIR/$tfile
8040 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8041         do_facet mds1 lctl set_param fail_loc=0x15b
8042         rm $DIR/$tfile
8043 }
8044 run_test 60e "no space while new llog is being created"
8045
8046 test_60f() {
8047         local old_path=$($LCTL get_param -n debug_path)
8048
8049         stack_trap "$LCTL set_param debug_path=$old_path"
8050         stack_trap "rm -f $TMP/$tfile*"
8051         rm -f $TMP/$tfile* 2> /dev/null
8052         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8053         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8054         test_mkdir $DIR/$tdir
8055         # retry in case the open is cached and not released
8056         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8057                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8058                 sleep 0.1
8059         done
8060         ls $TMP/$tfile*
8061         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8062 }
8063 run_test 60f "change debug_path works"
8064
8065 test_60g() {
8066         local pid
8067         local i
8068
8069         test_mkdir -c $MDSCOUNT $DIR/$tdir
8070
8071         (
8072                 local index=0
8073                 while true; do
8074                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8075                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8076                                 2>/dev/null
8077                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8078                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8079                         index=$((index + 1))
8080                 done
8081         ) &
8082
8083         pid=$!
8084
8085         for i in {0..100}; do
8086                 # define OBD_FAIL_OSD_TXN_START    0x19a
8087                 local index=$((i % MDSCOUNT + 1))
8088
8089                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8090                         > /dev/null
8091                 sleep 0.01
8092         done
8093
8094         kill -9 $pid
8095
8096         for i in $(seq $MDSCOUNT); do
8097                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8098         done
8099
8100         mkdir $DIR/$tdir/new || error "mkdir failed"
8101         rmdir $DIR/$tdir/new || error "rmdir failed"
8102
8103         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8104                 -t namespace
8105         for i in $(seq $MDSCOUNT); do
8106                 wait_update_facet mds$i "$LCTL get_param -n \
8107                         mdd.$(facet_svc mds$i).lfsck_namespace |
8108                         awk '/^status/ { print \\\$2 }'" "completed"
8109         done
8110
8111         ls -R $DIR/$tdir || error "ls failed"
8112         rm -rf $DIR/$tdir || error "rmdir failed"
8113 }
8114 run_test 60g "transaction abort won't cause MDT hung"
8115
8116 test_60h() {
8117         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8118                 skip "Need MDS version at least 2.12.52"
8119         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8120
8121         local f
8122
8123         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8124         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8125         for fail_loc in 0x80000188 0x80000189; do
8126                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8127                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8128                         error "mkdir $dir-$fail_loc failed"
8129                 for i in {0..10}; do
8130                         # create may fail on missing stripe
8131                         echo $i > $DIR/$tdir-$fail_loc/$i
8132                 done
8133                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8134                         error "getdirstripe $tdir-$fail_loc failed"
8135                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8136                         error "migrate $tdir-$fail_loc failed"
8137                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8138                         error "getdirstripe $tdir-$fail_loc failed"
8139                 pushd $DIR/$tdir-$fail_loc
8140                 for f in *; do
8141                         echo $f | cmp $f - || error "$f data mismatch"
8142                 done
8143                 popd
8144                 rm -rf $DIR/$tdir-$fail_loc
8145         done
8146 }
8147 run_test 60h "striped directory with missing stripes can be accessed"
8148
8149 test_61a() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         f="$DIR/f61"
8153         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8154         cancel_lru_locks osc
8155         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8156         sync
8157 }
8158 run_test 61a "mmap() writes don't make sync hang ================"
8159
8160 test_61b() {
8161         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8162 }
8163 run_test 61b "mmap() of unstriped file is successful"
8164
8165 # bug 2330 - insufficient obd_match error checking causes LBUG
8166 test_62() {
8167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8168
8169         f="$DIR/f62"
8170         echo foo > $f
8171         cancel_lru_locks osc
8172         lctl set_param fail_loc=0x405
8173         cat $f && error "cat succeeded, expect -EIO"
8174         lctl set_param fail_loc=0
8175 }
8176 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8177 # match every page all of the time.
8178 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8179
8180 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8181 # Though this test is irrelevant anymore, it helped to reveal some
8182 # other grant bugs (LU-4482), let's keep it.
8183 test_63a() {   # was test_63
8184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8185
8186         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8187
8188         for i in `seq 10` ; do
8189                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8190                 sleep 5
8191                 kill $!
8192                 sleep 1
8193         done
8194
8195         rm -f $DIR/f63 || true
8196 }
8197 run_test 63a "Verify oig_wait interruption does not crash ======="
8198
8199 # bug 2248 - async write errors didn't return to application on sync
8200 # bug 3677 - async write errors left page locked
8201 test_63b() {
8202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8203
8204         debugsave
8205         lctl set_param debug=-1
8206
8207         # ensure we have a grant to do async writes
8208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8209         rm $DIR/$tfile
8210
8211         sync    # sync lest earlier test intercept the fail_loc
8212
8213         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8214         lctl set_param fail_loc=0x80000406
8215         $MULTIOP $DIR/$tfile Owy && \
8216                 error "sync didn't return ENOMEM"
8217         sync; sleep 2; sync     # do a real sync this time to flush page
8218         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8219                 error "locked page left in cache after async error" || true
8220         debugrestore
8221 }
8222 run_test 63b "async write errors should be returned to fsync ==="
8223
8224 test_64a () {
8225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8226
8227         lfs df $DIR
8228         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8229 }
8230 run_test 64a "verify filter grant calculations (in kernel) ====="
8231
8232 test_64b () {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234
8235         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8236 }
8237 run_test 64b "check out-of-space detection on client"
8238
8239 test_64c() {
8240         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8241 }
8242 run_test 64c "verify grant shrink"
8243
8244 import_param() {
8245         local tgt=$1
8246         local param=$2
8247
8248         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8249 }
8250
8251 # this does exactly what osc_request.c:osc_announce_cached() does in
8252 # order to calculate max amount of grants to ask from server
8253 want_grant() {
8254         local tgt=$1
8255
8256         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8257         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8258
8259         ((rpc_in_flight++));
8260         nrpages=$((nrpages * rpc_in_flight))
8261
8262         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8263
8264         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8265
8266         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8267         local undirty=$((nrpages * PAGE_SIZE))
8268
8269         local max_extent_pages
8270         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8271         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8272         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8273         local grant_extent_tax
8274         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8275
8276         undirty=$((undirty + nrextents * grant_extent_tax))
8277
8278         echo $undirty
8279 }
8280
8281 # this is size of unit for grant allocation. It should be equal to
8282 # what tgt_grant.c:tgt_grant_chunk() calculates
8283 grant_chunk() {
8284         local tgt=$1
8285         local max_brw_size
8286         local grant_extent_tax
8287
8288         max_brw_size=$(import_param $tgt max_brw_size)
8289
8290         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8291
8292         echo $(((max_brw_size + grant_extent_tax) * 2))
8293 }
8294
8295 test_64d() {
8296         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8297                 skip "OST < 2.10.55 doesn't limit grants enough"
8298
8299         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8300
8301         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8302                 skip "no grant_param connect flag"
8303
8304         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8305
8306         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8307         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8308
8309
8310         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8311         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8312
8313         $LFS setstripe $DIR/$tfile -i 0 -c 1
8314         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8315         ddpid=$!
8316
8317         while kill -0 $ddpid; do
8318                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8319
8320                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8321                         kill $ddpid
8322                         error "cur_grant $cur_grant > $max_cur_granted"
8323                 fi
8324
8325                 sleep 1
8326         done
8327 }
8328 run_test 64d "check grant limit exceed"
8329
8330 check_grants() {
8331         local tgt=$1
8332         local expected=$2
8333         local msg=$3
8334         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8335
8336         ((cur_grants == expected)) ||
8337                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8338 }
8339
8340 round_up_p2() {
8341         echo $((($1 + $2 - 1) & ~($2 - 1)))
8342 }
8343
8344 test_64e() {
8345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8346         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8347                 skip "Need OSS version at least 2.11.56"
8348
8349         # Remount client to reset grant
8350         remount_client $MOUNT || error "failed to remount client"
8351         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8352
8353         local init_grants=$(import_param $osc_tgt initial_grant)
8354
8355         check_grants $osc_tgt $init_grants "init grants"
8356
8357         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8358         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8359         local gbs=$(import_param $osc_tgt grant_block_size)
8360
8361         # write random number of bytes from max_brw_size / 4 to max_brw_size
8362         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8363         # align for direct io
8364         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8365         # round to grant consumption unit
8366         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8367
8368         local grants=$((wb_round_up + extent_tax))
8369
8370         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8371
8372         # define OBD_FAIL_TGT_NO_GRANT 0x725
8373         # make the server not grant more back
8374         do_facet ost1 $LCTL set_param fail_loc=0x725
8375         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8376
8377         do_facet ost1 $LCTL set_param fail_loc=0
8378
8379         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8380
8381         rm -f $DIR/$tfile || error "rm failed"
8382
8383         # Remount client to reset grant
8384         remount_client $MOUNT || error "failed to remount client"
8385         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8386
8387         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8388
8389         # define OBD_FAIL_TGT_NO_GRANT 0x725
8390         # make the server not grant more back
8391         do_facet ost1 $LCTL set_param fail_loc=0x725
8392         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8393         do_facet ost1 $LCTL set_param fail_loc=0
8394
8395         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8396 }
8397 run_test 64e "check grant consumption (no grant allocation)"
8398
8399 test_64f() {
8400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8401
8402         # Remount client to reset grant
8403         remount_client $MOUNT || error "failed to remount client"
8404         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8405
8406         local init_grants=$(import_param $osc_tgt initial_grant)
8407         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8408         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8409         local gbs=$(import_param $osc_tgt grant_block_size)
8410         local chunk=$(grant_chunk $osc_tgt)
8411
8412         # write random number of bytes from max_brw_size / 4 to max_brw_size
8413         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8414         # align for direct io
8415         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8416         # round to grant consumption unit
8417         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8418
8419         local grants=$((wb_round_up + extent_tax))
8420
8421         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8422         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8423                 error "error writing to $DIR/$tfile"
8424
8425         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8426                 "direct io with grant allocation"
8427
8428         rm -f $DIR/$tfile || error "rm failed"
8429
8430         # Remount client to reset grant
8431         remount_client $MOUNT || error "failed to remount client"
8432         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8433
8434         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8435
8436         local cmd="oO_WRONLY:w${write_bytes}_yc"
8437
8438         $MULTIOP $DIR/$tfile $cmd &
8439         MULTIPID=$!
8440         sleep 1
8441
8442         check_grants $osc_tgt $((init_grants - grants)) \
8443                 "buffered io, not write rpc"
8444
8445         kill -USR1 $MULTIPID
8446         wait
8447
8448         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8449                 "buffered io, one RPC"
8450 }
8451 run_test 64f "check grant consumption (with grant allocation)"
8452
8453 # bug 1414 - set/get directories' stripe info
8454 test_65a() {
8455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8456
8457         test_mkdir $DIR/$tdir
8458         touch $DIR/$tdir/f1
8459         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8460 }
8461 run_test 65a "directory with no stripe info"
8462
8463 test_65b() {
8464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8465
8466         test_mkdir $DIR/$tdir
8467         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8468
8469         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8470                                                 error "setstripe"
8471         touch $DIR/$tdir/f2
8472         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8473 }
8474 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8475
8476 test_65c() {
8477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8478         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8479
8480         test_mkdir $DIR/$tdir
8481         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8482
8483         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8484                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8485         touch $DIR/$tdir/f3
8486         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8487 }
8488 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8489
8490 test_65d() {
8491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8492
8493         test_mkdir $DIR/$tdir
8494         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8495         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8496
8497         if [[ $STRIPECOUNT -le 0 ]]; then
8498                 sc=1
8499         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8500                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8501                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8502         else
8503                 sc=$(($STRIPECOUNT - 1))
8504         fi
8505         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8506         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8507         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8508                 error "lverify failed"
8509 }
8510 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8511
8512 test_65e() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         test_mkdir $DIR/$tdir
8516
8517         $LFS setstripe $DIR/$tdir || error "setstripe"
8518         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8519                                         error "no stripe info failed"
8520         touch $DIR/$tdir/f6
8521         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8522 }
8523 run_test 65e "directory setstripe defaults"
8524
8525 test_65f() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527
8528         test_mkdir $DIR/${tdir}f
8529         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8530                 error "setstripe succeeded" || true
8531 }
8532 run_test 65f "dir setstripe permission (should return error) ==="
8533
8534 test_65g() {
8535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8536
8537         test_mkdir $DIR/$tdir
8538         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8539
8540         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8541                 error "setstripe -S failed"
8542         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8543         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8544                 error "delete default stripe failed"
8545 }
8546 run_test 65g "directory setstripe -d"
8547
8548 test_65h() {
8549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8550
8551         test_mkdir $DIR/$tdir
8552         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8553
8554         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8555                 error "setstripe -S failed"
8556         test_mkdir $DIR/$tdir/dd1
8557         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8558                 error "stripe info inherit failed"
8559 }
8560 run_test 65h "directory stripe info inherit ===================="
8561
8562 test_65i() {
8563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8564
8565         save_layout_restore_at_exit $MOUNT
8566
8567         # bug6367: set non-default striping on root directory
8568         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8569
8570         # bug12836: getstripe on -1 default directory striping
8571         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8572
8573         # bug12836: getstripe -v on -1 default directory striping
8574         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8575
8576         # bug12836: new find on -1 default directory striping
8577         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8578 }
8579 run_test 65i "various tests to set root directory striping"
8580
8581 test_65j() { # bug6367
8582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8583
8584         sync; sleep 1
8585
8586         # if we aren't already remounting for each test, do so for this test
8587         if [ "$I_MOUNTED" = "yes" ]; then
8588                 cleanup || error "failed to unmount"
8589                 setup
8590         fi
8591
8592         save_layout_restore_at_exit $MOUNT
8593
8594         $LFS setstripe -d $MOUNT || error "setstripe failed"
8595 }
8596 run_test 65j "set default striping on root directory (bug 6367)="
8597
8598 cleanup_65k() {
8599         rm -rf $DIR/$tdir
8600         wait_delete_completed
8601         do_facet $SINGLEMDS "lctl set_param -n \
8602                 osp.$ost*MDT0000.max_create_count=$max_count"
8603         do_facet $SINGLEMDS "lctl set_param -n \
8604                 osp.$ost*MDT0000.create_count=$count"
8605         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8606         echo $INACTIVE_OSC "is Activate"
8607
8608         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8609 }
8610
8611 test_65k() { # bug11679
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8614         remote_mds_nodsh && skip "remote MDS with nodsh"
8615
8616         local disable_precreate=true
8617         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8618                 disable_precreate=false
8619
8620         echo "Check OST status: "
8621         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8622                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8623
8624         for OSC in $MDS_OSCS; do
8625                 echo $OSC "is active"
8626                 do_facet $SINGLEMDS lctl --device %$OSC activate
8627         done
8628
8629         for INACTIVE_OSC in $MDS_OSCS; do
8630                 local ost=$(osc_to_ost $INACTIVE_OSC)
8631                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8632                                lov.*md*.target_obd |
8633                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8634
8635                 mkdir -p $DIR/$tdir
8636                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8637                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8638
8639                 echo "Deactivate: " $INACTIVE_OSC
8640                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8641
8642                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8643                               osp.$ost*MDT0000.create_count")
8644                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8645                                   osp.$ost*MDT0000.max_create_count")
8646                 $disable_precreate &&
8647                         do_facet $SINGLEMDS "lctl set_param -n \
8648                                 osp.$ost*MDT0000.max_create_count=0"
8649
8650                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8651                         [ -f $DIR/$tdir/$idx ] && continue
8652                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8653                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8654                                 { cleanup_65k;
8655                                   error "setstripe $idx should succeed"; }
8656                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8657                 done
8658                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8659                 rmdir $DIR/$tdir
8660
8661                 do_facet $SINGLEMDS "lctl set_param -n \
8662                         osp.$ost*MDT0000.max_create_count=$max_count"
8663                 do_facet $SINGLEMDS "lctl set_param -n \
8664                         osp.$ost*MDT0000.create_count=$count"
8665                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8666                 echo $INACTIVE_OSC "is Activate"
8667
8668                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8669         done
8670 }
8671 run_test 65k "validate manual striping works properly with deactivated OSCs"
8672
8673 test_65l() { # bug 12836
8674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8675
8676         test_mkdir -p $DIR/$tdir/test_dir
8677         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8678         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8679 }
8680 run_test 65l "lfs find on -1 stripe dir ========================"
8681
8682 test_65m() {
8683         local layout=$(save_layout $MOUNT)
8684         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8685                 restore_layout $MOUNT $layout
8686                 error "setstripe should fail by non-root users"
8687         }
8688         true
8689 }
8690 run_test 65m "normal user can't set filesystem default stripe"
8691
8692 test_65n() {
8693         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8694         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8695                 skip "Need MDS version at least 2.12.50"
8696         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8697
8698         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8699         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8700         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8701
8702         local root_layout=$(save_layout $MOUNT)
8703         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8704
8705         # new subdirectory under root directory should not inherit
8706         # the default layout from root
8707         local dir1=$MOUNT/$tdir-1
8708         mkdir $dir1 || error "mkdir $dir1 failed"
8709         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8710                 error "$dir1 shouldn't have LOV EA"
8711
8712         # delete the default layout on root directory
8713         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8714
8715         local dir2=$MOUNT/$tdir-2
8716         mkdir $dir2 || error "mkdir $dir2 failed"
8717         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8718                 error "$dir2 shouldn't have LOV EA"
8719
8720         # set a new striping pattern on root directory
8721         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8722         local new_def_stripe_size=$((def_stripe_size * 2))
8723         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8724                 error "set stripe size on $MOUNT failed"
8725
8726         # new file created in $dir2 should inherit the new stripe size from
8727         # the filesystem default
8728         local file2=$dir2/$tfile-2
8729         touch $file2 || error "touch $file2 failed"
8730
8731         local file2_stripe_size=$($LFS getstripe -S $file2)
8732         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8733         {
8734                 echo "file2_stripe_size: '$file2_stripe_size'"
8735                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8736                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8737         }
8738
8739         local dir3=$MOUNT/$tdir-3
8740         mkdir $dir3 || error "mkdir $dir3 failed"
8741         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8742         # the root layout, which is the actual default layout that will be used
8743         # when new files are created in $dir3.
8744         local dir3_layout=$(get_layout_param $dir3)
8745         local root_dir_layout=$(get_layout_param $MOUNT)
8746         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8747         {
8748                 echo "dir3_layout: '$dir3_layout'"
8749                 echo "root_dir_layout: '$root_dir_layout'"
8750                 error "$dir3 should show the default layout from $MOUNT"
8751         }
8752
8753         # set OST pool on root directory
8754         local pool=$TESTNAME
8755         pool_add $pool || error "add $pool failed"
8756         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8757                 error "add targets to $pool failed"
8758
8759         $LFS setstripe -p $pool $MOUNT ||
8760                 error "set OST pool on $MOUNT failed"
8761
8762         # new file created in $dir3 should inherit the pool from
8763         # the filesystem default
8764         local file3=$dir3/$tfile-3
8765         touch $file3 || error "touch $file3 failed"
8766
8767         local file3_pool=$($LFS getstripe -p $file3)
8768         [[ "$file3_pool" = "$pool" ]] ||
8769                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8770
8771         local dir4=$MOUNT/$tdir-4
8772         mkdir $dir4 || error "mkdir $dir4 failed"
8773         local dir4_layout=$(get_layout_param $dir4)
8774         root_dir_layout=$(get_layout_param $MOUNT)
8775         echo "$LFS getstripe -d $dir4"
8776         $LFS getstripe -d $dir4
8777         echo "$LFS getstripe -d $MOUNT"
8778         $LFS getstripe -d $MOUNT
8779         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8780         {
8781                 echo "dir4_layout: '$dir4_layout'"
8782                 echo "root_dir_layout: '$root_dir_layout'"
8783                 error "$dir4 should show the default layout from $MOUNT"
8784         }
8785
8786         # new file created in $dir4 should inherit the pool from
8787         # the filesystem default
8788         local file4=$dir4/$tfile-4
8789         touch $file4 || error "touch $file4 failed"
8790
8791         local file4_pool=$($LFS getstripe -p $file4)
8792         [[ "$file4_pool" = "$pool" ]] ||
8793                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8794
8795         # new subdirectory under non-root directory should inherit
8796         # the default layout from its parent directory
8797         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8798                 error "set directory layout on $dir4 failed"
8799
8800         local dir5=$dir4/$tdir-5
8801         mkdir $dir5 || error "mkdir $dir5 failed"
8802
8803         dir4_layout=$(get_layout_param $dir4)
8804         local dir5_layout=$(get_layout_param $dir5)
8805         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8806         {
8807                 echo "dir4_layout: '$dir4_layout'"
8808                 echo "dir5_layout: '$dir5_layout'"
8809                 error "$dir5 should inherit the default layout from $dir4"
8810         }
8811
8812         # though subdir under ROOT doesn't inherit default layout, but
8813         # its sub dir/file should be created with default layout.
8814         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8815         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8816                 skip "Need MDS version at least 2.12.59"
8817
8818         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8819         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8820         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8821
8822         if [ $default_lmv_hash == "none" ]; then
8823                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8824         else
8825                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8826                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8827         fi
8828
8829         $LFS setdirstripe -D -c 2 $MOUNT ||
8830                 error "setdirstripe -D -c 2 failed"
8831         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8832         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8833         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8834 }
8835 run_test 65n "don't inherit default layout from root for new subdirectories"
8836
8837 # bug 2543 - update blocks count on client
8838 test_66() {
8839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8840
8841         COUNT=${COUNT:-8}
8842         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8843         sync; sync_all_data; sync; sync_all_data
8844         cancel_lru_locks osc
8845         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8846         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8847 }
8848 run_test 66 "update inode blocks count on client ==============="
8849
8850 meminfo() {
8851         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8852 }
8853
8854 swap_used() {
8855         swapon -s | awk '($1 == "'$1'") { print $4 }'
8856 }
8857
8858 # bug5265, obdfilter oa2dentry return -ENOENT
8859 # #define OBD_FAIL_SRV_ENOENT 0x217
8860 test_69() {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862         remote_ost_nodsh && skip "remote OST with nodsh"
8863
8864         f="$DIR/$tfile"
8865         $LFS setstripe -c 1 -i 0 $f
8866
8867         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8868
8869         do_facet ost1 lctl set_param fail_loc=0x217
8870         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8871         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8872
8873         do_facet ost1 lctl set_param fail_loc=0
8874         $DIRECTIO write $f 0 2 || error "write error"
8875
8876         cancel_lru_locks osc
8877         $DIRECTIO read $f 0 1 || error "read error"
8878
8879         do_facet ost1 lctl set_param fail_loc=0x217
8880         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8881
8882         do_facet ost1 lctl set_param fail_loc=0
8883         rm -f $f
8884 }
8885 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8886
8887 test_71() {
8888         test_mkdir $DIR/$tdir
8889         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8890         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8891 }
8892 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8893
8894 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896         [ "$RUNAS_ID" = "$UID" ] &&
8897                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8898         # Check that testing environment is properly set up. Skip if not
8899         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8900                 skip_env "User $RUNAS_ID does not exist - skipping"
8901
8902         touch $DIR/$tfile
8903         chmod 777 $DIR/$tfile
8904         chmod ug+s $DIR/$tfile
8905         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8906                 error "$RUNAS dd $DIR/$tfile failed"
8907         # See if we are still setuid/sgid
8908         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8909                 error "S/gid is not dropped on write"
8910         # Now test that MDS is updated too
8911         cancel_lru_locks mdc
8912         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8913                 error "S/gid is not dropped on MDS"
8914         rm -f $DIR/$tfile
8915 }
8916 run_test 72a "Test that remove suid works properly (bug5695) ===="
8917
8918 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8919         local perm
8920
8921         [ "$RUNAS_ID" = "$UID" ] &&
8922                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8923         [ "$RUNAS_ID" -eq 0 ] &&
8924                 skip_env "RUNAS_ID = 0 -- skipping"
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926         # Check that testing environment is properly set up. Skip if not
8927         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8928                 skip_env "User $RUNAS_ID does not exist - skipping"
8929
8930         touch $DIR/${tfile}-f{g,u}
8931         test_mkdir $DIR/${tfile}-dg
8932         test_mkdir $DIR/${tfile}-du
8933         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8934         chmod g+s $DIR/${tfile}-{f,d}g
8935         chmod u+s $DIR/${tfile}-{f,d}u
8936         for perm in 777 2777 4777; do
8937                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8938                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8939                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8940                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8941         done
8942         true
8943 }
8944 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8945
8946 # bug 3462 - multiple simultaneous MDC requests
8947 test_73() {
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949
8950         test_mkdir $DIR/d73-1
8951         test_mkdir $DIR/d73-2
8952         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8953         pid1=$!
8954
8955         lctl set_param fail_loc=0x80000129
8956         $MULTIOP $DIR/d73-1/f73-2 Oc &
8957         sleep 1
8958         lctl set_param fail_loc=0
8959
8960         $MULTIOP $DIR/d73-2/f73-3 Oc &
8961         pid3=$!
8962
8963         kill -USR1 $pid1
8964         wait $pid1 || return 1
8965
8966         sleep 25
8967
8968         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8969         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8970         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8971
8972         rm -rf $DIR/d73-*
8973 }
8974 run_test 73 "multiple MDC requests (should not deadlock)"
8975
8976 test_74a() { # bug 6149, 6184
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8978
8979         touch $DIR/f74a
8980         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8981         #
8982         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8983         # will spin in a tight reconnection loop
8984         $LCTL set_param fail_loc=0x8000030e
8985         # get any lock that won't be difficult - lookup works.
8986         ls $DIR/f74a
8987         $LCTL set_param fail_loc=0
8988         rm -f $DIR/f74a
8989         true
8990 }
8991 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8992
8993 test_74b() { # bug 13310
8994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8995
8996         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8997         #
8998         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8999         # will spin in a tight reconnection loop
9000         $LCTL set_param fail_loc=0x8000030e
9001         # get a "difficult" lock
9002         touch $DIR/f74b
9003         $LCTL set_param fail_loc=0
9004         rm -f $DIR/f74b
9005         true
9006 }
9007 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9008
9009 test_74c() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         #define OBD_FAIL_LDLM_NEW_LOCK
9013         $LCTL set_param fail_loc=0x319
9014         touch $DIR/$tfile && error "touch successful"
9015         $LCTL set_param fail_loc=0
9016         true
9017 }
9018 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9019
9020 slab_lic=/sys/kernel/slab/lustre_inode_cache
9021 num_objects() {
9022         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9023         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9024                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9025 }
9026
9027 test_76a() { # Now for b=20433, added originally in b=1443
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029
9030         cancel_lru_locks osc
9031         # there may be some slab objects cached per core
9032         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9033         local before=$(num_objects)
9034         local count=$((512 * cpus))
9035         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9036         local margin=$((count / 10))
9037         if [[ -f $slab_lic/aliases ]]; then
9038                 local aliases=$(cat $slab_lic/aliases)
9039                 (( aliases > 0 )) && margin=$((margin * aliases))
9040         fi
9041
9042         echo "before slab objects: $before"
9043         for i in $(seq $count); do
9044                 touch $DIR/$tfile
9045                 rm -f $DIR/$tfile
9046         done
9047         cancel_lru_locks osc
9048         local after=$(num_objects)
9049         echo "created: $count, after slab objects: $after"
9050         # shared slab counts are not very accurate, allow significant margin
9051         # the main goal is that the cache growth is not permanently > $count
9052         while (( after > before + margin )); do
9053                 sleep 1
9054                 after=$(num_objects)
9055                 wait=$((wait + 1))
9056                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9057                 if (( wait > 60 )); then
9058                         error "inode slab grew from $before+$margin to $after"
9059                 fi
9060         done
9061 }
9062 run_test 76a "confirm clients recycle inodes properly ===="
9063
9064 test_76b() {
9065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9066         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9067
9068         local count=512
9069         local before=$(num_objects)
9070
9071         for i in $(seq $count); do
9072                 mkdir $DIR/$tdir
9073                 rmdir $DIR/$tdir
9074         done
9075
9076         local after=$(num_objects)
9077         local wait=0
9078
9079         while (( after > before )); do
9080                 sleep 1
9081                 after=$(num_objects)
9082                 wait=$((wait + 1))
9083                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9084                 if (( wait > 60 )); then
9085                         error "inode slab grew from $before to $after"
9086                 fi
9087         done
9088
9089         echo "slab objects before: $before, after: $after"
9090 }
9091 run_test 76b "confirm clients recycle directory inodes properly ===="
9092
9093 export ORIG_CSUM=""
9094 set_checksums()
9095 {
9096         # Note: in sptlrpc modes which enable its own bulk checksum, the
9097         # original crc32_le bulk checksum will be automatically disabled,
9098         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9099         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9100         # In this case set_checksums() will not be no-op, because sptlrpc
9101         # bulk checksum will be enabled all through the test.
9102
9103         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9104         lctl set_param -n osc.*.checksums $1
9105         return 0
9106 }
9107
9108 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9109                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9110 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9111                              tr -d [] | head -n1)}
9112 set_checksum_type()
9113 {
9114         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9115         rc=$?
9116         log "set checksum type to $1, rc = $rc"
9117         return $rc
9118 }
9119
9120 get_osc_checksum_type()
9121 {
9122         # arugment 1: OST name, like OST0000
9123         ost=$1
9124         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9125                         sed 's/.*\[\(.*\)\].*/\1/g')
9126         rc=$?
9127         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9128         echo $checksum_type
9129 }
9130
9131 F77_TMP=$TMP/f77-temp
9132 F77SZ=8
9133 setup_f77() {
9134         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9135                 error "error writing to $F77_TMP"
9136 }
9137
9138 test_77a() { # bug 10889
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140         $GSS && skip_env "could not run with gss"
9141
9142         [ ! -f $F77_TMP ] && setup_f77
9143         set_checksums 1
9144         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9145         set_checksums 0
9146         rm -f $DIR/$tfile
9147 }
9148 run_test 77a "normal checksum read/write operation"
9149
9150 test_77b() { # bug 10889
9151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9152         $GSS && skip_env "could not run with gss"
9153
9154         [ ! -f $F77_TMP ] && setup_f77
9155         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9156         $LCTL set_param fail_loc=0x80000409
9157         set_checksums 1
9158
9159         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9160                 error "dd error: $?"
9161         $LCTL set_param fail_loc=0
9162
9163         for algo in $CKSUM_TYPES; do
9164                 cancel_lru_locks osc
9165                 set_checksum_type $algo
9166                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9167                 $LCTL set_param fail_loc=0x80000408
9168                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9169                 $LCTL set_param fail_loc=0
9170         done
9171         set_checksums 0
9172         set_checksum_type $ORIG_CSUM_TYPE
9173         rm -f $DIR/$tfile
9174 }
9175 run_test 77b "checksum error on client write, read"
9176
9177 cleanup_77c() {
9178         trap 0
9179         set_checksums 0
9180         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9181         $check_ost &&
9182                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9183         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9184         $check_ost && [ -n "$ost_file_prefix" ] &&
9185                 do_facet ost1 rm -f ${ost_file_prefix}\*
9186 }
9187
9188 test_77c() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190         $GSS && skip_env "could not run with gss"
9191         remote_ost_nodsh && skip "remote OST with nodsh"
9192
9193         local bad1
9194         local osc_file_prefix
9195         local osc_file
9196         local check_ost=false
9197         local ost_file_prefix
9198         local ost_file
9199         local orig_cksum
9200         local dump_cksum
9201         local fid
9202
9203         # ensure corruption will occur on first OSS/OST
9204         $LFS setstripe -i 0 $DIR/$tfile
9205
9206         [ ! -f $F77_TMP ] && setup_f77
9207         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9208                 error "dd write error: $?"
9209         fid=$($LFS path2fid $DIR/$tfile)
9210
9211         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9212         then
9213                 check_ost=true
9214                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9215                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9216         else
9217                 echo "OSS do not support bulk pages dump upon error"
9218         fi
9219
9220         osc_file_prefix=$($LCTL get_param -n debug_path)
9221         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9222
9223         trap cleanup_77c EXIT
9224
9225         set_checksums 1
9226         # enable bulk pages dump upon error on Client
9227         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9228         # enable bulk pages dump upon error on OSS
9229         $check_ost &&
9230                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9231
9232         # flush Client cache to allow next read to reach OSS
9233         cancel_lru_locks osc
9234
9235         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9236         $LCTL set_param fail_loc=0x80000408
9237         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9238         $LCTL set_param fail_loc=0
9239
9240         rm -f $DIR/$tfile
9241
9242         # check cksum dump on Client
9243         osc_file=$(ls ${osc_file_prefix}*)
9244         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9245         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9246         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9247         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9248         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9249                      cksum)
9250         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9251         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9252                 error "dump content does not match on Client"
9253
9254         $check_ost || skip "No need to check cksum dump on OSS"
9255
9256         # check cksum dump on OSS
9257         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9258         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9259         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9260         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9261         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9262                 error "dump content does not match on OSS"
9263
9264         cleanup_77c
9265 }
9266 run_test 77c "checksum error on client read with debug"
9267
9268 test_77d() { # bug 10889
9269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9270         $GSS && skip_env "could not run with gss"
9271
9272         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9273         $LCTL set_param fail_loc=0x80000409
9274         set_checksums 1
9275         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9276                 error "direct write: rc=$?"
9277         $LCTL set_param fail_loc=0
9278         set_checksums 0
9279
9280         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9281         $LCTL set_param fail_loc=0x80000408
9282         set_checksums 1
9283         cancel_lru_locks osc
9284         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9285                 error "direct read: rc=$?"
9286         $LCTL set_param fail_loc=0
9287         set_checksums 0
9288 }
9289 run_test 77d "checksum error on OST direct write, read"
9290
9291 test_77f() { # bug 10889
9292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9293         $GSS && skip_env "could not run with gss"
9294
9295         set_checksums 1
9296         for algo in $CKSUM_TYPES; do
9297                 cancel_lru_locks osc
9298                 set_checksum_type $algo
9299                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9300                 $LCTL set_param fail_loc=0x409
9301                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9302                         error "direct write succeeded"
9303                 $LCTL set_param fail_loc=0
9304         done
9305         set_checksum_type $ORIG_CSUM_TYPE
9306         set_checksums 0
9307 }
9308 run_test 77f "repeat checksum error on write (expect error)"
9309
9310 test_77g() { # bug 10889
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312         $GSS && skip_env "could not run with gss"
9313         remote_ost_nodsh && skip "remote OST with nodsh"
9314
9315         [ ! -f $F77_TMP ] && setup_f77
9316
9317         local file=$DIR/$tfile
9318         stack_trap "rm -f $file" EXIT
9319
9320         $LFS setstripe -c 1 -i 0 $file
9321         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9322         do_facet ost1 lctl set_param fail_loc=0x8000021a
9323         set_checksums 1
9324         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9325                 error "write error: rc=$?"
9326         do_facet ost1 lctl set_param fail_loc=0
9327         set_checksums 0
9328
9329         cancel_lru_locks osc
9330         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9331         do_facet ost1 lctl set_param fail_loc=0x8000021b
9332         set_checksums 1
9333         cmp $F77_TMP $file || error "file compare failed"
9334         do_facet ost1 lctl set_param fail_loc=0
9335         set_checksums 0
9336 }
9337 run_test 77g "checksum error on OST write, read"
9338
9339 test_77k() { # LU-10906
9340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9341         $GSS && skip_env "could not run with gss"
9342
9343         local cksum_param="osc.$FSNAME*.checksums"
9344         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9345         local checksum
9346         local i
9347
9348         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9349         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9350         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9351
9352         for i in 0 1; do
9353                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9354                         error "failed to set checksum=$i on MGS"
9355                 wait_update $HOSTNAME "$get_checksum" $i
9356                 #remount
9357                 echo "remount client, checksum should be $i"
9358                 remount_client $MOUNT || error "failed to remount client"
9359                 checksum=$(eval $get_checksum)
9360                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9361         done
9362         # remove persistent param to avoid races with checksum mountopt below
9363         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9364                 error "failed to delete checksum on MGS"
9365
9366         for opt in "checksum" "nochecksum"; do
9367                 #remount with mount option
9368                 echo "remount client with option $opt, checksum should be $i"
9369                 umount_client $MOUNT || error "failed to umount client"
9370                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9371                         error "failed to mount client with option '$opt'"
9372                 checksum=$(eval $get_checksum)
9373                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9374                 i=$((i - 1))
9375         done
9376
9377         remount_client $MOUNT || error "failed to remount client"
9378 }
9379 run_test 77k "enable/disable checksum correctly"
9380
9381 test_77l() {
9382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9383         $GSS && skip_env "could not run with gss"
9384
9385         set_checksums 1
9386         stack_trap "set_checksums $ORIG_CSUM" EXIT
9387         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9388
9389         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9390
9391         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9392         for algo in $CKSUM_TYPES; do
9393                 set_checksum_type $algo || error "fail to set checksum type $algo"
9394                 osc_algo=$(get_osc_checksum_type OST0000)
9395                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9396
9397                 # no locks, no reqs to let the connection idle
9398                 cancel_lru_locks osc
9399                 lru_resize_disable osc
9400                 wait_osc_import_state client ost1 IDLE
9401
9402                 # ensure ost1 is connected
9403                 stat $DIR/$tfile >/dev/null || error "can't stat"
9404                 wait_osc_import_state client ost1 FULL
9405
9406                 osc_algo=$(get_osc_checksum_type OST0000)
9407                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9408         done
9409         return 0
9410 }
9411 run_test 77l "preferred checksum type is remembered after reconnected"
9412
9413 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9414 rm -f $F77_TMP
9415 unset F77_TMP
9416
9417 cleanup_test_78() {
9418         trap 0
9419         rm -f $DIR/$tfile
9420 }
9421
9422 test_78() { # bug 10901
9423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9424         remote_ost || skip_env "local OST"
9425
9426         NSEQ=5
9427         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9428         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9429         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9430         echo "MemTotal: $MEMTOTAL"
9431
9432         # reserve 256MB of memory for the kernel and other running processes,
9433         # and then take 1/2 of the remaining memory for the read/write buffers.
9434         if [ $MEMTOTAL -gt 512 ] ;then
9435                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9436         else
9437                 # for those poor memory-starved high-end clusters...
9438                 MEMTOTAL=$((MEMTOTAL / 2))
9439         fi
9440         echo "Mem to use for directio: $MEMTOTAL"
9441
9442         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9443         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9444         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9445         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9446                 head -n1)
9447         echo "Smallest OST: $SMALLESTOST"
9448         [[ $SMALLESTOST -lt 10240 ]] &&
9449                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9450
9451         trap cleanup_test_78 EXIT
9452
9453         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9454                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9455
9456         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9457         echo "File size: $F78SIZE"
9458         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9459         for i in $(seq 1 $NSEQ); do
9460                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9461                 echo directIO rdwr round $i of $NSEQ
9462                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9463         done
9464
9465         cleanup_test_78
9466 }
9467 run_test 78 "handle large O_DIRECT writes correctly ============"
9468
9469 test_79() { # bug 12743
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471
9472         wait_delete_completed
9473
9474         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9475         BKFREE=$(calc_osc_kbytes kbytesfree)
9476         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9477
9478         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9479         DFTOTAL=`echo $STRING | cut -d, -f1`
9480         DFUSED=`echo $STRING  | cut -d, -f2`
9481         DFAVAIL=`echo $STRING | cut -d, -f3`
9482         DFFREE=$(($DFTOTAL - $DFUSED))
9483
9484         ALLOWANCE=$((64 * $OSTCOUNT))
9485
9486         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9487            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9488                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9489         fi
9490         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9491            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9492                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9493         fi
9494         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9495            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9496                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9497         fi
9498 }
9499 run_test 79 "df report consistency check ======================="
9500
9501 test_80() { # bug 10718
9502         remote_ost_nodsh && skip "remote OST with nodsh"
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504
9505         # relax strong synchronous semantics for slow backends like ZFS
9506         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9507                 local soc="obdfilter.*.sync_lock_cancel"
9508                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9509
9510                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9511                 if [ -z "$save" ]; then
9512                         soc="obdfilter.*.sync_on_lock_cancel"
9513                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9514                 fi
9515
9516                 if [ "$save" != "never" ]; then
9517                         local hosts=$(comma_list $(osts_nodes))
9518
9519                         do_nodes $hosts $LCTL set_param $soc=never
9520                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9521                 fi
9522         fi
9523
9524         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9525         sync; sleep 1; sync
9526         local before=$(date +%s)
9527         cancel_lru_locks osc
9528         local after=$(date +%s)
9529         local diff=$((after - before))
9530         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9531
9532         rm -f $DIR/$tfile
9533 }
9534 run_test 80 "Page eviction is equally fast at high offsets too"
9535
9536 test_81a() { # LU-456
9537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9538         remote_ost_nodsh && skip "remote OST with nodsh"
9539
9540         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9541         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9542         do_facet ost1 lctl set_param fail_loc=0x80000228
9543
9544         # write should trigger a retry and success
9545         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9547         RC=$?
9548         if [ $RC -ne 0 ] ; then
9549                 error "write should success, but failed for $RC"
9550         fi
9551 }
9552 run_test 81a "OST should retry write when get -ENOSPC ==============="
9553
9554 test_81b() { # LU-456
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556         remote_ost_nodsh && skip "remote OST with nodsh"
9557
9558         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9559         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9560         do_facet ost1 lctl set_param fail_loc=0x228
9561
9562         # write should retry several times and return -ENOSPC finally
9563         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9564         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9565         RC=$?
9566         ENOSPC=28
9567         if [ $RC -ne $ENOSPC ] ; then
9568                 error "dd should fail for -ENOSPC, but succeed."
9569         fi
9570 }
9571 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9572
9573 test_99() {
9574         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9575
9576         test_mkdir $DIR/$tdir.cvsroot
9577         chown $RUNAS_ID $DIR/$tdir.cvsroot
9578
9579         cd $TMP
9580         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9581
9582         cd /etc/init.d
9583         # some versions of cvs import exit(1) when asked to import links or
9584         # files they can't read.  ignore those files.
9585         local toignore=$(find . -type l -printf '-I %f\n' -o \
9586                          ! -perm /4 -printf '-I %f\n')
9587         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9588                 $tdir.reposname vtag rtag
9589
9590         cd $DIR
9591         test_mkdir $DIR/$tdir.reposname
9592         chown $RUNAS_ID $DIR/$tdir.reposname
9593         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9594
9595         cd $DIR/$tdir.reposname
9596         $RUNAS touch foo99
9597         $RUNAS cvs add -m 'addmsg' foo99
9598         $RUNAS cvs update
9599         $RUNAS cvs commit -m 'nomsg' foo99
9600         rm -fr $DIR/$tdir.cvsroot
9601 }
9602 run_test 99 "cvs strange file/directory operations"
9603
9604 test_100() {
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         [[ "$NETTYPE" =~ tcp ]] ||
9607                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9608         remote_ost_nodsh && skip "remote OST with nodsh"
9609         remote_mds_nodsh && skip "remote MDS with nodsh"
9610         remote_servers ||
9611                 skip "useless for local single node setup"
9612
9613         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9614                 [ "$PROT" != "tcp" ] && continue
9615                 RPORT=$(echo $REMOTE | cut -d: -f2)
9616                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9617
9618                 rc=0
9619                 LPORT=`echo $LOCAL | cut -d: -f2`
9620                 if [ $LPORT -ge 1024 ]; then
9621                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9622                         netstat -tna
9623                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9624                 fi
9625         done
9626         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9627 }
9628 run_test 100 "check local port using privileged port ==========="
9629
9630 function get_named_value()
9631 {
9632     local tag=$1
9633
9634     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9635 }
9636
9637 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9638                    awk '/^max_cached_mb/ { print $2 }')
9639
9640 cleanup_101a() {
9641         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9642         trap 0
9643 }
9644
9645 test_101a() {
9646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9647
9648         local s
9649         local discard
9650         local nreads=10000
9651         local cache_limit=32
9652
9653         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9654         trap cleanup_101a EXIT
9655         $LCTL set_param -n llite.*.read_ahead_stats=0
9656         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9657
9658         #
9659         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9660         #
9661         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9662         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9663
9664         discard=0
9665         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9666                    get_named_value 'read.but.discarded'); do
9667                         discard=$(($discard + $s))
9668         done
9669         cleanup_101a
9670
9671         $LCTL get_param osc.*-osc*.rpc_stats
9672         $LCTL get_param llite.*.read_ahead_stats
9673
9674         # Discard is generally zero, but sometimes a few random reads line up
9675         # and trigger larger readahead, which is wasted & leads to discards.
9676         if [[ $(($discard)) -gt $nreads ]]; then
9677                 error "too many ($discard) discarded pages"
9678         fi
9679         rm -f $DIR/$tfile || true
9680 }
9681 run_test 101a "check read-ahead for random reads"
9682
9683 setup_test101bc() {
9684         test_mkdir $DIR/$tdir
9685         local ssize=$1
9686         local FILE_LENGTH=$2
9687         STRIPE_OFFSET=0
9688
9689         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9690
9691         local list=$(comma_list $(osts_nodes))
9692         set_osd_param $list '' read_cache_enable 0
9693         set_osd_param $list '' writethrough_cache_enable 0
9694
9695         trap cleanup_test101bc EXIT
9696         # prepare the read-ahead file
9697         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9698
9699         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9700                                 count=$FILE_SIZE_MB 2> /dev/null
9701
9702 }
9703
9704 cleanup_test101bc() {
9705         trap 0
9706         rm -rf $DIR/$tdir
9707         rm -f $DIR/$tfile
9708
9709         local list=$(comma_list $(osts_nodes))
9710         set_osd_param $list '' read_cache_enable 1
9711         set_osd_param $list '' writethrough_cache_enable 1
9712 }
9713
9714 calc_total() {
9715         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9716 }
9717
9718 ra_check_101() {
9719         local READ_SIZE=$1
9720         local STRIPE_SIZE=$2
9721         local FILE_LENGTH=$3
9722         local RA_INC=1048576
9723         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9724         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9725                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9726         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9727                   get_named_value 'read.but.discarded' | calc_total)
9728         if [[ $DISCARD -gt $discard_limit ]]; then
9729                 $LCTL get_param llite.*.read_ahead_stats
9730                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9731         else
9732                 echo "Read-ahead success for size ${READ_SIZE}"
9733         fi
9734 }
9735
9736 test_101b() {
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9739
9740         local STRIPE_SIZE=1048576
9741         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9742
9743         if [ $SLOW == "yes" ]; then
9744                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9745         else
9746                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9747         fi
9748
9749         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9750
9751         # prepare the read-ahead file
9752         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9753         cancel_lru_locks osc
9754         for BIDX in 2 4 8 16 32 64 128 256
9755         do
9756                 local BSIZE=$((BIDX*4096))
9757                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9758                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9759                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9760                 $LCTL set_param -n llite.*.read_ahead_stats=0
9761                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9762                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9763                 cancel_lru_locks osc
9764                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9765         done
9766         cleanup_test101bc
9767         true
9768 }
9769 run_test 101b "check stride-io mode read-ahead ================="
9770
9771 test_101c() {
9772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9773
9774         local STRIPE_SIZE=1048576
9775         local FILE_LENGTH=$((STRIPE_SIZE*100))
9776         local nreads=10000
9777         local rsize=65536
9778         local osc_rpc_stats
9779
9780         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9781
9782         cancel_lru_locks osc
9783         $LCTL set_param osc.*.rpc_stats=0
9784         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9785         $LCTL get_param osc.*.rpc_stats
9786         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9787                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9788                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9789                 local size
9790
9791                 if [ $lines -le 20 ]; then
9792                         echo "continue debug"
9793                         continue
9794                 fi
9795                 for size in 1 2 4 8; do
9796                         local rpc=$(echo "$stats" |
9797                                     awk '($1 == "'$size':") {print $2; exit; }')
9798                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9799                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9800                 done
9801                 echo "$osc_rpc_stats check passed!"
9802         done
9803         cleanup_test101bc
9804         true
9805 }
9806 run_test 101c "check stripe_size aligned read-ahead"
9807
9808 test_101d() {
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         local file=$DIR/$tfile
9812         local sz_MB=${FILESIZE_101d:-80}
9813         local ra_MB=${READAHEAD_MB:-40}
9814
9815         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9816         [ $free_MB -lt $sz_MB ] &&
9817                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9818
9819         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9820         $LFS setstripe -c -1 $file || error "setstripe failed"
9821
9822         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9823         echo Cancel LRU locks on lustre client to flush the client cache
9824         cancel_lru_locks osc
9825
9826         echo Disable read-ahead
9827         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9828         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9829         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9830         $LCTL get_param -n llite.*.max_read_ahead_mb
9831
9832         echo "Reading the test file $file with read-ahead disabled"
9833         local sz_KB=$((sz_MB * 1024 / 4))
9834         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9835         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9836         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9837                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9838
9839         echo "Cancel LRU locks on lustre client to flush the client cache"
9840         cancel_lru_locks osc
9841         echo Enable read-ahead with ${ra_MB}MB
9842         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9843
9844         echo "Reading the test file $file with read-ahead enabled"
9845         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9846                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9847
9848         echo "read-ahead disabled time read $raOFF"
9849         echo "read-ahead enabled time read $raON"
9850
9851         rm -f $file
9852         wait_delete_completed
9853
9854         # use awk for this check instead of bash because it handles decimals
9855         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9856                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9857 }
9858 run_test 101d "file read with and without read-ahead enabled"
9859
9860 test_101e() {
9861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9862
9863         local file=$DIR/$tfile
9864         local size_KB=500  #KB
9865         local count=100
9866         local bsize=1024
9867
9868         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9869         local need_KB=$((count * size_KB))
9870         [[ $free_KB -le $need_KB ]] &&
9871                 skip_env "Need free space $need_KB, have $free_KB"
9872
9873         echo "Creating $count ${size_KB}K test files"
9874         for ((i = 0; i < $count; i++)); do
9875                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9876         done
9877
9878         echo "Cancel LRU locks on lustre client to flush the client cache"
9879         cancel_lru_locks $OSC
9880
9881         echo "Reset readahead stats"
9882         $LCTL set_param -n llite.*.read_ahead_stats=0
9883
9884         for ((i = 0; i < $count; i++)); do
9885                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9886         done
9887
9888         $LCTL get_param llite.*.max_cached_mb
9889         $LCTL get_param llite.*.read_ahead_stats
9890         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9891                      get_named_value 'misses' | calc_total)
9892
9893         for ((i = 0; i < $count; i++)); do
9894                 rm -rf $file.$i 2>/dev/null
9895         done
9896
9897         #10000 means 20% reads are missing in readahead
9898         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9899 }
9900 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9901
9902 test_101f() {
9903         which iozone || skip_env "no iozone installed"
9904
9905         local old_debug=$($LCTL get_param debug)
9906         old_debug=${old_debug#*=}
9907         $LCTL set_param debug="reada mmap"
9908
9909         # create a test file
9910         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9911
9912         echo Cancel LRU locks on lustre client to flush the client cache
9913         cancel_lru_locks osc
9914
9915         echo Reset readahead stats
9916         $LCTL set_param -n llite.*.read_ahead_stats=0
9917
9918         echo mmap read the file with small block size
9919         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9920                 > /dev/null 2>&1
9921
9922         echo checking missing pages
9923         $LCTL get_param llite.*.read_ahead_stats
9924         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9925                         get_named_value 'misses' | calc_total)
9926
9927         $LCTL set_param debug="$old_debug"
9928         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9929         rm -f $DIR/$tfile
9930 }
9931 run_test 101f "check mmap read performance"
9932
9933 test_101g_brw_size_test() {
9934         local mb=$1
9935         local pages=$((mb * 1048576 / PAGE_SIZE))
9936         local file=$DIR/$tfile
9937
9938         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9939                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9940         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9941                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9942                         return 2
9943         done
9944
9945         stack_trap "rm -f $file" EXIT
9946         $LCTL set_param -n osc.*.rpc_stats=0
9947
9948         # 10 RPCs should be enough for the test
9949         local count=10
9950         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9951                 { error "dd write ${mb} MB blocks failed"; return 3; }
9952         cancel_lru_locks osc
9953         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9954                 { error "dd write ${mb} MB blocks failed"; return 4; }
9955
9956         # calculate number of full-sized read and write RPCs
9957         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9958                 sed -n '/pages per rpc/,/^$/p' |
9959                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9960                 END { print reads,writes }'))
9961         # allow one extra full-sized read RPC for async readahead
9962         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9963                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9964         [[ ${rpcs[1]} == $count ]] ||
9965                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9966 }
9967
9968 test_101g() {
9969         remote_ost_nodsh && skip "remote OST with nodsh"
9970
9971         local rpcs
9972         local osts=$(get_facets OST)
9973         local list=$(comma_list $(osts_nodes))
9974         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9975         local brw_size="obdfilter.*.brw_size"
9976
9977         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9978
9979         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9980
9981         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9982                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9983                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9984            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9985                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9986                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9987
9988                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9989                         suffix="M"
9990
9991                 if [[ $orig_mb -lt 16 ]]; then
9992                         save_lustre_params $osts "$brw_size" > $p
9993                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9994                                 error "set 16MB RPC size failed"
9995
9996                         echo "remount client to enable new RPC size"
9997                         remount_client $MOUNT || error "remount_client failed"
9998                 fi
9999
10000                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10001                 # should be able to set brw_size=12, but no rpc_stats for that
10002                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10003         fi
10004
10005         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10006
10007         if [[ $orig_mb -lt 16 ]]; then
10008                 restore_lustre_params < $p
10009                 remount_client $MOUNT || error "remount_client restore failed"
10010         fi
10011
10012         rm -f $p $DIR/$tfile
10013 }
10014 run_test 101g "Big bulk(4/16 MiB) readahead"
10015
10016 test_101h() {
10017         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10018
10019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10020                 error "dd 70M file failed"
10021         echo Cancel LRU locks on lustre client to flush the client cache
10022         cancel_lru_locks osc
10023
10024         echo "Reset readahead stats"
10025         $LCTL set_param -n llite.*.read_ahead_stats 0
10026
10027         echo "Read 10M of data but cross 64M bundary"
10028         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10029         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10030                      get_named_value 'misses' | calc_total)
10031         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10032         rm -f $p $DIR/$tfile
10033 }
10034 run_test 101h "Readahead should cover current read window"
10035
10036 test_101i() {
10037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10038                 error "dd 10M file failed"
10039
10040         local max_per_file_mb=$($LCTL get_param -n \
10041                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10042         cancel_lru_locks osc
10043         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10044         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10045                 error "set max_read_ahead_per_file_mb to 1 failed"
10046
10047         echo "Reset readahead stats"
10048         $LCTL set_param llite.*.read_ahead_stats=0
10049
10050         dd if=$DIR/$tfile of=/dev/null bs=2M
10051
10052         $LCTL get_param llite.*.read_ahead_stats
10053         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10054                      awk '/misses/ { print $2 }')
10055         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10056         rm -f $DIR/$tfile
10057 }
10058 run_test 101i "allow current readahead to exceed reservation"
10059
10060 test_101j() {
10061         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10062                 error "setstripe $DIR/$tfile failed"
10063         local file_size=$((1048576 * 16))
10064         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10065         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10066
10067         echo Disable read-ahead
10068         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10069
10070         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10071         for blk in $PAGE_SIZE 1048576 $file_size; do
10072                 cancel_lru_locks osc
10073                 echo "Reset readahead stats"
10074                 $LCTL set_param -n llite.*.read_ahead_stats=0
10075                 local count=$(($file_size / $blk))
10076                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10077                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10078                              get_named_value 'failed.to.fast.read' | calc_total)
10079                 $LCTL get_param -n llite.*.read_ahead_stats
10080                 [ $miss -eq $count ] || error "expected $count got $miss"
10081         done
10082
10083         rm -f $p $DIR/$tfile
10084 }
10085 run_test 101j "A complete read block should be submitted when no RA"
10086
10087 setup_test102() {
10088         test_mkdir $DIR/$tdir
10089         chown $RUNAS_ID $DIR/$tdir
10090         STRIPE_SIZE=65536
10091         STRIPE_OFFSET=1
10092         STRIPE_COUNT=$OSTCOUNT
10093         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10094
10095         trap cleanup_test102 EXIT
10096         cd $DIR
10097         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10098         cd $DIR/$tdir
10099         for num in 1 2 3 4; do
10100                 for count in $(seq 1 $STRIPE_COUNT); do
10101                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10102                                 local size=`expr $STRIPE_SIZE \* $num`
10103                                 local file=file"$num-$idx-$count"
10104                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10105                         done
10106                 done
10107         done
10108
10109         cd $DIR
10110         $1 tar cf $TMP/f102.tar $tdir --xattrs
10111 }
10112
10113 cleanup_test102() {
10114         trap 0
10115         rm -f $TMP/f102.tar
10116         rm -rf $DIR/d0.sanity/d102
10117 }
10118
10119 test_102a() {
10120         [ "$UID" != 0 ] && skip "must run as root"
10121         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10122                 skip_env "must have user_xattr"
10123
10124         [ -z "$(which setfattr 2>/dev/null)" ] &&
10125                 skip_env "could not find setfattr"
10126
10127         local testfile=$DIR/$tfile
10128
10129         touch $testfile
10130         echo "set/get xattr..."
10131         setfattr -n trusted.name1 -v value1 $testfile ||
10132                 error "setfattr -n trusted.name1=value1 $testfile failed"
10133         getfattr -n trusted.name1 $testfile 2> /dev/null |
10134           grep "trusted.name1=.value1" ||
10135                 error "$testfile missing trusted.name1=value1"
10136
10137         setfattr -n user.author1 -v author1 $testfile ||
10138                 error "setfattr -n user.author1=author1 $testfile failed"
10139         getfattr -n user.author1 $testfile 2> /dev/null |
10140           grep "user.author1=.author1" ||
10141                 error "$testfile missing trusted.author1=author1"
10142
10143         echo "listxattr..."
10144         setfattr -n trusted.name2 -v value2 $testfile ||
10145                 error "$testfile unable to set trusted.name2"
10146         setfattr -n trusted.name3 -v value3 $testfile ||
10147                 error "$testfile unable to set trusted.name3"
10148         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10149             grep "trusted.name" | wc -l) -eq 3 ] ||
10150                 error "$testfile missing 3 trusted.name xattrs"
10151
10152         setfattr -n user.author2 -v author2 $testfile ||
10153                 error "$testfile unable to set user.author2"
10154         setfattr -n user.author3 -v author3 $testfile ||
10155                 error "$testfile unable to set user.author3"
10156         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10157             grep "user.author" | wc -l) -eq 3 ] ||
10158                 error "$testfile missing 3 user.author xattrs"
10159
10160         echo "remove xattr..."
10161         setfattr -x trusted.name1 $testfile ||
10162                 error "$testfile error deleting trusted.name1"
10163         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10164                 error "$testfile did not delete trusted.name1 xattr"
10165
10166         setfattr -x user.author1 $testfile ||
10167                 error "$testfile error deleting user.author1"
10168         echo "set lustre special xattr ..."
10169         $LFS setstripe -c1 $testfile
10170         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10171                 awk -F "=" '/trusted.lov/ { print $2 }' )
10172         setfattr -n "trusted.lov" -v $lovea $testfile ||
10173                 error "$testfile doesn't ignore setting trusted.lov again"
10174         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10175                 error "$testfile allow setting invalid trusted.lov"
10176         rm -f $testfile
10177 }
10178 run_test 102a "user xattr test =================================="
10179
10180 check_102b_layout() {
10181         local layout="$*"
10182         local testfile=$DIR/$tfile
10183
10184         echo "test layout '$layout'"
10185         $LFS setstripe $layout $testfile || error "setstripe failed"
10186         $LFS getstripe -y $testfile
10187
10188         echo "get/set/list trusted.lov xattr ..." # b=10930
10189         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10190         [[ "$value" =~ "trusted.lov" ]] ||
10191                 error "can't get trusted.lov from $testfile"
10192         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10193                 error "getstripe failed"
10194
10195         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10196
10197         value=$(cut -d= -f2 <<<$value)
10198         # LU-13168: truncated xattr should fail if short lov_user_md header
10199         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10200                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10201         for len in $lens; do
10202                 echo "setfattr $len $testfile.2"
10203                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10204                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10205         done
10206         local stripe_size=$($LFS getstripe -S $testfile.2)
10207         local stripe_count=$($LFS getstripe -c $testfile.2)
10208         [[ $stripe_size -eq 65536 ]] ||
10209                 error "stripe size $stripe_size != 65536"
10210         [[ $stripe_count -eq $stripe_count_orig ]] ||
10211                 error "stripe count $stripe_count != $stripe_count_orig"
10212         rm $testfile $testfile.2
10213 }
10214
10215 test_102b() {
10216         [ -z "$(which setfattr 2>/dev/null)" ] &&
10217                 skip_env "could not find setfattr"
10218         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10219
10220         # check plain layout
10221         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10222
10223         # and also check composite layout
10224         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10225
10226 }
10227 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10228
10229 test_102c() {
10230         [ -z "$(which setfattr 2>/dev/null)" ] &&
10231                 skip_env "could not find setfattr"
10232         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10233
10234         # b10930: get/set/list lustre.lov xattr
10235         echo "get/set/list lustre.lov xattr ..."
10236         test_mkdir $DIR/$tdir
10237         chown $RUNAS_ID $DIR/$tdir
10238         local testfile=$DIR/$tdir/$tfile
10239         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10240                 error "setstripe failed"
10241         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10242                 error "getstripe failed"
10243         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10244         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10245
10246         local testfile2=${testfile}2
10247         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10248                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10249
10250         $RUNAS $MCREATE $testfile2
10251         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10252         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10253         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10254         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10255         [ $stripe_count -eq $STRIPECOUNT ] ||
10256                 error "stripe count $stripe_count != $STRIPECOUNT"
10257 }
10258 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10259
10260 compare_stripe_info1() {
10261         local stripe_index_all_zero=true
10262
10263         for num in 1 2 3 4; do
10264                 for count in $(seq 1 $STRIPE_COUNT); do
10265                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10266                                 local size=$((STRIPE_SIZE * num))
10267                                 local file=file"$num-$offset-$count"
10268                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10269                                 [[ $stripe_size -ne $size ]] &&
10270                                     error "$file: size $stripe_size != $size"
10271                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10272                                 # allow fewer stripes to be created, ORI-601
10273                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10274                                     error "$file: count $stripe_count != $count"
10275                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10276                                 [[ $stripe_index -ne 0 ]] &&
10277                                         stripe_index_all_zero=false
10278                         done
10279                 done
10280         done
10281         $stripe_index_all_zero &&
10282                 error "all files are being extracted starting from OST index 0"
10283         return 0
10284 }
10285
10286 have_xattrs_include() {
10287         tar --help | grep -q xattrs-include &&
10288                 echo --xattrs-include="lustre.*"
10289 }
10290
10291 test_102d() {
10292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10294
10295         XINC=$(have_xattrs_include)
10296         setup_test102
10297         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10298         cd $DIR/$tdir/$tdir
10299         compare_stripe_info1
10300 }
10301 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10302
10303 test_102f() {
10304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10305         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10306
10307         XINC=$(have_xattrs_include)
10308         setup_test102
10309         test_mkdir $DIR/$tdir.restore
10310         cd $DIR
10311         tar cf - --xattrs $tdir | tar xf - \
10312                 -C $DIR/$tdir.restore --xattrs $XINC
10313         cd $DIR/$tdir.restore/$tdir
10314         compare_stripe_info1
10315 }
10316 run_test 102f "tar copy files, not keep osts"
10317
10318 grow_xattr() {
10319         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10320                 skip "must have user_xattr"
10321         [ -z "$(which setfattr 2>/dev/null)" ] &&
10322                 skip_env "could not find setfattr"
10323         [ -z "$(which getfattr 2>/dev/null)" ] &&
10324                 skip_env "could not find getfattr"
10325
10326         local xsize=${1:-1024}  # in bytes
10327         local file=$DIR/$tfile
10328         local value="$(generate_string $xsize)"
10329         local xbig=trusted.big
10330         local toobig=$2
10331
10332         touch $file
10333         log "save $xbig on $file"
10334         if [ -z "$toobig" ]
10335         then
10336                 setfattr -n $xbig -v $value $file ||
10337                         error "saving $xbig on $file failed"
10338         else
10339                 setfattr -n $xbig -v $value $file &&
10340                         error "saving $xbig on $file succeeded"
10341                 return 0
10342         fi
10343
10344         local orig=$(get_xattr_value $xbig $file)
10345         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10346
10347         local xsml=trusted.sml
10348         log "save $xsml on $file"
10349         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10350
10351         local new=$(get_xattr_value $xbig $file)
10352         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10353
10354         log "grow $xsml on $file"
10355         setfattr -n $xsml -v "$value" $file ||
10356                 error "growing $xsml on $file failed"
10357
10358         new=$(get_xattr_value $xbig $file)
10359         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10360         log "$xbig still valid after growing $xsml"
10361
10362         rm -f $file
10363 }
10364
10365 test_102h() { # bug 15777
10366         grow_xattr 1024
10367 }
10368 run_test 102h "grow xattr from inside inode to external block"
10369
10370 test_102ha() {
10371         large_xattr_enabled || skip_env "ea_inode feature disabled"
10372
10373         echo "setting xattr of max xattr size: $(max_xattr_size)"
10374         grow_xattr $(max_xattr_size)
10375
10376         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10377         echo "This should fail:"
10378         grow_xattr $(($(max_xattr_size) + 10)) 1
10379 }
10380 run_test 102ha "grow xattr from inside inode to external inode"
10381
10382 test_102i() { # bug 17038
10383         [ -z "$(which getfattr 2>/dev/null)" ] &&
10384                 skip "could not find getfattr"
10385
10386         touch $DIR/$tfile
10387         ln -s $DIR/$tfile $DIR/${tfile}link
10388         getfattr -n trusted.lov $DIR/$tfile ||
10389                 error "lgetxattr on $DIR/$tfile failed"
10390         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10391                 grep -i "no such attr" ||
10392                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10393         rm -f $DIR/$tfile $DIR/${tfile}link
10394 }
10395 run_test 102i "lgetxattr test on symbolic link ============"
10396
10397 test_102j() {
10398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10400
10401         XINC=$(have_xattrs_include)
10402         setup_test102 "$RUNAS"
10403         chown $RUNAS_ID $DIR/$tdir
10404         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10405         cd $DIR/$tdir/$tdir
10406         compare_stripe_info1 "$RUNAS"
10407 }
10408 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10409
10410 test_102k() {
10411         [ -z "$(which setfattr 2>/dev/null)" ] &&
10412                 skip "could not find setfattr"
10413
10414         touch $DIR/$tfile
10415         # b22187 just check that does not crash for regular file.
10416         setfattr -n trusted.lov $DIR/$tfile
10417         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10418         local test_kdir=$DIR/$tdir
10419         test_mkdir $test_kdir
10420         local default_size=$($LFS getstripe -S $test_kdir)
10421         local default_count=$($LFS getstripe -c $test_kdir)
10422         local default_offset=$($LFS getstripe -i $test_kdir)
10423         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10424                 error 'dir setstripe failed'
10425         setfattr -n trusted.lov $test_kdir
10426         local stripe_size=$($LFS getstripe -S $test_kdir)
10427         local stripe_count=$($LFS getstripe -c $test_kdir)
10428         local stripe_offset=$($LFS getstripe -i $test_kdir)
10429         [ $stripe_size -eq $default_size ] ||
10430                 error "stripe size $stripe_size != $default_size"
10431         [ $stripe_count -eq $default_count ] ||
10432                 error "stripe count $stripe_count != $default_count"
10433         [ $stripe_offset -eq $default_offset ] ||
10434                 error "stripe offset $stripe_offset != $default_offset"
10435         rm -rf $DIR/$tfile $test_kdir
10436 }
10437 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10438
10439 test_102l() {
10440         [ -z "$(which getfattr 2>/dev/null)" ] &&
10441                 skip "could not find getfattr"
10442
10443         # LU-532 trusted. xattr is invisible to non-root
10444         local testfile=$DIR/$tfile
10445
10446         touch $testfile
10447
10448         echo "listxattr as user..."
10449         chown $RUNAS_ID $testfile
10450         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10451             grep -q "trusted" &&
10452                 error "$testfile trusted xattrs are user visible"
10453
10454         return 0;
10455 }
10456 run_test 102l "listxattr size test =================================="
10457
10458 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10459         local path=$DIR/$tfile
10460         touch $path
10461
10462         listxattr_size_check $path || error "listattr_size_check $path failed"
10463 }
10464 run_test 102m "Ensure listxattr fails on small bufffer ========"
10465
10466 cleanup_test102
10467
10468 getxattr() { # getxattr path name
10469         # Return the base64 encoding of the value of xattr name on path.
10470         local path=$1
10471         local name=$2
10472
10473         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10474         # file: $path
10475         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10476         #
10477         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10478
10479         getfattr --absolute-names --encoding=base64 --name=$name $path |
10480                 awk -F= -v name=$name '$1 == name {
10481                         print substr($0, index($0, "=") + 1);
10482         }'
10483 }
10484
10485 test_102n() { # LU-4101 mdt: protect internal xattrs
10486         [ -z "$(which setfattr 2>/dev/null)" ] &&
10487                 skip "could not find setfattr"
10488         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10489         then
10490                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10491         fi
10492
10493         local file0=$DIR/$tfile.0
10494         local file1=$DIR/$tfile.1
10495         local xattr0=$TMP/$tfile.0
10496         local xattr1=$TMP/$tfile.1
10497         local namelist="lov lma lmv link fid version som hsm"
10498         local name
10499         local value
10500
10501         rm -rf $file0 $file1 $xattr0 $xattr1
10502         touch $file0 $file1
10503
10504         # Get 'before' xattrs of $file1.
10505         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10506
10507         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10508                 namelist+=" lfsck_namespace"
10509         for name in $namelist; do
10510                 # Try to copy xattr from $file0 to $file1.
10511                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10512
10513                 setfattr --name=trusted.$name --value="$value" $file1 ||
10514                         error "setxattr 'trusted.$name' failed"
10515
10516                 # Try to set a garbage xattr.
10517                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10518
10519                 if [[ x$name == "xlov" ]]; then
10520                         setfattr --name=trusted.lov --value="$value" $file1 &&
10521                         error "setxattr invalid 'trusted.lov' success"
10522                 else
10523                         setfattr --name=trusted.$name --value="$value" $file1 ||
10524                                 error "setxattr invalid 'trusted.$name' failed"
10525                 fi
10526
10527                 # Try to remove the xattr from $file1. We don't care if this
10528                 # appears to succeed or fail, we just don't want there to be
10529                 # any changes or crashes.
10530                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10531         done
10532
10533         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10534         then
10535                 name="lfsck_ns"
10536                 # Try to copy xattr from $file0 to $file1.
10537                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10538
10539                 setfattr --name=trusted.$name --value="$value" $file1 ||
10540                         error "setxattr 'trusted.$name' failed"
10541
10542                 # Try to set a garbage xattr.
10543                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10544
10545                 setfattr --name=trusted.$name --value="$value" $file1 ||
10546                         error "setxattr 'trusted.$name' failed"
10547
10548                 # Try to remove the xattr from $file1. We don't care if this
10549                 # appears to succeed or fail, we just don't want there to be
10550                 # any changes or crashes.
10551                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10552         fi
10553
10554         # Get 'after' xattrs of file1.
10555         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10556
10557         if ! diff $xattr0 $xattr1; then
10558                 error "before and after xattrs of '$file1' differ"
10559         fi
10560
10561         rm -rf $file0 $file1 $xattr0 $xattr1
10562
10563         return 0
10564 }
10565 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10566
10567 test_102p() { # LU-4703 setxattr did not check ownership
10568         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10569                 skip "MDS needs to be at least 2.5.56"
10570
10571         local testfile=$DIR/$tfile
10572
10573         touch $testfile
10574
10575         echo "setfacl as user..."
10576         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10577         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10578
10579         echo "setfattr as user..."
10580         setfacl -m "u:$RUNAS_ID:---" $testfile
10581         $RUNAS setfattr -x system.posix_acl_access $testfile
10582         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10583 }
10584 run_test 102p "check setxattr(2) correctly fails without permission"
10585
10586 test_102q() {
10587         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10588                 skip "MDS needs to be at least 2.6.92"
10589
10590         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10591 }
10592 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10593
10594 test_102r() {
10595         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10596                 skip "MDS needs to be at least 2.6.93"
10597
10598         touch $DIR/$tfile || error "touch"
10599         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10600         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10601         rm $DIR/$tfile || error "rm"
10602
10603         #normal directory
10604         mkdir -p $DIR/$tdir || error "mkdir"
10605         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10606         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10607         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10608                 error "$testfile error deleting user.author1"
10609         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10610                 grep "user.$(basename $tdir)" &&
10611                 error "$tdir did not delete user.$(basename $tdir)"
10612         rmdir $DIR/$tdir || error "rmdir"
10613
10614         #striped directory
10615         test_mkdir $DIR/$tdir
10616         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10617         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10618         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10619                 error "$testfile error deleting user.author1"
10620         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10621                 grep "user.$(basename $tdir)" &&
10622                 error "$tdir did not delete user.$(basename $tdir)"
10623         rmdir $DIR/$tdir || error "rm striped dir"
10624 }
10625 run_test 102r "set EAs with empty values"
10626
10627 test_102s() {
10628         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10629                 skip "MDS needs to be at least 2.11.52"
10630
10631         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10632
10633         save_lustre_params client "llite.*.xattr_cache" > $save
10634
10635         for cache in 0 1; do
10636                 lctl set_param llite.*.xattr_cache=$cache
10637
10638                 rm -f $DIR/$tfile
10639                 touch $DIR/$tfile || error "touch"
10640                 for prefix in lustre security system trusted user; do
10641                         # Note getxattr() may fail with 'Operation not
10642                         # supported' or 'No such attribute' depending
10643                         # on prefix and cache.
10644                         getfattr -n $prefix.n102s $DIR/$tfile &&
10645                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10646                 done
10647         done
10648
10649         restore_lustre_params < $save
10650 }
10651 run_test 102s "getting nonexistent xattrs should fail"
10652
10653 test_102t() {
10654         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10655                 skip "MDS needs to be at least 2.11.52"
10656
10657         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10658
10659         save_lustre_params client "llite.*.xattr_cache" > $save
10660
10661         for cache in 0 1; do
10662                 lctl set_param llite.*.xattr_cache=$cache
10663
10664                 for buf_size in 0 256; do
10665                         rm -f $DIR/$tfile
10666                         touch $DIR/$tfile || error "touch"
10667                         setfattr -n user.multiop $DIR/$tfile
10668                         $MULTIOP $DIR/$tfile oa$buf_size ||
10669                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10670                 done
10671         done
10672
10673         restore_lustre_params < $save
10674 }
10675 run_test 102t "zero length xattr values handled correctly"
10676
10677 run_acl_subtest()
10678 {
10679     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10680     return $?
10681 }
10682
10683 test_103a() {
10684         [ "$UID" != 0 ] && skip "must run as root"
10685         $GSS && skip_env "could not run under gss"
10686         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10687                 skip_env "must have acl enabled"
10688         [ -z "$(which setfacl 2>/dev/null)" ] &&
10689                 skip_env "could not find setfacl"
10690         remote_mds_nodsh && skip "remote MDS with nodsh"
10691
10692         gpasswd -a daemon bin                           # LU-5641
10693         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10694
10695         declare -a identity_old
10696
10697         for num in $(seq $MDSCOUNT); do
10698                 switch_identity $num true || identity_old[$num]=$?
10699         done
10700
10701         SAVE_UMASK=$(umask)
10702         umask 0022
10703         mkdir -p $DIR/$tdir
10704         cd $DIR/$tdir
10705
10706         echo "performing cp ..."
10707         run_acl_subtest cp || error "run_acl_subtest cp failed"
10708         echo "performing getfacl-noacl..."
10709         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10710         echo "performing misc..."
10711         run_acl_subtest misc || error  "misc test failed"
10712         echo "performing permissions..."
10713         run_acl_subtest permissions || error "permissions failed"
10714         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10715         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10716                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10717                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10718         then
10719                 echo "performing permissions xattr..."
10720                 run_acl_subtest permissions_xattr ||
10721                         error "permissions_xattr failed"
10722         fi
10723         echo "performing setfacl..."
10724         run_acl_subtest setfacl || error  "setfacl test failed"
10725
10726         # inheritance test got from HP
10727         echo "performing inheritance..."
10728         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10729         chmod +x make-tree || error "chmod +x failed"
10730         run_acl_subtest inheritance || error "inheritance test failed"
10731         rm -f make-tree
10732
10733         echo "LU-974 ignore umask when acl is enabled..."
10734         run_acl_subtest 974 || error "LU-974 umask test failed"
10735         if [ $MDSCOUNT -ge 2 ]; then
10736                 run_acl_subtest 974_remote ||
10737                         error "LU-974 umask test failed under remote dir"
10738         fi
10739
10740         echo "LU-2561 newly created file is same size as directory..."
10741         if [ "$mds1_FSTYPE" != "zfs" ]; then
10742                 run_acl_subtest 2561 || error "LU-2561 test failed"
10743         else
10744                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10745         fi
10746
10747         run_acl_subtest 4924 || error "LU-4924 test failed"
10748
10749         cd $SAVE_PWD
10750         umask $SAVE_UMASK
10751
10752         for num in $(seq $MDSCOUNT); do
10753                 if [ "${identity_old[$num]}" = 1 ]; then
10754                         switch_identity $num false || identity_old[$num]=$?
10755                 fi
10756         done
10757 }
10758 run_test 103a "acl test"
10759
10760 test_103b() {
10761         declare -a pids
10762         local U
10763
10764         for U in {0..511}; do
10765                 {
10766                 local O=$(printf "%04o" $U)
10767
10768                 umask $(printf "%04o" $((511 ^ $O)))
10769                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10770                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10771
10772                 (( $S == ($O & 0666) )) ||
10773                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10774
10775                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10776                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10777                 (( $S == ($O & 0666) )) ||
10778                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10779
10780                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10781                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10782                 (( $S == ($O & 0666) )) ||
10783                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10784                 rm -f $DIR/$tfile.[smp]$0
10785                 } &
10786                 local pid=$!
10787
10788                 # limit the concurrently running threads to 64. LU-11878
10789                 local idx=$((U % 64))
10790                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10791                 pids[idx]=$pid
10792         done
10793         wait
10794 }
10795 run_test 103b "umask lfs setstripe"
10796
10797 test_103c() {
10798         mkdir -p $DIR/$tdir
10799         cp -rp $DIR/$tdir $DIR/$tdir.bak
10800
10801         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10802                 error "$DIR/$tdir shouldn't contain default ACL"
10803         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10804                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10805         true
10806 }
10807 run_test 103c "'cp -rp' won't set empty acl"
10808
10809 test_103e() {
10810         local numacl
10811         local fileacl
10812         local saved_debug=$($LCTL get_param -n debug)
10813
10814         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10815                 skip "MDS needs to be at least 2.14.0"
10816
10817         large_xattr_enabled || skip_env "ea_inode feature disabled"
10818
10819         mkdir -p $DIR/$tdir
10820         # add big LOV EA to cause reply buffer overflow earlier
10821         $LFS setstripe -C 1000 $DIR/$tdir
10822         lctl set_param mdc.*-mdc*.stats=clear
10823
10824         $LCTL set_param debug=0
10825         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10826         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10827
10828         # add a large number of default ACLs (expect 8000+ for 2.13+)
10829         for U in {2..7000}; do
10830                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10831                         error "Able to add just $U default ACLs"
10832         done
10833         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10834         echo "$numacl default ACLs created"
10835
10836         stat $DIR/$tdir || error "Cannot stat directory"
10837         # check file creation
10838         touch $DIR/$tdir/$tfile ||
10839                 error "failed to create $tfile with $numacl default ACLs"
10840         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10841         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10842         echo "$fileacl ACLs were inherited"
10843         (( $fileacl == $numacl )) ||
10844                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10845         # check that new ACLs creation adds new ACLs to inherited ACLs
10846         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10847                 error "Cannot set new ACL"
10848         numacl=$((numacl + 1))
10849         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10850         (( $fileacl == $numacl )) ||
10851                 error "failed to add new ACL: $fileacl != $numacl as expected"
10852         # adds more ACLs to a file to reach their maximum at 8000+
10853         numacl=0
10854         for U in {20000..25000}; do
10855                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10856                 numacl=$((numacl + 1))
10857         done
10858         echo "Added $numacl more ACLs to the file"
10859         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10860         echo "Total $fileacl ACLs in file"
10861         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10862         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10863         rmdir $DIR/$tdir || error "Cannot remove directory"
10864 }
10865 run_test 103e "inheritance of big amount of default ACLs"
10866
10867 test_104a() {
10868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10869
10870         touch $DIR/$tfile
10871         lfs df || error "lfs df failed"
10872         lfs df -ih || error "lfs df -ih failed"
10873         lfs df -h $DIR || error "lfs df -h $DIR failed"
10874         lfs df -i $DIR || error "lfs df -i $DIR failed"
10875         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10876         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10877
10878         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10879         lctl --device %$OSC deactivate
10880         lfs df || error "lfs df with deactivated OSC failed"
10881         lctl --device %$OSC activate
10882         # wait the osc back to normal
10883         wait_osc_import_ready client ost
10884
10885         lfs df || error "lfs df with reactivated OSC failed"
10886         rm -f $DIR/$tfile
10887 }
10888 run_test 104a "lfs df [-ih] [path] test ========================="
10889
10890 test_104b() {
10891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10892         [ $RUNAS_ID -eq $UID ] &&
10893                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10894
10895         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10896                         grep "Permission denied" | wc -l)))
10897         if [ $denied_cnt -ne 0 ]; then
10898                 error "lfs check servers test failed"
10899         fi
10900 }
10901 run_test 104b "$RUNAS lfs check servers test ===================="
10902
10903 #
10904 # Verify $1 is within range of $2.
10905 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
10906 # $1 is <= 2% of $2. Else Fail.
10907 #
10908 value_in_range() {
10909         # Strip all units (M, G, T)
10910         actual=$(echo $1 | tr -d A-Z)
10911         expect=$(echo $2 | tr -d A-Z)
10912
10913         expect_lo=$(($expect * 98 / 100)) # 2% below
10914         expect_hi=$(($expect * 102 / 100)) # 2% above
10915
10916         # permit 2% drift above and below
10917         (( $actual >= $expect_lo && $actual <= $expect_hi ))
10918 }
10919
10920 test_104c() {
10921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10922         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
10923
10924         local ost_param="osd-zfs.$FSNAME-OST0000."
10925         local mdt_param="osd-zfs.$FSNAME-MDT0000."
10926         local ofacets=$(get_facets OST)
10927         local mfacets=$(get_facets MDS)
10928         local saved_ost_blocks=
10929         local saved_mdt_blocks=
10930
10931         echo "Before recordsize change"
10932         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
10933         df=($(df -h | grep "/mnt/lustre"$))
10934
10935         # For checking.
10936         echo "lfs output : ${lfs_df[*]}"
10937         echo "df  output : ${df[*]}"
10938
10939         for facet in ${ofacets//,/ }; do
10940                 if [ -z $saved_ost_blocks ]; then
10941                         saved_ost_blocks=$(do_facet $facet \
10942                                 lctl get_param -n $ost_param.blocksize)
10943                         echo "OST Blocksize: $saved_ost_blocks"
10944                 fi
10945                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
10946                 do_facet $facet zfs set recordsize=32768 $ost
10947         done
10948
10949         # BS too small. Sufficient for functional testing.
10950         for facet in ${mfacets//,/ }; do
10951                 if [ -z $saved_mdt_blocks ]; then
10952                         saved_mdt_blocks=$(do_facet $facet \
10953                                 lctl get_param -n $mdt_param.blocksize)
10954                         echo "MDT Blocksize: $saved_mdt_blocks"
10955                 fi
10956                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
10957                 do_facet $facet zfs set recordsize=32768 $mdt
10958         done
10959
10960         # Give new values chance to reflect change
10961         sleep 2
10962
10963         echo "After recordsize change"
10964         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
10965         df_after=($(df -h | grep "/mnt/lustre"$))
10966
10967         # For checking.
10968         echo "lfs output : ${lfs_df_after[*]}"
10969         echo "df  output : ${df_after[*]}"
10970
10971         # Verify lfs df
10972         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
10973                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
10974         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
10975                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
10976         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
10977                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
10978
10979         # Verify df
10980         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
10981                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
10982         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
10983                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
10984         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
10985                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
10986
10987         # Restore MDT recordize back to original
10988         for facet in ${mfacets//,/ }; do
10989                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
10990                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
10991         done
10992
10993         # Restore OST recordize back to original
10994         for facet in ${ofacets//,/ }; do
10995                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
10996                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
10997         done
10998
10999         return 0
11000 }
11001 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11002
11003 test_105a() {
11004         # doesn't work on 2.4 kernels
11005         touch $DIR/$tfile
11006         if $(flock_is_enabled); then
11007                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11008         else
11009                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11010         fi
11011         rm -f $DIR/$tfile
11012 }
11013 run_test 105a "flock when mounted without -o flock test ========"
11014
11015 test_105b() {
11016         touch $DIR/$tfile
11017         if $(flock_is_enabled); then
11018                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11019         else
11020                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11021         fi
11022         rm -f $DIR/$tfile
11023 }
11024 run_test 105b "fcntl when mounted without -o flock test ========"
11025
11026 test_105c() {
11027         touch $DIR/$tfile
11028         if $(flock_is_enabled); then
11029                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11030         else
11031                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11032         fi
11033         rm -f $DIR/$tfile
11034 }
11035 run_test 105c "lockf when mounted without -o flock test"
11036
11037 test_105d() { # bug 15924
11038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11039
11040         test_mkdir $DIR/$tdir
11041         flock_is_enabled || skip_env "mount w/o flock enabled"
11042         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11043         $LCTL set_param fail_loc=0x80000315
11044         flocks_test 2 $DIR/$tdir
11045 }
11046 run_test 105d "flock race (should not freeze) ========"
11047
11048 test_105e() { # bug 22660 && 22040
11049         flock_is_enabled || skip_env "mount w/o flock enabled"
11050
11051         touch $DIR/$tfile
11052         flocks_test 3 $DIR/$tfile
11053 }
11054 run_test 105e "Two conflicting flocks from same process"
11055
11056 test_106() { #bug 10921
11057         test_mkdir $DIR/$tdir
11058         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11059         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11060 }
11061 run_test 106 "attempt exec of dir followed by chown of that dir"
11062
11063 test_107() {
11064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11065
11066         CDIR=`pwd`
11067         local file=core
11068
11069         cd $DIR
11070         rm -f $file
11071
11072         local save_pattern=$(sysctl -n kernel.core_pattern)
11073         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11074         sysctl -w kernel.core_pattern=$file
11075         sysctl -w kernel.core_uses_pid=0
11076
11077         ulimit -c unlimited
11078         sleep 60 &
11079         SLEEPPID=$!
11080
11081         sleep 1
11082
11083         kill -s 11 $SLEEPPID
11084         wait $SLEEPPID
11085         if [ -e $file ]; then
11086                 size=`stat -c%s $file`
11087                 [ $size -eq 0 ] && error "Fail to create core file $file"
11088         else
11089                 error "Fail to create core file $file"
11090         fi
11091         rm -f $file
11092         sysctl -w kernel.core_pattern=$save_pattern
11093         sysctl -w kernel.core_uses_pid=$save_uses_pid
11094         cd $CDIR
11095 }
11096 run_test 107 "Coredump on SIG"
11097
11098 test_110() {
11099         test_mkdir $DIR/$tdir
11100         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11101         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11102                 error "mkdir with 256 char should fail, but did not"
11103         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11104                 error "create with 255 char failed"
11105         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11106                 error "create with 256 char should fail, but did not"
11107
11108         ls -l $DIR/$tdir
11109         rm -rf $DIR/$tdir
11110 }
11111 run_test 110 "filename length checking"
11112
11113 #
11114 # Purpose: To verify dynamic thread (OSS) creation.
11115 #
11116 test_115() {
11117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11118         remote_ost_nodsh && skip "remote OST with nodsh"
11119
11120         # Lustre does not stop service threads once they are started.
11121         # Reset number of running threads to default.
11122         stopall
11123         setupall
11124
11125         local OSTIO_pre
11126         local save_params="$TMP/sanity-$TESTNAME.parameters"
11127
11128         # Get ll_ost_io count before I/O
11129         OSTIO_pre=$(do_facet ost1 \
11130                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11131         # Exit if lustre is not running (ll_ost_io not running).
11132         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11133
11134         echo "Starting with $OSTIO_pre threads"
11135         local thread_max=$((OSTIO_pre * 2))
11136         local rpc_in_flight=$((thread_max * 2))
11137         # Number of I/O Process proposed to be started.
11138         local nfiles
11139         local facets=$(get_facets OST)
11140
11141         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11142         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11143
11144         # Set in_flight to $rpc_in_flight
11145         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11146                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11147         nfiles=${rpc_in_flight}
11148         # Set ost thread_max to $thread_max
11149         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11150
11151         # 5 Minutes should be sufficient for max number of OSS
11152         # threads(thread_max) to be created.
11153         local timeout=300
11154
11155         # Start I/O.
11156         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11157         test_mkdir $DIR/$tdir
11158         for i in $(seq $nfiles); do
11159                 local file=$DIR/$tdir/${tfile}-$i
11160                 $LFS setstripe -c -1 -i 0 $file
11161                 ($WTL $file $timeout)&
11162         done
11163
11164         # I/O Started - Wait for thread_started to reach thread_max or report
11165         # error if thread_started is more than thread_max.
11166         echo "Waiting for thread_started to reach thread_max"
11167         local thread_started=0
11168         local end_time=$((SECONDS + timeout))
11169
11170         while [ $SECONDS -le $end_time ] ; do
11171                 echo -n "."
11172                 # Get ost i/o thread_started count.
11173                 thread_started=$(do_facet ost1 \
11174                         "$LCTL get_param \
11175                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11176                 # Break out if thread_started is equal/greater than thread_max
11177                 if [[ $thread_started -ge $thread_max ]]; then
11178                         echo ll_ost_io thread_started $thread_started, \
11179                                 equal/greater than thread_max $thread_max
11180                         break
11181                 fi
11182                 sleep 1
11183         done
11184
11185         # Cleanup - We have the numbers, Kill i/o jobs if running.
11186         jobcount=($(jobs -p))
11187         for i in $(seq 0 $((${#jobcount[@]}-1)))
11188         do
11189                 kill -9 ${jobcount[$i]}
11190                 if [ $? -ne 0 ] ; then
11191                         echo Warning: \
11192                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11193                 fi
11194         done
11195
11196         # Cleanup files left by WTL binary.
11197         for i in $(seq $nfiles); do
11198                 local file=$DIR/$tdir/${tfile}-$i
11199                 rm -rf $file
11200                 if [ $? -ne 0 ] ; then
11201                         echo "Warning: Failed to delete file $file"
11202                 fi
11203         done
11204
11205         restore_lustre_params <$save_params
11206         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11207
11208         # Error out if no new thread has started or Thread started is greater
11209         # than thread max.
11210         if [[ $thread_started -le $OSTIO_pre ||
11211                         $thread_started -gt $thread_max ]]; then
11212                 error "ll_ost_io: thread_started $thread_started" \
11213                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11214                       "No new thread started or thread started greater " \
11215                       "than thread_max."
11216         fi
11217 }
11218 run_test 115 "verify dynamic thread creation===================="
11219
11220 free_min_max () {
11221         wait_delete_completed
11222         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11223         echo "OST kbytes available: ${AVAIL[@]}"
11224         MAXV=${AVAIL[0]}
11225         MAXI=0
11226         MINV=${AVAIL[0]}
11227         MINI=0
11228         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11229                 #echo OST $i: ${AVAIL[i]}kb
11230                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11231                         MAXV=${AVAIL[i]}
11232                         MAXI=$i
11233                 fi
11234                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11235                         MINV=${AVAIL[i]}
11236                         MINI=$i
11237                 fi
11238         done
11239         echo "Min free space: OST $MINI: $MINV"
11240         echo "Max free space: OST $MAXI: $MAXV"
11241 }
11242
11243 test_116a() { # was previously test_116()
11244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11245         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11246         remote_mds_nodsh && skip "remote MDS with nodsh"
11247
11248         echo -n "Free space priority "
11249         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11250                 head -n1
11251         declare -a AVAIL
11252         free_min_max
11253
11254         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11255         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11256         trap simple_cleanup_common EXIT
11257
11258         # Check if we need to generate uneven OSTs
11259         test_mkdir -p $DIR/$tdir/OST${MINI}
11260         local FILL=$((MINV / 4))
11261         local DIFF=$((MAXV - MINV))
11262         local DIFF2=$((DIFF * 100 / MINV))
11263
11264         local threshold=$(do_facet $SINGLEMDS \
11265                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11266         threshold=${threshold%%%}
11267         echo -n "Check for uneven OSTs: "
11268         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11269
11270         if [[ $DIFF2 -gt $threshold ]]; then
11271                 echo "ok"
11272                 echo "Don't need to fill OST$MINI"
11273         else
11274                 # generate uneven OSTs. Write 2% over the QOS threshold value
11275                 echo "no"
11276                 DIFF=$((threshold - DIFF2 + 2))
11277                 DIFF2=$((MINV * DIFF / 100))
11278                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11279                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11280                         error "setstripe failed"
11281                 DIFF=$((DIFF2 / 2048))
11282                 i=0
11283                 while [ $i -lt $DIFF ]; do
11284                         i=$((i + 1))
11285                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11286                                 bs=2M count=1 2>/dev/null
11287                         echo -n .
11288                 done
11289                 echo .
11290                 sync
11291                 sleep_maxage
11292                 free_min_max
11293         fi
11294
11295         DIFF=$((MAXV - MINV))
11296         DIFF2=$((DIFF * 100 / MINV))
11297         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11298         if [ $DIFF2 -gt $threshold ]; then
11299                 echo "ok"
11300         else
11301                 echo "failed - QOS mode won't be used"
11302                 simple_cleanup_common
11303                 skip "QOS imbalance criteria not met"
11304         fi
11305
11306         MINI1=$MINI
11307         MINV1=$MINV
11308         MAXI1=$MAXI
11309         MAXV1=$MAXV
11310
11311         # now fill using QOS
11312         $LFS setstripe -c 1 $DIR/$tdir
11313         FILL=$((FILL / 200))
11314         if [ $FILL -gt 600 ]; then
11315                 FILL=600
11316         fi
11317         echo "writing $FILL files to QOS-assigned OSTs"
11318         i=0
11319         while [ $i -lt $FILL ]; do
11320                 i=$((i + 1))
11321                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11322                         count=1 2>/dev/null
11323                 echo -n .
11324         done
11325         echo "wrote $i 200k files"
11326         sync
11327         sleep_maxage
11328
11329         echo "Note: free space may not be updated, so measurements might be off"
11330         free_min_max
11331         DIFF2=$((MAXV - MINV))
11332         echo "free space delta: orig $DIFF final $DIFF2"
11333         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11334         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11335         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11336         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11337         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11338         if [[ $DIFF -gt 0 ]]; then
11339                 FILL=$((DIFF2 * 100 / DIFF - 100))
11340                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11341         fi
11342
11343         # Figure out which files were written where
11344         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11345                awk '/'$MINI1': / {print $2; exit}')
11346         echo $UUID
11347         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11348         echo "$MINC files created on smaller OST $MINI1"
11349         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11350                awk '/'$MAXI1': / {print $2; exit}')
11351         echo $UUID
11352         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11353         echo "$MAXC files created on larger OST $MAXI1"
11354         if [[ $MINC -gt 0 ]]; then
11355                 FILL=$((MAXC * 100 / MINC - 100))
11356                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11357         fi
11358         [[ $MAXC -gt $MINC ]] ||
11359                 error_ignore LU-9 "stripe QOS didn't balance free space"
11360         simple_cleanup_common
11361 }
11362 run_test 116a "stripe QOS: free space balance ==================="
11363
11364 test_116b() { # LU-2093
11365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11366         remote_mds_nodsh && skip "remote MDS with nodsh"
11367
11368 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11369         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11370                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11371         [ -z "$old_rr" ] && skip "no QOS"
11372         do_facet $SINGLEMDS lctl set_param \
11373                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11374         mkdir -p $DIR/$tdir
11375         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11376         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11377         do_facet $SINGLEMDS lctl set_param fail_loc=0
11378         rm -rf $DIR/$tdir
11379         do_facet $SINGLEMDS lctl set_param \
11380                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11381 }
11382 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11383
11384 test_117() # bug 10891
11385 {
11386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11387
11388         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11389         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11390         lctl set_param fail_loc=0x21e
11391         > $DIR/$tfile || error "truncate failed"
11392         lctl set_param fail_loc=0
11393         echo "Truncate succeeded."
11394         rm -f $DIR/$tfile
11395 }
11396 run_test 117 "verify osd extend =========="
11397
11398 NO_SLOW_RESENDCOUNT=4
11399 export OLD_RESENDCOUNT=""
11400 set_resend_count () {
11401         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11402         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11403         lctl set_param -n $PROC_RESENDCOUNT $1
11404         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11405 }
11406
11407 # for reduce test_118* time (b=14842)
11408 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11409
11410 # Reset async IO behavior after error case
11411 reset_async() {
11412         FILE=$DIR/reset_async
11413
11414         # Ensure all OSCs are cleared
11415         $LFS setstripe -c -1 $FILE
11416         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11417         sync
11418         rm $FILE
11419 }
11420
11421 test_118a() #bug 11710
11422 {
11423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11424
11425         reset_async
11426
11427         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11428         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11429         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11430
11431         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11432                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11433                 return 1;
11434         fi
11435         rm -f $DIR/$tfile
11436 }
11437 run_test 118a "verify O_SYNC works =========="
11438
11439 test_118b()
11440 {
11441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11442         remote_ost_nodsh && skip "remote OST with nodsh"
11443
11444         reset_async
11445
11446         #define OBD_FAIL_SRV_ENOENT 0x217
11447         set_nodes_failloc "$(osts_nodes)" 0x217
11448         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11449         RC=$?
11450         set_nodes_failloc "$(osts_nodes)" 0
11451         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11452         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11453                     grep -c writeback)
11454
11455         if [[ $RC -eq 0 ]]; then
11456                 error "Must return error due to dropped pages, rc=$RC"
11457                 return 1;
11458         fi
11459
11460         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11461                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11462                 return 1;
11463         fi
11464
11465         echo "Dirty pages not leaked on ENOENT"
11466
11467         # Due to the above error the OSC will issue all RPCs syncronously
11468         # until a subsequent RPC completes successfully without error.
11469         $MULTIOP $DIR/$tfile Ow4096yc
11470         rm -f $DIR/$tfile
11471
11472         return 0
11473 }
11474 run_test 118b "Reclaim dirty pages on fatal error =========="
11475
11476 test_118c()
11477 {
11478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11479
11480         # for 118c, restore the original resend count, LU-1940
11481         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11482                                 set_resend_count $OLD_RESENDCOUNT
11483         remote_ost_nodsh && skip "remote OST with nodsh"
11484
11485         reset_async
11486
11487         #define OBD_FAIL_OST_EROFS               0x216
11488         set_nodes_failloc "$(osts_nodes)" 0x216
11489
11490         # multiop should block due to fsync until pages are written
11491         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11492         MULTIPID=$!
11493         sleep 1
11494
11495         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11496                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11497         fi
11498
11499         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11500                     grep -c writeback)
11501         if [[ $WRITEBACK -eq 0 ]]; then
11502                 error "No page in writeback, writeback=$WRITEBACK"
11503         fi
11504
11505         set_nodes_failloc "$(osts_nodes)" 0
11506         wait $MULTIPID
11507         RC=$?
11508         if [[ $RC -ne 0 ]]; then
11509                 error "Multiop fsync failed, rc=$RC"
11510         fi
11511
11512         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11513         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11514                     grep -c writeback)
11515         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11516                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11517         fi
11518
11519         rm -f $DIR/$tfile
11520         echo "Dirty pages flushed via fsync on EROFS"
11521         return 0
11522 }
11523 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11524
11525 # continue to use small resend count to reduce test_118* time (b=14842)
11526 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11527
11528 test_118d()
11529 {
11530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11531         remote_ost_nodsh && skip "remote OST with nodsh"
11532
11533         reset_async
11534
11535         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11536         set_nodes_failloc "$(osts_nodes)" 0x214
11537         # multiop should block due to fsync until pages are written
11538         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11539         MULTIPID=$!
11540         sleep 1
11541
11542         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11543                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11544         fi
11545
11546         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11547                     grep -c writeback)
11548         if [[ $WRITEBACK -eq 0 ]]; then
11549                 error "No page in writeback, writeback=$WRITEBACK"
11550         fi
11551
11552         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11553         set_nodes_failloc "$(osts_nodes)" 0
11554
11555         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11556         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11557                     grep -c writeback)
11558         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11559                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11560         fi
11561
11562         rm -f $DIR/$tfile
11563         echo "Dirty pages gaurenteed flushed via fsync"
11564         return 0
11565 }
11566 run_test 118d "Fsync validation inject a delay of the bulk =========="
11567
11568 test_118f() {
11569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11570
11571         reset_async
11572
11573         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11574         lctl set_param fail_loc=0x8000040a
11575
11576         # Should simulate EINVAL error which is fatal
11577         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11578         RC=$?
11579         if [[ $RC -eq 0 ]]; then
11580                 error "Must return error due to dropped pages, rc=$RC"
11581         fi
11582
11583         lctl set_param fail_loc=0x0
11584
11585         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11586         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11587         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11588                     grep -c writeback)
11589         if [[ $LOCKED -ne 0 ]]; then
11590                 error "Locked pages remain in cache, locked=$LOCKED"
11591         fi
11592
11593         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11594                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11595         fi
11596
11597         rm -f $DIR/$tfile
11598         echo "No pages locked after fsync"
11599
11600         reset_async
11601         return 0
11602 }
11603 run_test 118f "Simulate unrecoverable OSC side error =========="
11604
11605 test_118g() {
11606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11607
11608         reset_async
11609
11610         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11611         lctl set_param fail_loc=0x406
11612
11613         # simulate local -ENOMEM
11614         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11615         RC=$?
11616
11617         lctl set_param fail_loc=0
11618         if [[ $RC -eq 0 ]]; then
11619                 error "Must return error due to dropped pages, rc=$RC"
11620         fi
11621
11622         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11623         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11624         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11625                         grep -c writeback)
11626         if [[ $LOCKED -ne 0 ]]; then
11627                 error "Locked pages remain in cache, locked=$LOCKED"
11628         fi
11629
11630         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11631                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11632         fi
11633
11634         rm -f $DIR/$tfile
11635         echo "No pages locked after fsync"
11636
11637         reset_async
11638         return 0
11639 }
11640 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11641
11642 test_118h() {
11643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11644         remote_ost_nodsh && skip "remote OST with nodsh"
11645
11646         reset_async
11647
11648         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11649         set_nodes_failloc "$(osts_nodes)" 0x20e
11650         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11651         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11652         RC=$?
11653
11654         set_nodes_failloc "$(osts_nodes)" 0
11655         if [[ $RC -eq 0 ]]; then
11656                 error "Must return error due to dropped pages, rc=$RC"
11657         fi
11658
11659         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11660         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11661         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11662                     grep -c writeback)
11663         if [[ $LOCKED -ne 0 ]]; then
11664                 error "Locked pages remain in cache, locked=$LOCKED"
11665         fi
11666
11667         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11668                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11669         fi
11670
11671         rm -f $DIR/$tfile
11672         echo "No pages locked after fsync"
11673
11674         return 0
11675 }
11676 run_test 118h "Verify timeout in handling recoverables errors  =========="
11677
11678 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11679
11680 test_118i() {
11681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11682         remote_ost_nodsh && skip "remote OST with nodsh"
11683
11684         reset_async
11685
11686         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11687         set_nodes_failloc "$(osts_nodes)" 0x20e
11688
11689         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11690         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11691         PID=$!
11692         sleep 5
11693         set_nodes_failloc "$(osts_nodes)" 0
11694
11695         wait $PID
11696         RC=$?
11697         if [[ $RC -ne 0 ]]; then
11698                 error "got error, but should be not, rc=$RC"
11699         fi
11700
11701         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11702         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11703         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11704         if [[ $LOCKED -ne 0 ]]; then
11705                 error "Locked pages remain in cache, locked=$LOCKED"
11706         fi
11707
11708         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11709                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11710         fi
11711
11712         rm -f $DIR/$tfile
11713         echo "No pages locked after fsync"
11714
11715         return 0
11716 }
11717 run_test 118i "Fix error before timeout in recoverable error  =========="
11718
11719 [ "$SLOW" = "no" ] && set_resend_count 4
11720
11721 test_118j() {
11722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11723         remote_ost_nodsh && skip "remote OST with nodsh"
11724
11725         reset_async
11726
11727         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11728         set_nodes_failloc "$(osts_nodes)" 0x220
11729
11730         # return -EIO from OST
11731         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11732         RC=$?
11733         set_nodes_failloc "$(osts_nodes)" 0x0
11734         if [[ $RC -eq 0 ]]; then
11735                 error "Must return error due to dropped pages, rc=$RC"
11736         fi
11737
11738         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11739         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11740         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11741         if [[ $LOCKED -ne 0 ]]; then
11742                 error "Locked pages remain in cache, locked=$LOCKED"
11743         fi
11744
11745         # in recoverable error on OST we want resend and stay until it finished
11746         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11747                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11748         fi
11749
11750         rm -f $DIR/$tfile
11751         echo "No pages locked after fsync"
11752
11753         return 0
11754 }
11755 run_test 118j "Simulate unrecoverable OST side error =========="
11756
11757 test_118k()
11758 {
11759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11760         remote_ost_nodsh && skip "remote OSTs with nodsh"
11761
11762         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11763         set_nodes_failloc "$(osts_nodes)" 0x20e
11764         test_mkdir $DIR/$tdir
11765
11766         for ((i=0;i<10;i++)); do
11767                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11768                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11769                 SLEEPPID=$!
11770                 sleep 0.500s
11771                 kill $SLEEPPID
11772                 wait $SLEEPPID
11773         done
11774
11775         set_nodes_failloc "$(osts_nodes)" 0
11776         rm -rf $DIR/$tdir
11777 }
11778 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11779
11780 test_118l() # LU-646
11781 {
11782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11783
11784         test_mkdir $DIR/$tdir
11785         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11786         rm -rf $DIR/$tdir
11787 }
11788 run_test 118l "fsync dir"
11789
11790 test_118m() # LU-3066
11791 {
11792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11793
11794         test_mkdir $DIR/$tdir
11795         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11796         rm -rf $DIR/$tdir
11797 }
11798 run_test 118m "fdatasync dir ========="
11799
11800 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11801
11802 test_118n()
11803 {
11804         local begin
11805         local end
11806
11807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11808         remote_ost_nodsh && skip "remote OSTs with nodsh"
11809
11810         # Sleep to avoid a cached response.
11811         #define OBD_STATFS_CACHE_SECONDS 1
11812         sleep 2
11813
11814         # Inject a 10 second delay in the OST_STATFS handler.
11815         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11816         set_nodes_failloc "$(osts_nodes)" 0x242
11817
11818         begin=$SECONDS
11819         stat --file-system $MOUNT > /dev/null
11820         end=$SECONDS
11821
11822         set_nodes_failloc "$(osts_nodes)" 0
11823
11824         if ((end - begin > 20)); then
11825             error "statfs took $((end - begin)) seconds, expected 10"
11826         fi
11827 }
11828 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11829
11830 test_119a() # bug 11737
11831 {
11832         BSIZE=$((512 * 1024))
11833         directio write $DIR/$tfile 0 1 $BSIZE
11834         # We ask to read two blocks, which is more than a file size.
11835         # directio will indicate an error when requested and actual
11836         # sizes aren't equeal (a normal situation in this case) and
11837         # print actual read amount.
11838         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11839         if [ "$NOB" != "$BSIZE" ]; then
11840                 error "read $NOB bytes instead of $BSIZE"
11841         fi
11842         rm -f $DIR/$tfile
11843 }
11844 run_test 119a "Short directIO read must return actual read amount"
11845
11846 test_119b() # bug 11737
11847 {
11848         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11849
11850         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11851         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11852         sync
11853         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11854                 error "direct read failed"
11855         rm -f $DIR/$tfile
11856 }
11857 run_test 119b "Sparse directIO read must return actual read amount"
11858
11859 test_119c() # bug 13099
11860 {
11861         BSIZE=1048576
11862         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11863         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11864         rm -f $DIR/$tfile
11865 }
11866 run_test 119c "Testing for direct read hitting hole"
11867
11868 test_119d() # bug 15950
11869 {
11870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11871
11872         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11873         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11874         BSIZE=1048576
11875         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11876         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11877         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11878         lctl set_param fail_loc=0x40d
11879         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11880         pid_dio=$!
11881         sleep 1
11882         cat $DIR/$tfile > /dev/null &
11883         lctl set_param fail_loc=0
11884         pid_reads=$!
11885         wait $pid_dio
11886         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11887         sleep 2
11888         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11889         error "the read rpcs have not completed in 2s"
11890         rm -f $DIR/$tfile
11891         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11892 }
11893 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11894
11895 test_120a() {
11896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11897         remote_mds_nodsh && skip "remote MDS with nodsh"
11898         test_mkdir -i0 -c1 $DIR/$tdir
11899         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11900                 skip_env "no early lock cancel on server"
11901
11902         lru_resize_disable mdc
11903         lru_resize_disable osc
11904         cancel_lru_locks mdc
11905         # asynchronous object destroy at MDT could cause bl ast to client
11906         cancel_lru_locks osc
11907
11908         stat $DIR/$tdir > /dev/null
11909         can1=$(do_facet mds1 \
11910                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11911                awk '/ldlm_cancel/ {print $2}')
11912         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11913                awk '/ldlm_bl_callback/ {print $2}')
11914         test_mkdir -i0 -c1 $DIR/$tdir/d1
11915         can2=$(do_facet mds1 \
11916                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11917                awk '/ldlm_cancel/ {print $2}')
11918         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11919                awk '/ldlm_bl_callback/ {print $2}')
11920         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11921         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11922         lru_resize_enable mdc
11923         lru_resize_enable osc
11924 }
11925 run_test 120a "Early Lock Cancel: mkdir test"
11926
11927 test_120b() {
11928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11929         remote_mds_nodsh && skip "remote MDS with nodsh"
11930         test_mkdir $DIR/$tdir
11931         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11932                 skip_env "no early lock cancel on server"
11933
11934         lru_resize_disable mdc
11935         lru_resize_disable osc
11936         cancel_lru_locks mdc
11937         stat $DIR/$tdir > /dev/null
11938         can1=$(do_facet $SINGLEMDS \
11939                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11940                awk '/ldlm_cancel/ {print $2}')
11941         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11942                awk '/ldlm_bl_callback/ {print $2}')
11943         touch $DIR/$tdir/f1
11944         can2=$(do_facet $SINGLEMDS \
11945                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11946                awk '/ldlm_cancel/ {print $2}')
11947         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11948                awk '/ldlm_bl_callback/ {print $2}')
11949         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11950         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11951         lru_resize_enable mdc
11952         lru_resize_enable osc
11953 }
11954 run_test 120b "Early Lock Cancel: create test"
11955
11956 test_120c() {
11957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11958         remote_mds_nodsh && skip "remote MDS with nodsh"
11959         test_mkdir -i0 -c1 $DIR/$tdir
11960         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11961                 skip "no early lock cancel on server"
11962
11963         lru_resize_disable mdc
11964         lru_resize_disable osc
11965         test_mkdir -i0 -c1 $DIR/$tdir/d1
11966         test_mkdir -i0 -c1 $DIR/$tdir/d2
11967         touch $DIR/$tdir/d1/f1
11968         cancel_lru_locks mdc
11969         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11970         can1=$(do_facet mds1 \
11971                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11972                awk '/ldlm_cancel/ {print $2}')
11973         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11974                awk '/ldlm_bl_callback/ {print $2}')
11975         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11976         can2=$(do_facet mds1 \
11977                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11978                awk '/ldlm_cancel/ {print $2}')
11979         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11980                awk '/ldlm_bl_callback/ {print $2}')
11981         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11982         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11983         lru_resize_enable mdc
11984         lru_resize_enable osc
11985 }
11986 run_test 120c "Early Lock Cancel: link test"
11987
11988 test_120d() {
11989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11990         remote_mds_nodsh && skip "remote MDS with nodsh"
11991         test_mkdir -i0 -c1 $DIR/$tdir
11992         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11993                 skip_env "no early lock cancel on server"
11994
11995         lru_resize_disable mdc
11996         lru_resize_disable osc
11997         touch $DIR/$tdir
11998         cancel_lru_locks mdc
11999         stat $DIR/$tdir > /dev/null
12000         can1=$(do_facet mds1 \
12001                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12002                awk '/ldlm_cancel/ {print $2}')
12003         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12004                awk '/ldlm_bl_callback/ {print $2}')
12005         chmod a+x $DIR/$tdir
12006         can2=$(do_facet mds1 \
12007                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12008                awk '/ldlm_cancel/ {print $2}')
12009         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12010                awk '/ldlm_bl_callback/ {print $2}')
12011         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12012         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12013         lru_resize_enable mdc
12014         lru_resize_enable osc
12015 }
12016 run_test 120d "Early Lock Cancel: setattr test"
12017
12018 test_120e() {
12019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12020         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12021                 skip_env "no early lock cancel on server"
12022         remote_mds_nodsh && skip "remote MDS with nodsh"
12023
12024         local dlmtrace_set=false
12025
12026         test_mkdir -i0 -c1 $DIR/$tdir
12027         lru_resize_disable mdc
12028         lru_resize_disable osc
12029         ! $LCTL get_param debug | grep -q dlmtrace &&
12030                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12031         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12032         cancel_lru_locks mdc
12033         cancel_lru_locks osc
12034         dd if=$DIR/$tdir/f1 of=/dev/null
12035         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12036         # XXX client can not do early lock cancel of OST lock
12037         # during unlink (LU-4206), so cancel osc lock now.
12038         sleep 2
12039         cancel_lru_locks osc
12040         can1=$(do_facet mds1 \
12041                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12042                awk '/ldlm_cancel/ {print $2}')
12043         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12044                awk '/ldlm_bl_callback/ {print $2}')
12045         unlink $DIR/$tdir/f1
12046         sleep 5
12047         can2=$(do_facet mds1 \
12048                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12049                awk '/ldlm_cancel/ {print $2}')
12050         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12051                awk '/ldlm_bl_callback/ {print $2}')
12052         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12053                 $LCTL dk $TMP/cancel.debug.txt
12054         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12055                 $LCTL dk $TMP/blocking.debug.txt
12056         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12057         lru_resize_enable mdc
12058         lru_resize_enable osc
12059 }
12060 run_test 120e "Early Lock Cancel: unlink test"
12061
12062 test_120f() {
12063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12064         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12065                 skip_env "no early lock cancel on server"
12066         remote_mds_nodsh && skip "remote MDS with nodsh"
12067
12068         test_mkdir -i0 -c1 $DIR/$tdir
12069         lru_resize_disable mdc
12070         lru_resize_disable osc
12071         test_mkdir -i0 -c1 $DIR/$tdir/d1
12072         test_mkdir -i0 -c1 $DIR/$tdir/d2
12073         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12074         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12075         cancel_lru_locks mdc
12076         cancel_lru_locks osc
12077         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12078         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12079         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12080         # XXX client can not do early lock cancel of OST lock
12081         # during rename (LU-4206), so cancel osc lock now.
12082         sleep 2
12083         cancel_lru_locks osc
12084         can1=$(do_facet mds1 \
12085                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12086                awk '/ldlm_cancel/ {print $2}')
12087         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12088                awk '/ldlm_bl_callback/ {print $2}')
12089         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12090         sleep 5
12091         can2=$(do_facet mds1 \
12092                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12093                awk '/ldlm_cancel/ {print $2}')
12094         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12095                awk '/ldlm_bl_callback/ {print $2}')
12096         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12097         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12098         lru_resize_enable mdc
12099         lru_resize_enable osc
12100 }
12101 run_test 120f "Early Lock Cancel: rename test"
12102
12103 test_120g() {
12104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12105         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12106                 skip_env "no early lock cancel on server"
12107         remote_mds_nodsh && skip "remote MDS with nodsh"
12108
12109         lru_resize_disable mdc
12110         lru_resize_disable osc
12111         count=10000
12112         echo create $count files
12113         test_mkdir $DIR/$tdir
12114         cancel_lru_locks mdc
12115         cancel_lru_locks osc
12116         t0=$(date +%s)
12117
12118         can0=$(do_facet $SINGLEMDS \
12119                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12120                awk '/ldlm_cancel/ {print $2}')
12121         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12122                awk '/ldlm_bl_callback/ {print $2}')
12123         createmany -o $DIR/$tdir/f $count
12124         sync
12125         can1=$(do_facet $SINGLEMDS \
12126                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12127                awk '/ldlm_cancel/ {print $2}')
12128         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12129                awk '/ldlm_bl_callback/ {print $2}')
12130         t1=$(date +%s)
12131         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12132         echo rm $count files
12133         rm -r $DIR/$tdir
12134         sync
12135         can2=$(do_facet $SINGLEMDS \
12136                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12137                awk '/ldlm_cancel/ {print $2}')
12138         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12139                awk '/ldlm_bl_callback/ {print $2}')
12140         t2=$(date +%s)
12141         echo total: $count removes in $((t2-t1))
12142         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12143         sleep 2
12144         # wait for commitment of removal
12145         lru_resize_enable mdc
12146         lru_resize_enable osc
12147 }
12148 run_test 120g "Early Lock Cancel: performance test"
12149
12150 test_121() { #bug #10589
12151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12152
12153         rm -rf $DIR/$tfile
12154         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12155 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12156         lctl set_param fail_loc=0x310
12157         cancel_lru_locks osc > /dev/null
12158         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12159         lctl set_param fail_loc=0
12160         [[ $reads -eq $writes ]] ||
12161                 error "read $reads blocks, must be $writes blocks"
12162 }
12163 run_test 121 "read cancel race ========="
12164
12165 test_123a_base() { # was test 123, statahead(bug 11401)
12166         local lsx="$1"
12167
12168         SLOWOK=0
12169         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12170                 log "testing UP system. Performance may be lower than expected."
12171                 SLOWOK=1
12172         fi
12173
12174         rm -rf $DIR/$tdir
12175         test_mkdir $DIR/$tdir
12176         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12177         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12178         MULT=10
12179         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12180                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12181
12182                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12183                 lctl set_param -n llite.*.statahead_max 0
12184                 lctl get_param llite.*.statahead_max
12185                 cancel_lru_locks mdc
12186                 cancel_lru_locks osc
12187                 stime=$(date +%s)
12188                 time $lsx $DIR/$tdir | wc -l
12189                 etime=$(date +%s)
12190                 delta=$((etime - stime))
12191                 log "$lsx $i files without statahead: $delta sec"
12192                 lctl set_param llite.*.statahead_max=$max
12193
12194                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12195                         grep "statahead wrong:" | awk '{print $3}')
12196                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12197                 cancel_lru_locks mdc
12198                 cancel_lru_locks osc
12199                 stime=$(date +%s)
12200                 time $lsx $DIR/$tdir | wc -l
12201                 etime=$(date +%s)
12202                 delta_sa=$((etime - stime))
12203                 log "$lsx $i files with statahead: $delta_sa sec"
12204                 lctl get_param -n llite.*.statahead_stats
12205                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12206                         grep "statahead wrong:" | awk '{print $3}')
12207
12208                 [[ $swrong -lt $ewrong ]] &&
12209                         log "statahead was stopped, maybe too many locks held!"
12210                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12211
12212                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12213                         max=$(lctl get_param -n llite.*.statahead_max |
12214                                 head -n 1)
12215                         lctl set_param -n llite.*.statahead_max 0
12216                         lctl get_param llite.*.statahead_max
12217                         cancel_lru_locks mdc
12218                         cancel_lru_locks osc
12219                         stime=$(date +%s)
12220                         time $lsx $DIR/$tdir | wc -l
12221                         etime=$(date +%s)
12222                         delta=$((etime - stime))
12223                         log "$lsx $i files again without statahead: $delta sec"
12224                         lctl set_param llite.*.statahead_max=$max
12225                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12226                                 if [  $SLOWOK -eq 0 ]; then
12227                                         error "$lsx $i files is slower with statahead!"
12228                                 else
12229                                         log "$lsx $i files is slower with statahead!"
12230                                 fi
12231                                 break
12232                         fi
12233                 fi
12234
12235                 [ $delta -gt 20 ] && break
12236                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12237                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12238         done
12239         log "$lsx done"
12240
12241         stime=$(date +%s)
12242         rm -r $DIR/$tdir
12243         sync
12244         etime=$(date +%s)
12245         delta=$((etime - stime))
12246         log "rm -r $DIR/$tdir/: $delta seconds"
12247         log "rm done"
12248         lctl get_param -n llite.*.statahead_stats
12249 }
12250
12251 test_123aa() {
12252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12253
12254         test_123a_base "ls -l"
12255 }
12256 run_test 123aa "verify statahead work"
12257
12258 test_123ab() {
12259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12260
12261         statx_supported || skip_env "Test must be statx() syscall supported"
12262
12263         test_123a_base "$STATX -l"
12264 }
12265 run_test 123ab "verify statahead work by using statx"
12266
12267 test_123ac() {
12268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12269
12270         statx_supported || skip_env "Test must be statx() syscall supported"
12271
12272         local rpcs_before
12273         local rpcs_after
12274         local agl_before
12275         local agl_after
12276
12277         cancel_lru_locks $OSC
12278         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12279         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12280                 awk '/agl.total:/ {print $3}')
12281         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12282         test_123a_base "$STATX --cached=always -D"
12283         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12284                 awk '/agl.total:/ {print $3}')
12285         [ $agl_before -eq $agl_after ] ||
12286                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12287         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12288         [ $rpcs_after -eq $rpcs_before ] ||
12289                 error "$STATX should not send glimpse RPCs to $OSC"
12290 }
12291 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12292
12293 test_123b () { # statahead(bug 15027)
12294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12295
12296         test_mkdir $DIR/$tdir
12297         createmany -o $DIR/$tdir/$tfile-%d 1000
12298
12299         cancel_lru_locks mdc
12300         cancel_lru_locks osc
12301
12302 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12303         lctl set_param fail_loc=0x80000803
12304         ls -lR $DIR/$tdir > /dev/null
12305         log "ls done"
12306         lctl set_param fail_loc=0x0
12307         lctl get_param -n llite.*.statahead_stats
12308         rm -r $DIR/$tdir
12309         sync
12310
12311 }
12312 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12313
12314 test_123c() {
12315         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12316
12317         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12318         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12319         touch $DIR/$tdir.1/{1..3}
12320         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12321
12322         remount_client $MOUNT
12323
12324         $MULTIOP $DIR/$tdir.0 Q
12325
12326         # let statahead to complete
12327         ls -l $DIR/$tdir.0 > /dev/null
12328
12329         testid=$(echo $TESTNAME | tr '_' ' ')
12330         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12331                 error "statahead warning" || true
12332 }
12333 run_test 123c "Can not initialize inode warning on DNE statahead"
12334
12335 test_124a() {
12336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12337         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12338                 skip_env "no lru resize on server"
12339
12340         local NR=2000
12341
12342         test_mkdir $DIR/$tdir
12343
12344         log "create $NR files at $DIR/$tdir"
12345         createmany -o $DIR/$tdir/f $NR ||
12346                 error "failed to create $NR files in $DIR/$tdir"
12347
12348         cancel_lru_locks mdc
12349         ls -l $DIR/$tdir > /dev/null
12350
12351         local NSDIR=""
12352         local LRU_SIZE=0
12353         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12354                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12355                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12356                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12357                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12358                         log "NSDIR=$NSDIR"
12359                         log "NS=$(basename $NSDIR)"
12360                         break
12361                 fi
12362         done
12363
12364         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12365                 skip "Not enough cached locks created!"
12366         fi
12367         log "LRU=$LRU_SIZE"
12368
12369         local SLEEP=30
12370
12371         # We know that lru resize allows one client to hold $LIMIT locks
12372         # for 10h. After that locks begin to be killed by client.
12373         local MAX_HRS=10
12374         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12375         log "LIMIT=$LIMIT"
12376         if [ $LIMIT -lt $LRU_SIZE ]; then
12377                 skip "Limit is too small $LIMIT"
12378         fi
12379
12380         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12381         # killing locks. Some time was spent for creating locks. This means
12382         # that up to the moment of sleep finish we must have killed some of
12383         # them (10-100 locks). This depends on how fast ther were created.
12384         # Many of them were touched in almost the same moment and thus will
12385         # be killed in groups.
12386         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12387
12388         # Use $LRU_SIZE_B here to take into account real number of locks
12389         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12390         local LRU_SIZE_B=$LRU_SIZE
12391         log "LVF=$LVF"
12392         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12393         log "OLD_LVF=$OLD_LVF"
12394         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12395
12396         # Let's make sure that we really have some margin. Client checks
12397         # cached locks every 10 sec.
12398         SLEEP=$((SLEEP+20))
12399         log "Sleep ${SLEEP} sec"
12400         local SEC=0
12401         while ((SEC<$SLEEP)); do
12402                 echo -n "..."
12403                 sleep 5
12404                 SEC=$((SEC+5))
12405                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12406                 echo -n "$LRU_SIZE"
12407         done
12408         echo ""
12409         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12410         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12411
12412         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12413                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12414                 unlinkmany $DIR/$tdir/f $NR
12415                 return
12416         }
12417
12418         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12419         log "unlink $NR files at $DIR/$tdir"
12420         unlinkmany $DIR/$tdir/f $NR
12421 }
12422 run_test 124a "lru resize ======================================="
12423
12424 get_max_pool_limit()
12425 {
12426         local limit=$($LCTL get_param \
12427                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12428         local max=0
12429         for l in $limit; do
12430                 if [[ $l -gt $max ]]; then
12431                         max=$l
12432                 fi
12433         done
12434         echo $max
12435 }
12436
12437 test_124b() {
12438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12439         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12440                 skip_env "no lru resize on server"
12441
12442         LIMIT=$(get_max_pool_limit)
12443
12444         NR=$(($(default_lru_size)*20))
12445         if [[ $NR -gt $LIMIT ]]; then
12446                 log "Limit lock number by $LIMIT locks"
12447                 NR=$LIMIT
12448         fi
12449
12450         IFree=$(mdsrate_inodes_available)
12451         if [ $IFree -lt $NR ]; then
12452                 log "Limit lock number by $IFree inodes"
12453                 NR=$IFree
12454         fi
12455
12456         lru_resize_disable mdc
12457         test_mkdir -p $DIR/$tdir/disable_lru_resize
12458
12459         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12460         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12461         cancel_lru_locks mdc
12462         stime=`date +%s`
12463         PID=""
12464         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12465         PID="$PID $!"
12466         sleep 2
12467         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12468         PID="$PID $!"
12469         sleep 2
12470         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12471         PID="$PID $!"
12472         wait $PID
12473         etime=`date +%s`
12474         nolruresize_delta=$((etime-stime))
12475         log "ls -la time: $nolruresize_delta seconds"
12476         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12477         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12478
12479         lru_resize_enable mdc
12480         test_mkdir -p $DIR/$tdir/enable_lru_resize
12481
12482         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12483         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12484         cancel_lru_locks mdc
12485         stime=`date +%s`
12486         PID=""
12487         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12488         PID="$PID $!"
12489         sleep 2
12490         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12491         PID="$PID $!"
12492         sleep 2
12493         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12494         PID="$PID $!"
12495         wait $PID
12496         etime=`date +%s`
12497         lruresize_delta=$((etime-stime))
12498         log "ls -la time: $lruresize_delta seconds"
12499         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12500
12501         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12502                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12503         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12504                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12505         else
12506                 log "lru resize performs the same with no lru resize"
12507         fi
12508         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12509 }
12510 run_test 124b "lru resize (performance test) ======================="
12511
12512 test_124c() {
12513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12514         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12515                 skip_env "no lru resize on server"
12516
12517         # cache ununsed locks on client
12518         local nr=100
12519         cancel_lru_locks mdc
12520         test_mkdir $DIR/$tdir
12521         createmany -o $DIR/$tdir/f $nr ||
12522                 error "failed to create $nr files in $DIR/$tdir"
12523         ls -l $DIR/$tdir > /dev/null
12524
12525         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12526         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12527         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12528         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12529         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12530
12531         # set lru_max_age to 1 sec
12532         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12533         echo "sleep $((recalc_p * 2)) seconds..."
12534         sleep $((recalc_p * 2))
12535
12536         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12537         # restore lru_max_age
12538         $LCTL set_param -n $nsdir.lru_max_age $max_age
12539         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12540         unlinkmany $DIR/$tdir/f $nr
12541 }
12542 run_test 124c "LRUR cancel very aged locks"
12543
12544 test_124d() {
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12547                 skip_env "no lru resize on server"
12548
12549         # cache ununsed locks on client
12550         local nr=100
12551
12552         lru_resize_disable mdc
12553         stack_trap "lru_resize_enable mdc" EXIT
12554
12555         cancel_lru_locks mdc
12556
12557         # asynchronous object destroy at MDT could cause bl ast to client
12558         test_mkdir $DIR/$tdir
12559         createmany -o $DIR/$tdir/f $nr ||
12560                 error "failed to create $nr files in $DIR/$tdir"
12561         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12562
12563         ls -l $DIR/$tdir > /dev/null
12564
12565         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12566         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12567         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12568         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12569
12570         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12571
12572         # set lru_max_age to 1 sec
12573         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12574         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12575
12576         echo "sleep $((recalc_p * 2)) seconds..."
12577         sleep $((recalc_p * 2))
12578
12579         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12580
12581         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12582 }
12583 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12584
12585 test_125() { # 13358
12586         $LCTL get_param -n llite.*.client_type | grep -q local ||
12587                 skip "must run as local client"
12588         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12589                 skip_env "must have acl enabled"
12590         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12591
12592         test_mkdir $DIR/$tdir
12593         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12594         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12595         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12596 }
12597 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12598
12599 test_126() { # bug 12829/13455
12600         $GSS && skip_env "must run as gss disabled"
12601         $LCTL get_param -n llite.*.client_type | grep -q local ||
12602                 skip "must run as local client"
12603         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12604
12605         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12606         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12607         rm -f $DIR/$tfile
12608         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12609 }
12610 run_test 126 "check that the fsgid provided by the client is taken into account"
12611
12612 test_127a() { # bug 15521
12613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12614         local name count samp unit min max sum sumsq
12615
12616         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12617         echo "stats before reset"
12618         $LCTL get_param osc.*.stats
12619         $LCTL set_param osc.*.stats=0
12620         local fsize=$((2048 * 1024))
12621
12622         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12623         cancel_lru_locks osc
12624         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12625
12626         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12627         stack_trap "rm -f $TMP/$tfile.tmp"
12628         while read name count samp unit min max sum sumsq; do
12629                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12630                 [ ! $min ] && error "Missing min value for $name proc entry"
12631                 eval $name=$count || error "Wrong proc format"
12632
12633                 case $name in
12634                 read_bytes|write_bytes)
12635                         [[ "$unit" =~ "bytes" ]] ||
12636                                 error "unit is not 'bytes': $unit"
12637                         (( $min >= 4096 )) || error "min is too small: $min"
12638                         (( $min <= $fsize )) || error "min is too big: $min"
12639                         (( $max >= 4096 )) || error "max is too small: $max"
12640                         (( $max <= $fsize )) || error "max is too big: $max"
12641                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12642                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12643                                 error "sumsquare is too small: $sumsq"
12644                         (( $sumsq <= $fsize * $fsize )) ||
12645                                 error "sumsquare is too big: $sumsq"
12646                         ;;
12647                 ost_read|ost_write)
12648                         [[ "$unit" =~ "usec" ]] ||
12649                                 error "unit is not 'usec': $unit"
12650                         ;;
12651                 *)      ;;
12652                 esac
12653         done < $DIR/$tfile.tmp
12654
12655         #check that we actually got some stats
12656         [ "$read_bytes" ] || error "Missing read_bytes stats"
12657         [ "$write_bytes" ] || error "Missing write_bytes stats"
12658         [ "$read_bytes" != 0 ] || error "no read done"
12659         [ "$write_bytes" != 0 ] || error "no write done"
12660 }
12661 run_test 127a "verify the client stats are sane"
12662
12663 test_127b() { # bug LU-333
12664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12665         local name count samp unit min max sum sumsq
12666
12667         echo "stats before reset"
12668         $LCTL get_param llite.*.stats
12669         $LCTL set_param llite.*.stats=0
12670
12671         # perform 2 reads and writes so MAX is different from SUM.
12672         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12673         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12674         cancel_lru_locks osc
12675         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12676         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12677
12678         $LCTL get_param llite.*.stats | grep samples > $TMP/$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                 eval $name=$count || error "Wrong proc format"
12683
12684                 case $name in
12685                 read_bytes|write_bytes)
12686                         [[ "$unit" =~ "bytes" ]] ||
12687                                 error "unit is not 'bytes': $unit"
12688                         (( $count == 2 )) || error "count is not 2: $count"
12689                         (( $min == $PAGE_SIZE )) ||
12690                                 error "min is not $PAGE_SIZE: $min"
12691                         (( $max == $PAGE_SIZE )) ||
12692                                 error "max is not $PAGE_SIZE: $max"
12693                         (( $sum == $PAGE_SIZE * 2 )) ||
12694                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12695                         ;;
12696                 read|write)
12697                         [[ "$unit" =~ "usec" ]] ||
12698                                 error "unit is not 'usec': $unit"
12699                         ;;
12700                 *)      ;;
12701                 esac
12702         done < $TMP/$tfile.tmp
12703
12704         #check that we actually got some stats
12705         [ "$read_bytes" ] || error "Missing read_bytes stats"
12706         [ "$write_bytes" ] || error "Missing write_bytes stats"
12707         [ "$read_bytes" != 0 ] || error "no read done"
12708         [ "$write_bytes" != 0 ] || error "no write done"
12709 }
12710 run_test 127b "verify the llite client stats are sane"
12711
12712 test_127c() { # LU-12394
12713         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12714         local size
12715         local bsize
12716         local reads
12717         local writes
12718         local count
12719
12720         $LCTL set_param llite.*.extents_stats=1
12721         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12722
12723         # Use two stripes so there is enough space in default config
12724         $LFS setstripe -c 2 $DIR/$tfile
12725
12726         # Extent stats start at 0-4K and go in power of two buckets
12727         # LL_HIST_START = 12 --> 2^12 = 4K
12728         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12729         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12730         # small configs
12731         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12732                 do
12733                 # Write and read, 2x each, second time at a non-zero offset
12734                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12735                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12736                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12737                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12738                 rm -f $DIR/$tfile
12739         done
12740
12741         $LCTL get_param llite.*.extents_stats
12742
12743         count=2
12744         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12745                 do
12746                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12747                                 grep -m 1 $bsize)
12748                 reads=$(echo $bucket | awk '{print $5}')
12749                 writes=$(echo $bucket | awk '{print $9}')
12750                 [ "$reads" -eq $count ] ||
12751                         error "$reads reads in < $bsize bucket, expect $count"
12752                 [ "$writes" -eq $count ] ||
12753                         error "$writes writes in < $bsize bucket, expect $count"
12754         done
12755
12756         # Test mmap write and read
12757         $LCTL set_param llite.*.extents_stats=c
12758         size=512
12759         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12760         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12761         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12762
12763         $LCTL get_param llite.*.extents_stats
12764
12765         count=$(((size*1024) / PAGE_SIZE))
12766
12767         bsize=$((2 * PAGE_SIZE / 1024))K
12768
12769         bucket=$($LCTL get_param -n llite.*.extents_stats |
12770                         grep -m 1 $bsize)
12771         reads=$(echo $bucket | awk '{print $5}')
12772         writes=$(echo $bucket | awk '{print $9}')
12773         # mmap writes fault in the page first, creating an additonal read
12774         [ "$reads" -eq $((2 * count)) ] ||
12775                 error "$reads reads in < $bsize bucket, expect $count"
12776         [ "$writes" -eq $count ] ||
12777                 error "$writes writes in < $bsize bucket, expect $count"
12778 }
12779 run_test 127c "test llite extent stats with regular & mmap i/o"
12780
12781 test_128() { # bug 15212
12782         touch $DIR/$tfile
12783         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12784                 find $DIR/$tfile
12785                 find $DIR/$tfile
12786         EOF
12787
12788         result=$(grep error $TMP/$tfile.log)
12789         rm -f $DIR/$tfile $TMP/$tfile.log
12790         [ -z "$result" ] ||
12791                 error "consecutive find's under interactive lfs failed"
12792 }
12793 run_test 128 "interactive lfs for 2 consecutive find's"
12794
12795 set_dir_limits () {
12796         local mntdev
12797         local canondev
12798         local node
12799
12800         local ldproc=/proc/fs/ldiskfs
12801         local facets=$(get_facets MDS)
12802
12803         for facet in ${facets//,/ }; do
12804                 canondev=$(ldiskfs_canon \
12805                            *.$(convert_facet2label $facet).mntdev $facet)
12806                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12807                         ldproc=/sys/fs/ldiskfs
12808                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12809                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12810         done
12811 }
12812
12813 check_mds_dmesg() {
12814         local facets=$(get_facets MDS)
12815         for facet in ${facets//,/ }; do
12816                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12817         done
12818         return 1
12819 }
12820
12821 test_129() {
12822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12823         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12824                 skip "Need MDS version with at least 2.5.56"
12825         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12826                 skip_env "ldiskfs only test"
12827         fi
12828         remote_mds_nodsh && skip "remote MDS with nodsh"
12829
12830         local ENOSPC=28
12831         local has_warning=false
12832
12833         rm -rf $DIR/$tdir
12834         mkdir -p $DIR/$tdir
12835
12836         # block size of mds1
12837         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12838         set_dir_limits $maxsize $((maxsize * 6 / 8))
12839         stack_trap "set_dir_limits 0 0"
12840         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12841         local dirsize=$(stat -c%s "$DIR/$tdir")
12842         local nfiles=0
12843         while (( $dirsize <= $maxsize )); do
12844                 $MCREATE $DIR/$tdir/file_base_$nfiles
12845                 rc=$?
12846                 # check two errors:
12847                 # ENOSPC for ext4 max_dir_size, which has been used since
12848                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12849                 if (( rc == ENOSPC )); then
12850                         set_dir_limits 0 0
12851                         echo "rc=$rc returned as expected after $nfiles files"
12852
12853                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12854                                 error "create failed w/o dir size limit"
12855
12856                         # messages may be rate limited if test is run repeatedly
12857                         check_mds_dmesg '"is approaching max"' ||
12858                                 echo "warning message should be output"
12859                         check_mds_dmesg '"has reached max"' ||
12860                                 echo "reached message should be output"
12861
12862                         dirsize=$(stat -c%s "$DIR/$tdir")
12863
12864                         [[ $dirsize -ge $maxsize ]] && return 0
12865                         error "dirsize $dirsize < $maxsize after $nfiles files"
12866                 elif (( rc != 0 )); then
12867                         break
12868                 fi
12869                 nfiles=$((nfiles + 1))
12870                 dirsize=$(stat -c%s "$DIR/$tdir")
12871         done
12872
12873         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12874 }
12875 run_test 129 "test directory size limit ========================"
12876
12877 OLDIFS="$IFS"
12878 cleanup_130() {
12879         trap 0
12880         IFS="$OLDIFS"
12881 }
12882
12883 test_130a() {
12884         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12885         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12886
12887         trap cleanup_130 EXIT RETURN
12888
12889         local fm_file=$DIR/$tfile
12890         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12891         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12892                 error "dd failed for $fm_file"
12893
12894         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12895         filefrag -ves $fm_file
12896         RC=$?
12897         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12898                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12899         [ $RC != 0 ] && error "filefrag $fm_file failed"
12900
12901         filefrag_op=$(filefrag -ve -k $fm_file |
12902                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12903         lun=$($LFS getstripe -i $fm_file)
12904
12905         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12906         IFS=$'\n'
12907         tot_len=0
12908         for line in $filefrag_op
12909         do
12910                 frag_lun=`echo $line | cut -d: -f5`
12911                 ext_len=`echo $line | cut -d: -f4`
12912                 if (( $frag_lun != $lun )); then
12913                         cleanup_130
12914                         error "FIEMAP on 1-stripe file($fm_file) failed"
12915                         return
12916                 fi
12917                 (( tot_len += ext_len ))
12918         done
12919
12920         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12921                 cleanup_130
12922                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12923                 return
12924         fi
12925
12926         cleanup_130
12927
12928         echo "FIEMAP on single striped file succeeded"
12929 }
12930 run_test 130a "FIEMAP (1-stripe file)"
12931
12932 test_130b() {
12933         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12934
12935         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12936         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12937
12938         trap cleanup_130 EXIT RETURN
12939
12940         local fm_file=$DIR/$tfile
12941         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12942                         error "setstripe on $fm_file"
12943         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12944                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12945
12946         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12947                 error "dd failed on $fm_file"
12948
12949         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12950         filefrag_op=$(filefrag -ve -k $fm_file |
12951                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12952
12953         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12954                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12955
12956         IFS=$'\n'
12957         tot_len=0
12958         num_luns=1
12959         for line in $filefrag_op
12960         do
12961                 frag_lun=$(echo $line | cut -d: -f5 |
12962                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12963                 ext_len=$(echo $line | cut -d: -f4)
12964                 if (( $frag_lun != $last_lun )); then
12965                         if (( tot_len != 1024 )); then
12966                                 cleanup_130
12967                                 error "FIEMAP on $fm_file failed; returned " \
12968                                 "len $tot_len for OST $last_lun instead of 1024"
12969                                 return
12970                         else
12971                                 (( num_luns += 1 ))
12972                                 tot_len=0
12973                         fi
12974                 fi
12975                 (( tot_len += ext_len ))
12976                 last_lun=$frag_lun
12977         done
12978         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12979                 cleanup_130
12980                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12981                         "luns or wrong len for OST $last_lun"
12982                 return
12983         fi
12984
12985         cleanup_130
12986
12987         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12988 }
12989 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12990
12991 test_130c() {
12992         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12993
12994         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12995         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12996
12997         trap cleanup_130 EXIT RETURN
12998
12999         local fm_file=$DIR/$tfile
13000         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13001         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13002                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13003
13004         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13005                         error "dd failed on $fm_file"
13006
13007         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13008         filefrag_op=$(filefrag -ve -k $fm_file |
13009                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13010
13011         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13012                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13013
13014         IFS=$'\n'
13015         tot_len=0
13016         num_luns=1
13017         for line in $filefrag_op
13018         do
13019                 frag_lun=$(echo $line | cut -d: -f5 |
13020                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13021                 ext_len=$(echo $line | cut -d: -f4)
13022                 if (( $frag_lun != $last_lun )); then
13023                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13024                         if (( logical != 512 )); then
13025                                 cleanup_130
13026                                 error "FIEMAP on $fm_file failed; returned " \
13027                                 "logical start for lun $logical instead of 512"
13028                                 return
13029                         fi
13030                         if (( tot_len != 512 )); then
13031                                 cleanup_130
13032                                 error "FIEMAP on $fm_file failed; returned " \
13033                                 "len $tot_len for OST $last_lun instead of 1024"
13034                                 return
13035                         else
13036                                 (( num_luns += 1 ))
13037                                 tot_len=0
13038                         fi
13039                 fi
13040                 (( tot_len += ext_len ))
13041                 last_lun=$frag_lun
13042         done
13043         if (( num_luns != 2 || tot_len != 512 )); then
13044                 cleanup_130
13045                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13046                         "luns or wrong len for OST $last_lun"
13047                 return
13048         fi
13049
13050         cleanup_130
13051
13052         echo "FIEMAP on 2-stripe file with hole succeeded"
13053 }
13054 run_test 130c "FIEMAP (2-stripe file with hole)"
13055
13056 test_130d() {
13057         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13058
13059         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13060         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13061
13062         trap cleanup_130 EXIT RETURN
13063
13064         local fm_file=$DIR/$tfile
13065         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13066                         error "setstripe on $fm_file"
13067         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13068                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13069
13070         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13071         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13072                 error "dd failed on $fm_file"
13073
13074         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13075         filefrag_op=$(filefrag -ve -k $fm_file |
13076                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13077
13078         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13079                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13080
13081         IFS=$'\n'
13082         tot_len=0
13083         num_luns=1
13084         for line in $filefrag_op
13085         do
13086                 frag_lun=$(echo $line | cut -d: -f5 |
13087                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13088                 ext_len=$(echo $line | cut -d: -f4)
13089                 if (( $frag_lun != $last_lun )); then
13090                         if (( tot_len != 1024 )); then
13091                                 cleanup_130
13092                                 error "FIEMAP on $fm_file failed; returned " \
13093                                 "len $tot_len for OST $last_lun instead of 1024"
13094                                 return
13095                         else
13096                                 (( num_luns += 1 ))
13097                                 tot_len=0
13098                         fi
13099                 fi
13100                 (( tot_len += ext_len ))
13101                 last_lun=$frag_lun
13102         done
13103         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13104                 cleanup_130
13105                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13106                         "luns or wrong len for OST $last_lun"
13107                 return
13108         fi
13109
13110         cleanup_130
13111
13112         echo "FIEMAP on N-stripe file succeeded"
13113 }
13114 run_test 130d "FIEMAP (N-stripe file)"
13115
13116 test_130e() {
13117         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13118
13119         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13120         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13121
13122         trap cleanup_130 EXIT RETURN
13123
13124         local fm_file=$DIR/$tfile
13125         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13126
13127         NUM_BLKS=512
13128         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13129         for ((i = 0; i < $NUM_BLKS; i++)); do
13130                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13131                         conv=notrunc > /dev/null 2>&1
13132         done
13133
13134         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13135         filefrag_op=$(filefrag -ve -k $fm_file |
13136                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13137
13138         last_lun=$(echo $filefrag_op | cut -d: -f5)
13139
13140         IFS=$'\n'
13141         tot_len=0
13142         num_luns=1
13143         for line in $filefrag_op; do
13144                 frag_lun=$(echo $line | cut -d: -f5)
13145                 ext_len=$(echo $line | cut -d: -f4)
13146                 if [[ "$frag_lun" != "$last_lun" ]]; then
13147                         if (( tot_len != $EXPECTED_LEN )); then
13148                                 cleanup_130
13149                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13150                         else
13151                                 (( num_luns += 1 ))
13152                                 tot_len=0
13153                         fi
13154                 fi
13155                 (( tot_len += ext_len ))
13156                 last_lun=$frag_lun
13157         done
13158         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13159                 cleanup_130
13160                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13161         fi
13162
13163         echo "FIEMAP with continuation calls succeeded"
13164 }
13165 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13166
13167 test_130f() {
13168         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13169         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13170
13171         local fm_file=$DIR/$tfile
13172         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13173                 error "multiop create with lov_delay_create on $fm_file"
13174
13175         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13176         filefrag_extents=$(filefrag -vek $fm_file |
13177                            awk '/extents? found/ { print $2 }')
13178         if [[ "$filefrag_extents" != "0" ]]; then
13179                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13180         fi
13181
13182         rm -f $fm_file
13183 }
13184 run_test 130f "FIEMAP (unstriped file)"
13185
13186 test_130g() {
13187         local file=$DIR/$tfile
13188         local nr=$((OSTCOUNT * 100))
13189
13190         $LFS setstripe -C $nr $file ||
13191                 error "failed to setstripe -C $nr $file"
13192
13193         dd if=/dev/zero of=$file count=$nr bs=1M
13194         sync
13195         nr=$($LFS getstripe -c $file)
13196
13197         local extents=$(filefrag -v $file |
13198                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13199
13200         echo "filefrag list $extents extents in file with stripecount $nr"
13201         if (( extents < nr )); then
13202                 $LFS getstripe $file
13203                 filefrag -v $file
13204                 error "filefrag printed $extents < $nr extents"
13205         fi
13206
13207         rm -f $file
13208 }
13209 run_test 130g "FIEMAP (overstripe file)"
13210
13211 # Test for writev/readv
13212 test_131a() {
13213         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13214                 error "writev test failed"
13215         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13216                 error "readv failed"
13217         rm -f $DIR/$tfile
13218 }
13219 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13220
13221 test_131b() {
13222         local fsize=$((524288 + 1048576 + 1572864))
13223         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13224                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13225                         error "append writev test failed"
13226
13227         ((fsize += 1572864 + 1048576))
13228         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13229                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13230                         error "append writev test failed"
13231         rm -f $DIR/$tfile
13232 }
13233 run_test 131b "test append writev"
13234
13235 test_131c() {
13236         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13237         error "NOT PASS"
13238 }
13239 run_test 131c "test read/write on file w/o objects"
13240
13241 test_131d() {
13242         rwv -f $DIR/$tfile -w -n 1 1572864
13243         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13244         if [ "$NOB" != 1572864 ]; then
13245                 error "Short read filed: read $NOB bytes instead of 1572864"
13246         fi
13247         rm -f $DIR/$tfile
13248 }
13249 run_test 131d "test short read"
13250
13251 test_131e() {
13252         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13253         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13254         error "read hitting hole failed"
13255         rm -f $DIR/$tfile
13256 }
13257 run_test 131e "test read hitting hole"
13258
13259 check_stats() {
13260         local facet=$1
13261         local op=$2
13262         local want=${3:-0}
13263         local res
13264
13265         case $facet in
13266         mds*) res=$(do_facet $facet \
13267                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13268                  ;;
13269         ost*) res=$(do_facet $facet \
13270                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13271                  ;;
13272         *) error "Wrong facet '$facet'" ;;
13273         esac
13274         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13275         # if the argument $3 is zero, it means any stat increment is ok.
13276         if [[ $want -gt 0 ]]; then
13277                 local count=$(echo $res | awk '{ print $2 }')
13278                 [[ $count -ne $want ]] &&
13279                         error "The $op counter on $facet is $count, not $want"
13280         fi
13281 }
13282
13283 test_133a() {
13284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13285         remote_ost_nodsh && skip "remote OST with nodsh"
13286         remote_mds_nodsh && skip "remote MDS with nodsh"
13287         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13288                 skip_env "MDS doesn't support rename stats"
13289
13290         local testdir=$DIR/${tdir}/stats_testdir
13291
13292         mkdir -p $DIR/${tdir}
13293
13294         # clear stats.
13295         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13296         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13297
13298         # verify mdt stats first.
13299         mkdir ${testdir} || error "mkdir failed"
13300         check_stats $SINGLEMDS "mkdir" 1
13301         touch ${testdir}/${tfile} || error "touch failed"
13302         check_stats $SINGLEMDS "open" 1
13303         check_stats $SINGLEMDS "close" 1
13304         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13305                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13306                 check_stats $SINGLEMDS "mknod" 2
13307         }
13308         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13309         check_stats $SINGLEMDS "unlink" 1
13310         rm -f ${testdir}/${tfile} || error "file remove failed"
13311         check_stats $SINGLEMDS "unlink" 2
13312
13313         # remove working dir and check mdt stats again.
13314         rmdir ${testdir} || error "rmdir failed"
13315         check_stats $SINGLEMDS "rmdir" 1
13316
13317         local testdir1=$DIR/${tdir}/stats_testdir1
13318         mkdir -p ${testdir}
13319         mkdir -p ${testdir1}
13320         touch ${testdir1}/test1
13321         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13322         check_stats $SINGLEMDS "crossdir_rename" 1
13323
13324         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13325         check_stats $SINGLEMDS "samedir_rename" 1
13326
13327         rm -rf $DIR/${tdir}
13328 }
13329 run_test 133a "Verifying MDT stats ========================================"
13330
13331 test_133b() {
13332         local res
13333
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335         remote_ost_nodsh && skip "remote OST with nodsh"
13336         remote_mds_nodsh && skip "remote MDS with nodsh"
13337
13338         local testdir=$DIR/${tdir}/stats_testdir
13339
13340         mkdir -p ${testdir} || error "mkdir failed"
13341         touch ${testdir}/${tfile} || error "touch failed"
13342         cancel_lru_locks mdc
13343
13344         # clear stats.
13345         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13346         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13347
13348         # extra mdt stats verification.
13349         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13350         check_stats $SINGLEMDS "setattr" 1
13351         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13352         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13353         then            # LU-1740
13354                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13355                 check_stats $SINGLEMDS "getattr" 1
13356         fi
13357         rm -rf $DIR/${tdir}
13358
13359         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13360         # so the check below is not reliable
13361         [ $MDSCOUNT -eq 1 ] || return 0
13362
13363         # Sleep to avoid a cached response.
13364         #define OBD_STATFS_CACHE_SECONDS 1
13365         sleep 2
13366         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13367         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13368         $LFS df || error "lfs failed"
13369         check_stats $SINGLEMDS "statfs" 1
13370
13371         # check aggregated statfs (LU-10018)
13372         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13373                 return 0
13374         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13375                 return 0
13376         sleep 2
13377         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13378         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13379         df $DIR
13380         check_stats $SINGLEMDS "statfs" 1
13381
13382         # We want to check that the client didn't send OST_STATFS to
13383         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13384         # extra care is needed here.
13385         if remote_mds; then
13386                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13387                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13388
13389                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13390                 [ "$res" ] && error "OST got STATFS"
13391         fi
13392
13393         return 0
13394 }
13395 run_test 133b "Verifying extra MDT stats =================================="
13396
13397 test_133c() {
13398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13399         remote_ost_nodsh && skip "remote OST with nodsh"
13400         remote_mds_nodsh && skip "remote MDS with nodsh"
13401
13402         local testdir=$DIR/$tdir/stats_testdir
13403
13404         test_mkdir -p $testdir
13405
13406         # verify obdfilter stats.
13407         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13408         sync
13409         cancel_lru_locks osc
13410         wait_delete_completed
13411
13412         # clear stats.
13413         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13414         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13415
13416         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13417                 error "dd failed"
13418         sync
13419         cancel_lru_locks osc
13420         check_stats ost1 "write" 1
13421
13422         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13423         check_stats ost1 "read" 1
13424
13425         > $testdir/$tfile || error "truncate failed"
13426         check_stats ost1 "punch" 1
13427
13428         rm -f $testdir/$tfile || error "file remove failed"
13429         wait_delete_completed
13430         check_stats ost1 "destroy" 1
13431
13432         rm -rf $DIR/$tdir
13433 }
13434 run_test 133c "Verifying OST stats ========================================"
13435
13436 order_2() {
13437         local value=$1
13438         local orig=$value
13439         local order=1
13440
13441         while [ $value -ge 2 ]; do
13442                 order=$((order*2))
13443                 value=$((value/2))
13444         done
13445
13446         if [ $orig -gt $order ]; then
13447                 order=$((order*2))
13448         fi
13449         echo $order
13450 }
13451
13452 size_in_KMGT() {
13453     local value=$1
13454     local size=('K' 'M' 'G' 'T');
13455     local i=0
13456     local size_string=$value
13457
13458     while [ $value -ge 1024 ]; do
13459         if [ $i -gt 3 ]; then
13460             #T is the biggest unit we get here, if that is bigger,
13461             #just return XXXT
13462             size_string=${value}T
13463             break
13464         fi
13465         value=$((value >> 10))
13466         if [ $value -lt 1024 ]; then
13467             size_string=${value}${size[$i]}
13468             break
13469         fi
13470         i=$((i + 1))
13471     done
13472
13473     echo $size_string
13474 }
13475
13476 get_rename_size() {
13477         local size=$1
13478         local context=${2:-.}
13479         local sample=$(do_facet $SINGLEMDS $LCTL \
13480                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13481                 grep -A1 $context |
13482                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13483         echo $sample
13484 }
13485
13486 test_133d() {
13487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13488         remote_ost_nodsh && skip "remote OST with nodsh"
13489         remote_mds_nodsh && skip "remote MDS with nodsh"
13490         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13491                 skip_env "MDS doesn't support rename stats"
13492
13493         local testdir1=$DIR/${tdir}/stats_testdir1
13494         local testdir2=$DIR/${tdir}/stats_testdir2
13495         mkdir -p $DIR/${tdir}
13496
13497         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13498
13499         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13500         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13501
13502         createmany -o $testdir1/test 512 || error "createmany failed"
13503
13504         # check samedir rename size
13505         mv ${testdir1}/test0 ${testdir1}/test_0
13506
13507         local testdir1_size=$(ls -l $DIR/${tdir} |
13508                 awk '/stats_testdir1/ {print $5}')
13509         local testdir2_size=$(ls -l $DIR/${tdir} |
13510                 awk '/stats_testdir2/ {print $5}')
13511
13512         testdir1_size=$(order_2 $testdir1_size)
13513         testdir2_size=$(order_2 $testdir2_size)
13514
13515         testdir1_size=$(size_in_KMGT $testdir1_size)
13516         testdir2_size=$(size_in_KMGT $testdir2_size)
13517
13518         echo "source rename dir size: ${testdir1_size}"
13519         echo "target rename dir size: ${testdir2_size}"
13520
13521         local cmd="do_facet $SINGLEMDS $LCTL "
13522         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13523
13524         eval $cmd || error "$cmd failed"
13525         local samedir=$($cmd | grep 'same_dir')
13526         local same_sample=$(get_rename_size $testdir1_size)
13527         [ -z "$samedir" ] && error "samedir_rename_size count error"
13528         [[ $same_sample -eq 1 ]] ||
13529                 error "samedir_rename_size error $same_sample"
13530         echo "Check same dir rename stats success"
13531
13532         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13533
13534         # check crossdir rename size
13535         mv ${testdir1}/test_0 ${testdir2}/test_0
13536
13537         testdir1_size=$(ls -l $DIR/${tdir} |
13538                 awk '/stats_testdir1/ {print $5}')
13539         testdir2_size=$(ls -l $DIR/${tdir} |
13540                 awk '/stats_testdir2/ {print $5}')
13541
13542         testdir1_size=$(order_2 $testdir1_size)
13543         testdir2_size=$(order_2 $testdir2_size)
13544
13545         testdir1_size=$(size_in_KMGT $testdir1_size)
13546         testdir2_size=$(size_in_KMGT $testdir2_size)
13547
13548         echo "source rename dir size: ${testdir1_size}"
13549         echo "target rename dir size: ${testdir2_size}"
13550
13551         eval $cmd || error "$cmd failed"
13552         local crossdir=$($cmd | grep 'crossdir')
13553         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13554         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13555         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13556         [[ $src_sample -eq 1 ]] ||
13557                 error "crossdir_rename_size error $src_sample"
13558         [[ $tgt_sample -eq 1 ]] ||
13559                 error "crossdir_rename_size error $tgt_sample"
13560         echo "Check cross dir rename stats success"
13561         rm -rf $DIR/${tdir}
13562 }
13563 run_test 133d "Verifying rename_stats ========================================"
13564
13565 test_133e() {
13566         remote_mds_nodsh && skip "remote MDS with nodsh"
13567         remote_ost_nodsh && skip "remote OST with nodsh"
13568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13569
13570         local testdir=$DIR/${tdir}/stats_testdir
13571         local ctr f0 f1 bs=32768 count=42 sum
13572
13573         mkdir -p ${testdir} || error "mkdir failed"
13574
13575         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13576
13577         for ctr in {write,read}_bytes; do
13578                 sync
13579                 cancel_lru_locks osc
13580
13581                 do_facet ost1 $LCTL set_param -n \
13582                         "obdfilter.*.exports.clear=clear"
13583
13584                 if [ $ctr = write_bytes ]; then
13585                         f0=/dev/zero
13586                         f1=${testdir}/${tfile}
13587                 else
13588                         f0=${testdir}/${tfile}
13589                         f1=/dev/null
13590                 fi
13591
13592                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13593                         error "dd failed"
13594                 sync
13595                 cancel_lru_locks osc
13596
13597                 sum=$(do_facet ost1 $LCTL get_param \
13598                         "obdfilter.*.exports.*.stats" |
13599                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13600                                 $1 == ctr { sum += $7 }
13601                                 END { printf("%0.0f", sum) }')
13602
13603                 if ((sum != bs * count)); then
13604                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13605                 fi
13606         done
13607
13608         rm -rf $DIR/${tdir}
13609 }
13610 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13611
13612 test_133f() {
13613         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13614                 skip "too old lustre for get_param -R ($facet_ver)"
13615
13616         # verifying readability.
13617         $LCTL get_param -R '*' &> /dev/null
13618
13619         # Verifing writability with badarea_io.
13620         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13621                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13622                 error "client badarea_io failed"
13623
13624         # remount the FS in case writes/reads /proc break the FS
13625         cleanup || error "failed to unmount"
13626         setup || error "failed to setup"
13627 }
13628 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13629
13630 test_133g() {
13631         remote_mds_nodsh && skip "remote MDS with nodsh"
13632         remote_ost_nodsh && skip "remote OST with nodsh"
13633
13634         local facet
13635         for facet in mds1 ost1; do
13636                 local facet_ver=$(lustre_version_code $facet)
13637                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13638                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13639                 else
13640                         log "$facet: too old lustre for get_param -R"
13641                 fi
13642                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13643                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13644                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13645                                 xargs badarea_io" ||
13646                                         error "$facet badarea_io failed"
13647                 else
13648                         skip_noexit "$facet: too old lustre for get_param -R"
13649                 fi
13650         done
13651
13652         # remount the FS in case writes/reads /proc break the FS
13653         cleanup || error "failed to unmount"
13654         setup || error "failed to setup"
13655 }
13656 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13657
13658 test_133h() {
13659         remote_mds_nodsh && skip "remote MDS with nodsh"
13660         remote_ost_nodsh && skip "remote OST with nodsh"
13661         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13662                 skip "Need MDS version at least 2.9.54"
13663
13664         local facet
13665         for facet in client mds1 ost1; do
13666                 # Get the list of files that are missing the terminating newline
13667                 local plist=$(do_facet $facet
13668                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13669                 local ent
13670                 for ent in $plist; do
13671                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13672                                 awk -v FS='\v' -v RS='\v\v' \
13673                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13674                                         print FILENAME}'" 2>/dev/null)
13675                         [ -z $missing ] || {
13676                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13677                                 error "file does not end with newline: $facet-$ent"
13678                         }
13679                 done
13680         done
13681 }
13682 run_test 133h "Proc files should end with newlines"
13683
13684 test_134a() {
13685         remote_mds_nodsh && skip "remote MDS with nodsh"
13686         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13687                 skip "Need MDS version at least 2.7.54"
13688
13689         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13690         cancel_lru_locks mdc
13691
13692         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13693         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13694         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13695
13696         local nr=1000
13697         createmany -o $DIR/$tdir/f $nr ||
13698                 error "failed to create $nr files in $DIR/$tdir"
13699         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13700
13701         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13702         do_facet mds1 $LCTL set_param fail_loc=0x327
13703         do_facet mds1 $LCTL set_param fail_val=500
13704         touch $DIR/$tdir/m
13705
13706         echo "sleep 10 seconds ..."
13707         sleep 10
13708         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13709
13710         do_facet mds1 $LCTL set_param fail_loc=0
13711         do_facet mds1 $LCTL set_param fail_val=0
13712         [ $lck_cnt -lt $unused ] ||
13713                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13714
13715         rm $DIR/$tdir/m
13716         unlinkmany $DIR/$tdir/f $nr
13717 }
13718 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13719
13720 test_134b() {
13721         remote_mds_nodsh && skip "remote MDS with nodsh"
13722         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13723                 skip "Need MDS version at least 2.7.54"
13724
13725         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13726         cancel_lru_locks mdc
13727
13728         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13729                         ldlm.lock_reclaim_threshold_mb)
13730         # disable reclaim temporarily
13731         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13732
13733         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13734         do_facet mds1 $LCTL set_param fail_loc=0x328
13735         do_facet mds1 $LCTL set_param fail_val=500
13736
13737         $LCTL set_param debug=+trace
13738
13739         local nr=600
13740         createmany -o $DIR/$tdir/f $nr &
13741         local create_pid=$!
13742
13743         echo "Sleep $TIMEOUT seconds ..."
13744         sleep $TIMEOUT
13745         if ! ps -p $create_pid  > /dev/null 2>&1; then
13746                 do_facet mds1 $LCTL set_param fail_loc=0
13747                 do_facet mds1 $LCTL set_param fail_val=0
13748                 do_facet mds1 $LCTL set_param \
13749                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13750                 error "createmany finished incorrectly!"
13751         fi
13752         do_facet mds1 $LCTL set_param fail_loc=0
13753         do_facet mds1 $LCTL set_param fail_val=0
13754         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13755         wait $create_pid || return 1
13756
13757         unlinkmany $DIR/$tdir/f $nr
13758 }
13759 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13760
13761 test_135() {
13762         remote_mds_nodsh && skip "remote MDS with nodsh"
13763         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13764                 skip "Need MDS version at least 2.13.50"
13765         local fname
13766
13767         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13768
13769 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13770         #set only one record at plain llog
13771         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13772
13773         #fill already existed plain llog each 64767
13774         #wrapping whole catalog
13775         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13776
13777         createmany -o $DIR/$tdir/$tfile_ 64700
13778         for (( i = 0; i < 64700; i = i + 2 ))
13779         do
13780                 rm $DIR/$tdir/$tfile_$i &
13781                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13782                 local pid=$!
13783                 wait $pid
13784         done
13785
13786         #waiting osp synchronization
13787         wait_delete_completed
13788 }
13789 run_test 135 "Race catalog processing"
13790
13791 test_136() {
13792         remote_mds_nodsh && skip "remote MDS with nodsh"
13793         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13794                 skip "Need MDS version at least 2.13.50"
13795         local fname
13796
13797         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13798         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13799         #set only one record at plain llog
13800 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13801         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13802
13803         #fill already existed 2 plain llogs each 64767
13804         #wrapping whole catalog
13805         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13806         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13807         wait_delete_completed
13808
13809         createmany -o $DIR/$tdir/$tfile_ 10
13810         sleep 25
13811
13812         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13813         for (( i = 0; i < 10; i = i + 3 ))
13814         do
13815                 rm $DIR/$tdir/$tfile_$i &
13816                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13817                 local pid=$!
13818                 wait $pid
13819                 sleep 7
13820                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13821         done
13822
13823         #waiting osp synchronization
13824         wait_delete_completed
13825 }
13826 run_test 136 "Race catalog processing 2"
13827
13828 test_140() { #bug-17379
13829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13830
13831         test_mkdir $DIR/$tdir
13832         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13833         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13834
13835         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13836         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13837         local i=0
13838         while i=$((i + 1)); do
13839                 test_mkdir $i
13840                 cd $i || error "Changing to $i"
13841                 ln -s ../stat stat || error "Creating stat symlink"
13842                 # Read the symlink until ELOOP present,
13843                 # not LBUGing the system is considered success,
13844                 # we didn't overrun the stack.
13845                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13846                 if [ $ret -ne 0 ]; then
13847                         if [ $ret -eq 40 ]; then
13848                                 break  # -ELOOP
13849                         else
13850                                 error "Open stat symlink"
13851                                         return
13852                         fi
13853                 fi
13854         done
13855         i=$((i - 1))
13856         echo "The symlink depth = $i"
13857         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13858                 error "Invalid symlink depth"
13859
13860         # Test recursive symlink
13861         ln -s symlink_self symlink_self
13862         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13863         echo "open symlink_self returns $ret"
13864         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13865 }
13866 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13867
13868 test_150a() {
13869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13870
13871         local TF="$TMP/$tfile"
13872
13873         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13874         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13875         cp $TF $DIR/$tfile
13876         cancel_lru_locks $OSC
13877         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13878         remount_client $MOUNT
13879         df -P $MOUNT
13880         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13881
13882         $TRUNCATE $TF 6000
13883         $TRUNCATE $DIR/$tfile 6000
13884         cancel_lru_locks $OSC
13885         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13886
13887         echo "12345" >>$TF
13888         echo "12345" >>$DIR/$tfile
13889         cancel_lru_locks $OSC
13890         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13891
13892         echo "12345" >>$TF
13893         echo "12345" >>$DIR/$tfile
13894         cancel_lru_locks $OSC
13895         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13896 }
13897 run_test 150a "truncate/append tests"
13898
13899 test_150b() {
13900         check_set_fallocate_or_skip
13901
13902         touch $DIR/$tfile
13903         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13904         check_fallocate $DIR/$tfile || error "fallocate failed"
13905 }
13906 run_test 150b "Verify fallocate (prealloc) functionality"
13907
13908 test_150bb() {
13909         check_set_fallocate_or_skip
13910
13911         touch $DIR/$tfile
13912         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13913         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13914         > $DIR/$tfile
13915         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13916         # precomputed md5sum for 20MB of zeroes
13917         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13918         local sum=($(md5sum $DIR/$tfile))
13919
13920         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13921
13922         check_set_fallocate 1
13923
13924         > $DIR/$tfile
13925         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13926         sum=($(md5sum $DIR/$tfile))
13927
13928         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13929 }
13930 run_test 150bb "Verify fallocate modes both zero space"
13931
13932 test_150c() {
13933         check_set_fallocate_or_skip
13934
13935         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13936         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13937         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13938         sync; sync_all_data
13939         cancel_lru_locks $OSC
13940         sleep 5
13941         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13942         want=$((OSTCOUNT * 1048576))
13943
13944         # Must allocate all requested space, not more than 5% extra
13945         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13946                 error "bytes $bytes is not $want"
13947
13948         rm -f $DIR/$tfile
13949         # verify fallocate on PFL file
13950         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13951                 error "Create $DIR/$tfile failed"
13952         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13953                         error "fallocate failed"
13954         sync; sync_all_data
13955         cancel_lru_locks $OSC
13956         sleep 5
13957         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13958         local want=$((1024 * 1048576))
13959
13960         # Must allocate all requested space, not more than 5% extra
13961         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13962                 error "bytes $bytes is not $want"
13963 }
13964 run_test 150c "Verify fallocate Size and Blocks"
13965
13966 test_150d() {
13967         check_set_fallocate_or_skip
13968
13969         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13970         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13971         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13972         sync; sync_all_data
13973         cancel_lru_locks $OSC
13974         sleep 5
13975         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13976         local want=$((OSTCOUNT * 1048576))
13977
13978         # Must allocate all requested space, not more than 5% extra
13979         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13980                 error "bytes $bytes is not $want"
13981 }
13982 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13983
13984 test_150e() {
13985         check_set_fallocate_or_skip
13986
13987         echo "df before:"
13988         $LFS df
13989         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13990         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13991                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13992
13993         # Find OST with Minimum Size
13994         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13995                        sort -un | head -1)
13996
13997         # Get 100MB per OST of the available space to reduce run time
13998         # else 60% of the available space if we are running SLOW tests
13999         if [ $SLOW == "no" ]; then
14000                 local space=$((1024 * 100 * OSTCOUNT))
14001         else
14002                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14003         fi
14004
14005         fallocate -l${space}k $DIR/$tfile ||
14006                 error "fallocate ${space}k $DIR/$tfile failed"
14007         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14008
14009         # get size immediately after fallocate. This should be correctly
14010         # updated
14011         local size=$(stat -c '%s' $DIR/$tfile)
14012         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14013
14014         # Sleep for a while for statfs to get updated. And not pull from cache.
14015         sleep 2
14016
14017         echo "df after fallocate:"
14018         $LFS df
14019
14020         (( size / 1024 == space )) || error "size $size != requested $space"
14021         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14022                 error "used $used < space $space"
14023
14024         rm $DIR/$tfile || error "rm failed"
14025         sync
14026         wait_delete_completed
14027
14028         echo "df after unlink:"
14029         $LFS df
14030 }
14031 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14032
14033 test_150f() {
14034         local size
14035         local blocks
14036         local want_size_before=20480 # in bytes
14037         local want_blocks_before=40 # 512 sized blocks
14038         local want_blocks_after=24  # 512 sized blocks
14039         local length=$(((want_blocks_before - want_blocks_after) * 512))
14040
14041         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14042                 skip "need at least 2.14.0 for fallocate punch"
14043
14044         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14045                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14046         fi
14047
14048         check_set_fallocate_or_skip
14049         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14050
14051         echo "Verify fallocate punch: Range within the file range"
14052         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14053                 error "dd failed for bs 4096 and count 5"
14054
14055         # Call fallocate with punch range which is within the file range
14056         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14057                 error "fallocate failed: offset 4096 and length $length"
14058         # client must see changes immediately after fallocate
14059         size=$(stat -c '%s' $DIR/$tfile)
14060         blocks=$(stat -c '%b' $DIR/$tfile)
14061
14062         # Verify punch worked.
14063         (( blocks == want_blocks_after )) ||
14064                 error "punch failed: blocks $blocks != $want_blocks_after"
14065
14066         (( size == want_size_before )) ||
14067                 error "punch failed: size $size != $want_size_before"
14068
14069         # Verify there is hole in file
14070         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14071         # precomputed md5sum
14072         local expect="4a9a834a2db02452929c0a348273b4aa"
14073
14074         cksum=($(md5sum $DIR/$tfile))
14075         [[ "${cksum[0]}" == "$expect" ]] ||
14076                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14077
14078         # Start second sub-case for fallocate punch.
14079         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14080         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14081                 error "dd failed for bs 4096 and count 5"
14082
14083         # Punch range less than block size will have no change in block count
14084         want_blocks_after=40  # 512 sized blocks
14085
14086         # Punch overlaps two blocks and less than blocksize
14087         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14088                 error "fallocate failed: offset 4000 length 3000"
14089         size=$(stat -c '%s' $DIR/$tfile)
14090         blocks=$(stat -c '%b' $DIR/$tfile)
14091
14092         # Verify punch worked.
14093         (( blocks == want_blocks_after )) ||
14094                 error "punch failed: blocks $blocks != $want_blocks_after"
14095
14096         (( size == want_size_before )) ||
14097                 error "punch failed: size $size != $want_size_before"
14098
14099         # Verify if range is really zero'ed out. We expect Zeros.
14100         # precomputed md5sum
14101         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14102         cksum=($(md5sum $DIR/$tfile))
14103         [[ "${cksum[0]}" == "$expect" ]] ||
14104                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14105 }
14106 run_test 150f "Verify fallocate punch functionality"
14107
14108 test_150g() {
14109         local space
14110         local size
14111         local blocks
14112         local blocks_after
14113         local size_after
14114         local BS=4096 # Block size in bytes
14115
14116         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14117                 skip "need at least 2.14.0 for fallocate punch"
14118
14119         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14120                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14121         fi
14122
14123         check_set_fallocate_or_skip
14124         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14125
14126         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14127                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14128
14129         # Get 100MB per OST of the available space to reduce run time
14130         # else 60% of the available space if we are running SLOW tests
14131         if [ $SLOW == "no" ]; then
14132                 space=$((1024 * 100 * OSTCOUNT))
14133         else
14134                 # Find OST with Minimum Size
14135                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14136                         sort -un | head -1)
14137                 echo "min size OST: $space"
14138                 space=$(((space * 60)/100 * OSTCOUNT))
14139         fi
14140         # space in 1k units, round to 4k blocks
14141         local blkcount=$((space * 1024 / $BS))
14142
14143         echo "Verify fallocate punch: Very large Range"
14144         fallocate -l${space}k $DIR/$tfile ||
14145                 error "fallocate ${space}k $DIR/$tfile failed"
14146         # write 1M at the end, start and in the middle
14147         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14148                 error "dd failed: bs $BS count 256"
14149         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14150                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14151         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14152                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14153
14154         # Gather stats.
14155         size=$(stat -c '%s' $DIR/$tfile)
14156
14157         # gather punch length.
14158         local punch_size=$((size - (BS * 2)))
14159
14160         echo "punch_size = $punch_size"
14161         echo "size - punch_size: $((size - punch_size))"
14162         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14163
14164         # Call fallocate to punch all except 2 blocks. We leave the
14165         # first and the last block
14166         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14167         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14168                 error "fallocate failed: offset $BS length $punch_size"
14169
14170         size_after=$(stat -c '%s' $DIR/$tfile)
14171         blocks_after=$(stat -c '%b' $DIR/$tfile)
14172
14173         # Verify punch worked.
14174         # Size should be kept
14175         (( size == size_after )) ||
14176                 error "punch failed: size $size != $size_after"
14177
14178         # two 4k data blocks to remain plus possible 1 extra extent block
14179         (( blocks_after <= ((BS / 512) * 3) )) ||
14180                 error "too many blocks remains: $blocks_after"
14181
14182         # Verify that file has hole between the first and the last blocks
14183         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14184         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14185
14186         echo "Hole at [$hole_start, $hole_end)"
14187         (( hole_start == BS )) ||
14188                 error "no hole at offset $BS after punch"
14189
14190         (( hole_end == BS + punch_size )) ||
14191                 error "data at offset $hole_end < $((BS + punch_size))"
14192 }
14193 run_test 150g "Verify fallocate punch on large range"
14194
14195 #LU-2902 roc_hit was not able to read all values from lproc
14196 function roc_hit_init() {
14197         local list=$(comma_list $(osts_nodes))
14198         local dir=$DIR/$tdir-check
14199         local file=$dir/$tfile
14200         local BEFORE
14201         local AFTER
14202         local idx
14203
14204         test_mkdir $dir
14205         #use setstripe to do a write to every ost
14206         for i in $(seq 0 $((OSTCOUNT-1))); do
14207                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14208                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14209                 idx=$(printf %04x $i)
14210                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14211                         awk '$1 == "cache_access" {sum += $7}
14212                                 END { printf("%0.0f", sum) }')
14213
14214                 cancel_lru_locks osc
14215                 cat $file >/dev/null
14216
14217                 AFTER=$(get_osd_param $list *OST*$idx stats |
14218                         awk '$1 == "cache_access" {sum += $7}
14219                                 END { printf("%0.0f", sum) }')
14220
14221                 echo BEFORE:$BEFORE AFTER:$AFTER
14222                 if ! let "AFTER - BEFORE == 4"; then
14223                         rm -rf $dir
14224                         error "roc_hit is not safe to use"
14225                 fi
14226                 rm $file
14227         done
14228
14229         rm -rf $dir
14230 }
14231
14232 function roc_hit() {
14233         local list=$(comma_list $(osts_nodes))
14234         echo $(get_osd_param $list '' stats |
14235                 awk '$1 == "cache_hit" {sum += $7}
14236                         END { printf("%0.0f", sum) }')
14237 }
14238
14239 function set_cache() {
14240         local on=1
14241
14242         if [ "$2" == "off" ]; then
14243                 on=0;
14244         fi
14245         local list=$(comma_list $(osts_nodes))
14246         set_osd_param $list '' $1_cache_enable $on
14247
14248         cancel_lru_locks osc
14249 }
14250
14251 test_151() {
14252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14253         remote_ost_nodsh && skip "remote OST with nodsh"
14254
14255         local CPAGES=3
14256         local list=$(comma_list $(osts_nodes))
14257
14258         # check whether obdfilter is cache capable at all
14259         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14260                 skip "not cache-capable obdfilter"
14261         fi
14262
14263         # check cache is enabled on all obdfilters
14264         if get_osd_param $list '' read_cache_enable | grep 0; then
14265                 skip "oss cache is disabled"
14266         fi
14267
14268         set_osd_param $list '' writethrough_cache_enable 1
14269
14270         # check write cache is enabled on all obdfilters
14271         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14272                 skip "oss write cache is NOT enabled"
14273         fi
14274
14275         roc_hit_init
14276
14277         #define OBD_FAIL_OBD_NO_LRU  0x609
14278         do_nodes $list $LCTL set_param fail_loc=0x609
14279
14280         # pages should be in the case right after write
14281         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14282                 error "dd failed"
14283
14284         local BEFORE=$(roc_hit)
14285         cancel_lru_locks osc
14286         cat $DIR/$tfile >/dev/null
14287         local AFTER=$(roc_hit)
14288
14289         do_nodes $list $LCTL set_param fail_loc=0
14290
14291         if ! let "AFTER - BEFORE == CPAGES"; then
14292                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14293         fi
14294
14295         cancel_lru_locks osc
14296         # invalidates OST cache
14297         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14298         set_osd_param $list '' read_cache_enable 0
14299         cat $DIR/$tfile >/dev/null
14300
14301         # now data shouldn't be found in the cache
14302         BEFORE=$(roc_hit)
14303         cancel_lru_locks osc
14304         cat $DIR/$tfile >/dev/null
14305         AFTER=$(roc_hit)
14306         if let "AFTER - BEFORE != 0"; then
14307                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14308         fi
14309
14310         set_osd_param $list '' read_cache_enable 1
14311         rm -f $DIR/$tfile
14312 }
14313 run_test 151 "test cache on oss and controls ==============================="
14314
14315 test_152() {
14316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14317
14318         local TF="$TMP/$tfile"
14319
14320         # simulate ENOMEM during write
14321 #define OBD_FAIL_OST_NOMEM      0x226
14322         lctl set_param fail_loc=0x80000226
14323         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14324         cp $TF $DIR/$tfile
14325         sync || error "sync failed"
14326         lctl set_param fail_loc=0
14327
14328         # discard client's cache
14329         cancel_lru_locks osc
14330
14331         # simulate ENOMEM during read
14332         lctl set_param fail_loc=0x80000226
14333         cmp $TF $DIR/$tfile || error "cmp failed"
14334         lctl set_param fail_loc=0
14335
14336         rm -f $TF
14337 }
14338 run_test 152 "test read/write with enomem ============================"
14339
14340 test_153() {
14341         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14342 }
14343 run_test 153 "test if fdatasync does not crash ======================="
14344
14345 dot_lustre_fid_permission_check() {
14346         local fid=$1
14347         local ffid=$MOUNT/.lustre/fid/$fid
14348         local test_dir=$2
14349
14350         echo "stat fid $fid"
14351         stat $ffid > /dev/null || error "stat $ffid failed."
14352         echo "touch fid $fid"
14353         touch $ffid || error "touch $ffid failed."
14354         echo "write to fid $fid"
14355         cat /etc/hosts > $ffid || error "write $ffid failed."
14356         echo "read fid $fid"
14357         diff /etc/hosts $ffid || error "read $ffid failed."
14358         echo "append write to fid $fid"
14359         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14360         echo "rename fid $fid"
14361         mv $ffid $test_dir/$tfile.1 &&
14362                 error "rename $ffid to $tfile.1 should fail."
14363         touch $test_dir/$tfile.1
14364         mv $test_dir/$tfile.1 $ffid &&
14365                 error "rename $tfile.1 to $ffid should fail."
14366         rm -f $test_dir/$tfile.1
14367         echo "truncate fid $fid"
14368         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14369         echo "link fid $fid"
14370         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14371         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14372                 echo "setfacl fid $fid"
14373                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14374                 echo "getfacl fid $fid"
14375                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14376         fi
14377         echo "unlink fid $fid"
14378         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14379         echo "mknod fid $fid"
14380         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14381
14382         fid=[0xf00000400:0x1:0x0]
14383         ffid=$MOUNT/.lustre/fid/$fid
14384
14385         echo "stat non-exist fid $fid"
14386         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14387         echo "write to non-exist fid $fid"
14388         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14389         echo "link new fid $fid"
14390         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14391
14392         mkdir -p $test_dir/$tdir
14393         touch $test_dir/$tdir/$tfile
14394         fid=$($LFS path2fid $test_dir/$tdir)
14395         rc=$?
14396         [ $rc -ne 0 ] &&
14397                 error "error: could not get fid for $test_dir/$dir/$tfile."
14398
14399         ffid=$MOUNT/.lustre/fid/$fid
14400
14401         echo "ls $fid"
14402         ls $ffid > /dev/null || error "ls $ffid failed."
14403         echo "touch $fid/$tfile.1"
14404         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14405
14406         echo "touch $MOUNT/.lustre/fid/$tfile"
14407         touch $MOUNT/.lustre/fid/$tfile && \
14408                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14409
14410         echo "setxattr to $MOUNT/.lustre/fid"
14411         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14412
14413         echo "listxattr for $MOUNT/.lustre/fid"
14414         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14415
14416         echo "delxattr from $MOUNT/.lustre/fid"
14417         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14418
14419         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14420         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14421                 error "touch invalid fid should fail."
14422
14423         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14424         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14425                 error "touch non-normal fid should fail."
14426
14427         echo "rename $tdir to $MOUNT/.lustre/fid"
14428         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14429                 error "rename to $MOUNT/.lustre/fid should fail."
14430
14431         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14432         then            # LU-3547
14433                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14434                 local new_obf_mode=777
14435
14436                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14437                 chmod $new_obf_mode $DIR/.lustre/fid ||
14438                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14439
14440                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14441                 [ $obf_mode -eq $new_obf_mode ] ||
14442                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14443
14444                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14445                 chmod $old_obf_mode $DIR/.lustre/fid ||
14446                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14447         fi
14448
14449         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14450         fid=$($LFS path2fid $test_dir/$tfile-2)
14451
14452         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14453         then # LU-5424
14454                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14455                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14456                         error "create lov data thru .lustre failed"
14457         fi
14458         echo "cp /etc/passwd $test_dir/$tfile-2"
14459         cp /etc/passwd $test_dir/$tfile-2 ||
14460                 error "copy to $test_dir/$tfile-2 failed."
14461         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14462         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14463                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14464
14465         rm -rf $test_dir/tfile.lnk
14466         rm -rf $test_dir/$tfile-2
14467 }
14468
14469 test_154A() {
14470         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14471                 skip "Need MDS version at least 2.4.1"
14472
14473         local tf=$DIR/$tfile
14474         touch $tf
14475
14476         local fid=$($LFS path2fid $tf)
14477         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14478
14479         # check that we get the same pathname back
14480         local rootpath
14481         local found
14482         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14483                 echo "$rootpath $fid"
14484                 found=$($LFS fid2path $rootpath "$fid")
14485                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14486                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14487         done
14488
14489         # check wrong root path format
14490         rootpath=$MOUNT"_wrong"
14491         found=$($LFS fid2path $rootpath "$fid")
14492         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14493 }
14494 run_test 154A "lfs path2fid and fid2path basic checks"
14495
14496 test_154B() {
14497         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14498                 skip "Need MDS version at least 2.4.1"
14499
14500         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14501         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14502         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14503         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14504
14505         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14506         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14507
14508         # check that we get the same pathname
14509         echo "PFID: $PFID, name: $name"
14510         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14511         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14512         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14513                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14514
14515         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14516 }
14517 run_test 154B "verify the ll_decode_linkea tool"
14518
14519 test_154a() {
14520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14521         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14522         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14523                 skip "Need MDS version at least 2.2.51"
14524         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14525
14526         cp /etc/hosts $DIR/$tfile
14527
14528         fid=$($LFS path2fid $DIR/$tfile)
14529         rc=$?
14530         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14531
14532         dot_lustre_fid_permission_check "$fid" $DIR ||
14533                 error "dot lustre permission check $fid failed"
14534
14535         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14536
14537         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14538
14539         touch $MOUNT/.lustre/file &&
14540                 error "creation is not allowed under .lustre"
14541
14542         mkdir $MOUNT/.lustre/dir &&
14543                 error "mkdir is not allowed under .lustre"
14544
14545         rm -rf $DIR/$tfile
14546 }
14547 run_test 154a "Open-by-FID"
14548
14549 test_154b() {
14550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14551         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14553         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14554                 skip "Need MDS version at least 2.2.51"
14555
14556         local remote_dir=$DIR/$tdir/remote_dir
14557         local MDTIDX=1
14558         local rc=0
14559
14560         mkdir -p $DIR/$tdir
14561         $LFS mkdir -i $MDTIDX $remote_dir ||
14562                 error "create remote directory failed"
14563
14564         cp /etc/hosts $remote_dir/$tfile
14565
14566         fid=$($LFS path2fid $remote_dir/$tfile)
14567         rc=$?
14568         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14569
14570         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14571                 error "dot lustre permission check $fid failed"
14572         rm -rf $DIR/$tdir
14573 }
14574 run_test 154b "Open-by-FID for remote directory"
14575
14576 test_154c() {
14577         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14578                 skip "Need MDS version at least 2.4.1"
14579
14580         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14581         local FID1=$($LFS path2fid $DIR/$tfile.1)
14582         local FID2=$($LFS path2fid $DIR/$tfile.2)
14583         local FID3=$($LFS path2fid $DIR/$tfile.3)
14584
14585         local N=1
14586         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14587                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14588                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14589                 local want=FID$N
14590                 [ "$FID" = "${!want}" ] ||
14591                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14592                 N=$((N + 1))
14593         done
14594
14595         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14596         do
14597                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14598                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14599                 N=$((N + 1))
14600         done
14601 }
14602 run_test 154c "lfs path2fid and fid2path multiple arguments"
14603
14604 test_154d() {
14605         remote_mds_nodsh && skip "remote MDS with nodsh"
14606         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14607                 skip "Need MDS version at least 2.5.53"
14608
14609         if remote_mds; then
14610                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14611         else
14612                 nid="0@lo"
14613         fi
14614         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14615         local fd
14616         local cmd
14617
14618         rm -f $DIR/$tfile
14619         touch $DIR/$tfile
14620
14621         local fid=$($LFS path2fid $DIR/$tfile)
14622         # Open the file
14623         fd=$(free_fd)
14624         cmd="exec $fd<$DIR/$tfile"
14625         eval $cmd
14626         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14627         echo "$fid_list" | grep "$fid"
14628         rc=$?
14629
14630         cmd="exec $fd>/dev/null"
14631         eval $cmd
14632         if [ $rc -ne 0 ]; then
14633                 error "FID $fid not found in open files list $fid_list"
14634         fi
14635 }
14636 run_test 154d "Verify open file fid"
14637
14638 test_154e()
14639 {
14640         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14641                 skip "Need MDS version at least 2.6.50"
14642
14643         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14644                 error ".lustre returned by readdir"
14645         fi
14646 }
14647 run_test 154e ".lustre is not returned by readdir"
14648
14649 test_154f() {
14650         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14651
14652         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14653         test_mkdir -p -c1 $DIR/$tdir/d
14654         # test dirs inherit from its stripe
14655         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14656         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14657         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14658         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14659         touch $DIR/f
14660
14661         # get fid of parents
14662         local FID0=$($LFS path2fid $DIR/$tdir/d)
14663         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14664         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14665         local FID3=$($LFS path2fid $DIR)
14666
14667         # check that path2fid --parents returns expected <parent_fid>/name
14668         # 1) test for a directory (single parent)
14669         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14670         [ "$parent" == "$FID0/foo1" ] ||
14671                 error "expected parent: $FID0/foo1, got: $parent"
14672
14673         # 2) test for a file with nlink > 1 (multiple parents)
14674         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14675         echo "$parent" | grep -F "$FID1/$tfile" ||
14676                 error "$FID1/$tfile not returned in parent list"
14677         echo "$parent" | grep -F "$FID2/link" ||
14678                 error "$FID2/link not returned in parent list"
14679
14680         # 3) get parent by fid
14681         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14682         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14683         echo "$parent" | grep -F "$FID1/$tfile" ||
14684                 error "$FID1/$tfile not returned in parent list (by fid)"
14685         echo "$parent" | grep -F "$FID2/link" ||
14686                 error "$FID2/link not returned in parent list (by fid)"
14687
14688         # 4) test for entry in root directory
14689         parent=$($LFS path2fid --parents $DIR/f)
14690         echo "$parent" | grep -F "$FID3/f" ||
14691                 error "$FID3/f not returned in parent list"
14692
14693         # 5) test it on root directory
14694         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14695                 error "$MOUNT should not have parents"
14696
14697         # enable xattr caching and check that linkea is correctly updated
14698         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14699         save_lustre_params client "llite.*.xattr_cache" > $save
14700         lctl set_param llite.*.xattr_cache 1
14701
14702         # 6.1) linkea update on rename
14703         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14704
14705         # get parents by fid
14706         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14707         # foo1 should no longer be returned in parent list
14708         echo "$parent" | grep -F "$FID1" &&
14709                 error "$FID1 should no longer be in parent list"
14710         # the new path should appear
14711         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14712                 error "$FID2/$tfile.moved is not in parent list"
14713
14714         # 6.2) linkea update on unlink
14715         rm -f $DIR/$tdir/d/foo2/link
14716         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14717         # foo2/link should no longer be returned in parent list
14718         echo "$parent" | grep -F "$FID2/link" &&
14719                 error "$FID2/link should no longer be in parent list"
14720         true
14721
14722         rm -f $DIR/f
14723         restore_lustre_params < $save
14724         rm -f $save
14725 }
14726 run_test 154f "get parent fids by reading link ea"
14727
14728 test_154g()
14729 {
14730         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14731         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14732            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14733                 skip "Need MDS version at least 2.6.92"
14734
14735         mkdir -p $DIR/$tdir
14736         llapi_fid_test -d $DIR/$tdir
14737 }
14738 run_test 154g "various llapi FID tests"
14739
14740 test_155_small_load() {
14741     local temp=$TMP/$tfile
14742     local file=$DIR/$tfile
14743
14744     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14745         error "dd of=$temp bs=6096 count=1 failed"
14746     cp $temp $file
14747     cancel_lru_locks $OSC
14748     cmp $temp $file || error "$temp $file differ"
14749
14750     $TRUNCATE $temp 6000
14751     $TRUNCATE $file 6000
14752     cmp $temp $file || error "$temp $file differ (truncate1)"
14753
14754     echo "12345" >>$temp
14755     echo "12345" >>$file
14756     cmp $temp $file || error "$temp $file differ (append1)"
14757
14758     echo "12345" >>$temp
14759     echo "12345" >>$file
14760     cmp $temp $file || error "$temp $file differ (append2)"
14761
14762     rm -f $temp $file
14763     true
14764 }
14765
14766 test_155_big_load() {
14767         remote_ost_nodsh && skip "remote OST with nodsh"
14768
14769         local temp=$TMP/$tfile
14770         local file=$DIR/$tfile
14771
14772         free_min_max
14773         local cache_size=$(do_facet ost$((MAXI+1)) \
14774                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14775         local large_file_size=$((cache_size * 2))
14776
14777         echo "OSS cache size: $cache_size KB"
14778         echo "Large file size: $large_file_size KB"
14779
14780         [ $MAXV -le $large_file_size ] &&
14781                 skip_env "max available OST size needs > $large_file_size KB"
14782
14783         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14784
14785         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14786                 error "dd of=$temp bs=$large_file_size count=1k failed"
14787         cp $temp $file
14788         ls -lh $temp $file
14789         cancel_lru_locks osc
14790         cmp $temp $file || error "$temp $file differ"
14791
14792         rm -f $temp $file
14793         true
14794 }
14795
14796 save_writethrough() {
14797         local facets=$(get_facets OST)
14798
14799         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14800 }
14801
14802 test_155a() {
14803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14804
14805         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14806
14807         save_writethrough $p
14808
14809         set_cache read on
14810         set_cache writethrough on
14811         test_155_small_load
14812         restore_lustre_params < $p
14813         rm -f $p
14814 }
14815 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14816
14817 test_155b() {
14818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14819
14820         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14821
14822         save_writethrough $p
14823
14824         set_cache read on
14825         set_cache writethrough off
14826         test_155_small_load
14827         restore_lustre_params < $p
14828         rm -f $p
14829 }
14830 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14831
14832 test_155c() {
14833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14834
14835         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14836
14837         save_writethrough $p
14838
14839         set_cache read off
14840         set_cache writethrough on
14841         test_155_small_load
14842         restore_lustre_params < $p
14843         rm -f $p
14844 }
14845 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14846
14847 test_155d() {
14848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14849
14850         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14851
14852         save_writethrough $p
14853
14854         set_cache read off
14855         set_cache writethrough off
14856         test_155_small_load
14857         restore_lustre_params < $p
14858         rm -f $p
14859 }
14860 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14861
14862 test_155e() {
14863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14864
14865         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14866
14867         save_writethrough $p
14868
14869         set_cache read on
14870         set_cache writethrough on
14871         test_155_big_load
14872         restore_lustre_params < $p
14873         rm -f $p
14874 }
14875 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14876
14877 test_155f() {
14878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14879
14880         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14881
14882         save_writethrough $p
14883
14884         set_cache read on
14885         set_cache writethrough off
14886         test_155_big_load
14887         restore_lustre_params < $p
14888         rm -f $p
14889 }
14890 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14891
14892 test_155g() {
14893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14894
14895         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14896
14897         save_writethrough $p
14898
14899         set_cache read off
14900         set_cache writethrough on
14901         test_155_big_load
14902         restore_lustre_params < $p
14903         rm -f $p
14904 }
14905 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14906
14907 test_155h() {
14908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14909
14910         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14911
14912         save_writethrough $p
14913
14914         set_cache read off
14915         set_cache writethrough off
14916         test_155_big_load
14917         restore_lustre_params < $p
14918         rm -f $p
14919 }
14920 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14921
14922 test_156() {
14923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14924         remote_ost_nodsh && skip "remote OST with nodsh"
14925         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14926                 skip "stats not implemented on old servers"
14927         [ "$ost1_FSTYPE" = "zfs" ] &&
14928                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14929
14930         local CPAGES=3
14931         local BEFORE
14932         local AFTER
14933         local file="$DIR/$tfile"
14934         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14935
14936         save_writethrough $p
14937         roc_hit_init
14938
14939         log "Turn on read and write cache"
14940         set_cache read on
14941         set_cache writethrough on
14942
14943         log "Write data and read it back."
14944         log "Read should be satisfied from the cache."
14945         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14946         BEFORE=$(roc_hit)
14947         cancel_lru_locks osc
14948         cat $file >/dev/null
14949         AFTER=$(roc_hit)
14950         if ! let "AFTER - BEFORE == CPAGES"; then
14951                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14952         else
14953                 log "cache hits: before: $BEFORE, after: $AFTER"
14954         fi
14955
14956         log "Read again; it should be satisfied from the cache."
14957         BEFORE=$AFTER
14958         cancel_lru_locks osc
14959         cat $file >/dev/null
14960         AFTER=$(roc_hit)
14961         if ! let "AFTER - BEFORE == CPAGES"; then
14962                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14963         else
14964                 log "cache hits:: before: $BEFORE, after: $AFTER"
14965         fi
14966
14967         log "Turn off the read cache and turn on the write cache"
14968         set_cache read off
14969         set_cache writethrough on
14970
14971         log "Read again; it should be satisfied from the cache."
14972         BEFORE=$(roc_hit)
14973         cancel_lru_locks osc
14974         cat $file >/dev/null
14975         AFTER=$(roc_hit)
14976         if ! let "AFTER - BEFORE == CPAGES"; then
14977                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14978         else
14979                 log "cache hits:: before: $BEFORE, after: $AFTER"
14980         fi
14981
14982         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14983                 # > 2.12.56 uses pagecache if cached
14984                 log "Read again; it should not be satisfied from the cache."
14985                 BEFORE=$AFTER
14986                 cancel_lru_locks osc
14987                 cat $file >/dev/null
14988                 AFTER=$(roc_hit)
14989                 if ! let "AFTER - BEFORE == 0"; then
14990                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14991                 else
14992                         log "cache hits:: before: $BEFORE, after: $AFTER"
14993                 fi
14994         fi
14995
14996         log "Write data and read it back."
14997         log "Read should be satisfied from the cache."
14998         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14999         BEFORE=$(roc_hit)
15000         cancel_lru_locks osc
15001         cat $file >/dev/null
15002         AFTER=$(roc_hit)
15003         if ! let "AFTER - BEFORE == CPAGES"; then
15004                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15005         else
15006                 log "cache hits:: before: $BEFORE, after: $AFTER"
15007         fi
15008
15009         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15010                 # > 2.12.56 uses pagecache if cached
15011                 log "Read again; it should not be satisfied from the cache."
15012                 BEFORE=$AFTER
15013                 cancel_lru_locks osc
15014                 cat $file >/dev/null
15015                 AFTER=$(roc_hit)
15016                 if ! let "AFTER - BEFORE == 0"; then
15017                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15018                 else
15019                         log "cache hits:: before: $BEFORE, after: $AFTER"
15020                 fi
15021         fi
15022
15023         log "Turn off read and write cache"
15024         set_cache read off
15025         set_cache writethrough off
15026
15027         log "Write data and read it back"
15028         log "It should not be satisfied from the cache."
15029         rm -f $file
15030         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15031         cancel_lru_locks osc
15032         BEFORE=$(roc_hit)
15033         cat $file >/dev/null
15034         AFTER=$(roc_hit)
15035         if ! let "AFTER - BEFORE == 0"; then
15036                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15037         else
15038                 log "cache hits:: before: $BEFORE, after: $AFTER"
15039         fi
15040
15041         log "Turn on the read cache and turn off the write cache"
15042         set_cache read on
15043         set_cache writethrough off
15044
15045         log "Write data and read it back"
15046         log "It should not be satisfied from the cache."
15047         rm -f $file
15048         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15049         BEFORE=$(roc_hit)
15050         cancel_lru_locks osc
15051         cat $file >/dev/null
15052         AFTER=$(roc_hit)
15053         if ! let "AFTER - BEFORE == 0"; then
15054                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15055         else
15056                 log "cache hits:: before: $BEFORE, after: $AFTER"
15057         fi
15058
15059         log "Read again; it should be satisfied from the cache."
15060         BEFORE=$(roc_hit)
15061         cancel_lru_locks osc
15062         cat $file >/dev/null
15063         AFTER=$(roc_hit)
15064         if ! let "AFTER - BEFORE == CPAGES"; then
15065                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15066         else
15067                 log "cache hits:: before: $BEFORE, after: $AFTER"
15068         fi
15069
15070         restore_lustre_params < $p
15071         rm -f $p $file
15072 }
15073 run_test 156 "Verification of tunables"
15074
15075 test_160a() {
15076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15077         remote_mds_nodsh && skip "remote MDS with nodsh"
15078         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15079                 skip "Need MDS version at least 2.2.0"
15080
15081         changelog_register || error "changelog_register failed"
15082         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15083         changelog_users $SINGLEMDS | grep -q $cl_user ||
15084                 error "User $cl_user not found in changelog_users"
15085
15086         # change something
15087         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15088         changelog_clear 0 || error "changelog_clear failed"
15089         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15090         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15091         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15092         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15093         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15094         rm $DIR/$tdir/pics/desktop.jpg
15095
15096         changelog_dump | tail -10
15097
15098         echo "verifying changelog mask"
15099         changelog_chmask "-MKDIR"
15100         changelog_chmask "-CLOSE"
15101
15102         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15103         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15104
15105         changelog_chmask "+MKDIR"
15106         changelog_chmask "+CLOSE"
15107
15108         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15109         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15110
15111         changelog_dump | tail -10
15112         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15113         CLOSES=$(changelog_dump | grep -c "CLOSE")
15114         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15115         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15116
15117         # verify contents
15118         echo "verifying target fid"
15119         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15120         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15121         [ "$fidc" == "$fidf" ] ||
15122                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15123         echo "verifying parent fid"
15124         # The FID returned from the Changelog may be the directory shard on
15125         # a different MDT, and not the FID returned by path2fid on the parent.
15126         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15127         # since this is what will matter when recreating this file in the tree.
15128         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15129         local pathp=$($LFS fid2path $MOUNT "$fidp")
15130         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15131                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15132
15133         echo "getting records for $cl_user"
15134         changelog_users $SINGLEMDS
15135         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15136         local nclr=3
15137         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15138                 error "changelog_clear failed"
15139         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15140         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15141         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15142                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15143
15144         local min0_rec=$(changelog_users $SINGLEMDS |
15145                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15146         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15147                           awk '{ print $1; exit; }')
15148
15149         changelog_dump | tail -n 5
15150         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15151         [ $first_rec == $((min0_rec + 1)) ] ||
15152                 error "first index should be $min0_rec + 1 not $first_rec"
15153
15154         # LU-3446 changelog index reset on MDT restart
15155         local cur_rec1=$(changelog_users $SINGLEMDS |
15156                          awk '/^current.index:/ { print $NF }')
15157         changelog_clear 0 ||
15158                 error "clear all changelog records for $cl_user failed"
15159         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15160         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15161                 error "Fail to start $SINGLEMDS"
15162         local cur_rec2=$(changelog_users $SINGLEMDS |
15163                          awk '/^current.index:/ { print $NF }')
15164         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15165         [ $cur_rec1 == $cur_rec2 ] ||
15166                 error "current index should be $cur_rec1 not $cur_rec2"
15167
15168         echo "verifying users from this test are deregistered"
15169         changelog_deregister || error "changelog_deregister failed"
15170         changelog_users $SINGLEMDS | grep -q $cl_user &&
15171                 error "User '$cl_user' still in changelog_users"
15172
15173         # lctl get_param -n mdd.*.changelog_users
15174         # current index: 144
15175         # ID    index (idle seconds)
15176         # cl3   144 (2)
15177         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15178                 # this is the normal case where all users were deregistered
15179                 # make sure no new records are added when no users are present
15180                 local last_rec1=$(changelog_users $SINGLEMDS |
15181                                   awk '/^current.index:/ { print $NF }')
15182                 touch $DIR/$tdir/chloe
15183                 local last_rec2=$(changelog_users $SINGLEMDS |
15184                                   awk '/^current.index:/ { print $NF }')
15185                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15186                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15187         else
15188                 # any changelog users must be leftovers from a previous test
15189                 changelog_users $SINGLEMDS
15190                 echo "other changelog users; can't verify off"
15191         fi
15192 }
15193 run_test 160a "changelog sanity"
15194
15195 test_160b() { # LU-3587
15196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15197         remote_mds_nodsh && skip "remote MDS with nodsh"
15198         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15199                 skip "Need MDS version at least 2.2.0"
15200
15201         changelog_register || error "changelog_register failed"
15202         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15203         changelog_users $SINGLEMDS | grep -q $cl_user ||
15204                 error "User '$cl_user' not found in changelog_users"
15205
15206         local longname1=$(str_repeat a 255)
15207         local longname2=$(str_repeat b 255)
15208
15209         cd $DIR
15210         echo "creating very long named file"
15211         touch $longname1 || error "create of '$longname1' failed"
15212         echo "renaming very long named file"
15213         mv $longname1 $longname2
15214
15215         changelog_dump | grep RENME | tail -n 5
15216         rm -f $longname2
15217 }
15218 run_test 160b "Verify that very long rename doesn't crash in changelog"
15219
15220 test_160c() {
15221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15222         remote_mds_nodsh && skip "remote MDS with nodsh"
15223
15224         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15225                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15226                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15227                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15228
15229         local rc=0
15230
15231         # Registration step
15232         changelog_register || error "changelog_register failed"
15233
15234         rm -rf $DIR/$tdir
15235         mkdir -p $DIR/$tdir
15236         $MCREATE $DIR/$tdir/foo_160c
15237         changelog_chmask "-TRUNC"
15238         $TRUNCATE $DIR/$tdir/foo_160c 200
15239         changelog_chmask "+TRUNC"
15240         $TRUNCATE $DIR/$tdir/foo_160c 199
15241         changelog_dump | tail -n 5
15242         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15243         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15244 }
15245 run_test 160c "verify that changelog log catch the truncate event"
15246
15247 test_160d() {
15248         remote_mds_nodsh && skip "remote MDS with nodsh"
15249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15251         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15252                 skip "Need MDS version at least 2.7.60"
15253
15254         # Registration step
15255         changelog_register || error "changelog_register failed"
15256
15257         mkdir -p $DIR/$tdir/migrate_dir
15258         changelog_clear 0 || error "changelog_clear failed"
15259
15260         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15261         changelog_dump | tail -n 5
15262         local migrates=$(changelog_dump | grep -c "MIGRT")
15263         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15264 }
15265 run_test 160d "verify that changelog log catch the migrate event"
15266
15267 test_160e() {
15268         remote_mds_nodsh && skip "remote MDS with nodsh"
15269
15270         # Create a user
15271         changelog_register || error "changelog_register failed"
15272
15273         # Delete a future user (expect fail)
15274         local MDT0=$(facet_svc $SINGLEMDS)
15275         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15276         local rc=$?
15277
15278         if [ $rc -eq 0 ]; then
15279                 error "Deleted non-existant user cl77"
15280         elif [ $rc -ne 2 ]; then
15281                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15282         fi
15283
15284         # Clear to a bad index (1 billion should be safe)
15285         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15286         rc=$?
15287
15288         if [ $rc -eq 0 ]; then
15289                 error "Successfully cleared to invalid CL index"
15290         elif [ $rc -ne 22 ]; then
15291                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15292         fi
15293 }
15294 run_test 160e "changelog negative testing (should return errors)"
15295
15296 test_160f() {
15297         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15298         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15299                 skip "Need MDS version at least 2.10.56"
15300
15301         local mdts=$(comma_list $(mdts_nodes))
15302
15303         # Create a user
15304         changelog_register || error "first changelog_register failed"
15305         changelog_register || error "second changelog_register failed"
15306         local cl_users
15307         declare -A cl_user1
15308         declare -A cl_user2
15309         local user_rec1
15310         local user_rec2
15311         local i
15312
15313         # generate some changelog records to accumulate on each MDT
15314         # use all_char because created files should be evenly distributed
15315         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15316                 error "test_mkdir $tdir failed"
15317         log "$(date +%s): creating first files"
15318         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15319                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15320                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15321         done
15322
15323         # check changelogs have been generated
15324         local start=$SECONDS
15325         local idle_time=$((MDSCOUNT * 5 + 5))
15326         local nbcl=$(changelog_dump | wc -l)
15327         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15328
15329         for param in "changelog_max_idle_time=$idle_time" \
15330                      "changelog_gc=1" \
15331                      "changelog_min_gc_interval=2" \
15332                      "changelog_min_free_cat_entries=3"; do
15333                 local MDT0=$(facet_svc $SINGLEMDS)
15334                 local var="${param%=*}"
15335                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15336
15337                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15338                 do_nodes $mdts $LCTL set_param mdd.*.$param
15339         done
15340
15341         # force cl_user2 to be idle (1st part), but also cancel the
15342         # cl_user1 records so that it is not evicted later in the test.
15343         local sleep1=$((idle_time / 2))
15344         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15345         sleep $sleep1
15346
15347         # simulate changelog catalog almost full
15348         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15349         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15350
15351         for i in $(seq $MDSCOUNT); do
15352                 cl_users=(${CL_USERS[mds$i]})
15353                 cl_user1[mds$i]="${cl_users[0]}"
15354                 cl_user2[mds$i]="${cl_users[1]}"
15355
15356                 [ -n "${cl_user1[mds$i]}" ] ||
15357                         error "mds$i: no user registered"
15358                 [ -n "${cl_user2[mds$i]}" ] ||
15359                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15360
15361                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15362                 [ -n "$user_rec1" ] ||
15363                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15364                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15365                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15366                 [ -n "$user_rec2" ] ||
15367                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15368                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15369                      "$user_rec1 + 2 == $user_rec2"
15370                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15371                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15372                               "$user_rec1 + 2, but is $user_rec2"
15373                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15374                 [ -n "$user_rec2" ] ||
15375                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15376                 [ $user_rec1 == $user_rec2 ] ||
15377                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15378                               "$user_rec1, but is $user_rec2"
15379         done
15380
15381         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15382         local sleep2=$((idle_time - (SECONDS - start) + 1))
15383         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15384         sleep $sleep2
15385
15386         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15387         # cl_user1 should be OK because it recently processed records.
15388         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15389         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15390                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15391                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15392         done
15393
15394         # ensure gc thread is done
15395         for i in $(mdts_nodes); do
15396                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15397                         error "$i: GC-thread not done"
15398         done
15399
15400         local first_rec
15401         for (( i = 1; i <= MDSCOUNT; i++ )); do
15402                 # check cl_user1 still registered
15403                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15404                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15405                 # check cl_user2 unregistered
15406                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15407                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15408
15409                 # check changelogs are present and starting at $user_rec1 + 1
15410                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15411                 [ -n "$user_rec1" ] ||
15412                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15413                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15414                             awk '{ print $1; exit; }')
15415
15416                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15417                 [ $((user_rec1 + 1)) == $first_rec ] ||
15418                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15419         done
15420 }
15421 run_test 160f "changelog garbage collect (timestamped users)"
15422
15423 test_160g() {
15424         remote_mds_nodsh && skip "remote MDS with nodsh"
15425         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15426                 skip "Need MDS version at least 2.10.56"
15427
15428         local mdts=$(comma_list $(mdts_nodes))
15429
15430         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15431         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15432
15433         # Create a user
15434         changelog_register || error "first changelog_register failed"
15435         changelog_register || error "second changelog_register failed"
15436         local cl_users
15437         declare -A cl_user1
15438         declare -A cl_user2
15439         local user_rec1
15440         local user_rec2
15441         local i
15442
15443         # generate some changelog records to accumulate on each MDT
15444         # use all_char because created files should be evenly distributed
15445         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15446                 error "test_mkdir $tdir failed"
15447         for ((i = 0; i < MDSCOUNT; i++)); do
15448                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15449                         error "create $DIR/$tdir/d$i.1 failed"
15450         done
15451
15452         # check changelogs have been generated
15453         local nbcl=$(changelog_dump | wc -l)
15454         (( $nbcl > 0 )) || error "no changelogs found"
15455
15456         # reduce the max_idle_indexes value to make sure we exceed it
15457         for param in "changelog_max_idle_indexes=1" \
15458                      "changelog_gc=1" \
15459                      "changelog_min_gc_interval=2" \
15460                      "changelog_min_free_cat_entries=3"; do
15461                 local MDT0=$(facet_svc $SINGLEMDS)
15462                 local var="${param%=*}"
15463                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15464
15465                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15466                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15467                         error "unable to set mdd.*.$param"
15468         done
15469
15470         # simulate changelog catalog almost full
15471         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15472         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15473
15474         local start=$SECONDS
15475         for i in $(seq $MDSCOUNT); do
15476                 cl_users=(${CL_USERS[mds$i]})
15477                 cl_user1[mds$i]="${cl_users[0]}"
15478                 cl_user2[mds$i]="${cl_users[1]}"
15479
15480                 [ -n "${cl_user1[mds$i]}" ] ||
15481                         error "mds$i: no user registered"
15482                 [ -n "${cl_user2[mds$i]}" ] ||
15483                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15484
15485                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15486                 [ -n "$user_rec1" ] ||
15487                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15488                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15489                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15490                 [ -n "$user_rec2" ] ||
15491                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15492                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15493                      "$user_rec1 + 2 == $user_rec2"
15494                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15495                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15496                               "$user_rec1 + 2, but is $user_rec2"
15497                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15498                 [ -n "$user_rec2" ] ||
15499                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15500                 [ $user_rec1 == $user_rec2 ] ||
15501                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15502                               "$user_rec1, but is $user_rec2"
15503         done
15504
15505         # ensure we are past the previous changelog_min_gc_interval set above
15506         local sleep2=$((start + 2 - SECONDS))
15507         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15508
15509         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15510         # cl_user1 should be OK because it recently processed records.
15511         for ((i = 0; i < MDSCOUNT; i++)); do
15512                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15513                         error "create $DIR/$tdir/d$i.3 failed"
15514         done
15515
15516         # ensure gc thread is done
15517         for i in $(mdts_nodes); do
15518                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15519                         error "$i: GC-thread not done"
15520         done
15521
15522         local first_rec
15523         for (( i = 1; i <= MDSCOUNT; i++ )); do
15524                 # check cl_user1 still registered
15525                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15526                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15527                 # check cl_user2 unregistered
15528                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15529                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15530
15531                 # check changelogs are present and starting at $user_rec1 + 1
15532                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15533                 [ -n "$user_rec1" ] ||
15534                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15535                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15536                             awk '{ print $1; exit; }')
15537
15538                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15539                 [ $((user_rec1 + 1)) == $first_rec ] ||
15540                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15541         done
15542 }
15543 run_test 160g "changelog garbage collect (old users)"
15544
15545 test_160h() {
15546         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15547         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15548                 skip "Need MDS version at least 2.10.56"
15549
15550         local mdts=$(comma_list $(mdts_nodes))
15551
15552         # Create a user
15553         changelog_register || error "first changelog_register failed"
15554         changelog_register || error "second changelog_register failed"
15555         local cl_users
15556         declare -A cl_user1
15557         declare -A cl_user2
15558         local user_rec1
15559         local user_rec2
15560         local i
15561
15562         # generate some changelog records to accumulate on each MDT
15563         # use all_char because created files should be evenly distributed
15564         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15565                 error "test_mkdir $tdir failed"
15566         for ((i = 0; i < MDSCOUNT; i++)); do
15567                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15568                         error "create $DIR/$tdir/d$i.1 failed"
15569         done
15570
15571         # check changelogs have been generated
15572         local nbcl=$(changelog_dump | wc -l)
15573         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15574
15575         for param in "changelog_max_idle_time=10" \
15576                      "changelog_gc=1" \
15577                      "changelog_min_gc_interval=2"; do
15578                 local MDT0=$(facet_svc $SINGLEMDS)
15579                 local var="${param%=*}"
15580                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15581
15582                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15583                 do_nodes $mdts $LCTL set_param mdd.*.$param
15584         done
15585
15586         # force cl_user2 to be idle (1st part)
15587         sleep 9
15588
15589         for i in $(seq $MDSCOUNT); do
15590                 cl_users=(${CL_USERS[mds$i]})
15591                 cl_user1[mds$i]="${cl_users[0]}"
15592                 cl_user2[mds$i]="${cl_users[1]}"
15593
15594                 [ -n "${cl_user1[mds$i]}" ] ||
15595                         error "mds$i: no user registered"
15596                 [ -n "${cl_user2[mds$i]}" ] ||
15597                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15598
15599                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15600                 [ -n "$user_rec1" ] ||
15601                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15602                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15603                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15604                 [ -n "$user_rec2" ] ||
15605                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15606                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15607                      "$user_rec1 + 2 == $user_rec2"
15608                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15609                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15610                               "$user_rec1 + 2, but is $user_rec2"
15611                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15612                 [ -n "$user_rec2" ] ||
15613                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15614                 [ $user_rec1 == $user_rec2 ] ||
15615                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15616                               "$user_rec1, but is $user_rec2"
15617         done
15618
15619         # force cl_user2 to be idle (2nd part) and to reach
15620         # changelog_max_idle_time
15621         sleep 2
15622
15623         # force each GC-thread start and block then
15624         # one per MDT/MDD, set fail_val accordingly
15625         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15626         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15627
15628         # generate more changelogs to trigger fail_loc
15629         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15630                 error "create $DIR/$tdir/${tfile}bis failed"
15631
15632         # stop MDT to stop GC-thread, should be done in back-ground as it will
15633         # block waiting for the thread to be released and exit
15634         declare -A stop_pids
15635         for i in $(seq $MDSCOUNT); do
15636                 stop mds$i &
15637                 stop_pids[mds$i]=$!
15638         done
15639
15640         for i in $(mdts_nodes); do
15641                 local facet
15642                 local nb=0
15643                 local facets=$(facets_up_on_host $i)
15644
15645                 for facet in ${facets//,/ }; do
15646                         if [[ $facet == mds* ]]; then
15647                                 nb=$((nb + 1))
15648                         fi
15649                 done
15650                 # ensure each MDS's gc threads are still present and all in "R"
15651                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15652                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15653                         error "$i: expected $nb GC-thread"
15654                 wait_update $i \
15655                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15656                         "R" 20 ||
15657                         error "$i: GC-thread not found in R-state"
15658                 # check umounts of each MDT on MDS have reached kthread_stop()
15659                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15660                         error "$i: expected $nb umount"
15661                 wait_update $i \
15662                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15663                         error "$i: umount not found in D-state"
15664         done
15665
15666         # release all GC-threads
15667         do_nodes $mdts $LCTL set_param fail_loc=0
15668
15669         # wait for MDT stop to complete
15670         for i in $(seq $MDSCOUNT); do
15671                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15672         done
15673
15674         # XXX
15675         # may try to check if any orphan changelog records are present
15676         # via ldiskfs/zfs and llog_reader...
15677
15678         # re-start/mount MDTs
15679         for i in $(seq $MDSCOUNT); do
15680                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15681                         error "Fail to start mds$i"
15682         done
15683
15684         local first_rec
15685         for i in $(seq $MDSCOUNT); do
15686                 # check cl_user1 still registered
15687                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15688                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15689                 # check cl_user2 unregistered
15690                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15691                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15692
15693                 # check changelogs are present and starting at $user_rec1 + 1
15694                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15695                 [ -n "$user_rec1" ] ||
15696                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15697                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15698                             awk '{ print $1; exit; }')
15699
15700                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15701                 [ $((user_rec1 + 1)) == $first_rec ] ||
15702                         error "mds$i: first index should be $user_rec1 + 1, " \
15703                               "but is $first_rec"
15704         done
15705 }
15706 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15707               "during mount"
15708
15709 test_160i() {
15710
15711         local mdts=$(comma_list $(mdts_nodes))
15712
15713         changelog_register || error "first changelog_register failed"
15714
15715         # generate some changelog records to accumulate on each MDT
15716         # use all_char because created files should be evenly distributed
15717         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15718                 error "test_mkdir $tdir failed"
15719         for ((i = 0; i < MDSCOUNT; i++)); do
15720                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15721                         error "create $DIR/$tdir/d$i.1 failed"
15722         done
15723
15724         # check changelogs have been generated
15725         local nbcl=$(changelog_dump | wc -l)
15726         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15727
15728         # simulate race between register and unregister
15729         # XXX as fail_loc is set per-MDS, with DNE configs the race
15730         # simulation will only occur for one MDT per MDS and for the
15731         # others the normal race scenario will take place
15732         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15733         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15734         do_nodes $mdts $LCTL set_param fail_val=1
15735
15736         # unregister 1st user
15737         changelog_deregister &
15738         local pid1=$!
15739         # wait some time for deregister work to reach race rdv
15740         sleep 2
15741         # register 2nd user
15742         changelog_register || error "2nd user register failed"
15743
15744         wait $pid1 || error "1st user deregister failed"
15745
15746         local i
15747         local last_rec
15748         declare -A LAST_REC
15749         for i in $(seq $MDSCOUNT); do
15750                 if changelog_users mds$i | grep "^cl"; then
15751                         # make sure new records are added with one user present
15752                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15753                                           awk '/^current.index:/ { print $NF }')
15754                 else
15755                         error "mds$i has no user registered"
15756                 fi
15757         done
15758
15759         # generate more changelog records to accumulate on each MDT
15760         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15761                 error "create $DIR/$tdir/${tfile}bis failed"
15762
15763         for i in $(seq $MDSCOUNT); do
15764                 last_rec=$(changelog_users $SINGLEMDS |
15765                            awk '/^current.index:/ { print $NF }')
15766                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15767                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15768                         error "changelogs are off on mds$i"
15769         done
15770 }
15771 run_test 160i "changelog user register/unregister race"
15772
15773 test_160j() {
15774         remote_mds_nodsh && skip "remote MDS with nodsh"
15775         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15776                 skip "Need MDS version at least 2.12.56"
15777
15778         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15779         stack_trap "umount $MOUNT2" EXIT
15780
15781         changelog_register || error "first changelog_register failed"
15782         stack_trap "changelog_deregister" EXIT
15783
15784         # generate some changelog
15785         # use all_char because created files should be evenly distributed
15786         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15787                 error "mkdir $tdir failed"
15788         for ((i = 0; i < MDSCOUNT; i++)); do
15789                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15790                         error "create $DIR/$tdir/d$i.1 failed"
15791         done
15792
15793         # open the changelog device
15794         exec 3>/dev/changelog-$FSNAME-MDT0000
15795         stack_trap "exec 3>&-" EXIT
15796         exec 4</dev/changelog-$FSNAME-MDT0000
15797         stack_trap "exec 4<&-" EXIT
15798
15799         # umount the first lustre mount
15800         umount $MOUNT
15801         stack_trap "mount_client $MOUNT" EXIT
15802
15803         # read changelog, which may or may not fail, but should not crash
15804         cat <&4 >/dev/null
15805
15806         # clear changelog
15807         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15808         changelog_users $SINGLEMDS | grep -q $cl_user ||
15809                 error "User $cl_user not found in changelog_users"
15810
15811         printf 'clear:'$cl_user':0' >&3
15812 }
15813 run_test 160j "client can be umounted while its chanangelog is being used"
15814
15815 test_160k() {
15816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15817         remote_mds_nodsh && skip "remote MDS with nodsh"
15818
15819         mkdir -p $DIR/$tdir/1/1
15820
15821         changelog_register || error "changelog_register failed"
15822         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15823
15824         changelog_users $SINGLEMDS | grep -q $cl_user ||
15825                 error "User '$cl_user' not found in changelog_users"
15826 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15827         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15828         rmdir $DIR/$tdir/1/1 & sleep 1
15829         mkdir $DIR/$tdir/2
15830         touch $DIR/$tdir/2/2
15831         rm -rf $DIR/$tdir/2
15832
15833         wait
15834         sleep 4
15835
15836         changelog_dump | grep rmdir || error "rmdir not recorded"
15837 }
15838 run_test 160k "Verify that changelog records are not lost"
15839
15840 # Verifies that a file passed as a parameter has recently had an operation
15841 # performed on it that has generated an MTIME changelog which contains the
15842 # correct parent FID. As files might reside on a different MDT from the
15843 # parent directory in DNE configurations, the FIDs are translated to paths
15844 # before being compared, which should be identical
15845 compare_mtime_changelog() {
15846         local file="${1}"
15847         local mdtidx
15848         local mtime
15849         local cl_fid
15850         local pdir
15851         local dir
15852
15853         mdtidx=$($LFS getstripe --mdt-index $file)
15854         mdtidx=$(printf "%04x" $mdtidx)
15855
15856         # Obtain the parent FID from the MTIME changelog
15857         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15858         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15859
15860         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15861         [ -z "$cl_fid" ] && error "parent FID not present"
15862
15863         # Verify that the path for the parent FID is the same as the path for
15864         # the test directory
15865         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15866
15867         dir=$(dirname $1)
15868
15869         [[ "${pdir%/}" == "$dir" ]] ||
15870                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15871 }
15872
15873 test_160l() {
15874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15875
15876         remote_mds_nodsh && skip "remote MDS with nodsh"
15877         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15878                 skip "Need MDS version at least 2.13.55"
15879
15880         local cl_user
15881
15882         changelog_register || error "changelog_register failed"
15883         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15884
15885         changelog_users $SINGLEMDS | grep -q $cl_user ||
15886                 error "User '$cl_user' not found in changelog_users"
15887
15888         # Clear some types so that MTIME changelogs are generated
15889         changelog_chmask "-CREAT"
15890         changelog_chmask "-CLOSE"
15891
15892         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15893
15894         # Test CL_MTIME during setattr
15895         touch $DIR/$tdir/$tfile
15896         compare_mtime_changelog $DIR/$tdir/$tfile
15897
15898         # Test CL_MTIME during close
15899         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15900         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15901 }
15902 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15903
15904 test_160m() {
15905         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15906         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
15907                 skip "Need MDS version at least 2.14.51"
15908         local cl_users
15909         local cl_user1
15910         local cl_user2
15911         local pid1
15912
15913         # Create a user
15914         changelog_register || error "first changelog_register failed"
15915         changelog_register || error "second changelog_register failed"
15916
15917         cl_users=(${CL_USERS[mds1]})
15918         cl_user1="${cl_users[0]}"
15919         cl_user2="${cl_users[1]}"
15920         # generate some changelog records to accumulate on MDT0
15921         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
15922         createmany -m $DIR/$tdir/$tfile 50 ||
15923                 error "create $DIR/$tdir/$tfile failed"
15924         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
15925         rm -f $DIR/$tdir
15926
15927         # check changelogs have been generated
15928         local nbcl=$(changelog_dump | wc -l)
15929         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15930
15931 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
15932         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
15933
15934         __changelog_clear mds1 $cl_user1 +10
15935         __changelog_clear mds1 $cl_user2 0 &
15936         pid1=$!
15937         sleep 2
15938         __changelog_clear mds1 $cl_user1 0 ||
15939                 error "fail to cancel record for $cl_user1"
15940         wait $pid1
15941         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
15942 }
15943 run_test 160m "Changelog clear race"
15944
15945
15946 test_161a() {
15947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15948
15949         test_mkdir -c1 $DIR/$tdir
15950         cp /etc/hosts $DIR/$tdir/$tfile
15951         test_mkdir -c1 $DIR/$tdir/foo1
15952         test_mkdir -c1 $DIR/$tdir/foo2
15953         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15954         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15955         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15956         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15957         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15958         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15959                 $LFS fid2path $DIR $FID
15960                 error "bad link ea"
15961         fi
15962         # middle
15963         rm $DIR/$tdir/foo2/zachary
15964         # last
15965         rm $DIR/$tdir/foo2/thor
15966         # first
15967         rm $DIR/$tdir/$tfile
15968         # rename
15969         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15970         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15971                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15972         rm $DIR/$tdir/foo2/maggie
15973
15974         # overflow the EA
15975         local longname=$tfile.avg_len_is_thirty_two_
15976         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15977                 error_noexit 'failed to unlink many hardlinks'" EXIT
15978         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15979                 error "failed to hardlink many files"
15980         links=$($LFS fid2path $DIR $FID | wc -l)
15981         echo -n "${links}/1000 links in link EA"
15982         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15983 }
15984 run_test 161a "link ea sanity"
15985
15986 test_161b() {
15987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15988         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15989
15990         local MDTIDX=1
15991         local remote_dir=$DIR/$tdir/remote_dir
15992
15993         mkdir -p $DIR/$tdir
15994         $LFS mkdir -i $MDTIDX $remote_dir ||
15995                 error "create remote directory failed"
15996
15997         cp /etc/hosts $remote_dir/$tfile
15998         mkdir -p $remote_dir/foo1
15999         mkdir -p $remote_dir/foo2
16000         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16001         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16002         ln $remote_dir/$tfile $remote_dir/foo1/luna
16003         ln $remote_dir/$tfile $remote_dir/foo2/thor
16004
16005         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16006                      tr -d ']')
16007         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16008                 $LFS fid2path $DIR $FID
16009                 error "bad link ea"
16010         fi
16011         # middle
16012         rm $remote_dir/foo2/zachary
16013         # last
16014         rm $remote_dir/foo2/thor
16015         # first
16016         rm $remote_dir/$tfile
16017         # rename
16018         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16019         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16020         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16021                 $LFS fid2path $DIR $FID
16022                 error "bad link rename"
16023         fi
16024         rm $remote_dir/foo2/maggie
16025
16026         # overflow the EA
16027         local longname=filename_avg_len_is_thirty_two_
16028         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16029                 error "failed to hardlink many files"
16030         links=$($LFS fid2path $DIR $FID | wc -l)
16031         echo -n "${links}/1000 links in link EA"
16032         [[ ${links} -gt 60 ]] ||
16033                 error "expected at least 60 links in link EA"
16034         unlinkmany $remote_dir/foo2/$longname 1000 ||
16035         error "failed to unlink many hardlinks"
16036 }
16037 run_test 161b "link ea sanity under remote directory"
16038
16039 test_161c() {
16040         remote_mds_nodsh && skip "remote MDS with nodsh"
16041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16042         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16043                 skip "Need MDS version at least 2.1.5"
16044
16045         # define CLF_RENAME_LAST 0x0001
16046         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16047         changelog_register || error "changelog_register failed"
16048
16049         rm -rf $DIR/$tdir
16050         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16051         touch $DIR/$tdir/foo_161c
16052         touch $DIR/$tdir/bar_161c
16053         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16054         changelog_dump | grep RENME | tail -n 5
16055         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16056         changelog_clear 0 || error "changelog_clear failed"
16057         if [ x$flags != "x0x1" ]; then
16058                 error "flag $flags is not 0x1"
16059         fi
16060
16061         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16062         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16063         touch $DIR/$tdir/foo_161c
16064         touch $DIR/$tdir/bar_161c
16065         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16066         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16067         changelog_dump | grep RENME | tail -n 5
16068         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16069         changelog_clear 0 || error "changelog_clear failed"
16070         if [ x$flags != "x0x0" ]; then
16071                 error "flag $flags is not 0x0"
16072         fi
16073         echo "rename overwrite a target having nlink > 1," \
16074                 "changelog record has flags of $flags"
16075
16076         # rename doesn't overwrite a target (changelog flag 0x0)
16077         touch $DIR/$tdir/foo_161c
16078         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16079         changelog_dump | grep RENME | tail -n 5
16080         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16081         changelog_clear 0 || error "changelog_clear failed"
16082         if [ x$flags != "x0x0" ]; then
16083                 error "flag $flags is not 0x0"
16084         fi
16085         echo "rename doesn't overwrite a target," \
16086                 "changelog record has flags of $flags"
16087
16088         # define CLF_UNLINK_LAST 0x0001
16089         # unlink a file having nlink = 1 (changelog flag 0x1)
16090         rm -f $DIR/$tdir/foo2_161c
16091         changelog_dump | grep UNLNK | tail -n 5
16092         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16093         changelog_clear 0 || error "changelog_clear failed"
16094         if [ x$flags != "x0x1" ]; then
16095                 error "flag $flags is not 0x1"
16096         fi
16097         echo "unlink a file having nlink = 1," \
16098                 "changelog record has flags of $flags"
16099
16100         # unlink a file having nlink > 1 (changelog flag 0x0)
16101         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16102         rm -f $DIR/$tdir/foobar_161c
16103         changelog_dump | grep UNLNK | tail -n 5
16104         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16105         changelog_clear 0 || error "changelog_clear failed"
16106         if [ x$flags != "x0x0" ]; then
16107                 error "flag $flags is not 0x0"
16108         fi
16109         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16110 }
16111 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16112
16113 test_161d() {
16114         remote_mds_nodsh && skip "remote MDS with nodsh"
16115         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16116
16117         local pid
16118         local fid
16119
16120         changelog_register || error "changelog_register failed"
16121
16122         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16123         # interfer with $MOUNT/.lustre/fid/ access
16124         mkdir $DIR/$tdir
16125         [[ $? -eq 0 ]] || error "mkdir failed"
16126
16127         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16128         $LCTL set_param fail_loc=0x8000140c
16129         # 5s pause
16130         $LCTL set_param fail_val=5
16131
16132         # create file
16133         echo foofoo > $DIR/$tdir/$tfile &
16134         pid=$!
16135
16136         # wait for create to be delayed
16137         sleep 2
16138
16139         ps -p $pid
16140         [[ $? -eq 0 ]] || error "create should be blocked"
16141
16142         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16143         stack_trap "rm -f $tempfile"
16144         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16145         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16146         # some delay may occur during ChangeLog publishing and file read just
16147         # above, that could allow file write to happen finally
16148         [[ -s $tempfile ]] && echo "file should be empty"
16149
16150         $LCTL set_param fail_loc=0
16151
16152         wait $pid
16153         [[ $? -eq 0 ]] || error "create failed"
16154 }
16155 run_test 161d "create with concurrent .lustre/fid access"
16156
16157 check_path() {
16158         local expected="$1"
16159         shift
16160         local fid="$2"
16161
16162         local path
16163         path=$($LFS fid2path "$@")
16164         local rc=$?
16165
16166         if [ $rc -ne 0 ]; then
16167                 error "path looked up of '$expected' failed: rc=$rc"
16168         elif [ "$path" != "$expected" ]; then
16169                 error "path looked up '$path' instead of '$expected'"
16170         else
16171                 echo "FID '$fid' resolves to path '$path' as expected"
16172         fi
16173 }
16174
16175 test_162a() { # was test_162
16176         test_mkdir -p -c1 $DIR/$tdir/d2
16177         touch $DIR/$tdir/d2/$tfile
16178         touch $DIR/$tdir/d2/x1
16179         touch $DIR/$tdir/d2/x2
16180         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16181         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16182         # regular file
16183         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16184         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16185
16186         # softlink
16187         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16188         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16189         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16190
16191         # softlink to wrong file
16192         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16193         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16194         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16195
16196         # hardlink
16197         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16198         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16199         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16200         # fid2path dir/fsname should both work
16201         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16202         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16203
16204         # hardlink count: check that there are 2 links
16205         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16206         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16207
16208         # hardlink indexing: remove the first link
16209         rm $DIR/$tdir/d2/p/q/r/hlink
16210         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16211 }
16212 run_test 162a "path lookup sanity"
16213
16214 test_162b() {
16215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16217
16218         mkdir $DIR/$tdir
16219         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16220                                 error "create striped dir failed"
16221
16222         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16223                                         tail -n 1 | awk '{print $2}')
16224         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16225
16226         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16227         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16228
16229         # regular file
16230         for ((i=0;i<5;i++)); do
16231                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16232                         error "get fid for f$i failed"
16233                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16234
16235                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16236                         error "get fid for d$i failed"
16237                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16238         done
16239
16240         return 0
16241 }
16242 run_test 162b "striped directory path lookup sanity"
16243
16244 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16245 test_162c() {
16246         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16247                 skip "Need MDS version at least 2.7.51"
16248
16249         local lpath=$tdir.local
16250         local rpath=$tdir.remote
16251
16252         test_mkdir $DIR/$lpath
16253         test_mkdir $DIR/$rpath
16254
16255         for ((i = 0; i <= 101; i++)); do
16256                 lpath="$lpath/$i"
16257                 mkdir $DIR/$lpath
16258                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16259                         error "get fid for local directory $DIR/$lpath failed"
16260                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16261
16262                 rpath="$rpath/$i"
16263                 test_mkdir $DIR/$rpath
16264                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16265                         error "get fid for remote directory $DIR/$rpath failed"
16266                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16267         done
16268
16269         return 0
16270 }
16271 run_test 162c "fid2path works with paths 100 or more directories deep"
16272
16273 oalr_event_count() {
16274         local event="${1}"
16275         local trace="${2}"
16276
16277         awk -v name="${FSNAME}-OST0000" \
16278             -v event="${event}" \
16279             '$1 == "TRACE" && $2 == event && $3 == name' \
16280             "${trace}" |
16281         wc -l
16282 }
16283
16284 oalr_expect_event_count() {
16285         local event="${1}"
16286         local trace="${2}"
16287         local expect="${3}"
16288         local count
16289
16290         count=$(oalr_event_count "${event}" "${trace}")
16291         if ((count == expect)); then
16292                 return 0
16293         fi
16294
16295         error_noexit "${event} event count was '${count}', expected ${expect}"
16296         cat "${trace}" >&2
16297         exit 1
16298 }
16299
16300 cleanup_165() {
16301         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16302         stop ost1
16303         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16304 }
16305
16306 setup_165() {
16307         sync # Flush previous IOs so we can count log entries.
16308         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16309         stack_trap cleanup_165 EXIT
16310 }
16311
16312 test_165a() {
16313         local trace="/tmp/${tfile}.trace"
16314         local rc
16315         local count
16316
16317         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16318                 skip "OFD access log unsupported"
16319
16320         setup_165
16321         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16322         sleep 5
16323
16324         do_facet ost1 ofd_access_log_reader --list
16325         stop ost1
16326
16327         do_facet ost1 killall -TERM ofd_access_log_reader
16328         wait
16329         rc=$?
16330
16331         if ((rc != 0)); then
16332                 error "ofd_access_log_reader exited with rc = '${rc}'"
16333         fi
16334
16335         # Parse trace file for discovery events:
16336         oalr_expect_event_count alr_log_add "${trace}" 1
16337         oalr_expect_event_count alr_log_eof "${trace}" 1
16338         oalr_expect_event_count alr_log_free "${trace}" 1
16339 }
16340 run_test 165a "ofd access log discovery"
16341
16342 test_165b() {
16343         local trace="/tmp/${tfile}.trace"
16344         local file="${DIR}/${tfile}"
16345         local pfid1
16346         local pfid2
16347         local -a entry
16348         local rc
16349         local count
16350         local size
16351         local flags
16352
16353         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16354                 skip "OFD access log unsupported"
16355
16356         setup_165
16357         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16358         sleep 5
16359
16360         do_facet ost1 ofd_access_log_reader --list
16361
16362         lfs setstripe -c 1 -i 0 "${file}"
16363         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16364                 error "cannot create '${file}'"
16365
16366         sleep 5
16367         do_facet ost1 killall -TERM ofd_access_log_reader
16368         wait
16369         rc=$?
16370
16371         if ((rc != 0)); then
16372                 error "ofd_access_log_reader exited with rc = '${rc}'"
16373         fi
16374
16375         oalr_expect_event_count alr_log_entry "${trace}" 1
16376
16377         pfid1=$($LFS path2fid "${file}")
16378
16379         # 1     2             3   4    5     6   7    8    9     10
16380         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16381         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16382
16383         echo "entry = '${entry[*]}'" >&2
16384
16385         pfid2=${entry[4]}
16386         if [[ "${pfid1}" != "${pfid2}" ]]; then
16387                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16388         fi
16389
16390         size=${entry[8]}
16391         if ((size != 1048576)); then
16392                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16393         fi
16394
16395         flags=${entry[10]}
16396         if [[ "${flags}" != "w" ]]; then
16397                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16398         fi
16399
16400         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16401         sleep 5
16402
16403         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16404                 error "cannot read '${file}'"
16405         sleep 5
16406
16407         do_facet ost1 killall -TERM ofd_access_log_reader
16408         wait
16409         rc=$?
16410
16411         if ((rc != 0)); then
16412                 error "ofd_access_log_reader exited with rc = '${rc}'"
16413         fi
16414
16415         oalr_expect_event_count alr_log_entry "${trace}" 1
16416
16417         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16418         echo "entry = '${entry[*]}'" >&2
16419
16420         pfid2=${entry[4]}
16421         if [[ "${pfid1}" != "${pfid2}" ]]; then
16422                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16423         fi
16424
16425         size=${entry[8]}
16426         if ((size != 524288)); then
16427                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16428         fi
16429
16430         flags=${entry[10]}
16431         if [[ "${flags}" != "r" ]]; then
16432                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16433         fi
16434 }
16435 run_test 165b "ofd access log entries are produced and consumed"
16436
16437 test_165c() {
16438         local trace="/tmp/${tfile}.trace"
16439         local file="${DIR}/${tdir}/${tfile}"
16440
16441         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16442                 skip "OFD access log unsupported"
16443
16444         test_mkdir "${DIR}/${tdir}"
16445
16446         setup_165
16447         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16448         sleep 5
16449
16450         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16451
16452         # 4096 / 64 = 64. Create twice as many entries.
16453         for ((i = 0; i < 128; i++)); do
16454                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16455                         error "cannot create file"
16456         done
16457
16458         sync
16459
16460         do_facet ost1 killall -TERM ofd_access_log_reader
16461         wait
16462         rc=$?
16463         if ((rc != 0)); then
16464                 error "ofd_access_log_reader exited with rc = '${rc}'"
16465         fi
16466
16467         unlinkmany  "${file}-%d" 128
16468 }
16469 run_test 165c "full ofd access logs do not block IOs"
16470
16471 oal_get_read_count() {
16472         local stats="$1"
16473
16474         # STATS lustre-OST0001 alr_read_count 1
16475
16476         do_facet ost1 cat "${stats}" |
16477         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16478              END { print count; }'
16479 }
16480
16481 oal_expect_read_count() {
16482         local stats="$1"
16483         local count
16484         local expect="$2"
16485
16486         # Ask ofd_access_log_reader to write stats.
16487         do_facet ost1 killall -USR1 ofd_access_log_reader
16488
16489         # Allow some time for things to happen.
16490         sleep 1
16491
16492         count=$(oal_get_read_count "${stats}")
16493         if ((count == expect)); then
16494                 return 0
16495         fi
16496
16497         error_noexit "bad read count, got ${count}, expected ${expect}"
16498         do_facet ost1 cat "${stats}" >&2
16499         exit 1
16500 }
16501
16502 test_165d() {
16503         local stats="/tmp/${tfile}.stats"
16504         local file="${DIR}/${tdir}/${tfile}"
16505         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16506
16507         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16508                 skip "OFD access log unsupported"
16509
16510         test_mkdir "${DIR}/${tdir}"
16511
16512         setup_165
16513         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16514         sleep 5
16515
16516         lfs setstripe -c 1 -i 0 "${file}"
16517
16518         do_facet ost1 lctl set_param "${param}=rw"
16519         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16520                 error "cannot create '${file}'"
16521         oal_expect_read_count "${stats}" 1
16522
16523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16524                 error "cannot read '${file}'"
16525         oal_expect_read_count "${stats}" 2
16526
16527         do_facet ost1 lctl set_param "${param}=r"
16528         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16529                 error "cannot create '${file}'"
16530         oal_expect_read_count "${stats}" 2
16531
16532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16533                 error "cannot read '${file}'"
16534         oal_expect_read_count "${stats}" 3
16535
16536         do_facet ost1 lctl set_param "${param}=w"
16537         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16538                 error "cannot create '${file}'"
16539         oal_expect_read_count "${stats}" 4
16540
16541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16542                 error "cannot read '${file}'"
16543         oal_expect_read_count "${stats}" 4
16544
16545         do_facet ost1 lctl set_param "${param}=0"
16546         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16547                 error "cannot create '${file}'"
16548         oal_expect_read_count "${stats}" 4
16549
16550         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16551                 error "cannot read '${file}'"
16552         oal_expect_read_count "${stats}" 4
16553
16554         do_facet ost1 killall -TERM ofd_access_log_reader
16555         wait
16556         rc=$?
16557         if ((rc != 0)); then
16558                 error "ofd_access_log_reader exited with rc = '${rc}'"
16559         fi
16560 }
16561 run_test 165d "ofd_access_log mask works"
16562
16563 test_165e() {
16564         local stats="/tmp/${tfile}.stats"
16565         local file0="${DIR}/${tdir}-0/${tfile}"
16566         local file1="${DIR}/${tdir}-1/${tfile}"
16567
16568         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16569                 skip "OFD access log unsupported"
16570
16571         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16572
16573         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16574         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16575
16576         lfs setstripe -c 1 -i 0 "${file0}"
16577         lfs setstripe -c 1 -i 0 "${file1}"
16578
16579         setup_165
16580         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16581         sleep 5
16582
16583         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16584                 error "cannot create '${file0}'"
16585         sync
16586         oal_expect_read_count "${stats}" 0
16587
16588         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16589                 error "cannot create '${file1}'"
16590         sync
16591         oal_expect_read_count "${stats}" 1
16592
16593         do_facet ost1 killall -TERM ofd_access_log_reader
16594         wait
16595         rc=$?
16596         if ((rc != 0)); then
16597                 error "ofd_access_log_reader exited with rc = '${rc}'"
16598         fi
16599 }
16600 run_test 165e "ofd_access_log MDT index filter works"
16601
16602 test_165f() {
16603         local trace="/tmp/${tfile}.trace"
16604         local rc
16605         local count
16606
16607         setup_165
16608         do_facet ost1 timeout 60 ofd_access_log_reader \
16609                 --exit-on-close --debug=- --trace=- > "${trace}" &
16610         sleep 5
16611         stop ost1
16612
16613         wait
16614         rc=$?
16615
16616         if ((rc != 0)); then
16617                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16618                 cat "${trace}"
16619                 exit 1
16620         fi
16621 }
16622 run_test 165f "ofd_access_log_reader --exit-on-close works"
16623
16624 test_169() {
16625         # do directio so as not to populate the page cache
16626         log "creating a 10 Mb file"
16627         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16628                 error "multiop failed while creating a file"
16629         log "starting reads"
16630         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16631         log "truncating the file"
16632         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16633                 error "multiop failed while truncating the file"
16634         log "killing dd"
16635         kill %+ || true # reads might have finished
16636         echo "wait until dd is finished"
16637         wait
16638         log "removing the temporary file"
16639         rm -rf $DIR/$tfile || error "tmp file removal failed"
16640 }
16641 run_test 169 "parallel read and truncate should not deadlock"
16642
16643 test_170() {
16644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16645
16646         $LCTL clear     # bug 18514
16647         $LCTL debug_daemon start $TMP/${tfile}_log_good
16648         touch $DIR/$tfile
16649         $LCTL debug_daemon stop
16650         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16651                 error "sed failed to read log_good"
16652
16653         $LCTL debug_daemon start $TMP/${tfile}_log_good
16654         rm -rf $DIR/$tfile
16655         $LCTL debug_daemon stop
16656
16657         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16658                error "lctl df log_bad failed"
16659
16660         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16661         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16662
16663         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16664         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16665
16666         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16667                 error "bad_line good_line1 good_line2 are empty"
16668
16669         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16670         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16671         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16672
16673         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16674         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16675         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16676
16677         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16678                 error "bad_line_new good_line_new are empty"
16679
16680         local expected_good=$((good_line1 + good_line2*2))
16681
16682         rm -f $TMP/${tfile}*
16683         # LU-231, short malformed line may not be counted into bad lines
16684         if [ $bad_line -ne $bad_line_new ] &&
16685                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16686                 error "expected $bad_line bad lines, but got $bad_line_new"
16687                 return 1
16688         fi
16689
16690         if [ $expected_good -ne $good_line_new ]; then
16691                 error "expected $expected_good good lines, but got $good_line_new"
16692                 return 2
16693         fi
16694         true
16695 }
16696 run_test 170 "test lctl df to handle corrupted log ====================="
16697
16698 test_171() { # bug20592
16699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16700
16701         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16702         $LCTL set_param fail_loc=0x50e
16703         $LCTL set_param fail_val=3000
16704         multiop_bg_pause $DIR/$tfile O_s || true
16705         local MULTIPID=$!
16706         kill -USR1 $MULTIPID
16707         # cause log dump
16708         sleep 3
16709         wait $MULTIPID
16710         if dmesg | grep "recursive fault"; then
16711                 error "caught a recursive fault"
16712         fi
16713         $LCTL set_param fail_loc=0
16714         true
16715 }
16716 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16717
16718 # it would be good to share it with obdfilter-survey/iokit-libecho code
16719 setup_obdecho_osc () {
16720         local rc=0
16721         local ost_nid=$1
16722         local obdfilter_name=$2
16723         echo "Creating new osc for $obdfilter_name on $ost_nid"
16724         # make sure we can find loopback nid
16725         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16726
16727         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16728                            ${obdfilter_name}_osc_UUID || rc=2; }
16729         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16730                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16731         return $rc
16732 }
16733
16734 cleanup_obdecho_osc () {
16735         local obdfilter_name=$1
16736         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16737         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16738         return 0
16739 }
16740
16741 obdecho_test() {
16742         local OBD=$1
16743         local node=$2
16744         local pages=${3:-64}
16745         local rc=0
16746         local id
16747
16748         local count=10
16749         local obd_size=$(get_obd_size $node $OBD)
16750         local page_size=$(get_page_size $node)
16751         if [[ -n "$obd_size" ]]; then
16752                 local new_count=$((obd_size / (pages * page_size / 1024)))
16753                 [[ $new_count -ge $count ]] || count=$new_count
16754         fi
16755
16756         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16757         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16758                            rc=2; }
16759         if [ $rc -eq 0 ]; then
16760             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16761             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16762         fi
16763         echo "New object id is $id"
16764         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16765                            rc=4; }
16766         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16767                            "test_brw $count w v $pages $id" || rc=4; }
16768         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16769                            rc=4; }
16770         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16771                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16772         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16773                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16774         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16775         return $rc
16776 }
16777
16778 test_180a() {
16779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16780
16781         if ! [ -d /sys/fs/lustre/echo_client ] &&
16782            ! module_loaded obdecho; then
16783                 load_module obdecho/obdecho &&
16784                         stack_trap "rmmod obdecho" EXIT ||
16785                         error "unable to load obdecho on client"
16786         fi
16787
16788         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16789         local host=$($LCTL get_param -n osc.$osc.import |
16790                      awk '/current_connection:/ { print $2 }' )
16791         local target=$($LCTL get_param -n osc.$osc.import |
16792                        awk '/target:/ { print $2 }' )
16793         target=${target%_UUID}
16794
16795         if [ -n "$target" ]; then
16796                 setup_obdecho_osc $host $target &&
16797                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16798                         { error "obdecho setup failed with $?"; return; }
16799
16800                 obdecho_test ${target}_osc client ||
16801                         error "obdecho_test failed on ${target}_osc"
16802         else
16803                 $LCTL get_param osc.$osc.import
16804                 error "there is no osc.$osc.import target"
16805         fi
16806 }
16807 run_test 180a "test obdecho on osc"
16808
16809 test_180b() {
16810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16811         remote_ost_nodsh && skip "remote OST with nodsh"
16812
16813         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16814                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16815                 error "failed to load module obdecho"
16816
16817         local target=$(do_facet ost1 $LCTL dl |
16818                        awk '/obdfilter/ { print $4; exit; }')
16819
16820         if [ -n "$target" ]; then
16821                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16822         else
16823                 do_facet ost1 $LCTL dl
16824                 error "there is no obdfilter target on ost1"
16825         fi
16826 }
16827 run_test 180b "test obdecho directly on obdfilter"
16828
16829 test_180c() { # LU-2598
16830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16831         remote_ost_nodsh && skip "remote OST with nodsh"
16832         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16833                 skip "Need MDS version at least 2.4.0"
16834
16835         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16836                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16837                 error "failed to load module obdecho"
16838
16839         local target=$(do_facet ost1 $LCTL dl |
16840                        awk '/obdfilter/ { print $4; exit; }')
16841
16842         if [ -n "$target" ]; then
16843                 local pages=16384 # 64MB bulk I/O RPC size
16844
16845                 obdecho_test "$target" ost1 "$pages" ||
16846                         error "obdecho_test with pages=$pages failed with $?"
16847         else
16848                 do_facet ost1 $LCTL dl
16849                 error "there is no obdfilter target on ost1"
16850         fi
16851 }
16852 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16853
16854 test_181() { # bug 22177
16855         test_mkdir $DIR/$tdir
16856         # create enough files to index the directory
16857         createmany -o $DIR/$tdir/foobar 4000
16858         # print attributes for debug purpose
16859         lsattr -d .
16860         # open dir
16861         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16862         MULTIPID=$!
16863         # remove the files & current working dir
16864         unlinkmany $DIR/$tdir/foobar 4000
16865         rmdir $DIR/$tdir
16866         kill -USR1 $MULTIPID
16867         wait $MULTIPID
16868         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16869         return 0
16870 }
16871 run_test 181 "Test open-unlinked dir ========================"
16872
16873 test_182() {
16874         local fcount=1000
16875         local tcount=10
16876
16877         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16878
16879         $LCTL set_param mdc.*.rpc_stats=clear
16880
16881         for (( i = 0; i < $tcount; i++ )) ; do
16882                 mkdir $DIR/$tdir/$i
16883         done
16884
16885         for (( i = 0; i < $tcount; i++ )) ; do
16886                 createmany -o $DIR/$tdir/$i/f- $fcount &
16887         done
16888         wait
16889
16890         for (( i = 0; i < $tcount; i++ )) ; do
16891                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16892         done
16893         wait
16894
16895         $LCTL get_param mdc.*.rpc_stats
16896
16897         rm -rf $DIR/$tdir
16898 }
16899 run_test 182 "Test parallel modify metadata operations ================"
16900
16901 test_183() { # LU-2275
16902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16903         remote_mds_nodsh && skip "remote MDS with nodsh"
16904         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16905                 skip "Need MDS version at least 2.3.56"
16906
16907         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16908         echo aaa > $DIR/$tdir/$tfile
16909
16910 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16911         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16912
16913         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16914         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16915
16916         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16917
16918         # Flush negative dentry cache
16919         touch $DIR/$tdir/$tfile
16920
16921         # We are not checking for any leaked references here, they'll
16922         # become evident next time we do cleanup with module unload.
16923         rm -rf $DIR/$tdir
16924 }
16925 run_test 183 "No crash or request leak in case of strange dispositions ========"
16926
16927 # test suite 184 is for LU-2016, LU-2017
16928 test_184a() {
16929         check_swap_layouts_support
16930
16931         dir0=$DIR/$tdir/$testnum
16932         test_mkdir -p -c1 $dir0
16933         ref1=/etc/passwd
16934         ref2=/etc/group
16935         file1=$dir0/f1
16936         file2=$dir0/f2
16937         $LFS setstripe -c1 $file1
16938         cp $ref1 $file1
16939         $LFS setstripe -c2 $file2
16940         cp $ref2 $file2
16941         gen1=$($LFS getstripe -g $file1)
16942         gen2=$($LFS getstripe -g $file2)
16943
16944         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16945         gen=$($LFS getstripe -g $file1)
16946         [[ $gen1 != $gen ]] ||
16947                 "Layout generation on $file1 does not change"
16948         gen=$($LFS getstripe -g $file2)
16949         [[ $gen2 != $gen ]] ||
16950                 "Layout generation on $file2 does not change"
16951
16952         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16953         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16954
16955         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16956 }
16957 run_test 184a "Basic layout swap"
16958
16959 test_184b() {
16960         check_swap_layouts_support
16961
16962         dir0=$DIR/$tdir/$testnum
16963         mkdir -p $dir0 || error "creating dir $dir0"
16964         file1=$dir0/f1
16965         file2=$dir0/f2
16966         file3=$dir0/f3
16967         dir1=$dir0/d1
16968         dir2=$dir0/d2
16969         mkdir $dir1 $dir2
16970         $LFS setstripe -c1 $file1
16971         $LFS setstripe -c2 $file2
16972         $LFS setstripe -c1 $file3
16973         chown $RUNAS_ID $file3
16974         gen1=$($LFS getstripe -g $file1)
16975         gen2=$($LFS getstripe -g $file2)
16976
16977         $LFS swap_layouts $dir1 $dir2 &&
16978                 error "swap of directories layouts should fail"
16979         $LFS swap_layouts $dir1 $file1 &&
16980                 error "swap of directory and file layouts should fail"
16981         $RUNAS $LFS swap_layouts $file1 $file2 &&
16982                 error "swap of file we cannot write should fail"
16983         $LFS swap_layouts $file1 $file3 &&
16984                 error "swap of file with different owner should fail"
16985         /bin/true # to clear error code
16986 }
16987 run_test 184b "Forbidden layout swap (will generate errors)"
16988
16989 test_184c() {
16990         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16991         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16992         check_swap_layouts_support
16993         check_swap_layout_no_dom $DIR
16994
16995         local dir0=$DIR/$tdir/$testnum
16996         mkdir -p $dir0 || error "creating dir $dir0"
16997
16998         local ref1=$dir0/ref1
16999         local ref2=$dir0/ref2
17000         local file1=$dir0/file1
17001         local file2=$dir0/file2
17002         # create a file large enough for the concurrent test
17003         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17004         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17005         echo "ref file size: ref1($(stat -c %s $ref1))," \
17006              "ref2($(stat -c %s $ref2))"
17007
17008         cp $ref2 $file2
17009         dd if=$ref1 of=$file1 bs=16k &
17010         local DD_PID=$!
17011
17012         # Make sure dd starts to copy file, but wait at most 5 seconds
17013         local loops=0
17014         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17015
17016         $LFS swap_layouts $file1 $file2
17017         local rc=$?
17018         wait $DD_PID
17019         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17020         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17021
17022         # how many bytes copied before swapping layout
17023         local copied=$(stat -c %s $file2)
17024         local remaining=$(stat -c %s $ref1)
17025         remaining=$((remaining - copied))
17026         echo "Copied $copied bytes before swapping layout..."
17027
17028         cmp -n $copied $file1 $ref2 | grep differ &&
17029                 error "Content mismatch [0, $copied) of ref2 and file1"
17030         cmp -n $copied $file2 $ref1 ||
17031                 error "Content mismatch [0, $copied) of ref1 and file2"
17032         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17033                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17034
17035         # clean up
17036         rm -f $ref1 $ref2 $file1 $file2
17037 }
17038 run_test 184c "Concurrent write and layout swap"
17039
17040 test_184d() {
17041         check_swap_layouts_support
17042         check_swap_layout_no_dom $DIR
17043         [ -z "$(which getfattr 2>/dev/null)" ] &&
17044                 skip_env "no getfattr command"
17045
17046         local file1=$DIR/$tdir/$tfile-1
17047         local file2=$DIR/$tdir/$tfile-2
17048         local file3=$DIR/$tdir/$tfile-3
17049         local lovea1
17050         local lovea2
17051
17052         mkdir -p $DIR/$tdir
17053         touch $file1 || error "create $file1 failed"
17054         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17055                 error "create $file2 failed"
17056         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17057                 error "create $file3 failed"
17058         lovea1=$(get_layout_param $file1)
17059
17060         $LFS swap_layouts $file2 $file3 ||
17061                 error "swap $file2 $file3 layouts failed"
17062         $LFS swap_layouts $file1 $file2 ||
17063                 error "swap $file1 $file2 layouts failed"
17064
17065         lovea2=$(get_layout_param $file2)
17066         echo "$lovea1"
17067         echo "$lovea2"
17068         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17069
17070         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17071         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17072 }
17073 run_test 184d "allow stripeless layouts swap"
17074
17075 test_184e() {
17076         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17077                 skip "Need MDS version at least 2.6.94"
17078         check_swap_layouts_support
17079         check_swap_layout_no_dom $DIR
17080         [ -z "$(which getfattr 2>/dev/null)" ] &&
17081                 skip_env "no getfattr command"
17082
17083         local file1=$DIR/$tdir/$tfile-1
17084         local file2=$DIR/$tdir/$tfile-2
17085         local file3=$DIR/$tdir/$tfile-3
17086         local lovea
17087
17088         mkdir -p $DIR/$tdir
17089         touch $file1 || error "create $file1 failed"
17090         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17091                 error "create $file2 failed"
17092         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17093                 error "create $file3 failed"
17094
17095         $LFS swap_layouts $file1 $file2 ||
17096                 error "swap $file1 $file2 layouts failed"
17097
17098         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17099         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17100
17101         echo 123 > $file1 || error "Should be able to write into $file1"
17102
17103         $LFS swap_layouts $file1 $file3 ||
17104                 error "swap $file1 $file3 layouts failed"
17105
17106         echo 123 > $file1 || error "Should be able to write into $file1"
17107
17108         rm -rf $file1 $file2 $file3
17109 }
17110 run_test 184e "Recreate layout after stripeless layout swaps"
17111
17112 test_184f() {
17113         # Create a file with name longer than sizeof(struct stat) ==
17114         # 144 to see if we can get chars from the file name to appear
17115         # in the returned striping. Note that 'f' == 0x66.
17116         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17117
17118         mkdir -p $DIR/$tdir
17119         mcreate $DIR/$tdir/$file
17120         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17121                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17122         fi
17123 }
17124 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17125
17126 test_185() { # LU-2441
17127         # LU-3553 - no volatile file support in old servers
17128         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17129                 skip "Need MDS version at least 2.3.60"
17130
17131         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17132         touch $DIR/$tdir/spoo
17133         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17134         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17135                 error "cannot create/write a volatile file"
17136         [ "$FILESET" == "" ] &&
17137         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17138                 error "FID is still valid after close"
17139
17140         multiop_bg_pause $DIR/$tdir vVw4096_c
17141         local multi_pid=$!
17142
17143         local OLD_IFS=$IFS
17144         IFS=":"
17145         local fidv=($fid)
17146         IFS=$OLD_IFS
17147         # assume that the next FID for this client is sequential, since stdout
17148         # is unfortunately eaten by multiop_bg_pause
17149         local n=$((${fidv[1]} + 1))
17150         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17151         if [ "$FILESET" == "" ]; then
17152                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17153                         error "FID is missing before close"
17154         fi
17155         kill -USR1 $multi_pid
17156         # 1 second delay, so if mtime change we will see it
17157         sleep 1
17158         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17159         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17160 }
17161 run_test 185 "Volatile file support"
17162
17163 function create_check_volatile() {
17164         local idx=$1
17165         local tgt
17166
17167         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17168         local PID=$!
17169         sleep 1
17170         local FID=$(cat /tmp/${tfile}.fid)
17171         [ "$FID" == "" ] && error "can't get FID for volatile"
17172         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17173         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17174         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17175         kill -USR1 $PID
17176         wait
17177         sleep 1
17178         cancel_lru_locks mdc # flush opencache
17179         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17180         return 0
17181 }
17182
17183 test_185a(){
17184         # LU-12516 - volatile creation via .lustre
17185         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17186                 skip "Need MDS version at least 2.3.55"
17187
17188         create_check_volatile 0
17189         [ $MDSCOUNT -lt 2 ] && return 0
17190
17191         # DNE case
17192         create_check_volatile 1
17193
17194         return 0
17195 }
17196 run_test 185a "Volatile file creation in .lustre/fid/"
17197
17198 test_187a() {
17199         remote_mds_nodsh && skip "remote MDS with nodsh"
17200         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17201                 skip "Need MDS version at least 2.3.0"
17202
17203         local dir0=$DIR/$tdir/$testnum
17204         mkdir -p $dir0 || error "creating dir $dir0"
17205
17206         local file=$dir0/file1
17207         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17208         local dv1=$($LFS data_version $file)
17209         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17210         local dv2=$($LFS data_version $file)
17211         [[ $dv1 != $dv2 ]] ||
17212                 error "data version did not change on write $dv1 == $dv2"
17213
17214         # clean up
17215         rm -f $file1
17216 }
17217 run_test 187a "Test data version change"
17218
17219 test_187b() {
17220         remote_mds_nodsh && skip "remote MDS with nodsh"
17221         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17222                 skip "Need MDS version at least 2.3.0"
17223
17224         local dir0=$DIR/$tdir/$testnum
17225         mkdir -p $dir0 || error "creating dir $dir0"
17226
17227         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17228         [[ ${DV[0]} != ${DV[1]} ]] ||
17229                 error "data version did not change on write"\
17230                       " ${DV[0]} == ${DV[1]}"
17231
17232         # clean up
17233         rm -f $file1
17234 }
17235 run_test 187b "Test data version change on volatile file"
17236
17237 test_200() {
17238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17239         remote_mgs_nodsh && skip "remote MGS with nodsh"
17240         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17241
17242         local POOL=${POOL:-cea1}
17243         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17244         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17245         # Pool OST targets
17246         local first_ost=0
17247         local last_ost=$(($OSTCOUNT - 1))
17248         local ost_step=2
17249         local ost_list=$(seq $first_ost $ost_step $last_ost)
17250         local ost_range="$first_ost $last_ost $ost_step"
17251         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17252         local file_dir=$POOL_ROOT/file_tst
17253         local subdir=$test_path/subdir
17254         local rc=0
17255
17256         while : ; do
17257                 # former test_200a test_200b
17258                 pool_add $POOL                          || { rc=$? ; break; }
17259                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17260                 # former test_200c test_200d
17261                 mkdir -p $test_path
17262                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17263                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17264                 mkdir -p $subdir
17265                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17266                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17267                                                         || { rc=$? ; break; }
17268                 # former test_200e test_200f
17269                 local files=$((OSTCOUNT*3))
17270                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17271                                                         || { rc=$? ; break; }
17272                 pool_create_files $POOL $file_dir $files "$ost_list" \
17273                                                         || { rc=$? ; break; }
17274                 # former test_200g test_200h
17275                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17276                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17277
17278                 # former test_201a test_201b test_201c
17279                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17280
17281                 local f=$test_path/$tfile
17282                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17283                 pool_remove $POOL $f                    || { rc=$? ; break; }
17284                 break
17285         done
17286
17287         destroy_test_pools
17288
17289         return $rc
17290 }
17291 run_test 200 "OST pools"
17292
17293 # usage: default_attr <count | size | offset>
17294 default_attr() {
17295         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17296 }
17297
17298 # usage: check_default_stripe_attr
17299 check_default_stripe_attr() {
17300         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17301         case $1 in
17302         --stripe-count|-c)
17303                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17304         --stripe-size|-S)
17305                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17306         --stripe-index|-i)
17307                 EXPECTED=-1;;
17308         *)
17309                 error "unknown getstripe attr '$1'"
17310         esac
17311
17312         [ $ACTUAL == $EXPECTED ] ||
17313                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17314 }
17315
17316 test_204a() {
17317         test_mkdir $DIR/$tdir
17318         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17319
17320         check_default_stripe_attr --stripe-count
17321         check_default_stripe_attr --stripe-size
17322         check_default_stripe_attr --stripe-index
17323 }
17324 run_test 204a "Print default stripe attributes"
17325
17326 test_204b() {
17327         test_mkdir $DIR/$tdir
17328         $LFS setstripe --stripe-count 1 $DIR/$tdir
17329
17330         check_default_stripe_attr --stripe-size
17331         check_default_stripe_attr --stripe-index
17332 }
17333 run_test 204b "Print default stripe size and offset"
17334
17335 test_204c() {
17336         test_mkdir $DIR/$tdir
17337         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17338
17339         check_default_stripe_attr --stripe-count
17340         check_default_stripe_attr --stripe-index
17341 }
17342 run_test 204c "Print default stripe count and offset"
17343
17344 test_204d() {
17345         test_mkdir $DIR/$tdir
17346         $LFS setstripe --stripe-index 0 $DIR/$tdir
17347
17348         check_default_stripe_attr --stripe-count
17349         check_default_stripe_attr --stripe-size
17350 }
17351 run_test 204d "Print default stripe count and size"
17352
17353 test_204e() {
17354         test_mkdir $DIR/$tdir
17355         $LFS setstripe -d $DIR/$tdir
17356
17357         check_default_stripe_attr --stripe-count --raw
17358         check_default_stripe_attr --stripe-size --raw
17359         check_default_stripe_attr --stripe-index --raw
17360 }
17361 run_test 204e "Print raw stripe attributes"
17362
17363 test_204f() {
17364         test_mkdir $DIR/$tdir
17365         $LFS setstripe --stripe-count 1 $DIR/$tdir
17366
17367         check_default_stripe_attr --stripe-size --raw
17368         check_default_stripe_attr --stripe-index --raw
17369 }
17370 run_test 204f "Print raw stripe size and offset"
17371
17372 test_204g() {
17373         test_mkdir $DIR/$tdir
17374         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17375
17376         check_default_stripe_attr --stripe-count --raw
17377         check_default_stripe_attr --stripe-index --raw
17378 }
17379 run_test 204g "Print raw stripe count and offset"
17380
17381 test_204h() {
17382         test_mkdir $DIR/$tdir
17383         $LFS setstripe --stripe-index 0 $DIR/$tdir
17384
17385         check_default_stripe_attr --stripe-count --raw
17386         check_default_stripe_attr --stripe-size --raw
17387 }
17388 run_test 204h "Print raw stripe count and size"
17389
17390 # Figure out which job scheduler is being used, if any,
17391 # or use a fake one
17392 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17393         JOBENV=SLURM_JOB_ID
17394 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17395         JOBENV=LSB_JOBID
17396 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17397         JOBENV=PBS_JOBID
17398 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17399         JOBENV=LOADL_STEP_ID
17400 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17401         JOBENV=JOB_ID
17402 else
17403         $LCTL list_param jobid_name > /dev/null 2>&1
17404         if [ $? -eq 0 ]; then
17405                 JOBENV=nodelocal
17406         else
17407                 JOBENV=FAKE_JOBID
17408         fi
17409 fi
17410 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17411
17412 verify_jobstats() {
17413         local cmd=($1)
17414         shift
17415         local facets="$@"
17416
17417 # we don't really need to clear the stats for this test to work, since each
17418 # command has a unique jobid, but it makes debugging easier if needed.
17419 #       for facet in $facets; do
17420 #               local dev=$(convert_facet2label $facet)
17421 #               # clear old jobstats
17422 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17423 #       done
17424
17425         # use a new JobID for each test, or we might see an old one
17426         [ "$JOBENV" = "FAKE_JOBID" ] &&
17427                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17428
17429         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17430
17431         [ "$JOBENV" = "nodelocal" ] && {
17432                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17433                 $LCTL set_param jobid_name=$FAKE_JOBID
17434                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17435         }
17436
17437         log "Test: ${cmd[*]}"
17438         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17439
17440         if [ $JOBENV = "FAKE_JOBID" ]; then
17441                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17442         else
17443                 ${cmd[*]}
17444         fi
17445
17446         # all files are created on OST0000
17447         for facet in $facets; do
17448                 local stats="*.$(convert_facet2label $facet).job_stats"
17449
17450                 # strip out libtool wrappers for in-tree executables
17451                 if [ $(do_facet $facet lctl get_param $stats |
17452                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17453                         do_facet $facet lctl get_param $stats
17454                         error "No jobstats for $JOBVAL found on $facet::$stats"
17455                 fi
17456         done
17457 }
17458
17459 jobstats_set() {
17460         local new_jobenv=$1
17461
17462         set_persistent_param_and_check client "jobid_var" \
17463                 "$FSNAME.sys.jobid_var" $new_jobenv
17464 }
17465
17466 test_205a() { # Job stats
17467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17468         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17469                 skip "Need MDS version with at least 2.7.1"
17470         remote_mgs_nodsh && skip "remote MGS with nodsh"
17471         remote_mds_nodsh && skip "remote MDS with nodsh"
17472         remote_ost_nodsh && skip "remote OST with nodsh"
17473         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17474                 skip "Server doesn't support jobstats"
17475         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17476
17477         local old_jobenv=$($LCTL get_param -n jobid_var)
17478         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17479
17480         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17481                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17482         else
17483                 stack_trap "do_facet mgs $PERM_CMD \
17484                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17485         fi
17486         changelog_register
17487
17488         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17489                                 mdt.*.job_cleanup_interval | head -n 1)
17490         local new_interval=5
17491         do_facet $SINGLEMDS \
17492                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17493         stack_trap "do_facet $SINGLEMDS \
17494                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17495         local start=$SECONDS
17496
17497         local cmd
17498         # mkdir
17499         cmd="mkdir $DIR/$tdir"
17500         verify_jobstats "$cmd" "$SINGLEMDS"
17501         # rmdir
17502         cmd="rmdir $DIR/$tdir"
17503         verify_jobstats "$cmd" "$SINGLEMDS"
17504         # mkdir on secondary MDT
17505         if [ $MDSCOUNT -gt 1 ]; then
17506                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17507                 verify_jobstats "$cmd" "mds2"
17508         fi
17509         # mknod
17510         cmd="mknod $DIR/$tfile c 1 3"
17511         verify_jobstats "$cmd" "$SINGLEMDS"
17512         # unlink
17513         cmd="rm -f $DIR/$tfile"
17514         verify_jobstats "$cmd" "$SINGLEMDS"
17515         # create all files on OST0000 so verify_jobstats can find OST stats
17516         # open & close
17517         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17518         verify_jobstats "$cmd" "$SINGLEMDS"
17519         # setattr
17520         cmd="touch $DIR/$tfile"
17521         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17522         # write
17523         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17524         verify_jobstats "$cmd" "ost1"
17525         # read
17526         cancel_lru_locks osc
17527         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17528         verify_jobstats "$cmd" "ost1"
17529         # truncate
17530         cmd="$TRUNCATE $DIR/$tfile 0"
17531         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17532         # rename
17533         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17534         verify_jobstats "$cmd" "$SINGLEMDS"
17535         # jobstats expiry - sleep until old stats should be expired
17536         local left=$((new_interval + 5 - (SECONDS - start)))
17537         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17538                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17539                         "0" $left
17540         cmd="mkdir $DIR/$tdir.expire"
17541         verify_jobstats "$cmd" "$SINGLEMDS"
17542         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17543             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17544
17545         # Ensure that jobid are present in changelog (if supported by MDS)
17546         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17547                 changelog_dump | tail -10
17548                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17549                 [ $jobids -eq 9 ] ||
17550                         error "Wrong changelog jobid count $jobids != 9"
17551
17552                 # LU-5862
17553                 JOBENV="disable"
17554                 jobstats_set $JOBENV
17555                 touch $DIR/$tfile
17556                 changelog_dump | grep $tfile
17557                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17558                 [ $jobids -eq 0 ] ||
17559                         error "Unexpected jobids when jobid_var=$JOBENV"
17560         fi
17561
17562         # test '%j' access to environment variable - if supported
17563         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17564                 JOBENV="JOBCOMPLEX"
17565                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17566
17567                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17568         fi
17569
17570         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17571                 JOBENV="JOBCOMPLEX"
17572                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17573
17574                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17575         fi
17576
17577         # test '%j' access to per-session jobid - if supported
17578         if lctl list_param jobid_this_session > /dev/null 2>&1
17579         then
17580                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17581                 lctl set_param jobid_this_session=$USER
17582
17583                 JOBENV="JOBCOMPLEX"
17584                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17585
17586                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17587         fi
17588 }
17589 run_test 205a "Verify job stats"
17590
17591 # LU-13117, LU-13597
17592 test_205b() {
17593         job_stats="mdt.*.job_stats"
17594         $LCTL set_param $job_stats=clear
17595         # Setting jobid_var to USER might not be supported
17596         $LCTL set_param jobid_var=USER || true
17597         $LCTL set_param jobid_name="%e.%u"
17598         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17599         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17600                 grep "job_id:.*foolish" &&
17601                         error "Unexpected jobid found"
17602         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17603                 grep "open:.*min.*max.*sum" ||
17604                         error "wrong job_stats format found"
17605 }
17606 run_test 205b "Verify job stats jobid and output format"
17607
17608 # LU-13733
17609 test_205c() {
17610         $LCTL set_param llite.*.stats=0
17611         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17612         $LCTL get_param llite.*.stats
17613         $LCTL get_param llite.*.stats | grep \
17614                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17615                         error "wrong client stats format found"
17616 }
17617 run_test 205c "Verify client stats format"
17618
17619 # LU-1480, LU-1773 and LU-1657
17620 test_206() {
17621         mkdir -p $DIR/$tdir
17622         $LFS setstripe -c -1 $DIR/$tdir
17623 #define OBD_FAIL_LOV_INIT 0x1403
17624         $LCTL set_param fail_loc=0xa0001403
17625         $LCTL set_param fail_val=1
17626         touch $DIR/$tdir/$tfile || true
17627 }
17628 run_test 206 "fail lov_init_raid0() doesn't lbug"
17629
17630 test_207a() {
17631         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17632         local fsz=`stat -c %s $DIR/$tfile`
17633         cancel_lru_locks mdc
17634
17635         # do not return layout in getattr intent
17636 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17637         $LCTL set_param fail_loc=0x170
17638         local sz=`stat -c %s $DIR/$tfile`
17639
17640         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17641
17642         rm -rf $DIR/$tfile
17643 }
17644 run_test 207a "can refresh layout at glimpse"
17645
17646 test_207b() {
17647         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17648         local cksum=`md5sum $DIR/$tfile`
17649         local fsz=`stat -c %s $DIR/$tfile`
17650         cancel_lru_locks mdc
17651         cancel_lru_locks osc
17652
17653         # do not return layout in getattr intent
17654 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17655         $LCTL set_param fail_loc=0x171
17656
17657         # it will refresh layout after the file is opened but before read issues
17658         echo checksum is "$cksum"
17659         echo "$cksum" |md5sum -c --quiet || error "file differs"
17660
17661         rm -rf $DIR/$tfile
17662 }
17663 run_test 207b "can refresh layout at open"
17664
17665 test_208() {
17666         # FIXME: in this test suite, only RD lease is used. This is okay
17667         # for now as only exclusive open is supported. After generic lease
17668         # is done, this test suite should be revised. - Jinshan
17669
17670         remote_mds_nodsh && skip "remote MDS with nodsh"
17671         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17672                 skip "Need MDS version at least 2.4.52"
17673
17674         echo "==== test 1: verify get lease work"
17675         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17676
17677         echo "==== test 2: verify lease can be broken by upcoming open"
17678         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17679         local PID=$!
17680         sleep 1
17681
17682         $MULTIOP $DIR/$tfile oO_RDONLY:c
17683         kill -USR1 $PID && wait $PID || error "break lease error"
17684
17685         echo "==== test 3: verify lease can't be granted if an open already exists"
17686         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17687         local PID=$!
17688         sleep 1
17689
17690         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17691         kill -USR1 $PID && wait $PID || error "open file error"
17692
17693         echo "==== test 4: lease can sustain over recovery"
17694         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17695         PID=$!
17696         sleep 1
17697
17698         fail mds1
17699
17700         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17701
17702         echo "==== test 5: lease broken can't be regained by replay"
17703         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17704         PID=$!
17705         sleep 1
17706
17707         # open file to break lease and then recovery
17708         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17709         fail mds1
17710
17711         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17712
17713         rm -f $DIR/$tfile
17714 }
17715 run_test 208 "Exclusive open"
17716
17717 test_209() {
17718         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17719                 skip_env "must have disp_stripe"
17720
17721         touch $DIR/$tfile
17722         sync; sleep 5; sync;
17723
17724         echo 3 > /proc/sys/vm/drop_caches
17725         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17726                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17727         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17728
17729         # open/close 500 times
17730         for i in $(seq 500); do
17731                 cat $DIR/$tfile
17732         done
17733
17734         echo 3 > /proc/sys/vm/drop_caches
17735         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17736                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17737         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17738
17739         echo "before: $req_before, after: $req_after"
17740         [ $((req_after - req_before)) -ge 300 ] &&
17741                 error "open/close requests are not freed"
17742         return 0
17743 }
17744 run_test 209 "read-only open/close requests should be freed promptly"
17745
17746 test_210() {
17747         local pid
17748
17749         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17750         pid=$!
17751         sleep 1
17752
17753         $LFS getstripe $DIR/$tfile
17754         kill -USR1 $pid
17755         wait $pid || error "multiop failed"
17756
17757         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17758         pid=$!
17759         sleep 1
17760
17761         $LFS getstripe $DIR/$tfile
17762         kill -USR1 $pid
17763         wait $pid || error "multiop failed"
17764 }
17765 run_test 210 "lfs getstripe does not break leases"
17766
17767 test_212() {
17768         size=`date +%s`
17769         size=$((size % 8192 + 1))
17770         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17771         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17772         rm -f $DIR/f212 $DIR/f212.xyz
17773 }
17774 run_test 212 "Sendfile test ============================================"
17775
17776 test_213() {
17777         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17778         cancel_lru_locks osc
17779         lctl set_param fail_loc=0x8000040f
17780         # generate a read lock
17781         cat $DIR/$tfile > /dev/null
17782         # write to the file, it will try to cancel the above read lock.
17783         cat /etc/hosts >> $DIR/$tfile
17784 }
17785 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17786
17787 test_214() { # for bug 20133
17788         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17789         for (( i=0; i < 340; i++ )) ; do
17790                 touch $DIR/$tdir/d214c/a$i
17791         done
17792
17793         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17794         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17795         ls $DIR/d214c || error "ls $DIR/d214c failed"
17796         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17797         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17798 }
17799 run_test 214 "hash-indexed directory test - bug 20133"
17800
17801 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17802 create_lnet_proc_files() {
17803         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17804 }
17805
17806 # counterpart of create_lnet_proc_files
17807 remove_lnet_proc_files() {
17808         rm -f $TMP/lnet_$1.sys
17809 }
17810
17811 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17812 # 3rd arg as regexp for body
17813 check_lnet_proc_stats() {
17814         local l=$(cat "$TMP/lnet_$1" |wc -l)
17815         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17816
17817         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17818 }
17819
17820 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17821 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17822 # optional and can be regexp for 2nd line (lnet.routes case)
17823 check_lnet_proc_entry() {
17824         local blp=2          # blp stands for 'position of 1st line of body'
17825         [ -z "$5" ] || blp=3 # lnet.routes case
17826
17827         local l=$(cat "$TMP/lnet_$1" |wc -l)
17828         # subtracting one from $blp because the body can be empty
17829         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17830
17831         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17832                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17833
17834         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17835                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17836
17837         # bail out if any unexpected line happened
17838         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17839         [ "$?" != 0 ] || error "$2 misformatted"
17840 }
17841
17842 test_215() { # for bugs 18102, 21079, 21517
17843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17844
17845         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17846         local P='[1-9][0-9]*'           # positive numeric
17847         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17848         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17849         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17850         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17851
17852         local L1 # regexp for 1st line
17853         local L2 # regexp for 2nd line (optional)
17854         local BR # regexp for the rest (body)
17855
17856         # lnet.stats should look as 11 space-separated non-negative numerics
17857         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17858         create_lnet_proc_files "stats"
17859         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17860         remove_lnet_proc_files "stats"
17861
17862         # lnet.routes should look like this:
17863         # Routing disabled/enabled
17864         # net hops priority state router
17865         # where net is a string like tcp0, hops > 0, priority >= 0,
17866         # state is up/down,
17867         # router is a string like 192.168.1.1@tcp2
17868         L1="^Routing (disabled|enabled)$"
17869         L2="^net +hops +priority +state +router$"
17870         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17871         create_lnet_proc_files "routes"
17872         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17873         remove_lnet_proc_files "routes"
17874
17875         # lnet.routers should look like this:
17876         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17877         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17878         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17879         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17880         L1="^ref +rtr_ref +alive +router$"
17881         BR="^$P +$P +(up|down) +$NID$"
17882         create_lnet_proc_files "routers"
17883         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17884         remove_lnet_proc_files "routers"
17885
17886         # lnet.peers should look like this:
17887         # nid refs state last max rtr min tx min queue
17888         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17889         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17890         # numeric (0 or >0 or <0), queue >= 0.
17891         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17892         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17893         create_lnet_proc_files "peers"
17894         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17895         remove_lnet_proc_files "peers"
17896
17897         # lnet.buffers  should look like this:
17898         # pages count credits min
17899         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17900         L1="^pages +count +credits +min$"
17901         BR="^ +$N +$N +$I +$I$"
17902         create_lnet_proc_files "buffers"
17903         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17904         remove_lnet_proc_files "buffers"
17905
17906         # lnet.nis should look like this:
17907         # nid status alive refs peer rtr max tx min
17908         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17909         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17910         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17911         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17912         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17913         create_lnet_proc_files "nis"
17914         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17915         remove_lnet_proc_files "nis"
17916
17917         # can we successfully write to lnet.stats?
17918         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17919 }
17920 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17921
17922 test_216() { # bug 20317
17923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17924         remote_ost_nodsh && skip "remote OST with nodsh"
17925
17926         local node
17927         local facets=$(get_facets OST)
17928         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17929
17930         save_lustre_params client "osc.*.contention_seconds" > $p
17931         save_lustre_params $facets \
17932                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17933         save_lustre_params $facets \
17934                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17935         save_lustre_params $facets \
17936                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17937         clear_stats osc.*.osc_stats
17938
17939         # agressive lockless i/o settings
17940         do_nodes $(comma_list $(osts_nodes)) \
17941                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17942                         ldlm.namespaces.filter-*.contended_locks=0 \
17943                         ldlm.namespaces.filter-*.contention_seconds=60"
17944         lctl set_param -n osc.*.contention_seconds=60
17945
17946         $DIRECTIO write $DIR/$tfile 0 10 4096
17947         $CHECKSTAT -s 40960 $DIR/$tfile
17948
17949         # disable lockless i/o
17950         do_nodes $(comma_list $(osts_nodes)) \
17951                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17952                         ldlm.namespaces.filter-*.contended_locks=32 \
17953                         ldlm.namespaces.filter-*.contention_seconds=0"
17954         lctl set_param -n osc.*.contention_seconds=0
17955         clear_stats osc.*.osc_stats
17956
17957         dd if=/dev/zero of=$DIR/$tfile count=0
17958         $CHECKSTAT -s 0 $DIR/$tfile
17959
17960         restore_lustre_params <$p
17961         rm -f $p
17962         rm $DIR/$tfile
17963 }
17964 run_test 216 "check lockless direct write updates file size and kms correctly"
17965
17966 test_217() { # bug 22430
17967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17968
17969         local node
17970         local nid
17971
17972         for node in $(nodes_list); do
17973                 nid=$(host_nids_address $node $NETTYPE)
17974                 if [[ $nid = *-* ]] ; then
17975                         echo "lctl ping $(h2nettype $nid)"
17976                         lctl ping $(h2nettype $nid)
17977                 else
17978                         echo "skipping $node (no hyphen detected)"
17979                 fi
17980         done
17981 }
17982 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17983
17984 test_218() {
17985        # do directio so as not to populate the page cache
17986        log "creating a 10 Mb file"
17987        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17988        log "starting reads"
17989        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17990        log "truncating the file"
17991        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17992        log "killing dd"
17993        kill %+ || true # reads might have finished
17994        echo "wait until dd is finished"
17995        wait
17996        log "removing the temporary file"
17997        rm -rf $DIR/$tfile || error "tmp file removal failed"
17998 }
17999 run_test 218 "parallel read and truncate should not deadlock"
18000
18001 test_219() {
18002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18003
18004         # write one partial page
18005         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18006         # set no grant so vvp_io_commit_write will do sync write
18007         $LCTL set_param fail_loc=0x411
18008         # write a full page at the end of file
18009         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18010
18011         $LCTL set_param fail_loc=0
18012         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18013         $LCTL set_param fail_loc=0x411
18014         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18015
18016         # LU-4201
18017         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18018         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18019 }
18020 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18021
18022 test_220() { #LU-325
18023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18024         remote_ost_nodsh && skip "remote OST with nodsh"
18025         remote_mds_nodsh && skip "remote MDS with nodsh"
18026         remote_mgs_nodsh && skip "remote MGS with nodsh"
18027
18028         local OSTIDX=0
18029
18030         # create on MDT0000 so the last_id and next_id are correct
18031         mkdir $DIR/$tdir
18032         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18033         OST=${OST%_UUID}
18034
18035         # on the mdt's osc
18036         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18037         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18038                         osp.$mdtosc_proc1.prealloc_last_id)
18039         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18040                         osp.$mdtosc_proc1.prealloc_next_id)
18041
18042         $LFS df -i
18043
18044         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18045         #define OBD_FAIL_OST_ENOINO              0x229
18046         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18047         create_pool $FSNAME.$TESTNAME || return 1
18048         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18049
18050         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18051
18052         MDSOBJS=$((last_id - next_id))
18053         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18054
18055         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18056         echo "OST still has $count kbytes free"
18057
18058         echo "create $MDSOBJS files @next_id..."
18059         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18060
18061         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18062                         osp.$mdtosc_proc1.prealloc_last_id)
18063         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18064                         osp.$mdtosc_proc1.prealloc_next_id)
18065
18066         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18067         $LFS df -i
18068
18069         echo "cleanup..."
18070
18071         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18072         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18073
18074         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18075                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18076         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18077                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18078         echo "unlink $MDSOBJS files @$next_id..."
18079         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18080 }
18081 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18082
18083 test_221() {
18084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18085
18086         dd if=`which date` of=$MOUNT/date oflag=sync
18087         chmod +x $MOUNT/date
18088
18089         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18090         $LCTL set_param fail_loc=0x80001401
18091
18092         $MOUNT/date > /dev/null
18093         rm -f $MOUNT/date
18094 }
18095 run_test 221 "make sure fault and truncate race to not cause OOM"
18096
18097 test_222a () {
18098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18099
18100         rm -rf $DIR/$tdir
18101         test_mkdir $DIR/$tdir
18102         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18103         createmany -o $DIR/$tdir/$tfile 10
18104         cancel_lru_locks mdc
18105         cancel_lru_locks osc
18106         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18107         $LCTL set_param fail_loc=0x31a
18108         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18109         $LCTL set_param fail_loc=0
18110         rm -r $DIR/$tdir
18111 }
18112 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18113
18114 test_222b () {
18115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18116
18117         rm -rf $DIR/$tdir
18118         test_mkdir $DIR/$tdir
18119         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18120         createmany -o $DIR/$tdir/$tfile 10
18121         cancel_lru_locks mdc
18122         cancel_lru_locks osc
18123         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18124         $LCTL set_param fail_loc=0x31a
18125         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18126         $LCTL set_param fail_loc=0
18127 }
18128 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18129
18130 test_223 () {
18131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18132
18133         rm -rf $DIR/$tdir
18134         test_mkdir $DIR/$tdir
18135         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18136         createmany -o $DIR/$tdir/$tfile 10
18137         cancel_lru_locks mdc
18138         cancel_lru_locks osc
18139         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18140         $LCTL set_param fail_loc=0x31b
18141         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18142         $LCTL set_param fail_loc=0
18143         rm -r $DIR/$tdir
18144 }
18145 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18146
18147 test_224a() { # LU-1039, MRP-303
18148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18149
18150         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18151         $LCTL set_param fail_loc=0x508
18152         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18153         $LCTL set_param fail_loc=0
18154         df $DIR
18155 }
18156 run_test 224a "Don't panic on bulk IO failure"
18157
18158 test_224b() { # LU-1039, MRP-303
18159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18160
18161         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18162         cancel_lru_locks osc
18163         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18164         $LCTL set_param fail_loc=0x515
18165         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18166         $LCTL set_param fail_loc=0
18167         df $DIR
18168 }
18169 run_test 224b "Don't panic on bulk IO failure"
18170
18171 test_224c() { # LU-6441
18172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18173         remote_mds_nodsh && skip "remote MDS with nodsh"
18174
18175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18176         save_writethrough $p
18177         set_cache writethrough on
18178
18179         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18180         local at_max=$($LCTL get_param -n at_max)
18181         local timeout=$($LCTL get_param -n timeout)
18182         local test_at="at_max"
18183         local param_at="$FSNAME.sys.at_max"
18184         local test_timeout="timeout"
18185         local param_timeout="$FSNAME.sys.timeout"
18186
18187         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18188
18189         set_persistent_param_and_check client "$test_at" "$param_at" 0
18190         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18191
18192         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18193         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18194         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18195         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18196         sync
18197         do_facet ost1 "$LCTL set_param fail_loc=0"
18198
18199         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18200         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18201                 $timeout
18202
18203         $LCTL set_param -n $pages_per_rpc
18204         restore_lustre_params < $p
18205         rm -f $p
18206 }
18207 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18208
18209 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18210 test_225a () {
18211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18212         if [ -z ${MDSSURVEY} ]; then
18213                 skip_env "mds-survey not found"
18214         fi
18215         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18216                 skip "Need MDS version at least 2.2.51"
18217
18218         local mds=$(facet_host $SINGLEMDS)
18219         local target=$(do_nodes $mds 'lctl dl' |
18220                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18221
18222         local cmd1="file_count=1000 thrhi=4"
18223         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18224         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18225         local cmd="$cmd1 $cmd2 $cmd3"
18226
18227         rm -f ${TMP}/mds_survey*
18228         echo + $cmd
18229         eval $cmd || error "mds-survey with zero-stripe failed"
18230         cat ${TMP}/mds_survey*
18231         rm -f ${TMP}/mds_survey*
18232 }
18233 run_test 225a "Metadata survey sanity with zero-stripe"
18234
18235 test_225b () {
18236         if [ -z ${MDSSURVEY} ]; then
18237                 skip_env "mds-survey not found"
18238         fi
18239         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18240                 skip "Need MDS version at least 2.2.51"
18241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18242         remote_mds_nodsh && skip "remote MDS with nodsh"
18243         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18244                 skip_env "Need to mount OST to test"
18245         fi
18246
18247         local mds=$(facet_host $SINGLEMDS)
18248         local target=$(do_nodes $mds 'lctl dl' |
18249                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18250
18251         local cmd1="file_count=1000 thrhi=4"
18252         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18253         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18254         local cmd="$cmd1 $cmd2 $cmd3"
18255
18256         rm -f ${TMP}/mds_survey*
18257         echo + $cmd
18258         eval $cmd || error "mds-survey with stripe_count failed"
18259         cat ${TMP}/mds_survey*
18260         rm -f ${TMP}/mds_survey*
18261 }
18262 run_test 225b "Metadata survey sanity with stripe_count = 1"
18263
18264 mcreate_path2fid () {
18265         local mode=$1
18266         local major=$2
18267         local minor=$3
18268         local name=$4
18269         local desc=$5
18270         local path=$DIR/$tdir/$name
18271         local fid
18272         local rc
18273         local fid_path
18274
18275         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18276                 error "cannot create $desc"
18277
18278         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18279         rc=$?
18280         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18281
18282         fid_path=$($LFS fid2path $MOUNT $fid)
18283         rc=$?
18284         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18285
18286         [ "$path" == "$fid_path" ] ||
18287                 error "fid2path returned $fid_path, expected $path"
18288
18289         echo "pass with $path and $fid"
18290 }
18291
18292 test_226a () {
18293         rm -rf $DIR/$tdir
18294         mkdir -p $DIR/$tdir
18295
18296         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18297         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18298         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18299         mcreate_path2fid 0040666 0 0 dir "directory"
18300         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18301         mcreate_path2fid 0100666 0 0 file "regular file"
18302         mcreate_path2fid 0120666 0 0 link "symbolic link"
18303         mcreate_path2fid 0140666 0 0 sock "socket"
18304 }
18305 run_test 226a "call path2fid and fid2path on files of all type"
18306
18307 test_226b () {
18308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18309
18310         local MDTIDX=1
18311
18312         rm -rf $DIR/$tdir
18313         mkdir -p $DIR/$tdir
18314         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18315                 error "create remote directory failed"
18316         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18317         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18318                                 "character special file (null)"
18319         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18320                                 "character special file (no device)"
18321         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18322         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18323                                 "block special file (loop)"
18324         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18325         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18326         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18327 }
18328 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18329
18330 test_226c () {
18331         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18332         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18333                 skip "Need MDS version at least 2.13.55"
18334
18335         local submnt=/mnt/submnt
18336         local srcfile=/etc/passwd
18337         local dstfile=$submnt/passwd
18338         local path
18339         local fid
18340
18341         rm -rf $DIR/$tdir
18342         rm -rf $submnt
18343         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18344                 error "create remote directory failed"
18345         mkdir -p $submnt || error "create $submnt failed"
18346         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18347                 error "mount $submnt failed"
18348         stack_trap "umount $submnt" EXIT
18349
18350         cp $srcfile $dstfile
18351         fid=$($LFS path2fid $dstfile)
18352         path=$($LFS fid2path $submnt "$fid")
18353         [ "$path" = "$dstfile" ] ||
18354                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18355 }
18356 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18357
18358 # LU-1299 Executing or running ldd on a truncated executable does not
18359 # cause an out-of-memory condition.
18360 test_227() {
18361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18362         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18363
18364         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18365         chmod +x $MOUNT/date
18366
18367         $MOUNT/date > /dev/null
18368         ldd $MOUNT/date > /dev/null
18369         rm -f $MOUNT/date
18370 }
18371 run_test 227 "running truncated executable does not cause OOM"
18372
18373 # LU-1512 try to reuse idle OI blocks
18374 test_228a() {
18375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18376         remote_mds_nodsh && skip "remote MDS with nodsh"
18377         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18378
18379         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18380         local myDIR=$DIR/$tdir
18381
18382         mkdir -p $myDIR
18383         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18384         $LCTL set_param fail_loc=0x80001002
18385         createmany -o $myDIR/t- 10000
18386         $LCTL set_param fail_loc=0
18387         # The guard is current the largest FID holder
18388         touch $myDIR/guard
18389         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18390                     tr -d '[')
18391         local IDX=$(($SEQ % 64))
18392
18393         do_facet $SINGLEMDS sync
18394         # Make sure journal flushed.
18395         sleep 6
18396         local blk1=$(do_facet $SINGLEMDS \
18397                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18398                      grep Blockcount | awk '{print $4}')
18399
18400         # Remove old files, some OI blocks will become idle.
18401         unlinkmany $myDIR/t- 10000
18402         # Create new files, idle OI blocks should be reused.
18403         createmany -o $myDIR/t- 2000
18404         do_facet $SINGLEMDS sync
18405         # Make sure journal flushed.
18406         sleep 6
18407         local blk2=$(do_facet $SINGLEMDS \
18408                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18409                      grep Blockcount | awk '{print $4}')
18410
18411         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18412 }
18413 run_test 228a "try to reuse idle OI blocks"
18414
18415 test_228b() {
18416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18417         remote_mds_nodsh && skip "remote MDS with nodsh"
18418         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18419
18420         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18421         local myDIR=$DIR/$tdir
18422
18423         mkdir -p $myDIR
18424         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18425         $LCTL set_param fail_loc=0x80001002
18426         createmany -o $myDIR/t- 10000
18427         $LCTL set_param fail_loc=0
18428         # The guard is current the largest FID holder
18429         touch $myDIR/guard
18430         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18431                     tr -d '[')
18432         local IDX=$(($SEQ % 64))
18433
18434         do_facet $SINGLEMDS sync
18435         # Make sure journal flushed.
18436         sleep 6
18437         local blk1=$(do_facet $SINGLEMDS \
18438                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18439                      grep Blockcount | awk '{print $4}')
18440
18441         # Remove old files, some OI blocks will become idle.
18442         unlinkmany $myDIR/t- 10000
18443
18444         # stop the MDT
18445         stop $SINGLEMDS || error "Fail to stop MDT."
18446         # remount the MDT
18447         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18448
18449         df $MOUNT || error "Fail to df."
18450         # Create new files, idle OI blocks should be reused.
18451         createmany -o $myDIR/t- 2000
18452         do_facet $SINGLEMDS sync
18453         # Make sure journal flushed.
18454         sleep 6
18455         local blk2=$(do_facet $SINGLEMDS \
18456                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18457                      grep Blockcount | awk '{print $4}')
18458
18459         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18460 }
18461 run_test 228b "idle OI blocks can be reused after MDT restart"
18462
18463 #LU-1881
18464 test_228c() {
18465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18466         remote_mds_nodsh && skip "remote MDS with nodsh"
18467         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18468
18469         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18470         local myDIR=$DIR/$tdir
18471
18472         mkdir -p $myDIR
18473         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18474         $LCTL set_param fail_loc=0x80001002
18475         # 20000 files can guarantee there are index nodes in the OI file
18476         createmany -o $myDIR/t- 20000
18477         $LCTL set_param fail_loc=0
18478         # The guard is current the largest FID holder
18479         touch $myDIR/guard
18480         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18481                     tr -d '[')
18482         local IDX=$(($SEQ % 64))
18483
18484         do_facet $SINGLEMDS sync
18485         # Make sure journal flushed.
18486         sleep 6
18487         local blk1=$(do_facet $SINGLEMDS \
18488                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18489                      grep Blockcount | awk '{print $4}')
18490
18491         # Remove old files, some OI blocks will become idle.
18492         unlinkmany $myDIR/t- 20000
18493         rm -f $myDIR/guard
18494         # The OI file should become empty now
18495
18496         # Create new files, idle OI blocks should be reused.
18497         createmany -o $myDIR/t- 2000
18498         do_facet $SINGLEMDS sync
18499         # Make sure journal flushed.
18500         sleep 6
18501         local blk2=$(do_facet $SINGLEMDS \
18502                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18503                      grep Blockcount | awk '{print $4}')
18504
18505         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18506 }
18507 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18508
18509 test_229() { # LU-2482, LU-3448
18510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18511         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18512         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18513                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18514
18515         rm -f $DIR/$tfile
18516
18517         # Create a file with a released layout and stripe count 2.
18518         $MULTIOP $DIR/$tfile H2c ||
18519                 error "failed to create file with released layout"
18520
18521         $LFS getstripe -v $DIR/$tfile
18522
18523         local pattern=$($LFS getstripe -L $DIR/$tfile)
18524         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18525
18526         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18527                 error "getstripe"
18528         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18529         stat $DIR/$tfile || error "failed to stat released file"
18530
18531         chown $RUNAS_ID $DIR/$tfile ||
18532                 error "chown $RUNAS_ID $DIR/$tfile failed"
18533
18534         chgrp $RUNAS_ID $DIR/$tfile ||
18535                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18536
18537         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18538         rm $DIR/$tfile || error "failed to remove released file"
18539 }
18540 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18541
18542 test_230a() {
18543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18545         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18546                 skip "Need MDS version at least 2.11.52"
18547
18548         local MDTIDX=1
18549
18550         test_mkdir $DIR/$tdir
18551         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18552         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18553         [ $mdt_idx -ne 0 ] &&
18554                 error "create local directory on wrong MDT $mdt_idx"
18555
18556         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18557                         error "create remote directory failed"
18558         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18559         [ $mdt_idx -ne $MDTIDX ] &&
18560                 error "create remote directory on wrong MDT $mdt_idx"
18561
18562         createmany -o $DIR/$tdir/test_230/t- 10 ||
18563                 error "create files on remote directory failed"
18564         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18565         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18566         rm -r $DIR/$tdir || error "unlink remote directory failed"
18567 }
18568 run_test 230a "Create remote directory and files under the remote directory"
18569
18570 test_230b() {
18571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18573         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18574                 skip "Need MDS version at least 2.11.52"
18575
18576         local MDTIDX=1
18577         local mdt_index
18578         local i
18579         local file
18580         local pid
18581         local stripe_count
18582         local migrate_dir=$DIR/$tdir/migrate_dir
18583         local other_dir=$DIR/$tdir/other_dir
18584
18585         test_mkdir $DIR/$tdir
18586         test_mkdir -i0 -c1 $migrate_dir
18587         test_mkdir -i0 -c1 $other_dir
18588         for ((i=0; i<10; i++)); do
18589                 mkdir -p $migrate_dir/dir_${i}
18590                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18591                         error "create files under remote dir failed $i"
18592         done
18593
18594         cp /etc/passwd $migrate_dir/$tfile
18595         cp /etc/passwd $other_dir/$tfile
18596         chattr +SAD $migrate_dir
18597         chattr +SAD $migrate_dir/$tfile
18598
18599         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18600         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18601         local old_dir_mode=$(stat -c%f $migrate_dir)
18602         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18603
18604         mkdir -p $migrate_dir/dir_default_stripe2
18605         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18606         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18607
18608         mkdir -p $other_dir
18609         ln $migrate_dir/$tfile $other_dir/luna
18610         ln $migrate_dir/$tfile $migrate_dir/sofia
18611         ln $other_dir/$tfile $migrate_dir/david
18612         ln -s $migrate_dir/$tfile $other_dir/zachary
18613         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18614         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18615
18616         local len
18617         local lnktgt
18618
18619         # inline symlink
18620         for len in 58 59 60; do
18621                 lnktgt=$(str_repeat 'l' $len)
18622                 touch $migrate_dir/$lnktgt
18623                 ln -s $lnktgt $migrate_dir/${len}char_ln
18624         done
18625
18626         # PATH_MAX
18627         for len in 4094 4095; do
18628                 lnktgt=$(str_repeat 'l' $len)
18629                 ln -s $lnktgt $migrate_dir/${len}char_ln
18630         done
18631
18632         # NAME_MAX
18633         for len in 254 255; do
18634                 touch $migrate_dir/$(str_repeat 'l' $len)
18635         done
18636
18637         $LFS migrate -m $MDTIDX $migrate_dir ||
18638                 error "fails on migrating remote dir to MDT1"
18639
18640         echo "migratate to MDT1, then checking.."
18641         for ((i = 0; i < 10; i++)); do
18642                 for file in $(find $migrate_dir/dir_${i}); do
18643                         mdt_index=$($LFS getstripe -m $file)
18644                         # broken symlink getstripe will fail
18645                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18646                                 error "$file is not on MDT${MDTIDX}"
18647                 done
18648         done
18649
18650         # the multiple link file should still in MDT0
18651         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18652         [ $mdt_index == 0 ] ||
18653                 error "$file is not on MDT${MDTIDX}"
18654
18655         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18656         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18657                 error " expect $old_dir_flag get $new_dir_flag"
18658
18659         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18660         [ "$old_file_flag" = "$new_file_flag" ] ||
18661                 error " expect $old_file_flag get $new_file_flag"
18662
18663         local new_dir_mode=$(stat -c%f $migrate_dir)
18664         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18665                 error "expect mode $old_dir_mode get $new_dir_mode"
18666
18667         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18668         [ "$old_file_mode" = "$new_file_mode" ] ||
18669                 error "expect mode $old_file_mode get $new_file_mode"
18670
18671         diff /etc/passwd $migrate_dir/$tfile ||
18672                 error "$tfile different after migration"
18673
18674         diff /etc/passwd $other_dir/luna ||
18675                 error "luna different after migration"
18676
18677         diff /etc/passwd $migrate_dir/sofia ||
18678                 error "sofia different after migration"
18679
18680         diff /etc/passwd $migrate_dir/david ||
18681                 error "david different after migration"
18682
18683         diff /etc/passwd $other_dir/zachary ||
18684                 error "zachary different after migration"
18685
18686         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18687                 error "${tfile}_ln different after migration"
18688
18689         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18690                 error "${tfile}_ln_other different after migration"
18691
18692         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18693         [ $stripe_count = 2 ] ||
18694                 error "dir strpe_count $d != 2 after migration."
18695
18696         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18697         [ $stripe_count = 2 ] ||
18698                 error "file strpe_count $d != 2 after migration."
18699
18700         #migrate back to MDT0
18701         MDTIDX=0
18702
18703         $LFS migrate -m $MDTIDX $migrate_dir ||
18704                 error "fails on migrating remote dir to MDT0"
18705
18706         echo "migrate back to MDT0, checking.."
18707         for file in $(find $migrate_dir); do
18708                 mdt_index=$($LFS getstripe -m $file)
18709                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18710                         error "$file is not on MDT${MDTIDX}"
18711         done
18712
18713         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18714         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18715                 error " expect $old_dir_flag get $new_dir_flag"
18716
18717         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18718         [ "$old_file_flag" = "$new_file_flag" ] ||
18719                 error " expect $old_file_flag get $new_file_flag"
18720
18721         local new_dir_mode=$(stat -c%f $migrate_dir)
18722         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18723                 error "expect mode $old_dir_mode get $new_dir_mode"
18724
18725         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18726         [ "$old_file_mode" = "$new_file_mode" ] ||
18727                 error "expect mode $old_file_mode get $new_file_mode"
18728
18729         diff /etc/passwd ${migrate_dir}/$tfile ||
18730                 error "$tfile different after migration"
18731
18732         diff /etc/passwd ${other_dir}/luna ||
18733                 error "luna different after migration"
18734
18735         diff /etc/passwd ${migrate_dir}/sofia ||
18736                 error "sofia different after migration"
18737
18738         diff /etc/passwd ${other_dir}/zachary ||
18739                 error "zachary different after migration"
18740
18741         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18742                 error "${tfile}_ln different after migration"
18743
18744         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18745                 error "${tfile}_ln_other different after migration"
18746
18747         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18748         [ $stripe_count = 2 ] ||
18749                 error "dir strpe_count $d != 2 after migration."
18750
18751         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18752         [ $stripe_count = 2 ] ||
18753                 error "file strpe_count $d != 2 after migration."
18754
18755         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18756 }
18757 run_test 230b "migrate directory"
18758
18759 test_230c() {
18760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18762         remote_mds_nodsh && skip "remote MDS with nodsh"
18763         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18764                 skip "Need MDS version at least 2.11.52"
18765
18766         local MDTIDX=1
18767         local total=3
18768         local mdt_index
18769         local file
18770         local migrate_dir=$DIR/$tdir/migrate_dir
18771
18772         #If migrating directory fails in the middle, all entries of
18773         #the directory is still accessiable.
18774         test_mkdir $DIR/$tdir
18775         test_mkdir -i0 -c1 $migrate_dir
18776         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18777         stat $migrate_dir
18778         createmany -o $migrate_dir/f $total ||
18779                 error "create files under ${migrate_dir} failed"
18780
18781         # fail after migrating top dir, and this will fail only once, so the
18782         # first sub file migration will fail (currently f3), others succeed.
18783         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18784         do_facet mds1 lctl set_param fail_loc=0x1801
18785         local t=$(ls $migrate_dir | wc -l)
18786         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18787                 error "migrate should fail"
18788         local u=$(ls $migrate_dir | wc -l)
18789         [ "$u" == "$t" ] || error "$u != $t during migration"
18790
18791         # add new dir/file should succeed
18792         mkdir $migrate_dir/dir ||
18793                 error "mkdir failed under migrating directory"
18794         touch $migrate_dir/file ||
18795                 error "create file failed under migrating directory"
18796
18797         # add file with existing name should fail
18798         for file in $migrate_dir/f*; do
18799                 stat $file > /dev/null || error "stat $file failed"
18800                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18801                         error "open(O_CREAT|O_EXCL) $file should fail"
18802                 $MULTIOP $file m && error "create $file should fail"
18803                 touch $DIR/$tdir/remote_dir/$tfile ||
18804                         error "touch $tfile failed"
18805                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18806                         error "link $file should fail"
18807                 mdt_index=$($LFS getstripe -m $file)
18808                 if [ $mdt_index == 0 ]; then
18809                         # file failed to migrate is not allowed to rename to
18810                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18811                                 error "rename to $file should fail"
18812                 else
18813                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18814                                 error "rename to $file failed"
18815                 fi
18816                 echo hello >> $file || error "write $file failed"
18817         done
18818
18819         # resume migration with different options should fail
18820         $LFS migrate -m 0 $migrate_dir &&
18821                 error "migrate -m 0 $migrate_dir should fail"
18822
18823         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18824                 error "migrate -c 2 $migrate_dir should fail"
18825
18826         # resume migration should succeed
18827         $LFS migrate -m $MDTIDX $migrate_dir ||
18828                 error "migrate $migrate_dir failed"
18829
18830         echo "Finish migration, then checking.."
18831         for file in $(find $migrate_dir); do
18832                 mdt_index=$($LFS getstripe -m $file)
18833                 [ $mdt_index == $MDTIDX ] ||
18834                         error "$file is not on MDT${MDTIDX}"
18835         done
18836
18837         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18838 }
18839 run_test 230c "check directory accessiblity if migration failed"
18840
18841 test_230d() {
18842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18843         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18844         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18845                 skip "Need MDS version at least 2.11.52"
18846         # LU-11235
18847         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18848
18849         local migrate_dir=$DIR/$tdir/migrate_dir
18850         local old_index
18851         local new_index
18852         local old_count
18853         local new_count
18854         local new_hash
18855         local mdt_index
18856         local i
18857         local j
18858
18859         old_index=$((RANDOM % MDSCOUNT))
18860         old_count=$((MDSCOUNT - old_index))
18861         new_index=$((RANDOM % MDSCOUNT))
18862         new_count=$((MDSCOUNT - new_index))
18863         new_hash=1 # for all_char
18864
18865         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18866         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18867
18868         test_mkdir $DIR/$tdir
18869         test_mkdir -i $old_index -c $old_count $migrate_dir
18870
18871         for ((i=0; i<100; i++)); do
18872                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18873                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18874                         error "create files under remote dir failed $i"
18875         done
18876
18877         echo -n "Migrate from MDT$old_index "
18878         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18879         echo -n "to MDT$new_index"
18880         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18881         echo
18882
18883         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18884         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18885                 error "migrate remote dir error"
18886
18887         echo "Finish migration, then checking.."
18888         for file in $(find $migrate_dir); do
18889                 mdt_index=$($LFS getstripe -m $file)
18890                 if [ $mdt_index -lt $new_index ] ||
18891                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18892                         error "$file is on MDT$mdt_index"
18893                 fi
18894         done
18895
18896         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18897 }
18898 run_test 230d "check migrate big directory"
18899
18900 test_230e() {
18901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18903         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18904                 skip "Need MDS version at least 2.11.52"
18905
18906         local i
18907         local j
18908         local a_fid
18909         local b_fid
18910
18911         mkdir -p $DIR/$tdir
18912         mkdir $DIR/$tdir/migrate_dir
18913         mkdir $DIR/$tdir/other_dir
18914         touch $DIR/$tdir/migrate_dir/a
18915         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18916         ls $DIR/$tdir/other_dir
18917
18918         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18919                 error "migrate dir fails"
18920
18921         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18922         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18923
18924         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18925         [ $mdt_index == 0 ] || error "a is not on MDT0"
18926
18927         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18928                 error "migrate dir fails"
18929
18930         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18931         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18932
18933         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18934         [ $mdt_index == 1 ] || error "a is not on MDT1"
18935
18936         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18937         [ $mdt_index == 1 ] || error "b is not on MDT1"
18938
18939         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18940         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18941
18942         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18943
18944         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18945 }
18946 run_test 230e "migrate mulitple local link files"
18947
18948 test_230f() {
18949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18951         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18952                 skip "Need MDS version at least 2.11.52"
18953
18954         local a_fid
18955         local ln_fid
18956
18957         mkdir -p $DIR/$tdir
18958         mkdir $DIR/$tdir/migrate_dir
18959         $LFS mkdir -i1 $DIR/$tdir/other_dir
18960         touch $DIR/$tdir/migrate_dir/a
18961         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18962         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18963         ls $DIR/$tdir/other_dir
18964
18965         # a should be migrated to MDT1, since no other links on MDT0
18966         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18967                 error "#1 migrate dir fails"
18968         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18969         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18970         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18971         [ $mdt_index == 1 ] || error "a is not on MDT1"
18972
18973         # a should stay on MDT1, because it is a mulitple link file
18974         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18975                 error "#2 migrate dir fails"
18976         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18977         [ $mdt_index == 1 ] || error "a is not on MDT1"
18978
18979         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18980                 error "#3 migrate dir fails"
18981
18982         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18983         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18984         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18985
18986         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18987         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18988
18989         # a should be migrated to MDT0, since no other links on MDT1
18990         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18991                 error "#4 migrate dir fails"
18992         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18993         [ $mdt_index == 0 ] || error "a is not on MDT0"
18994
18995         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18996 }
18997 run_test 230f "migrate mulitple remote link files"
18998
18999 test_230g() {
19000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19002         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19003                 skip "Need MDS version at least 2.11.52"
19004
19005         mkdir -p $DIR/$tdir/migrate_dir
19006
19007         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19008                 error "migrating dir to non-exist MDT succeeds"
19009         true
19010 }
19011 run_test 230g "migrate dir to non-exist MDT"
19012
19013 test_230h() {
19014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19015         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19016         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19017                 skip "Need MDS version at least 2.11.52"
19018
19019         local mdt_index
19020
19021         mkdir -p $DIR/$tdir/migrate_dir
19022
19023         $LFS migrate -m1 $DIR &&
19024                 error "migrating mountpoint1 should fail"
19025
19026         $LFS migrate -m1 $DIR/$tdir/.. &&
19027                 error "migrating mountpoint2 should fail"
19028
19029         # same as mv
19030         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19031                 error "migrating $tdir/migrate_dir/.. should fail"
19032
19033         true
19034 }
19035 run_test 230h "migrate .. and root"
19036
19037 test_230i() {
19038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19039         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19040         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19041                 skip "Need MDS version at least 2.11.52"
19042
19043         mkdir -p $DIR/$tdir/migrate_dir
19044
19045         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19046                 error "migration fails with a tailing slash"
19047
19048         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19049                 error "migration fails with two tailing slashes"
19050 }
19051 run_test 230i "lfs migrate -m tolerates trailing slashes"
19052
19053 test_230j() {
19054         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19055         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19056                 skip "Need MDS version at least 2.11.52"
19057
19058         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19059         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19060                 error "create $tfile failed"
19061         cat /etc/passwd > $DIR/$tdir/$tfile
19062
19063         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19064
19065         cmp /etc/passwd $DIR/$tdir/$tfile ||
19066                 error "DoM file mismatch after migration"
19067 }
19068 run_test 230j "DoM file data not changed after dir migration"
19069
19070 test_230k() {
19071         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19072         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19073                 skip "Need MDS version at least 2.11.56"
19074
19075         local total=20
19076         local files_on_starting_mdt=0
19077
19078         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19079         $LFS getdirstripe $DIR/$tdir
19080         for i in $(seq $total); do
19081                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19082                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19083                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19084         done
19085
19086         echo "$files_on_starting_mdt files on MDT0"
19087
19088         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19089         $LFS getdirstripe $DIR/$tdir
19090
19091         files_on_starting_mdt=0
19092         for i in $(seq $total); do
19093                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19094                         error "file $tfile.$i mismatch after migration"
19095                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19096                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19097         done
19098
19099         echo "$files_on_starting_mdt files on MDT1 after migration"
19100         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19101
19102         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19103         $LFS getdirstripe $DIR/$tdir
19104
19105         files_on_starting_mdt=0
19106         for i in $(seq $total); do
19107                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19108                         error "file $tfile.$i mismatch after 2nd migration"
19109                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19110                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19111         done
19112
19113         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19114         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19115
19116         true
19117 }
19118 run_test 230k "file data not changed after dir migration"
19119
19120 test_230l() {
19121         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19122         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19123                 skip "Need MDS version at least 2.11.56"
19124
19125         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19126         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19127                 error "create files under remote dir failed $i"
19128         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19129 }
19130 run_test 230l "readdir between MDTs won't crash"
19131
19132 test_230m() {
19133         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19134         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19135                 skip "Need MDS version at least 2.11.56"
19136
19137         local MDTIDX=1
19138         local mig_dir=$DIR/$tdir/migrate_dir
19139         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19140         local shortstr="b"
19141         local val
19142
19143         echo "Creating files and dirs with xattrs"
19144         test_mkdir $DIR/$tdir
19145         test_mkdir -i0 -c1 $mig_dir
19146         mkdir $mig_dir/dir
19147         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19148                 error "cannot set xattr attr1 on dir"
19149         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19150                 error "cannot set xattr attr2 on dir"
19151         touch $mig_dir/dir/f0
19152         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19153                 error "cannot set xattr attr1 on file"
19154         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19155                 error "cannot set xattr attr2 on file"
19156         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19157         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19158         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19159         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19160         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19161         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19162         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19163         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19164         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19165
19166         echo "Migrating to MDT1"
19167         $LFS migrate -m $MDTIDX $mig_dir ||
19168                 error "fails on migrating dir to MDT1"
19169
19170         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19171         echo "Checking xattrs"
19172         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19173         [ "$val" = $longstr ] ||
19174                 error "expecting xattr1 $longstr on dir, found $val"
19175         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19176         [ "$val" = $shortstr ] ||
19177                 error "expecting xattr2 $shortstr on dir, found $val"
19178         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19179         [ "$val" = $longstr ] ||
19180                 error "expecting xattr1 $longstr on file, found $val"
19181         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19182         [ "$val" = $shortstr ] ||
19183                 error "expecting xattr2 $shortstr on file, found $val"
19184 }
19185 run_test 230m "xattrs not changed after dir migration"
19186
19187 test_230n() {
19188         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19189         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19190                 skip "Need MDS version at least 2.13.53"
19191
19192         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19193         cat /etc/hosts > $DIR/$tdir/$tfile
19194         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19195         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19196
19197         cmp /etc/hosts $DIR/$tdir/$tfile ||
19198                 error "File data mismatch after migration"
19199 }
19200 run_test 230n "Dir migration with mirrored file"
19201
19202 test_230o() {
19203         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19204         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19205                 skip "Need MDS version at least 2.13.52"
19206
19207         local mdts=$(comma_list $(mdts_nodes))
19208         local timeout=100
19209         local restripe_status
19210         local delta
19211         local i
19212
19213         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19214
19215         # in case "crush" hash type is not set
19216         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19217
19218         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19219                            mdt.*MDT0000.enable_dir_restripe)
19220         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19221         stack_trap "do_nodes $mdts $LCTL set_param \
19222                     mdt.*.enable_dir_restripe=$restripe_status"
19223
19224         mkdir $DIR/$tdir
19225         createmany -m $DIR/$tdir/f 100 ||
19226                 error "create files under remote dir failed $i"
19227         createmany -d $DIR/$tdir/d 100 ||
19228                 error "create dirs under remote dir failed $i"
19229
19230         for i in $(seq 2 $MDSCOUNT); do
19231                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19232                 $LFS setdirstripe -c $i $DIR/$tdir ||
19233                         error "split -c $i $tdir failed"
19234                 wait_update $HOSTNAME \
19235                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19236                         error "dir split not finished"
19237                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19238                         awk '/migrate/ {sum += $2} END { print sum }')
19239                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19240                 # delta is around total_files/stripe_count
19241                 (( $delta < 200 / (i - 1) + 4 )) ||
19242                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19243         done
19244 }
19245 run_test 230o "dir split"
19246
19247 test_230p() {
19248         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19249         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19250                 skip "Need MDS version at least 2.13.52"
19251
19252         local mdts=$(comma_list $(mdts_nodes))
19253         local timeout=100
19254         local restripe_status
19255         local delta
19256         local i
19257
19258         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19259
19260         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19261
19262         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19263                            mdt.*MDT0000.enable_dir_restripe)
19264         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19265         stack_trap "do_nodes $mdts $LCTL set_param \
19266                     mdt.*.enable_dir_restripe=$restripe_status"
19267
19268         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19269         createmany -m $DIR/$tdir/f 100 ||
19270                 error "create files under remote dir failed $i"
19271         createmany -d $DIR/$tdir/d 100 ||
19272                 error "create dirs under remote dir failed $i"
19273
19274         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19275                 local mdt_hash="crush"
19276
19277                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19278                 $LFS setdirstripe -c $i $DIR/$tdir ||
19279                         error "split -c $i $tdir failed"
19280                 [ $i -eq 1 ] && mdt_hash="none"
19281                 wait_update $HOSTNAME \
19282                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19283                         error "dir merge not finished"
19284                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19285                         awk '/migrate/ {sum += $2} END { print sum }')
19286                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19287                 # delta is around total_files/stripe_count
19288                 (( $delta < 200 / i + 4 )) ||
19289                         error "$delta files migrated >= $((200 / i + 4))"
19290         done
19291 }
19292 run_test 230p "dir merge"
19293
19294 test_230q() {
19295         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19296         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19297                 skip "Need MDS version at least 2.13.52"
19298
19299         local mdts=$(comma_list $(mdts_nodes))
19300         local saved_threshold=$(do_facet mds1 \
19301                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19302         local saved_delta=$(do_facet mds1 \
19303                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19304         local threshold=100
19305         local delta=2
19306         local total=0
19307         local stripe_count=0
19308         local stripe_index
19309         local nr_files
19310         local create
19311
19312         # test with fewer files on ZFS
19313         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19314
19315         stack_trap "do_nodes $mdts $LCTL set_param \
19316                     mdt.*.dir_split_count=$saved_threshold"
19317         stack_trap "do_nodes $mdts $LCTL set_param \
19318                     mdt.*.dir_split_delta=$saved_delta"
19319         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19320         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19321         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19322         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19323         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19324         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19325
19326         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19327         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19328
19329         create=$((threshold * 3 / 2))
19330         while [ $stripe_count -lt $MDSCOUNT ]; do
19331                 createmany -m $DIR/$tdir/f $total $create ||
19332                         error "create sub files failed"
19333                 stat $DIR/$tdir > /dev/null
19334                 total=$((total + create))
19335                 stripe_count=$((stripe_count + delta))
19336                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19337
19338                 wait_update $HOSTNAME \
19339                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19340                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19341
19342                 wait_update $HOSTNAME \
19343                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19344                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19345
19346                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19347                 echo "$nr_files/$total files on MDT$stripe_index after split"
19348                 # allow 10% margin of imbalance with crush hash
19349                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19350                         error "$nr_files files on MDT$stripe_index after split"
19351
19352                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19353                 [ $nr_files -eq $total ] ||
19354                         error "total sub files $nr_files != $total"
19355         done
19356 }
19357 run_test 230q "dir auto split"
19358
19359 test_230r() {
19360         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19361         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19362         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19363                 skip "Need MDS version at least 2.13.54"
19364
19365         # maximum amount of local locks:
19366         # parent striped dir - 2 locks
19367         # new stripe in parent to migrate to - 1 lock
19368         # source and target - 2 locks
19369         # Total 5 locks for regular file
19370         mkdir -p $DIR/$tdir
19371         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19372         touch $DIR/$tdir/dir1/eee
19373
19374         # create 4 hardlink for 4 more locks
19375         # Total: 9 locks > RS_MAX_LOCKS (8)
19376         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19377         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19378         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19379         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19380         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19381         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19382         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19383         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19384
19385         cancel_lru_locks mdc
19386
19387         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19388                 error "migrate dir fails"
19389
19390         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19391 }
19392 run_test 230r "migrate with too many local locks"
19393
19394 test_230s() {
19395         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19396                 skip "Need MDS version at least 2.13.57"
19397
19398         local mdts=$(comma_list $(mdts_nodes))
19399         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19400                                 mdt.*MDT0000.enable_dir_restripe)
19401
19402         stack_trap "do_nodes $mdts $LCTL set_param \
19403                     mdt.*.enable_dir_restripe=$restripe_status"
19404
19405         local st
19406         for st in 0 1; do
19407                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19408                 test_mkdir $DIR/$tdir
19409                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19410                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19411                 rmdir $DIR/$tdir
19412         done
19413 }
19414 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19415
19416 test_230t()
19417 {
19418         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19419         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19420                 skip "Need MDS version at least 2.14.50"
19421
19422         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19423         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19424         $LFS project -p 1 -s $DIR/$tdir ||
19425                 error "set $tdir project id failed"
19426         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19427                 error "set subdir project id failed"
19428         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19429 }
19430 run_test 230t "migrate directory with project ID set"
19431
19432 test_231a()
19433 {
19434         # For simplicity this test assumes that max_pages_per_rpc
19435         # is the same across all OSCs
19436         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19437         local bulk_size=$((max_pages * PAGE_SIZE))
19438         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19439                                        head -n 1)
19440
19441         mkdir -p $DIR/$tdir
19442         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19443                 error "failed to set stripe with -S ${brw_size}M option"
19444
19445         # clear the OSC stats
19446         $LCTL set_param osc.*.stats=0 &>/dev/null
19447         stop_writeback
19448
19449         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19450         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19451                 oflag=direct &>/dev/null || error "dd failed"
19452
19453         sync; sleep 1; sync # just to be safe
19454         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19455         if [ x$nrpcs != "x1" ]; then
19456                 $LCTL get_param osc.*.stats
19457                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19458         fi
19459
19460         start_writeback
19461         # Drop the OSC cache, otherwise we will read from it
19462         cancel_lru_locks osc
19463
19464         # clear the OSC stats
19465         $LCTL set_param osc.*.stats=0 &>/dev/null
19466
19467         # Client reads $bulk_size.
19468         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19469                 iflag=direct &>/dev/null || error "dd failed"
19470
19471         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19472         if [ x$nrpcs != "x1" ]; then
19473                 $LCTL get_param osc.*.stats
19474                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19475         fi
19476 }
19477 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19478
19479 test_231b() {
19480         mkdir -p $DIR/$tdir
19481         local i
19482         for i in {0..1023}; do
19483                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19484                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19485                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19486         done
19487         sync
19488 }
19489 run_test 231b "must not assert on fully utilized OST request buffer"
19490
19491 test_232a() {
19492         mkdir -p $DIR/$tdir
19493         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19494
19495         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19496         do_facet ost1 $LCTL set_param fail_loc=0x31c
19497
19498         # ignore dd failure
19499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19500
19501         do_facet ost1 $LCTL set_param fail_loc=0
19502         umount_client $MOUNT || error "umount failed"
19503         mount_client $MOUNT || error "mount failed"
19504         stop ost1 || error "cannot stop ost1"
19505         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19506 }
19507 run_test 232a "failed lock should not block umount"
19508
19509 test_232b() {
19510         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19511                 skip "Need MDS version at least 2.10.58"
19512
19513         mkdir -p $DIR/$tdir
19514         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19516         sync
19517         cancel_lru_locks osc
19518
19519         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19520         do_facet ost1 $LCTL set_param fail_loc=0x31c
19521
19522         # ignore failure
19523         $LFS data_version $DIR/$tdir/$tfile || true
19524
19525         do_facet ost1 $LCTL set_param fail_loc=0
19526         umount_client $MOUNT || error "umount failed"
19527         mount_client $MOUNT || error "mount failed"
19528         stop ost1 || error "cannot stop ost1"
19529         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19530 }
19531 run_test 232b "failed data version lock should not block umount"
19532
19533 test_233a() {
19534         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19535                 skip "Need MDS version at least 2.3.64"
19536         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19537
19538         local fid=$($LFS path2fid $MOUNT)
19539
19540         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19541                 error "cannot access $MOUNT using its FID '$fid'"
19542 }
19543 run_test 233a "checking that OBF of the FS root succeeds"
19544
19545 test_233b() {
19546         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19547                 skip "Need MDS version at least 2.5.90"
19548         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19549
19550         local fid=$($LFS path2fid $MOUNT/.lustre)
19551
19552         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19553                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19554
19555         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19556         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19557                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19558 }
19559 run_test 233b "checking that OBF of the FS .lustre succeeds"
19560
19561 test_234() {
19562         local p="$TMP/sanityN-$TESTNAME.parameters"
19563         save_lustre_params client "llite.*.xattr_cache" > $p
19564         lctl set_param llite.*.xattr_cache 1 ||
19565                 skip_env "xattr cache is not supported"
19566
19567         mkdir -p $DIR/$tdir || error "mkdir failed"
19568         touch $DIR/$tdir/$tfile || error "touch failed"
19569         # OBD_FAIL_LLITE_XATTR_ENOMEM
19570         $LCTL set_param fail_loc=0x1405
19571         getfattr -n user.attr $DIR/$tdir/$tfile &&
19572                 error "getfattr should have failed with ENOMEM"
19573         $LCTL set_param fail_loc=0x0
19574         rm -rf $DIR/$tdir
19575
19576         restore_lustre_params < $p
19577         rm -f $p
19578 }
19579 run_test 234 "xattr cache should not crash on ENOMEM"
19580
19581 test_235() {
19582         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19583                 skip "Need MDS version at least 2.4.52"
19584
19585         flock_deadlock $DIR/$tfile
19586         local RC=$?
19587         case $RC in
19588                 0)
19589                 ;;
19590                 124) error "process hangs on a deadlock"
19591                 ;;
19592                 *) error "error executing flock_deadlock $DIR/$tfile"
19593                 ;;
19594         esac
19595 }
19596 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19597
19598 #LU-2935
19599 test_236() {
19600         check_swap_layouts_support
19601
19602         local ref1=/etc/passwd
19603         local ref2=/etc/group
19604         local file1=$DIR/$tdir/f1
19605         local file2=$DIR/$tdir/f2
19606
19607         test_mkdir -c1 $DIR/$tdir
19608         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19609         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19610         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19611         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19612         local fd=$(free_fd)
19613         local cmd="exec $fd<>$file2"
19614         eval $cmd
19615         rm $file2
19616         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19617                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19618         cmd="exec $fd>&-"
19619         eval $cmd
19620         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19621
19622         #cleanup
19623         rm -rf $DIR/$tdir
19624 }
19625 run_test 236 "Layout swap on open unlinked file"
19626
19627 # LU-4659 linkea consistency
19628 test_238() {
19629         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19630                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19631                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19632                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19633
19634         touch $DIR/$tfile
19635         ln $DIR/$tfile $DIR/$tfile.lnk
19636         touch $DIR/$tfile.new
19637         mv $DIR/$tfile.new $DIR/$tfile
19638         local fid1=$($LFS path2fid $DIR/$tfile)
19639         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19640         local path1=$($LFS fid2path $FSNAME "$fid1")
19641         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19642         local path2=$($LFS fid2path $FSNAME "$fid2")
19643         [ $tfile.lnk == $path2 ] ||
19644                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19645         rm -f $DIR/$tfile*
19646 }
19647 run_test 238 "Verify linkea consistency"
19648
19649 test_239A() { # was test_239
19650         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19651                 skip "Need MDS version at least 2.5.60"
19652
19653         local list=$(comma_list $(mdts_nodes))
19654
19655         mkdir -p $DIR/$tdir
19656         createmany -o $DIR/$tdir/f- 5000
19657         unlinkmany $DIR/$tdir/f- 5000
19658         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19659                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19660         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19661                         osp.*MDT*.sync_in_flight" | calc_sum)
19662         [ "$changes" -eq 0 ] || error "$changes not synced"
19663 }
19664 run_test 239A "osp_sync test"
19665
19666 test_239a() { #LU-5297
19667         remote_mds_nodsh && skip "remote MDS with nodsh"
19668
19669         touch $DIR/$tfile
19670         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19671         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19672         chgrp $RUNAS_GID $DIR/$tfile
19673         wait_delete_completed
19674 }
19675 run_test 239a "process invalid osp sync record correctly"
19676
19677 test_239b() { #LU-5297
19678         remote_mds_nodsh && skip "remote MDS with nodsh"
19679
19680         touch $DIR/$tfile1
19681         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19682         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19683         chgrp $RUNAS_GID $DIR/$tfile1
19684         wait_delete_completed
19685         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19686         touch $DIR/$tfile2
19687         chgrp $RUNAS_GID $DIR/$tfile2
19688         wait_delete_completed
19689 }
19690 run_test 239b "process osp sync record with ENOMEM error correctly"
19691
19692 test_240() {
19693         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19694         remote_mds_nodsh && skip "remote MDS with nodsh"
19695
19696         mkdir -p $DIR/$tdir
19697
19698         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19699                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19700         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19701                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19702
19703         umount_client $MOUNT || error "umount failed"
19704         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19705         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19706         mount_client $MOUNT || error "failed to mount client"
19707
19708         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19709         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19710 }
19711 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19712
19713 test_241_bio() {
19714         local count=$1
19715         local bsize=$2
19716
19717         for LOOP in $(seq $count); do
19718                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19719                 cancel_lru_locks $OSC || true
19720         done
19721 }
19722
19723 test_241_dio() {
19724         local count=$1
19725         local bsize=$2
19726
19727         for LOOP in $(seq $1); do
19728                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19729                         2>/dev/null
19730         done
19731 }
19732
19733 test_241a() { # was test_241
19734         local bsize=$PAGE_SIZE
19735
19736         (( bsize < 40960 )) && bsize=40960
19737         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19738         ls -la $DIR/$tfile
19739         cancel_lru_locks $OSC
19740         test_241_bio 1000 $bsize &
19741         PID=$!
19742         test_241_dio 1000 $bsize
19743         wait $PID
19744 }
19745 run_test 241a "bio vs dio"
19746
19747 test_241b() {
19748         local bsize=$PAGE_SIZE
19749
19750         (( bsize < 40960 )) && bsize=40960
19751         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19752         ls -la $DIR/$tfile
19753         test_241_dio 1000 $bsize &
19754         PID=$!
19755         test_241_dio 1000 $bsize
19756         wait $PID
19757 }
19758 run_test 241b "dio vs dio"
19759
19760 test_242() {
19761         remote_mds_nodsh && skip "remote MDS with nodsh"
19762
19763         mkdir -p $DIR/$tdir
19764         touch $DIR/$tdir/$tfile
19765
19766         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19767         do_facet mds1 lctl set_param fail_loc=0x105
19768         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19769
19770         do_facet mds1 lctl set_param fail_loc=0
19771         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19772 }
19773 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19774
19775 test_243()
19776 {
19777         test_mkdir $DIR/$tdir
19778         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19779 }
19780 run_test 243 "various group lock tests"
19781
19782 test_244a()
19783 {
19784         test_mkdir $DIR/$tdir
19785         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19786         sendfile_grouplock $DIR/$tdir/$tfile || \
19787                 error "sendfile+grouplock failed"
19788         rm -rf $DIR/$tdir
19789 }
19790 run_test 244a "sendfile with group lock tests"
19791
19792 test_244b()
19793 {
19794         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19795
19796         local threads=50
19797         local size=$((1024*1024))
19798
19799         test_mkdir $DIR/$tdir
19800         for i in $(seq 1 $threads); do
19801                 local file=$DIR/$tdir/file_$((i / 10))
19802                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19803                 local pids[$i]=$!
19804         done
19805         for i in $(seq 1 $threads); do
19806                 wait ${pids[$i]}
19807         done
19808 }
19809 run_test 244b "multi-threaded write with group lock"
19810
19811 test_245() {
19812         local flagname="multi_mod_rpcs"
19813         local connect_data_name="max_mod_rpcs"
19814         local out
19815
19816         # check if multiple modify RPCs flag is set
19817         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19818                 grep "connect_flags:")
19819         echo "$out"
19820
19821         echo "$out" | grep -qw $flagname
19822         if [ $? -ne 0 ]; then
19823                 echo "connect flag $flagname is not set"
19824                 return
19825         fi
19826
19827         # check if multiple modify RPCs data is set
19828         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19829         echo "$out"
19830
19831         echo "$out" | grep -qw $connect_data_name ||
19832                 error "import should have connect data $connect_data_name"
19833 }
19834 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19835
19836 cleanup_247() {
19837         local submount=$1
19838
19839         trap 0
19840         umount_client $submount
19841         rmdir $submount
19842 }
19843
19844 test_247a() {
19845         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19846                 grep -q subtree ||
19847                 skip_env "Fileset feature is not supported"
19848
19849         local submount=${MOUNT}_$tdir
19850
19851         mkdir $MOUNT/$tdir
19852         mkdir -p $submount || error "mkdir $submount failed"
19853         FILESET="$FILESET/$tdir" mount_client $submount ||
19854                 error "mount $submount failed"
19855         trap "cleanup_247 $submount" EXIT
19856         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19857         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19858                 error "read $MOUNT/$tdir/$tfile failed"
19859         cleanup_247 $submount
19860 }
19861 run_test 247a "mount subdir as fileset"
19862
19863 test_247b() {
19864         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19865                 skip_env "Fileset feature is not supported"
19866
19867         local submount=${MOUNT}_$tdir
19868
19869         rm -rf $MOUNT/$tdir
19870         mkdir -p $submount || error "mkdir $submount failed"
19871         SKIP_FILESET=1
19872         FILESET="$FILESET/$tdir" mount_client $submount &&
19873                 error "mount $submount should fail"
19874         rmdir $submount
19875 }
19876 run_test 247b "mount subdir that dose not exist"
19877
19878 test_247c() {
19879         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19880                 skip_env "Fileset feature is not supported"
19881
19882         local submount=${MOUNT}_$tdir
19883
19884         mkdir -p $MOUNT/$tdir/dir1
19885         mkdir -p $submount || error "mkdir $submount failed"
19886         trap "cleanup_247 $submount" EXIT
19887         FILESET="$FILESET/$tdir" mount_client $submount ||
19888                 error "mount $submount failed"
19889         local fid=$($LFS path2fid $MOUNT/)
19890         $LFS fid2path $submount $fid && error "fid2path should fail"
19891         cleanup_247 $submount
19892 }
19893 run_test 247c "running fid2path outside subdirectory root"
19894
19895 test_247d() {
19896         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19897                 skip "Fileset feature is not supported"
19898
19899         local submount=${MOUNT}_$tdir
19900
19901         mkdir -p $MOUNT/$tdir/dir1
19902         mkdir -p $submount || error "mkdir $submount failed"
19903         FILESET="$FILESET/$tdir" mount_client $submount ||
19904                 error "mount $submount failed"
19905         trap "cleanup_247 $submount" EXIT
19906
19907         local td=$submount/dir1
19908         local fid=$($LFS path2fid $td)
19909         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19910
19911         # check that we get the same pathname back
19912         local rootpath
19913         local found
19914         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19915                 echo "$rootpath $fid"
19916                 found=$($LFS fid2path $rootpath "$fid")
19917                 [ -n "found" ] || error "fid2path should succeed"
19918                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19919         done
19920         # check wrong root path format
19921         rootpath=$submount"_wrong"
19922         found=$($LFS fid2path $rootpath "$fid")
19923         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19924
19925         cleanup_247 $submount
19926 }
19927 run_test 247d "running fid2path inside subdirectory root"
19928
19929 # LU-8037
19930 test_247e() {
19931         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19932                 grep -q subtree ||
19933                 skip "Fileset feature is not supported"
19934
19935         local submount=${MOUNT}_$tdir
19936
19937         mkdir $MOUNT/$tdir
19938         mkdir -p $submount || error "mkdir $submount failed"
19939         FILESET="$FILESET/.." mount_client $submount &&
19940                 error "mount $submount should fail"
19941         rmdir $submount
19942 }
19943 run_test 247e "mount .. as fileset"
19944
19945 test_247f() {
19946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19947         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19948                 skip "Need at least version 2.13.52"
19949         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19950                 skip "Need at least version 2.14.50"
19951         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19952                 grep -q subtree ||
19953                 skip "Fileset feature is not supported"
19954
19955         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19956         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19957                 error "mkdir remote failed"
19958         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19959         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19960                 error "mkdir striped failed"
19961         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19962
19963         local submount=${MOUNT}_$tdir
19964
19965         mkdir -p $submount || error "mkdir $submount failed"
19966         stack_trap "rmdir $submount"
19967
19968         local dir
19969         local stat
19970         local fileset=$FILESET
19971         local mdts=$(comma_list $(mdts_nodes))
19972
19973         stat=$(do_facet mds1 $LCTL get_param -n \
19974                 mdt.*MDT0000.enable_remote_subdir_mount)
19975         stack_trap "do_nodes $mdts $LCTL set_param \
19976                 mdt.*.enable_remote_subdir_mount=$stat"
19977
19978         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
19979         stack_trap "umount_client $submount"
19980         FILESET="$fileset/$tdir/remote" mount_client $submount &&
19981                 error "mount remote dir $dir should fail"
19982
19983         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
19984                 $tdir/striped/. ; do
19985                 FILESET="$fileset/$dir" mount_client $submount ||
19986                         error "mount $dir failed"
19987                 umount_client $submount
19988         done
19989
19990         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
19991         FILESET="$fileset/$tdir/remote" mount_client $submount ||
19992                 error "mount $tdir/remote failed"
19993 }
19994 run_test 247f "mount striped or remote directory as fileset"
19995
19996 test_247g() {
19997         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
19998         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19999                 skip "Need at least version 2.14.50"
20000
20001         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20002                 error "mkdir $tdir failed"
20003         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20004
20005         local submount=${MOUNT}_$tdir
20006
20007         mkdir -p $submount || error "mkdir $submount failed"
20008         stack_trap "rmdir $submount"
20009
20010         FILESET="$fileset/$tdir" mount_client $submount ||
20011                 error "mount $dir failed"
20012         stack_trap "umount $submount"
20013
20014         local mdts=$(comma_list $(mdts_nodes))
20015
20016         local nrpcs
20017
20018         stat $submount > /dev/null
20019         cancel_lru_locks $MDC
20020         stat $submount > /dev/null
20021         stat $submount/$tfile > /dev/null
20022         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20023         stat $submount/$tfile > /dev/null
20024         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20025                 awk '/getattr/ {sum += $2} END {print sum}')
20026
20027         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20028 }
20029 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20030
20031 test_248a() {
20032         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20033         [ -z "$fast_read_sav" ] && skip "no fast read support"
20034
20035         # create a large file for fast read verification
20036         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20037
20038         # make sure the file is created correctly
20039         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20040                 { rm -f $DIR/$tfile; skip "file creation error"; }
20041
20042         echo "Test 1: verify that fast read is 4 times faster on cache read"
20043
20044         # small read with fast read enabled
20045         $LCTL set_param -n llite.*.fast_read=1
20046         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20047                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20048                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20049         # small read with fast read disabled
20050         $LCTL set_param -n llite.*.fast_read=0
20051         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20052                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20053                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20054
20055         # verify that fast read is 4 times faster for cache read
20056         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20057                 error_not_in_vm "fast read was not 4 times faster: " \
20058                            "$t_fast vs $t_slow"
20059
20060         echo "Test 2: verify the performance between big and small read"
20061         $LCTL set_param -n llite.*.fast_read=1
20062
20063         # 1k non-cache read
20064         cancel_lru_locks osc
20065         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20066                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20067                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20068
20069         # 1M non-cache read
20070         cancel_lru_locks osc
20071         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20072                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20073                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20074
20075         # verify that big IO is not 4 times faster than small IO
20076         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20077                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20078
20079         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20080         rm -f $DIR/$tfile
20081 }
20082 run_test 248a "fast read verification"
20083
20084 test_248b() {
20085         # Default short_io_bytes=16384, try both smaller and larger sizes.
20086         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20087         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20088         echo "bs=53248 count=113 normal buffered write"
20089         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20090                 error "dd of initial data file failed"
20091         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20092
20093         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20094         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20095                 error "dd with sync normal writes failed"
20096         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20097
20098         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20099         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20100                 error "dd with sync small writes failed"
20101         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20102
20103         cancel_lru_locks osc
20104
20105         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20106         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20107         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20108         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20109                 iflag=direct || error "dd with O_DIRECT small read failed"
20110         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20111         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20112                 error "compare $TMP/$tfile.1 failed"
20113
20114         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20115         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20116
20117         # just to see what the maximum tunable value is, and test parsing
20118         echo "test invalid parameter 2MB"
20119         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20120                 error "too-large short_io_bytes allowed"
20121         echo "test maximum parameter 512KB"
20122         # if we can set a larger short_io_bytes, run test regardless of version
20123         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20124                 # older clients may not allow setting it this large, that's OK
20125                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20126                         skip "Need at least client version 2.13.50"
20127                 error "medium short_io_bytes failed"
20128         fi
20129         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20130         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20131
20132         echo "test large parameter 64KB"
20133         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20134         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20135
20136         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20137         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20138                 error "dd with sync large writes failed"
20139         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20140
20141         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20142         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20143         num=$((113 * 4096 / PAGE_SIZE))
20144         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20145         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20146                 error "dd with O_DIRECT large writes failed"
20147         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20148                 error "compare $DIR/$tfile.3 failed"
20149
20150         cancel_lru_locks osc
20151
20152         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20153         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20154                 error "dd with O_DIRECT large read failed"
20155         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20156                 error "compare $TMP/$tfile.2 failed"
20157
20158         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20159         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20160                 error "dd with O_DIRECT large read failed"
20161         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20162                 error "compare $TMP/$tfile.3 failed"
20163 }
20164 run_test 248b "test short_io read and write for both small and large sizes"
20165
20166 test_249() { # LU-7890
20167         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20168                 skip "Need at least version 2.8.54"
20169
20170         rm -f $DIR/$tfile
20171         $LFS setstripe -c 1 $DIR/$tfile
20172         # Offset 2T == 4k * 512M
20173         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20174                 error "dd to 2T offset failed"
20175 }
20176 run_test 249 "Write above 2T file size"
20177
20178 test_250() {
20179         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20180          && skip "no 16TB file size limit on ZFS"
20181
20182         $LFS setstripe -c 1 $DIR/$tfile
20183         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20184         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20185         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20186         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20187                 conv=notrunc,fsync && error "append succeeded"
20188         return 0
20189 }
20190 run_test 250 "Write above 16T limit"
20191
20192 test_251() {
20193         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20194
20195         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20196         #Skip once - writing the first stripe will succeed
20197         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20198         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20199                 error "short write happened"
20200
20201         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20202         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20203                 error "short read happened"
20204
20205         rm -f $DIR/$tfile
20206 }
20207 run_test 251 "Handling short read and write correctly"
20208
20209 test_252() {
20210         remote_mds_nodsh && skip "remote MDS with nodsh"
20211         remote_ost_nodsh && skip "remote OST with nodsh"
20212         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20213                 skip_env "ldiskfs only test"
20214         fi
20215
20216         local tgt
20217         local dev
20218         local out
20219         local uuid
20220         local num
20221         local gen
20222
20223         # check lr_reader on OST0000
20224         tgt=ost1
20225         dev=$(facet_device $tgt)
20226         out=$(do_facet $tgt $LR_READER $dev)
20227         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20228         echo "$out"
20229         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20230         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20231                 error "Invalid uuid returned by $LR_READER on target $tgt"
20232         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20233
20234         # check lr_reader -c on MDT0000
20235         tgt=mds1
20236         dev=$(facet_device $tgt)
20237         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20238                 skip "$LR_READER does not support additional options"
20239         fi
20240         out=$(do_facet $tgt $LR_READER -c $dev)
20241         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20242         echo "$out"
20243         num=$(echo "$out" | grep -c "mdtlov")
20244         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20245                 error "Invalid number of mdtlov clients returned by $LR_READER"
20246         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20247
20248         # check lr_reader -cr on MDT0000
20249         out=$(do_facet $tgt $LR_READER -cr $dev)
20250         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20251         echo "$out"
20252         echo "$out" | grep -q "^reply_data:$" ||
20253                 error "$LR_READER should have returned 'reply_data' section"
20254         num=$(echo "$out" | grep -c "client_generation")
20255         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20256 }
20257 run_test 252 "check lr_reader tool"
20258
20259 test_253() {
20260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20261         remote_mds_nodsh && skip "remote MDS with nodsh"
20262         remote_mgs_nodsh && skip "remote MGS with nodsh"
20263
20264         local ostidx=0
20265         local rc=0
20266         local ost_name=$(ostname_from_index $ostidx)
20267
20268         # on the mdt's osc
20269         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20270         do_facet $SINGLEMDS $LCTL get_param -n \
20271                 osp.$mdtosc_proc1.reserved_mb_high ||
20272                 skip  "remote MDS does not support reserved_mb_high"
20273
20274         rm -rf $DIR/$tdir
20275         wait_mds_ost_sync
20276         wait_delete_completed
20277         mkdir $DIR/$tdir
20278
20279         pool_add $TESTNAME || error "Pool creation failed"
20280         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20281
20282         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20283                 error "Setstripe failed"
20284
20285         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20286
20287         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20288                     grep "watermarks")
20289         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20290
20291         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20292                         osp.$mdtosc_proc1.prealloc_status)
20293         echo "prealloc_status $oa_status"
20294
20295         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20296                 error "File creation should fail"
20297
20298         #object allocation was stopped, but we still able to append files
20299         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20300                 oflag=append || error "Append failed"
20301
20302         rm -f $DIR/$tdir/$tfile.0
20303
20304         # For this test, we want to delete the files we created to go out of
20305         # space but leave the watermark, so we remain nearly out of space
20306         ost_watermarks_enospc_delete_files $tfile $ostidx
20307
20308         wait_delete_completed
20309
20310         sleep_maxage
20311
20312         for i in $(seq 10 12); do
20313                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20314                         2>/dev/null || error "File creation failed after rm"
20315         done
20316
20317         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20318                         osp.$mdtosc_proc1.prealloc_status)
20319         echo "prealloc_status $oa_status"
20320
20321         if (( oa_status != 0 )); then
20322                 error "Object allocation still disable after rm"
20323         fi
20324 }
20325 run_test 253 "Check object allocation limit"
20326
20327 test_254() {
20328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20329         remote_mds_nodsh && skip "remote MDS with nodsh"
20330         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20331                 skip "MDS does not support changelog_size"
20332
20333         local cl_user
20334         local MDT0=$(facet_svc $SINGLEMDS)
20335
20336         changelog_register || error "changelog_register failed"
20337
20338         changelog_clear 0 || error "changelog_clear failed"
20339
20340         local size1=$(do_facet $SINGLEMDS \
20341                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20342         echo "Changelog size $size1"
20343
20344         rm -rf $DIR/$tdir
20345         $LFS mkdir -i 0 $DIR/$tdir
20346         # change something
20347         mkdir -p $DIR/$tdir/pics/2008/zachy
20348         touch $DIR/$tdir/pics/2008/zachy/timestamp
20349         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20350         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20351         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20352         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20353         rm $DIR/$tdir/pics/desktop.jpg
20354
20355         local size2=$(do_facet $SINGLEMDS \
20356                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20357         echo "Changelog size after work $size2"
20358
20359         (( $size2 > $size1 )) ||
20360                 error "new Changelog size=$size2 less than old size=$size1"
20361 }
20362 run_test 254 "Check changelog size"
20363
20364 ladvise_no_type()
20365 {
20366         local type=$1
20367         local file=$2
20368
20369         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20370                 awk -F: '{print $2}' | grep $type > /dev/null
20371         if [ $? -ne 0 ]; then
20372                 return 0
20373         fi
20374         return 1
20375 }
20376
20377 ladvise_no_ioctl()
20378 {
20379         local file=$1
20380
20381         lfs ladvise -a willread $file > /dev/null 2>&1
20382         if [ $? -eq 0 ]; then
20383                 return 1
20384         fi
20385
20386         lfs ladvise -a willread $file 2>&1 |
20387                 grep "Inappropriate ioctl for device" > /dev/null
20388         if [ $? -eq 0 ]; then
20389                 return 0
20390         fi
20391         return 1
20392 }
20393
20394 percent() {
20395         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20396 }
20397
20398 # run a random read IO workload
20399 # usage: random_read_iops <filename> <filesize> <iosize>
20400 random_read_iops() {
20401         local file=$1
20402         local fsize=$2
20403         local iosize=${3:-4096}
20404
20405         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20406                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20407 }
20408
20409 drop_file_oss_cache() {
20410         local file="$1"
20411         local nodes="$2"
20412
20413         $LFS ladvise -a dontneed $file 2>/dev/null ||
20414                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20415 }
20416
20417 ladvise_willread_performance()
20418 {
20419         local repeat=10
20420         local average_origin=0
20421         local average_cache=0
20422         local average_ladvise=0
20423
20424         for ((i = 1; i <= $repeat; i++)); do
20425                 echo "Iter $i/$repeat: reading without willread hint"
20426                 cancel_lru_locks osc
20427                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20428                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20429                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20430                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20431
20432                 cancel_lru_locks osc
20433                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20434                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20435                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20436
20437                 cancel_lru_locks osc
20438                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20439                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20440                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20441                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20442                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20443         done
20444         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20445         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20446         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20447
20448         speedup_cache=$(percent $average_cache $average_origin)
20449         speedup_ladvise=$(percent $average_ladvise $average_origin)
20450
20451         echo "Average uncached read: $average_origin"
20452         echo "Average speedup with OSS cached read: " \
20453                 "$average_cache = +$speedup_cache%"
20454         echo "Average speedup with ladvise willread: " \
20455                 "$average_ladvise = +$speedup_ladvise%"
20456
20457         local lowest_speedup=20
20458         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20459                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20460                         "got $average_cache%. Skipping ladvise willread check."
20461                 return 0
20462         fi
20463
20464         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20465         # it is still good to run until then to exercise 'ladvise willread'
20466         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20467                 [ "$ost1_FSTYPE" = "zfs" ] &&
20468                 echo "osd-zfs does not support dontneed or drop_caches" &&
20469                 return 0
20470
20471         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20472         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20473                 error_not_in_vm "Speedup with willread is less than " \
20474                         "$lowest_speedup%, got $average_ladvise%"
20475 }
20476
20477 test_255a() {
20478         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20479                 skip "lustre < 2.8.54 does not support ladvise "
20480         remote_ost_nodsh && skip "remote OST with nodsh"
20481
20482         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20483
20484         ladvise_no_type willread $DIR/$tfile &&
20485                 skip "willread ladvise is not supported"
20486
20487         ladvise_no_ioctl $DIR/$tfile &&
20488                 skip "ladvise ioctl is not supported"
20489
20490         local size_mb=100
20491         local size=$((size_mb * 1048576))
20492         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20493                 error "dd to $DIR/$tfile failed"
20494
20495         lfs ladvise -a willread $DIR/$tfile ||
20496                 error "Ladvise failed with no range argument"
20497
20498         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20499                 error "Ladvise failed with no -l or -e argument"
20500
20501         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20502                 error "Ladvise failed with only -e argument"
20503
20504         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20505                 error "Ladvise failed with only -l argument"
20506
20507         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20508                 error "End offset should not be smaller than start offset"
20509
20510         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20511                 error "End offset should not be equal to start offset"
20512
20513         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20514                 error "Ladvise failed with overflowing -s argument"
20515
20516         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20517                 error "Ladvise failed with overflowing -e argument"
20518
20519         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20520                 error "Ladvise failed with overflowing -l argument"
20521
20522         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20523                 error "Ladvise succeeded with conflicting -l and -e arguments"
20524
20525         echo "Synchronous ladvise should wait"
20526         local delay=4
20527 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20528         do_nodes $(comma_list $(osts_nodes)) \
20529                 $LCTL set_param fail_val=$delay fail_loc=0x237
20530
20531         local start_ts=$SECONDS
20532         lfs ladvise -a willread $DIR/$tfile ||
20533                 error "Ladvise failed with no range argument"
20534         local end_ts=$SECONDS
20535         local inteval_ts=$((end_ts - start_ts))
20536
20537         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20538                 error "Synchronous advice didn't wait reply"
20539         fi
20540
20541         echo "Asynchronous ladvise shouldn't wait"
20542         local start_ts=$SECONDS
20543         lfs ladvise -a willread -b $DIR/$tfile ||
20544                 error "Ladvise failed with no range argument"
20545         local end_ts=$SECONDS
20546         local inteval_ts=$((end_ts - start_ts))
20547
20548         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20549                 error "Asynchronous advice blocked"
20550         fi
20551
20552         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20553         ladvise_willread_performance
20554 }
20555 run_test 255a "check 'lfs ladvise -a willread'"
20556
20557 facet_meminfo() {
20558         local facet=$1
20559         local info=$2
20560
20561         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20562 }
20563
20564 test_255b() {
20565         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20566                 skip "lustre < 2.8.54 does not support ladvise "
20567         remote_ost_nodsh && skip "remote OST with nodsh"
20568
20569         lfs setstripe -c 1 -i 0 $DIR/$tfile
20570
20571         ladvise_no_type dontneed $DIR/$tfile &&
20572                 skip "dontneed ladvise is not supported"
20573
20574         ladvise_no_ioctl $DIR/$tfile &&
20575                 skip "ladvise ioctl is not supported"
20576
20577         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20578                 [ "$ost1_FSTYPE" = "zfs" ] &&
20579                 skip "zfs-osd does not support 'ladvise dontneed'"
20580
20581         local size_mb=100
20582         local size=$((size_mb * 1048576))
20583         # In order to prevent disturbance of other processes, only check 3/4
20584         # of the memory usage
20585         local kibibytes=$((size_mb * 1024 * 3 / 4))
20586
20587         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20588                 error "dd to $DIR/$tfile failed"
20589
20590         #force write to complete before dropping OST cache & checking memory
20591         sync
20592
20593         local total=$(facet_meminfo ost1 MemTotal)
20594         echo "Total memory: $total KiB"
20595
20596         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20597         local before_read=$(facet_meminfo ost1 Cached)
20598         echo "Cache used before read: $before_read KiB"
20599
20600         lfs ladvise -a willread $DIR/$tfile ||
20601                 error "Ladvise willread failed"
20602         local after_read=$(facet_meminfo ost1 Cached)
20603         echo "Cache used after read: $after_read KiB"
20604
20605         lfs ladvise -a dontneed $DIR/$tfile ||
20606                 error "Ladvise dontneed again failed"
20607         local no_read=$(facet_meminfo ost1 Cached)
20608         echo "Cache used after dontneed ladvise: $no_read KiB"
20609
20610         if [ $total -lt $((before_read + kibibytes)) ]; then
20611                 echo "Memory is too small, abort checking"
20612                 return 0
20613         fi
20614
20615         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20616                 error "Ladvise willread should use more memory" \
20617                         "than $kibibytes KiB"
20618         fi
20619
20620         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20621                 error "Ladvise dontneed should release more memory" \
20622                         "than $kibibytes KiB"
20623         fi
20624 }
20625 run_test 255b "check 'lfs ladvise -a dontneed'"
20626
20627 test_255c() {
20628         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20629                 skip "lustre < 2.10.50 does not support lockahead"
20630
20631         local ost1_imp=$(get_osc_import_name client ost1)
20632         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20633                          cut -d'.' -f2)
20634         local count
20635         local new_count
20636         local difference
20637         local i
20638         local rc
20639
20640         test_mkdir -p $DIR/$tdir
20641         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20642
20643         #test 10 returns only success/failure
20644         i=10
20645         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20646         rc=$?
20647         if [ $rc -eq 255 ]; then
20648                 error "Ladvise test${i} failed, ${rc}"
20649         fi
20650
20651         #test 11 counts lock enqueue requests, all others count new locks
20652         i=11
20653         count=$(do_facet ost1 \
20654                 $LCTL get_param -n ost.OSS.ost.stats)
20655         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20656
20657         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20658         rc=$?
20659         if [ $rc -eq 255 ]; then
20660                 error "Ladvise test${i} failed, ${rc}"
20661         fi
20662
20663         new_count=$(do_facet ost1 \
20664                 $LCTL get_param -n ost.OSS.ost.stats)
20665         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20666                    awk '{ print $2 }')
20667
20668         difference="$((new_count - count))"
20669         if [ $difference -ne $rc ]; then
20670                 error "Ladvise test${i}, bad enqueue count, returned " \
20671                       "${rc}, actual ${difference}"
20672         fi
20673
20674         for i in $(seq 12 21); do
20675                 # If we do not do this, we run the risk of having too many
20676                 # locks and starting lock cancellation while we are checking
20677                 # lock counts.
20678                 cancel_lru_locks osc
20679
20680                 count=$($LCTL get_param -n \
20681                        ldlm.namespaces.$imp_name.lock_unused_count)
20682
20683                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20684                 rc=$?
20685                 if [ $rc -eq 255 ]; then
20686                         error "Ladvise test ${i} failed, ${rc}"
20687                 fi
20688
20689                 new_count=$($LCTL get_param -n \
20690                        ldlm.namespaces.$imp_name.lock_unused_count)
20691                 difference="$((new_count - count))"
20692
20693                 # Test 15 output is divided by 100 to map down to valid return
20694                 if [ $i -eq 15 ]; then
20695                         rc="$((rc * 100))"
20696                 fi
20697
20698                 if [ $difference -ne $rc ]; then
20699                         error "Ladvise test ${i}, bad lock count, returned " \
20700                               "${rc}, actual ${difference}"
20701                 fi
20702         done
20703
20704         #test 22 returns only success/failure
20705         i=22
20706         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20707         rc=$?
20708         if [ $rc -eq 255 ]; then
20709                 error "Ladvise test${i} failed, ${rc}"
20710         fi
20711 }
20712 run_test 255c "suite of ladvise lockahead tests"
20713
20714 test_256() {
20715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20716         remote_mds_nodsh && skip "remote MDS with nodsh"
20717         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20718         changelog_users $SINGLEMDS | grep "^cl" &&
20719                 skip "active changelog user"
20720
20721         local cl_user
20722         local cat_sl
20723         local mdt_dev
20724
20725         mdt_dev=$(mdsdevname 1)
20726         echo $mdt_dev
20727
20728         changelog_register || error "changelog_register failed"
20729
20730         rm -rf $DIR/$tdir
20731         mkdir -p $DIR/$tdir
20732
20733         changelog_clear 0 || error "changelog_clear failed"
20734
20735         # change something
20736         touch $DIR/$tdir/{1..10}
20737
20738         # stop the MDT
20739         stop $SINGLEMDS || error "Fail to stop MDT"
20740
20741         # remount the MDT
20742
20743         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20744
20745         #after mount new plainllog is used
20746         touch $DIR/$tdir/{11..19}
20747         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20748         stack_trap "rm -f $tmpfile"
20749         cat_sl=$(do_facet $SINGLEMDS "sync; \
20750                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20751                  llog_reader $tmpfile | grep -c type=1064553b")
20752         do_facet $SINGLEMDS llog_reader $tmpfile
20753
20754         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20755
20756         changelog_clear 0 || error "changelog_clear failed"
20757
20758         cat_sl=$(do_facet $SINGLEMDS "sync; \
20759                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20760                  llog_reader $tmpfile | grep -c type=1064553b")
20761
20762         if (( cat_sl == 2 )); then
20763                 error "Empty plain llog was not deleted from changelog catalog"
20764         elif (( cat_sl != 1 )); then
20765                 error "Active plain llog shouldn't be deleted from catalog"
20766         fi
20767 }
20768 run_test 256 "Check llog delete for empty and not full state"
20769
20770 test_257() {
20771         remote_mds_nodsh && skip "remote MDS with nodsh"
20772         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20773                 skip "Need MDS version at least 2.8.55"
20774
20775         test_mkdir $DIR/$tdir
20776
20777         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20778                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20779         stat $DIR/$tdir
20780
20781 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20782         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20783         local facet=mds$((mdtidx + 1))
20784         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20785         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20786
20787         stop $facet || error "stop MDS failed"
20788         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20789                 error "start MDS fail"
20790         wait_recovery_complete $facet
20791 }
20792 run_test 257 "xattr locks are not lost"
20793
20794 # Verify we take the i_mutex when security requires it
20795 test_258a() {
20796 #define OBD_FAIL_IMUTEX_SEC 0x141c
20797         $LCTL set_param fail_loc=0x141c
20798         touch $DIR/$tfile
20799         chmod u+s $DIR/$tfile
20800         chmod a+rwx $DIR/$tfile
20801         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20802         RC=$?
20803         if [ $RC -ne 0 ]; then
20804                 error "error, failed to take i_mutex, rc=$?"
20805         fi
20806         rm -f $DIR/$tfile
20807 }
20808 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20809
20810 # Verify we do NOT take the i_mutex in the normal case
20811 test_258b() {
20812 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20813         $LCTL set_param fail_loc=0x141d
20814         touch $DIR/$tfile
20815         chmod a+rwx $DIR
20816         chmod a+rw $DIR/$tfile
20817         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20818         RC=$?
20819         if [ $RC -ne 0 ]; then
20820                 error "error, took i_mutex unnecessarily, rc=$?"
20821         fi
20822         rm -f $DIR/$tfile
20823
20824 }
20825 run_test 258b "verify i_mutex security behavior"
20826
20827 test_259() {
20828         local file=$DIR/$tfile
20829         local before
20830         local after
20831
20832         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20833
20834         stack_trap "rm -f $file" EXIT
20835
20836         wait_delete_completed
20837         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20838         echo "before: $before"
20839
20840         $LFS setstripe -i 0 -c 1 $file
20841         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20842         sync_all_data
20843         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20844         echo "after write: $after"
20845
20846 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20847         do_facet ost1 $LCTL set_param fail_loc=0x2301
20848         $TRUNCATE $file 0
20849         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20850         echo "after truncate: $after"
20851
20852         stop ost1
20853         do_facet ost1 $LCTL set_param fail_loc=0
20854         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20855         sleep 2
20856         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20857         echo "after restart: $after"
20858         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20859                 error "missing truncate?"
20860
20861         return 0
20862 }
20863 run_test 259 "crash at delayed truncate"
20864
20865 test_260() {
20866 #define OBD_FAIL_MDC_CLOSE               0x806
20867         $LCTL set_param fail_loc=0x80000806
20868         touch $DIR/$tfile
20869
20870 }
20871 run_test 260 "Check mdc_close fail"
20872
20873 ### Data-on-MDT sanity tests ###
20874 test_270a() {
20875         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20876                 skip "Need MDS version at least 2.10.55 for DoM"
20877
20878         # create DoM file
20879         local dom=$DIR/$tdir/dom_file
20880         local tmp=$DIR/$tdir/tmp_file
20881
20882         mkdir -p $DIR/$tdir
20883
20884         # basic checks for DoM component creation
20885         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20886                 error "Can set MDT layout to non-first entry"
20887
20888         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20889                 error "Can define multiple entries as MDT layout"
20890
20891         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20892
20893         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20894         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20895         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20896
20897         local mdtidx=$($LFS getstripe -m $dom)
20898         local mdtname=MDT$(printf %04x $mdtidx)
20899         local facet=mds$((mdtidx + 1))
20900         local space_check=1
20901
20902         # Skip free space checks with ZFS
20903         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20904
20905         # write
20906         sync
20907         local size_tmp=$((65536 * 3))
20908         local mdtfree1=$(do_facet $facet \
20909                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20910
20911         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20912         # check also direct IO along write
20913         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20914         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20915         sync
20916         cmp $tmp $dom || error "file data is different"
20917         [ $(stat -c%s $dom) == $size_tmp ] ||
20918                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20919         if [ $space_check == 1 ]; then
20920                 local mdtfree2=$(do_facet $facet \
20921                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20922
20923                 # increase in usage from by $size_tmp
20924                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20925                         error "MDT free space wrong after write: " \
20926                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20927         fi
20928
20929         # truncate
20930         local size_dom=10000
20931
20932         $TRUNCATE $dom $size_dom
20933         [ $(stat -c%s $dom) == $size_dom ] ||
20934                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20935         if [ $space_check == 1 ]; then
20936                 mdtfree1=$(do_facet $facet \
20937                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20938                 # decrease in usage from $size_tmp to new $size_dom
20939                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20940                   $(((size_tmp - size_dom) / 1024)) ] ||
20941                         error "MDT free space is wrong after truncate: " \
20942                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20943         fi
20944
20945         # append
20946         cat $tmp >> $dom
20947         sync
20948         size_dom=$((size_dom + size_tmp))
20949         [ $(stat -c%s $dom) == $size_dom ] ||
20950                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20951         if [ $space_check == 1 ]; then
20952                 mdtfree2=$(do_facet $facet \
20953                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20954                 # increase in usage by $size_tmp from previous
20955                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20956                         error "MDT free space is wrong after append: " \
20957                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20958         fi
20959
20960         # delete
20961         rm $dom
20962         if [ $space_check == 1 ]; then
20963                 mdtfree1=$(do_facet $facet \
20964                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20965                 # decrease in usage by $size_dom from previous
20966                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20967                         error "MDT free space is wrong after removal: " \
20968                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20969         fi
20970
20971         # combined striping
20972         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20973                 error "Can't create DoM + OST striping"
20974
20975         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20976         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20977         # check also direct IO along write
20978         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20979         sync
20980         cmp $tmp $dom || error "file data is different"
20981         [ $(stat -c%s $dom) == $size_tmp ] ||
20982                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20983         rm $dom $tmp
20984
20985         return 0
20986 }
20987 run_test 270a "DoM: basic functionality tests"
20988
20989 test_270b() {
20990         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20991                 skip "Need MDS version at least 2.10.55"
20992
20993         local dom=$DIR/$tdir/dom_file
20994         local max_size=1048576
20995
20996         mkdir -p $DIR/$tdir
20997         $LFS setstripe -E $max_size -L mdt $dom
20998
20999         # truncate over the limit
21000         $TRUNCATE $dom $(($max_size + 1)) &&
21001                 error "successful truncate over the maximum size"
21002         # write over the limit
21003         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21004                 error "successful write over the maximum size"
21005         # append over the limit
21006         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21007         echo "12345" >> $dom && error "successful append over the maximum size"
21008         rm $dom
21009
21010         return 0
21011 }
21012 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21013
21014 test_270c() {
21015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21016                 skip "Need MDS version at least 2.10.55"
21017
21018         mkdir -p $DIR/$tdir
21019         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21020
21021         # check files inherit DoM EA
21022         touch $DIR/$tdir/first
21023         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21024                 error "bad pattern"
21025         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21026                 error "bad stripe count"
21027         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21028                 error "bad stripe size"
21029
21030         # check directory inherits DoM EA and uses it as default
21031         mkdir $DIR/$tdir/subdir
21032         touch $DIR/$tdir/subdir/second
21033         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21034                 error "bad pattern in sub-directory"
21035         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21036                 error "bad stripe count in sub-directory"
21037         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21038                 error "bad stripe size in sub-directory"
21039         return 0
21040 }
21041 run_test 270c "DoM: DoM EA inheritance tests"
21042
21043 test_270d() {
21044         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21045                 skip "Need MDS version at least 2.10.55"
21046
21047         mkdir -p $DIR/$tdir
21048         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21049
21050         # inherit default DoM striping
21051         mkdir $DIR/$tdir/subdir
21052         touch $DIR/$tdir/subdir/f1
21053
21054         # change default directory striping
21055         $LFS setstripe -c 1 $DIR/$tdir/subdir
21056         touch $DIR/$tdir/subdir/f2
21057         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21058                 error "wrong default striping in file 2"
21059         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21060                 error "bad pattern in file 2"
21061         return 0
21062 }
21063 run_test 270d "DoM: change striping from DoM to RAID0"
21064
21065 test_270e() {
21066         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21067                 skip "Need MDS version at least 2.10.55"
21068
21069         mkdir -p $DIR/$tdir/dom
21070         mkdir -p $DIR/$tdir/norm
21071         DOMFILES=20
21072         NORMFILES=10
21073         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21074         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21075
21076         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21077         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21078
21079         # find DoM files by layout
21080         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21081         [ $NUM -eq  $DOMFILES ] ||
21082                 error "lfs find -L: found $NUM, expected $DOMFILES"
21083         echo "Test 1: lfs find 20 DOM files by layout: OK"
21084
21085         # there should be 1 dir with default DOM striping
21086         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21087         [ $NUM -eq  1 ] ||
21088                 error "lfs find -L: found $NUM, expected 1 dir"
21089         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21090
21091         # find DoM files by stripe size
21092         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21093         [ $NUM -eq  $DOMFILES ] ||
21094                 error "lfs find -S: found $NUM, expected $DOMFILES"
21095         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21096
21097         # find files by stripe offset except DoM files
21098         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21099         [ $NUM -eq  $NORMFILES ] ||
21100                 error "lfs find -i: found $NUM, expected $NORMFILES"
21101         echo "Test 5: lfs find no DOM files by stripe index: OK"
21102         return 0
21103 }
21104 run_test 270e "DoM: lfs find with DoM files test"
21105
21106 test_270f() {
21107         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21108                 skip "Need MDS version at least 2.10.55"
21109
21110         local mdtname=${FSNAME}-MDT0000-mdtlov
21111         local dom=$DIR/$tdir/dom_file
21112         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21113                                                 lod.$mdtname.dom_stripesize)
21114         local dom_limit=131072
21115
21116         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21117         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21118                                                 lod.$mdtname.dom_stripesize)
21119         [ ${dom_limit} -eq ${dom_current} ] ||
21120                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21121
21122         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21123         $LFS setstripe -d $DIR/$tdir
21124         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21125                 error "Can't set directory default striping"
21126
21127         # exceed maximum stripe size
21128         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21129                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21130         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21131                 error "Able to create DoM component size more than LOD limit"
21132
21133         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21134         dom_current=$(do_facet mds1 $LCTL get_param -n \
21135                                                 lod.$mdtname.dom_stripesize)
21136         [ 0 -eq ${dom_current} ] ||
21137                 error "Can't set zero DoM stripe limit"
21138         rm $dom
21139
21140         # attempt to create DoM file on server with disabled DoM should
21141         # remove DoM entry from layout and be succeed
21142         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21143                 error "Can't create DoM file (DoM is disabled)"
21144         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21145                 error "File has DoM component while DoM is disabled"
21146         rm $dom
21147
21148         # attempt to create DoM file with only DoM stripe should return error
21149         $LFS setstripe -E $dom_limit -L mdt $dom &&
21150                 error "Able to create DoM-only file while DoM is disabled"
21151
21152         # too low values to be aligned with smallest stripe size 64K
21153         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21154         dom_current=$(do_facet mds1 $LCTL get_param -n \
21155                                                 lod.$mdtname.dom_stripesize)
21156         [ 30000 -eq ${dom_current} ] &&
21157                 error "Can set too small DoM stripe limit"
21158
21159         # 64K is a minimal stripe size in Lustre, expect limit of that size
21160         [ 65536 -eq ${dom_current} ] ||
21161                 error "Limit is not set to 64K but ${dom_current}"
21162
21163         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21164         dom_current=$(do_facet mds1 $LCTL get_param -n \
21165                                                 lod.$mdtname.dom_stripesize)
21166         echo $dom_current
21167         [ 2147483648 -eq ${dom_current} ] &&
21168                 error "Can set too large DoM stripe limit"
21169
21170         do_facet mds1 $LCTL set_param -n \
21171                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21172         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21173                 error "Can't create DoM component size after limit change"
21174         do_facet mds1 $LCTL set_param -n \
21175                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21176         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21177                 error "Can't create DoM file after limit decrease"
21178         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21179                 error "Can create big DoM component after limit decrease"
21180         touch ${dom}_def ||
21181                 error "Can't create file with old default layout"
21182
21183         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21184         return 0
21185 }
21186 run_test 270f "DoM: maximum DoM stripe size checks"
21187
21188 test_270g() {
21189         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21190                 skip "Need MDS version at least 2.13.52"
21191         local dom=$DIR/$tdir/$tfile
21192
21193         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21194         local lodname=${FSNAME}-MDT0000-mdtlov
21195
21196         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21197         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21198         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21199         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21200
21201         local dom_limit=1024
21202         local dom_threshold="50%"
21203
21204         $LFS setstripe -d $DIR/$tdir
21205         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21206                 error "Can't set directory default striping"
21207
21208         do_facet mds1 $LCTL set_param -n \
21209                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21210         # set 0 threshold and create DOM file to change tunable stripesize
21211         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21212         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21213                 error "Failed to create $dom file"
21214         # now tunable dom_cur_stripesize should reach maximum
21215         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21216                                         lod.${lodname}.dom_stripesize_cur_kb)
21217         [[ $dom_current == $dom_limit ]] ||
21218                 error "Current DOM stripesize is not maximum"
21219         rm $dom
21220
21221         # set threshold for further tests
21222         do_facet mds1 $LCTL set_param -n \
21223                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21224         echo "DOM threshold is $dom_threshold free space"
21225         local dom_def
21226         local dom_set
21227         # Spoof bfree to exceed threshold
21228         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21229         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21230         for spfree in 40 20 0 15 30 55; do
21231                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21232                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21233                         error "Failed to create $dom file"
21234                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21235                                         lod.${lodname}.dom_stripesize_cur_kb)
21236                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21237                 [[ $dom_def != $dom_current ]] ||
21238                         error "Default stripe size was not changed"
21239                 if [[ $spfree > 0 ]] ; then
21240                         dom_set=$($LFS getstripe -S $dom)
21241                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21242                                 error "DOM component size is still old"
21243                 else
21244                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21245                                 error "DoM component is set with no free space"
21246                 fi
21247                 rm $dom
21248                 dom_current=$dom_def
21249         done
21250 }
21251 run_test 270g "DoM: default DoM stripe size depends on free space"
21252
21253 test_270h() {
21254         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21255                 skip "Need MDS version at least 2.13.53"
21256
21257         local mdtname=${FSNAME}-MDT0000-mdtlov
21258         local dom=$DIR/$tdir/$tfile
21259         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21260
21261         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21262         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21263
21264         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21265         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21266                 error "can't create OST file"
21267         # mirrored file with DOM entry in the second mirror
21268         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21269                 error "can't create mirror with DoM component"
21270
21271         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21272
21273         # DOM component in the middle and has other enries in the same mirror,
21274         # should succeed but lost DoM component
21275         $LFS setstripe --copy=${dom}_1 $dom ||
21276                 error "Can't create file from OST|DOM mirror layout"
21277         # check new file has no DoM layout after all
21278         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21279                 error "File has DoM component while DoM is disabled"
21280 }
21281 run_test 270h "DoM: DoM stripe removal when disabled on server"
21282
21283 test_271a() {
21284         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21285                 skip "Need MDS version at least 2.10.55"
21286
21287         local dom=$DIR/$tdir/dom
21288
21289         mkdir -p $DIR/$tdir
21290
21291         $LFS setstripe -E 1024K -L mdt $dom
21292
21293         lctl set_param -n mdc.*.stats=clear
21294         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21295         cat $dom > /dev/null
21296         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21297         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21298         ls $dom
21299         rm -f $dom
21300 }
21301 run_test 271a "DoM: data is cached for read after write"
21302
21303 test_271b() {
21304         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21305                 skip "Need MDS version at least 2.10.55"
21306
21307         local dom=$DIR/$tdir/dom
21308
21309         mkdir -p $DIR/$tdir
21310
21311         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21312
21313         lctl set_param -n mdc.*.stats=clear
21314         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21315         cancel_lru_locks mdc
21316         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21317         # second stat to check size is cached on client
21318         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21319         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21320         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21321         rm -f $dom
21322 }
21323 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21324
21325 test_271ba() {
21326         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21327                 skip "Need MDS version at least 2.10.55"
21328
21329         local dom=$DIR/$tdir/dom
21330
21331         mkdir -p $DIR/$tdir
21332
21333         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21334
21335         lctl set_param -n mdc.*.stats=clear
21336         lctl set_param -n osc.*.stats=clear
21337         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21338         cancel_lru_locks mdc
21339         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21340         # second stat to check size is cached on client
21341         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21342         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21343         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21344         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21345         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21346         rm -f $dom
21347 }
21348 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21349
21350
21351 get_mdc_stats() {
21352         local mdtidx=$1
21353         local param=$2
21354         local mdt=MDT$(printf %04x $mdtidx)
21355
21356         if [ -z $param ]; then
21357                 lctl get_param -n mdc.*$mdt*.stats
21358         else
21359                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21360         fi
21361 }
21362
21363 test_271c() {
21364         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21365                 skip "Need MDS version at least 2.10.55"
21366
21367         local dom=$DIR/$tdir/dom
21368
21369         mkdir -p $DIR/$tdir
21370
21371         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21372
21373         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21374         local facet=mds$((mdtidx + 1))
21375
21376         cancel_lru_locks mdc
21377         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21378         createmany -o $dom 1000
21379         lctl set_param -n mdc.*.stats=clear
21380         smalliomany -w $dom 1000 200
21381         get_mdc_stats $mdtidx
21382         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21383         # Each file has 1 open, 1 IO enqueues, total 2000
21384         # but now we have also +1 getxattr for security.capability, total 3000
21385         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21386         unlinkmany $dom 1000
21387
21388         cancel_lru_locks mdc
21389         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21390         createmany -o $dom 1000
21391         lctl set_param -n mdc.*.stats=clear
21392         smalliomany -w $dom 1000 200
21393         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21394         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21395         # for OPEN and IO lock.
21396         [ $((enq - enq_2)) -ge 1000 ] ||
21397                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21398         unlinkmany $dom 1000
21399         return 0
21400 }
21401 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21402
21403 cleanup_271def_tests() {
21404         trap 0
21405         rm -f $1
21406 }
21407
21408 test_271d() {
21409         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21410                 skip "Need MDS version at least 2.10.57"
21411
21412         local dom=$DIR/$tdir/dom
21413         local tmp=$TMP/$tfile
21414         trap "cleanup_271def_tests $tmp" EXIT
21415
21416         mkdir -p $DIR/$tdir
21417
21418         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21419
21420         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21421
21422         cancel_lru_locks mdc
21423         dd if=/dev/urandom of=$tmp bs=1000 count=1
21424         dd if=$tmp of=$dom bs=1000 count=1
21425         cancel_lru_locks mdc
21426
21427         cat /etc/hosts >> $tmp
21428         lctl set_param -n mdc.*.stats=clear
21429
21430         # append data to the same file it should update local page
21431         echo "Append to the same page"
21432         cat /etc/hosts >> $dom
21433         local num=$(get_mdc_stats $mdtidx ost_read)
21434         local ra=$(get_mdc_stats $mdtidx req_active)
21435         local rw=$(get_mdc_stats $mdtidx req_waittime)
21436
21437         [ -z $num ] || error "$num READ RPC occured"
21438         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21439         echo "... DONE"
21440
21441         # compare content
21442         cmp $tmp $dom || error "file miscompare"
21443
21444         cancel_lru_locks mdc
21445         lctl set_param -n mdc.*.stats=clear
21446
21447         echo "Open and read file"
21448         cat $dom > /dev/null
21449         local num=$(get_mdc_stats $mdtidx ost_read)
21450         local ra=$(get_mdc_stats $mdtidx req_active)
21451         local rw=$(get_mdc_stats $mdtidx req_waittime)
21452
21453         [ -z $num ] || error "$num READ RPC occured"
21454         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21455         echo "... DONE"
21456
21457         # compare content
21458         cmp $tmp $dom || error "file miscompare"
21459
21460         return 0
21461 }
21462 run_test 271d "DoM: read on open (1K file in reply buffer)"
21463
21464 test_271f() {
21465         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21466                 skip "Need MDS version at least 2.10.57"
21467
21468         local dom=$DIR/$tdir/dom
21469         local tmp=$TMP/$tfile
21470         trap "cleanup_271def_tests $tmp" EXIT
21471
21472         mkdir -p $DIR/$tdir
21473
21474         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21475
21476         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21477
21478         cancel_lru_locks mdc
21479         dd if=/dev/urandom of=$tmp bs=265000 count=1
21480         dd if=$tmp of=$dom bs=265000 count=1
21481         cancel_lru_locks mdc
21482         cat /etc/hosts >> $tmp
21483         lctl set_param -n mdc.*.stats=clear
21484
21485         echo "Append to the same page"
21486         cat /etc/hosts >> $dom
21487         local num=$(get_mdc_stats $mdtidx ost_read)
21488         local ra=$(get_mdc_stats $mdtidx req_active)
21489         local rw=$(get_mdc_stats $mdtidx req_waittime)
21490
21491         [ -z $num ] || error "$num READ RPC occured"
21492         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21493         echo "... DONE"
21494
21495         # compare content
21496         cmp $tmp $dom || error "file miscompare"
21497
21498         cancel_lru_locks mdc
21499         lctl set_param -n mdc.*.stats=clear
21500
21501         echo "Open and read file"
21502         cat $dom > /dev/null
21503         local num=$(get_mdc_stats $mdtidx ost_read)
21504         local ra=$(get_mdc_stats $mdtidx req_active)
21505         local rw=$(get_mdc_stats $mdtidx req_waittime)
21506
21507         [ -z $num ] && num=0
21508         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21509         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21510         echo "... DONE"
21511
21512         # compare content
21513         cmp $tmp $dom || error "file miscompare"
21514
21515         return 0
21516 }
21517 run_test 271f "DoM: read on open (200K file and read tail)"
21518
21519 test_271g() {
21520         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21521                 skip "Skipping due to old client or server version"
21522
21523         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21524         # to get layout
21525         $CHECKSTAT -t file $DIR1/$tfile
21526
21527         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21528         MULTIOP_PID=$!
21529         sleep 1
21530         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21531         $LCTL set_param fail_loc=0x80000314
21532         rm $DIR1/$tfile || error "Unlink fails"
21533         RC=$?
21534         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21535         [ $RC -eq 0 ] || error "Failed write to stale object"
21536 }
21537 run_test 271g "Discard DoM data vs client flush race"
21538
21539 test_272a() {
21540         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21541                 skip "Need MDS version at least 2.11.50"
21542
21543         local dom=$DIR/$tdir/dom
21544         mkdir -p $DIR/$tdir
21545
21546         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21547         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21548                 error "failed to write data into $dom"
21549         local old_md5=$(md5sum $dom)
21550
21551         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21552                 error "failed to migrate to the same DoM component"
21553
21554         local new_md5=$(md5sum $dom)
21555
21556         [ "$old_md5" == "$new_md5" ] ||
21557                 error "md5sum differ: $old_md5, $new_md5"
21558
21559         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21560                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21561 }
21562 run_test 272a "DoM migration: new layout with the same DOM component"
21563
21564 test_272b() {
21565         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21566                 skip "Need MDS version at least 2.11.50"
21567
21568         local dom=$DIR/$tdir/dom
21569         mkdir -p $DIR/$tdir
21570         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21571
21572         local mdtidx=$($LFS getstripe -m $dom)
21573         local mdtname=MDT$(printf %04x $mdtidx)
21574         local facet=mds$((mdtidx + 1))
21575
21576         local mdtfree1=$(do_facet $facet \
21577                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21578         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21579                 error "failed to write data into $dom"
21580         local old_md5=$(md5sum $dom)
21581         cancel_lru_locks mdc
21582         local mdtfree1=$(do_facet $facet \
21583                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21584
21585         $LFS migrate -c2 $dom ||
21586                 error "failed to migrate to the new composite layout"
21587         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21588                 error "MDT stripe was not removed"
21589
21590         cancel_lru_locks mdc
21591         local new_md5=$(md5sum $dom)
21592         [ "$old_md5" == "$new_md5" ] ||
21593                 error "$old_md5 != $new_md5"
21594
21595         # Skip free space checks with ZFS
21596         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21597                 local mdtfree2=$(do_facet $facet \
21598                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21599                 [ $mdtfree2 -gt $mdtfree1 ] ||
21600                         error "MDT space is not freed after migration"
21601         fi
21602         return 0
21603 }
21604 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21605
21606 test_272c() {
21607         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21608                 skip "Need MDS version at least 2.11.50"
21609
21610         local dom=$DIR/$tdir/$tfile
21611         mkdir -p $DIR/$tdir
21612         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21613
21614         local mdtidx=$($LFS getstripe -m $dom)
21615         local mdtname=MDT$(printf %04x $mdtidx)
21616         local facet=mds$((mdtidx + 1))
21617
21618         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21619                 error "failed to write data into $dom"
21620         local old_md5=$(md5sum $dom)
21621         cancel_lru_locks mdc
21622         local mdtfree1=$(do_facet $facet \
21623                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21624
21625         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21626                 error "failed to migrate to the new composite layout"
21627         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21628                 error "MDT stripe was not removed"
21629
21630         cancel_lru_locks mdc
21631         local new_md5=$(md5sum $dom)
21632         [ "$old_md5" == "$new_md5" ] ||
21633                 error "$old_md5 != $new_md5"
21634
21635         # Skip free space checks with ZFS
21636         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21637                 local mdtfree2=$(do_facet $facet \
21638                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21639                 [ $mdtfree2 -gt $mdtfree1 ] ||
21640                         error "MDS space is not freed after migration"
21641         fi
21642         return 0
21643 }
21644 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21645
21646 test_272d() {
21647         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21648                 skip "Need MDS version at least 2.12.55"
21649
21650         local dom=$DIR/$tdir/$tfile
21651         mkdir -p $DIR/$tdir
21652         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21653
21654         local mdtidx=$($LFS getstripe -m $dom)
21655         local mdtname=MDT$(printf %04x $mdtidx)
21656         local facet=mds$((mdtidx + 1))
21657
21658         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21659                 error "failed to write data into $dom"
21660         local old_md5=$(md5sum $dom)
21661         cancel_lru_locks mdc
21662         local mdtfree1=$(do_facet $facet \
21663                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21664
21665         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21666                 error "failed mirroring to the new composite layout"
21667         $LFS mirror resync $dom ||
21668                 error "failed mirror resync"
21669         $LFS mirror split --mirror-id 1 -d $dom ||
21670                 error "failed mirror split"
21671
21672         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21673                 error "MDT stripe was not removed"
21674
21675         cancel_lru_locks mdc
21676         local new_md5=$(md5sum $dom)
21677         [ "$old_md5" == "$new_md5" ] ||
21678                 error "$old_md5 != $new_md5"
21679
21680         # Skip free space checks with ZFS
21681         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21682                 local mdtfree2=$(do_facet $facet \
21683                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21684                 [ $mdtfree2 -gt $mdtfree1 ] ||
21685                         error "MDS space is not freed after DOM mirror deletion"
21686         fi
21687         return 0
21688 }
21689 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21690
21691 test_272e() {
21692         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21693                 skip "Need MDS version at least 2.12.55"
21694
21695         local dom=$DIR/$tdir/$tfile
21696         mkdir -p $DIR/$tdir
21697         $LFS setstripe -c 2 $dom
21698
21699         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21700                 error "failed to write data into $dom"
21701         local old_md5=$(md5sum $dom)
21702         cancel_lru_locks mdc
21703
21704         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21705                 error "failed mirroring to the DOM layout"
21706         $LFS mirror resync $dom ||
21707                 error "failed mirror resync"
21708         $LFS mirror split --mirror-id 1 -d $dom ||
21709                 error "failed mirror split"
21710
21711         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21712                 error "MDT stripe was not removed"
21713
21714         cancel_lru_locks mdc
21715         local new_md5=$(md5sum $dom)
21716         [ "$old_md5" == "$new_md5" ] ||
21717                 error "$old_md5 != $new_md5"
21718
21719         return 0
21720 }
21721 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21722
21723 test_272f() {
21724         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21725                 skip "Need MDS version at least 2.12.55"
21726
21727         local dom=$DIR/$tdir/$tfile
21728         mkdir -p $DIR/$tdir
21729         $LFS setstripe -c 2 $dom
21730
21731         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21732                 error "failed to write data into $dom"
21733         local old_md5=$(md5sum $dom)
21734         cancel_lru_locks mdc
21735
21736         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21737                 error "failed migrating to the DOM file"
21738
21739         cancel_lru_locks mdc
21740         local new_md5=$(md5sum $dom)
21741         [ "$old_md5" != "$new_md5" ] &&
21742                 error "$old_md5 != $new_md5"
21743
21744         return 0
21745 }
21746 run_test 272f "DoM migration: OST-striped file to DOM file"
21747
21748 test_273a() {
21749         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21750                 skip "Need MDS version at least 2.11.50"
21751
21752         # Layout swap cannot be done if either file has DOM component,
21753         # this will never be supported, migration should be used instead
21754
21755         local dom=$DIR/$tdir/$tfile
21756         mkdir -p $DIR/$tdir
21757
21758         $LFS setstripe -c2 ${dom}_plain
21759         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21760         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21761                 error "can swap layout with DoM component"
21762         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21763                 error "can swap layout with DoM component"
21764
21765         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21766         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21767                 error "can swap layout with DoM component"
21768         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21769                 error "can swap layout with DoM component"
21770         return 0
21771 }
21772 run_test 273a "DoM: layout swapping should fail with DOM"
21773
21774 test_273b() {
21775         mkdir -p $DIR/$tdir
21776         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21777
21778 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21779         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21780
21781         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21782 }
21783 run_test 273b "DoM: race writeback and object destroy"
21784
21785 test_275() {
21786         remote_ost_nodsh && skip "remote OST with nodsh"
21787         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21788                 skip "Need OST version >= 2.10.57"
21789
21790         local file=$DIR/$tfile
21791         local oss
21792
21793         oss=$(comma_list $(osts_nodes))
21794
21795         dd if=/dev/urandom of=$file bs=1M count=2 ||
21796                 error "failed to create a file"
21797         cancel_lru_locks osc
21798
21799         #lock 1
21800         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21801                 error "failed to read a file"
21802
21803 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21804         $LCTL set_param fail_loc=0x8000031f
21805
21806         cancel_lru_locks osc &
21807         sleep 1
21808
21809 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21810         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21811         #IO takes another lock, but matches the PENDING one
21812         #and places it to the IO RPC
21813         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21814                 error "failed to read a file with PENDING lock"
21815 }
21816 run_test 275 "Read on a canceled duplicate lock"
21817
21818 test_276() {
21819         remote_ost_nodsh && skip "remote OST with nodsh"
21820         local pid
21821
21822         do_facet ost1 "(while true; do \
21823                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21824                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21825         pid=$!
21826
21827         for LOOP in $(seq 20); do
21828                 stop ost1
21829                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21830         done
21831         kill -9 $pid
21832         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21833                 rm $TMP/sanity_276_pid"
21834 }
21835 run_test 276 "Race between mount and obd_statfs"
21836
21837 test_277() {
21838         $LCTL set_param ldlm.namespaces.*.lru_size=0
21839         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21840         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21841                         grep ^used_mb | awk '{print $2}')
21842         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21843         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21844                 oflag=direct conv=notrunc
21845         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21846                         grep ^used_mb | awk '{print $2}')
21847         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21848 }
21849 run_test 277 "Direct IO shall drop page cache"
21850
21851 test_278() {
21852         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21853         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21854         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21855                 skip "needs the same host for mdt1 mdt2" && return
21856
21857         local pid1
21858         local pid2
21859
21860 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21861         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21862         stop mds2 &
21863         pid2=$!
21864
21865         stop mds1
21866
21867         echo "Starting MDTs"
21868         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21869         wait $pid2
21870 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21871 #will return NULL
21872         do_facet mds2 $LCTL set_param fail_loc=0
21873
21874         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21875         wait_recovery_complete mds2
21876 }
21877 run_test 278 "Race starting MDS between MDTs stop/start"
21878
21879 test_280() {
21880         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21881                 skip "Need MGS version at least 2.13.52"
21882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21883         combined_mgs_mds || skip "needs combined MGS/MDT"
21884
21885         umount_client $MOUNT
21886 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21887         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21888
21889         mount_client $MOUNT &
21890         sleep 1
21891         stop mgs || error "stop mgs failed"
21892         #for a race mgs would crash
21893         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21894         # make sure we unmount client before remounting
21895         wait
21896         umount_client $MOUNT
21897         mount_client $MOUNT || error "mount client failed"
21898 }
21899 run_test 280 "Race between MGS umount and client llog processing"
21900
21901 cleanup_test_300() {
21902         trap 0
21903         umask $SAVE_UMASK
21904 }
21905 test_striped_dir() {
21906         local mdt_index=$1
21907         local stripe_count
21908         local stripe_index
21909
21910         mkdir -p $DIR/$tdir
21911
21912         SAVE_UMASK=$(umask)
21913         trap cleanup_test_300 RETURN EXIT
21914
21915         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21916                                                 $DIR/$tdir/striped_dir ||
21917                 error "set striped dir error"
21918
21919         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21920         [ "$mode" = "755" ] || error "expect 755 got $mode"
21921
21922         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21923                 error "getdirstripe failed"
21924         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21925         if [ "$stripe_count" != "2" ]; then
21926                 error "1:stripe_count is $stripe_count, expect 2"
21927         fi
21928         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21929         if [ "$stripe_count" != "2" ]; then
21930                 error "2:stripe_count is $stripe_count, expect 2"
21931         fi
21932
21933         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21934         if [ "$stripe_index" != "$mdt_index" ]; then
21935                 error "stripe_index is $stripe_index, expect $mdt_index"
21936         fi
21937
21938         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21939                 error "nlink error after create striped dir"
21940
21941         mkdir $DIR/$tdir/striped_dir/a
21942         mkdir $DIR/$tdir/striped_dir/b
21943
21944         stat $DIR/$tdir/striped_dir/a ||
21945                 error "create dir under striped dir failed"
21946         stat $DIR/$tdir/striped_dir/b ||
21947                 error "create dir under striped dir failed"
21948
21949         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21950                 error "nlink error after mkdir"
21951
21952         rmdir $DIR/$tdir/striped_dir/a
21953         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21954                 error "nlink error after rmdir"
21955
21956         rmdir $DIR/$tdir/striped_dir/b
21957         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21958                 error "nlink error after rmdir"
21959
21960         chattr +i $DIR/$tdir/striped_dir
21961         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21962                 error "immutable flags not working under striped dir!"
21963         chattr -i $DIR/$tdir/striped_dir
21964
21965         rmdir $DIR/$tdir/striped_dir ||
21966                 error "rmdir striped dir error"
21967
21968         cleanup_test_300
21969
21970         true
21971 }
21972
21973 test_300a() {
21974         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21975                 skip "skipped for lustre < 2.7.0"
21976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21978
21979         test_striped_dir 0 || error "failed on striped dir on MDT0"
21980         test_striped_dir 1 || error "failed on striped dir on MDT0"
21981 }
21982 run_test 300a "basic striped dir sanity test"
21983
21984 test_300b() {
21985         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21986                 skip "skipped for lustre < 2.7.0"
21987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21989
21990         local i
21991         local mtime1
21992         local mtime2
21993         local mtime3
21994
21995         test_mkdir $DIR/$tdir || error "mkdir fail"
21996         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21997                 error "set striped dir error"
21998         for i in {0..9}; do
21999                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22000                 sleep 1
22001                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22002                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22003                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22004                 sleep 1
22005                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22006                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22007                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22008         done
22009         true
22010 }
22011 run_test 300b "check ctime/mtime for striped dir"
22012
22013 test_300c() {
22014         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22015                 skip "skipped for lustre < 2.7.0"
22016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22018
22019         local file_count
22020
22021         mkdir -p $DIR/$tdir
22022         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22023                 error "set striped dir error"
22024
22025         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22026                 error "chown striped dir failed"
22027
22028         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22029                 error "create 5k files failed"
22030
22031         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22032
22033         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22034
22035         rm -rf $DIR/$tdir
22036 }
22037 run_test 300c "chown && check ls under striped directory"
22038
22039 test_300d() {
22040         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22041                 skip "skipped for lustre < 2.7.0"
22042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22044
22045         local stripe_count
22046         local file
22047
22048         mkdir -p $DIR/$tdir
22049         $LFS setstripe -c 2 $DIR/$tdir
22050
22051         #local striped directory
22052         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22053                 error "set striped dir error"
22054         #look at the directories for debug purposes
22055         ls -l $DIR/$tdir
22056         $LFS getdirstripe $DIR/$tdir
22057         ls -l $DIR/$tdir/striped_dir
22058         $LFS getdirstripe $DIR/$tdir/striped_dir
22059         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22060                 error "create 10 files failed"
22061
22062         #remote striped directory
22063         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22064                 error "set striped dir error"
22065         #look at the directories for debug purposes
22066         ls -l $DIR/$tdir
22067         $LFS getdirstripe $DIR/$tdir
22068         ls -l $DIR/$tdir/remote_striped_dir
22069         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22070         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22071                 error "create 10 files failed"
22072
22073         for file in $(find $DIR/$tdir); do
22074                 stripe_count=$($LFS getstripe -c $file)
22075                 [ $stripe_count -eq 2 ] ||
22076                         error "wrong stripe $stripe_count for $file"
22077         done
22078
22079         rm -rf $DIR/$tdir
22080 }
22081 run_test 300d "check default stripe under striped directory"
22082
22083 test_300e() {
22084         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22085                 skip "Need MDS version at least 2.7.55"
22086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22088
22089         local stripe_count
22090         local file
22091
22092         mkdir -p $DIR/$tdir
22093
22094         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22095                 error "set striped dir error"
22096
22097         touch $DIR/$tdir/striped_dir/a
22098         touch $DIR/$tdir/striped_dir/b
22099         touch $DIR/$tdir/striped_dir/c
22100
22101         mkdir $DIR/$tdir/striped_dir/dir_a
22102         mkdir $DIR/$tdir/striped_dir/dir_b
22103         mkdir $DIR/$tdir/striped_dir/dir_c
22104
22105         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22106                 error "set striped adir under striped dir error"
22107
22108         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22109                 error "set striped bdir under striped dir error"
22110
22111         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22112                 error "set striped cdir under striped dir error"
22113
22114         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22115                 error "rename dir under striped dir fails"
22116
22117         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22118                 error "rename dir under different stripes fails"
22119
22120         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22121                 error "rename file under striped dir should succeed"
22122
22123         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22124                 error "rename dir under striped dir should succeed"
22125
22126         rm -rf $DIR/$tdir
22127 }
22128 run_test 300e "check rename under striped directory"
22129
22130 test_300f() {
22131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22133         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22134                 skip "Need MDS version at least 2.7.55"
22135
22136         local stripe_count
22137         local file
22138
22139         rm -rf $DIR/$tdir
22140         mkdir -p $DIR/$tdir
22141
22142         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22143                 error "set striped dir error"
22144
22145         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22146                 error "set striped dir error"
22147
22148         touch $DIR/$tdir/striped_dir/a
22149         mkdir $DIR/$tdir/striped_dir/dir_a
22150         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22151                 error "create striped dir under striped dir fails"
22152
22153         touch $DIR/$tdir/striped_dir1/b
22154         mkdir $DIR/$tdir/striped_dir1/dir_b
22155         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22156                 error "create striped dir under striped dir fails"
22157
22158         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22159                 error "rename dir under different striped dir should fail"
22160
22161         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22162                 error "rename striped dir under diff striped dir should fail"
22163
22164         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22165                 error "rename file under diff striped dirs fails"
22166
22167         rm -rf $DIR/$tdir
22168 }
22169 run_test 300f "check rename cross striped directory"
22170
22171 test_300_check_default_striped_dir()
22172 {
22173         local dirname=$1
22174         local default_count=$2
22175         local default_index=$3
22176         local stripe_count
22177         local stripe_index
22178         local dir_stripe_index
22179         local dir
22180
22181         echo "checking $dirname $default_count $default_index"
22182         $LFS setdirstripe -D -c $default_count -i $default_index \
22183                                 -H all_char $DIR/$tdir/$dirname ||
22184                 error "set default stripe on striped dir error"
22185         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22186         [ $stripe_count -eq $default_count ] ||
22187                 error "expect $default_count get $stripe_count for $dirname"
22188
22189         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22190         [ $stripe_index -eq $default_index ] ||
22191                 error "expect $default_index get $stripe_index for $dirname"
22192
22193         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22194                                                 error "create dirs failed"
22195
22196         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22197         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22198         for dir in $(find $DIR/$tdir/$dirname/*); do
22199                 stripe_count=$($LFS getdirstripe -c $dir)
22200                 (( $stripe_count == $default_count )) ||
22201                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22202                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22203                 error "stripe count $default_count != $stripe_count for $dir"
22204
22205                 stripe_index=$($LFS getdirstripe -i $dir)
22206                 [ $default_index -eq -1 ] ||
22207                         [ $stripe_index -eq $default_index ] ||
22208                         error "$stripe_index != $default_index for $dir"
22209
22210                 #check default stripe
22211                 stripe_count=$($LFS getdirstripe -D -c $dir)
22212                 [ $stripe_count -eq $default_count ] ||
22213                 error "default count $default_count != $stripe_count for $dir"
22214
22215                 stripe_index=$($LFS getdirstripe -D -i $dir)
22216                 [ $stripe_index -eq $default_index ] ||
22217                 error "default index $default_index != $stripe_index for $dir"
22218         done
22219         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22220 }
22221
22222 test_300g() {
22223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22224         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22225                 skip "Need MDS version at least 2.7.55"
22226
22227         local dir
22228         local stripe_count
22229         local stripe_index
22230
22231         mkdir $DIR/$tdir
22232         mkdir $DIR/$tdir/normal_dir
22233
22234         #Checking when client cache stripe index
22235         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22236         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22237                 error "create striped_dir failed"
22238
22239         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22240                 error "create dir0 fails"
22241         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22242         [ $stripe_index -eq 0 ] ||
22243                 error "dir0 expect index 0 got $stripe_index"
22244
22245         mkdir $DIR/$tdir/striped_dir/dir1 ||
22246                 error "create dir1 fails"
22247         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22248         [ $stripe_index -eq 1 ] ||
22249                 error "dir1 expect index 1 got $stripe_index"
22250
22251         #check default stripe count/stripe index
22252         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22253         test_300_check_default_striped_dir normal_dir 1 0
22254         test_300_check_default_striped_dir normal_dir -1 1
22255         test_300_check_default_striped_dir normal_dir 2 -1
22256
22257         #delete default stripe information
22258         echo "delete default stripeEA"
22259         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22260                 error "set default stripe on striped dir error"
22261
22262         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22263         for dir in $(find $DIR/$tdir/normal_dir/*); do
22264                 stripe_count=$($LFS getdirstripe -c $dir)
22265                 [ $stripe_count -eq 0 ] ||
22266                         error "expect 1 get $stripe_count for $dir"
22267                 stripe_index=$($LFS getdirstripe -i $dir)
22268                 [ $stripe_index -eq 0 ] ||
22269                         error "expect 0 get $stripe_index for $dir"
22270         done
22271 }
22272 run_test 300g "check default striped directory for normal directory"
22273
22274 test_300h() {
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
22282         mkdir $DIR/$tdir
22283         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22284                 error "set striped dir error"
22285
22286         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22287         test_300_check_default_striped_dir striped_dir 1 0
22288         test_300_check_default_striped_dir striped_dir -1 1
22289         test_300_check_default_striped_dir striped_dir 2 -1
22290
22291         #delete default stripe information
22292         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22293                 error "set default stripe on striped dir error"
22294
22295         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22296         for dir in $(find $DIR/$tdir/striped_dir/*); do
22297                 stripe_count=$($LFS getdirstripe -c $dir)
22298                 [ $stripe_count -eq 0 ] ||
22299                         error "expect 1 get $stripe_count for $dir"
22300         done
22301 }
22302 run_test 300h "check default striped directory for striped directory"
22303
22304 test_300i() {
22305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22307         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22308                 skip "Need MDS version at least 2.7.55"
22309
22310         local stripe_count
22311         local file
22312
22313         mkdir $DIR/$tdir
22314
22315         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22316                 error "set striped dir error"
22317
22318         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22319                 error "create files under striped dir failed"
22320
22321         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22322                 error "set striped hashdir error"
22323
22324         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22325                 error "create dir0 under hash dir failed"
22326         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22327                 error "create dir1 under hash dir failed"
22328         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22329                 error "create dir2 under hash dir failed"
22330
22331         # unfortunately, we need to umount to clear dir layout cache for now
22332         # once we fully implement dir layout, we can drop this
22333         umount_client $MOUNT || error "umount failed"
22334         mount_client $MOUNT || error "mount failed"
22335
22336         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22337         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22338         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22339
22340         #set the stripe to be unknown hash type
22341         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22342         $LCTL set_param fail_loc=0x1901
22343         for ((i = 0; i < 10; i++)); do
22344                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22345                         error "stat f-$i failed"
22346                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22347         done
22348
22349         touch $DIR/$tdir/striped_dir/f0 &&
22350                 error "create under striped dir with unknown hash should fail"
22351
22352         $LCTL set_param fail_loc=0
22353
22354         umount_client $MOUNT || error "umount failed"
22355         mount_client $MOUNT || error "mount failed"
22356
22357         return 0
22358 }
22359 run_test 300i "client handle unknown hash type striped directory"
22360
22361 test_300j() {
22362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22364         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22365                 skip "Need MDS version at least 2.7.55"
22366
22367         local stripe_count
22368         local file
22369
22370         mkdir $DIR/$tdir
22371
22372         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22373         $LCTL set_param fail_loc=0x1702
22374         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22375                 error "set striped dir error"
22376
22377         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22378                 error "create files under striped dir failed"
22379
22380         $LCTL set_param fail_loc=0
22381
22382         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22383
22384         return 0
22385 }
22386 run_test 300j "test large update record"
22387
22388 test_300k() {
22389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22390         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22391         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22392                 skip "Need MDS version at least 2.7.55"
22393
22394         # this test needs a huge transaction
22395         local kb
22396         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22397              osd*.$FSNAME-MDT0000.kbytestotal")
22398         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22399
22400         local stripe_count
22401         local file
22402
22403         mkdir $DIR/$tdir
22404
22405         #define OBD_FAIL_LARGE_STRIPE   0x1703
22406         $LCTL set_param fail_loc=0x1703
22407         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22408                 error "set striped dir error"
22409         $LCTL set_param fail_loc=0
22410
22411         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22412                 error "getstripeddir fails"
22413         rm -rf $DIR/$tdir/striped_dir ||
22414                 error "unlink striped dir fails"
22415
22416         return 0
22417 }
22418 run_test 300k "test large striped directory"
22419
22420 test_300l() {
22421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22423         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22424                 skip "Need MDS version at least 2.7.55"
22425
22426         local stripe_index
22427
22428         test_mkdir -p $DIR/$tdir/striped_dir
22429         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22430                         error "chown $RUNAS_ID failed"
22431         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22432                 error "set default striped dir failed"
22433
22434         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22435         $LCTL set_param fail_loc=0x80000158
22436         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22437
22438         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22439         [ $stripe_index -eq 1 ] ||
22440                 error "expect 1 get $stripe_index for $dir"
22441 }
22442 run_test 300l "non-root user to create dir under striped dir with stale layout"
22443
22444 test_300m() {
22445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22446         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22447         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22448                 skip "Need MDS version at least 2.7.55"
22449
22450         mkdir -p $DIR/$tdir/striped_dir
22451         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22452                 error "set default stripes dir error"
22453
22454         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22455
22456         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22457         [ $stripe_count -eq 0 ] ||
22458                         error "expect 0 get $stripe_count for a"
22459
22460         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22461                 error "set default stripes dir error"
22462
22463         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22464
22465         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22466         [ $stripe_count -eq 0 ] ||
22467                         error "expect 0 get $stripe_count for b"
22468
22469         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22470                 error "set default stripes dir error"
22471
22472         mkdir $DIR/$tdir/striped_dir/c &&
22473                 error "default stripe_index is invalid, mkdir c should fails"
22474
22475         rm -rf $DIR/$tdir || error "rmdir fails"
22476 }
22477 run_test 300m "setstriped directory on single MDT FS"
22478
22479 cleanup_300n() {
22480         local list=$(comma_list $(mdts_nodes))
22481
22482         trap 0
22483         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22484 }
22485
22486 test_300n() {
22487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22489         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22490                 skip "Need MDS version at least 2.7.55"
22491         remote_mds_nodsh && skip "remote MDS with nodsh"
22492
22493         local stripe_index
22494         local list=$(comma_list $(mdts_nodes))
22495
22496         trap cleanup_300n RETURN EXIT
22497         mkdir -p $DIR/$tdir
22498         chmod 777 $DIR/$tdir
22499         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22500                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22501                 error "create striped dir succeeds with gid=0"
22502
22503         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22504         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22505                 error "create striped dir fails with gid=-1"
22506
22507         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22508         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22509                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22510                 error "set default striped dir succeeds with gid=0"
22511
22512
22513         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22514         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22515                 error "set default striped dir fails with gid=-1"
22516
22517
22518         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22519         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22520                                         error "create test_dir fails"
22521         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22522                                         error "create test_dir1 fails"
22523         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22524                                         error "create test_dir2 fails"
22525         cleanup_300n
22526 }
22527 run_test 300n "non-root user to create dir under striped dir with default EA"
22528
22529 test_300o() {
22530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22531         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22532         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22533                 skip "Need MDS version at least 2.7.55"
22534
22535         local numfree1
22536         local numfree2
22537
22538         mkdir -p $DIR/$tdir
22539
22540         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22541         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22542         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22543                 skip "not enough free inodes $numfree1 $numfree2"
22544         fi
22545
22546         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22547         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22548         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22549                 skip "not enough free space $numfree1 $numfree2"
22550         fi
22551
22552         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22553                 error "setdirstripe fails"
22554
22555         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22556                 error "create dirs fails"
22557
22558         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22559         ls $DIR/$tdir/striped_dir > /dev/null ||
22560                 error "ls striped dir fails"
22561         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22562                 error "unlink big striped dir fails"
22563 }
22564 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22565
22566 test_300p() {
22567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22568         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22569         remote_mds_nodsh && skip "remote MDS with nodsh"
22570
22571         mkdir -p $DIR/$tdir
22572
22573         #define OBD_FAIL_OUT_ENOSPC     0x1704
22574         do_facet mds2 lctl set_param fail_loc=0x80001704
22575         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22576                  && error "create striped directory should fail"
22577
22578         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22579
22580         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22581         true
22582 }
22583 run_test 300p "create striped directory without space"
22584
22585 test_300q() {
22586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22588
22589         local fd=$(free_fd)
22590         local cmd="exec $fd<$tdir"
22591         cd $DIR
22592         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22593         eval $cmd
22594         cmd="exec $fd<&-"
22595         trap "eval $cmd" EXIT
22596         cd $tdir || error "cd $tdir fails"
22597         rmdir  ../$tdir || error "rmdir $tdir fails"
22598         mkdir local_dir && error "create dir succeeds"
22599         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22600         eval $cmd
22601         return 0
22602 }
22603 run_test 300q "create remote directory under orphan directory"
22604
22605 test_300r() {
22606         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22607                 skip "Need MDS version at least 2.7.55" && return
22608         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22609
22610         mkdir $DIR/$tdir
22611
22612         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22613                 error "set striped dir error"
22614
22615         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22616                 error "getstripeddir fails"
22617
22618         local stripe_count
22619         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22620                       awk '/lmv_stripe_count:/ { print $2 }')
22621
22622         [ $MDSCOUNT -ne $stripe_count ] &&
22623                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22624
22625         rm -rf $DIR/$tdir/striped_dir ||
22626                 error "unlink striped dir fails"
22627 }
22628 run_test 300r "test -1 striped directory"
22629
22630 test_300s_helper() {
22631         local count=$1
22632
22633         local stripe_dir=$DIR/$tdir/striped_dir.$count
22634
22635         $LFS mkdir -c $count $stripe_dir ||
22636                 error "lfs mkdir -c error"
22637
22638         $LFS getdirstripe $stripe_dir ||
22639                 error "lfs getdirstripe fails"
22640
22641         local stripe_count
22642         stripe_count=$($LFS getdirstripe $stripe_dir |
22643                       awk '/lmv_stripe_count:/ { print $2 }')
22644
22645         [ $count -ne $stripe_count ] &&
22646                 error_noexit "bad stripe count $stripe_count expected $count"
22647
22648         local dupe_stripes
22649         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22650                 awk '/0x/ {count[$1] += 1}; END {
22651                         for (idx in count) {
22652                                 if (count[idx]>1) {
22653                                         print "index " idx " count " count[idx]
22654                                 }
22655                         }
22656                 }')
22657
22658         if [[ -n "$dupe_stripes" ]] ; then
22659                 lfs getdirstripe $stripe_dir
22660                 error_noexit "Dupe MDT above: $dupe_stripes "
22661         fi
22662
22663         rm -rf $stripe_dir ||
22664                 error_noexit "unlink $stripe_dir fails"
22665 }
22666
22667 test_300s() {
22668         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22669                 skip "Need MDS version at least 2.7.55" && return
22670         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22671
22672         mkdir $DIR/$tdir
22673         for count in $(seq 2 $MDSCOUNT); do
22674                 test_300s_helper $count
22675         done
22676 }
22677 run_test 300s "test lfs mkdir -c without -i"
22678
22679
22680 prepare_remote_file() {
22681         mkdir $DIR/$tdir/src_dir ||
22682                 error "create remote source failed"
22683
22684         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22685                  error "cp to remote source failed"
22686         touch $DIR/$tdir/src_dir/a
22687
22688         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22689                 error "create remote target dir failed"
22690
22691         touch $DIR/$tdir/tgt_dir/b
22692
22693         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22694                 error "rename dir cross MDT failed!"
22695
22696         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22697                 error "src_child still exists after rename"
22698
22699         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22700                 error "missing file(a) after rename"
22701
22702         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22703                 error "diff after rename"
22704 }
22705
22706 test_310a() {
22707         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22709
22710         local remote_file=$DIR/$tdir/tgt_dir/b
22711
22712         mkdir -p $DIR/$tdir
22713
22714         prepare_remote_file || error "prepare remote file failed"
22715
22716         #open-unlink file
22717         $OPENUNLINK $remote_file $remote_file ||
22718                 error "openunlink $remote_file failed"
22719         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22720 }
22721 run_test 310a "open unlink remote file"
22722
22723 test_310b() {
22724         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22726
22727         local remote_file=$DIR/$tdir/tgt_dir/b
22728
22729         mkdir -p $DIR/$tdir
22730
22731         prepare_remote_file || error "prepare remote file failed"
22732
22733         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22734         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22735         $CHECKSTAT -t file $remote_file || error "check file failed"
22736 }
22737 run_test 310b "unlink remote file with multiple links while open"
22738
22739 test_310c() {
22740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22741         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22742
22743         local remote_file=$DIR/$tdir/tgt_dir/b
22744
22745         mkdir -p $DIR/$tdir
22746
22747         prepare_remote_file || error "prepare remote file failed"
22748
22749         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22750         multiop_bg_pause $remote_file O_uc ||
22751                         error "mulitop failed for remote file"
22752         MULTIPID=$!
22753         $MULTIOP $DIR/$tfile Ouc
22754         kill -USR1 $MULTIPID
22755         wait $MULTIPID
22756 }
22757 run_test 310c "open-unlink remote file with multiple links"
22758
22759 #LU-4825
22760 test_311() {
22761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22762         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22763         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22764                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22765         remote_mds_nodsh && skip "remote MDS with nodsh"
22766
22767         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22768         local mdts=$(comma_list $(mdts_nodes))
22769
22770         mkdir -p $DIR/$tdir
22771         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22772         createmany -o $DIR/$tdir/$tfile. 1000
22773
22774         # statfs data is not real time, let's just calculate it
22775         old_iused=$((old_iused + 1000))
22776
22777         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22778                         osp.*OST0000*MDT0000.create_count")
22779         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22780                                 osp.*OST0000*MDT0000.max_create_count")
22781         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22782
22783         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22784         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22785         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22786
22787         unlinkmany $DIR/$tdir/$tfile. 1000
22788
22789         do_nodes $mdts "$LCTL set_param -n \
22790                         osp.*OST0000*.max_create_count=$max_count"
22791         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22792                 do_nodes $mdts "$LCTL set_param -n \
22793                                 osp.*OST0000*.create_count=$count"
22794         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22795                         grep "=0" && error "create_count is zero"
22796
22797         local new_iused
22798         for i in $(seq 120); do
22799                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22800                 # system may be too busy to destroy all objs in time, use
22801                 # a somewhat small value to not fail autotest
22802                 [ $((old_iused - new_iused)) -gt 400 ] && break
22803                 sleep 1
22804         done
22805
22806         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22807         [ $((old_iused - new_iused)) -gt 400 ] ||
22808                 error "objs not destroyed after unlink"
22809 }
22810 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22811
22812 zfs_oid_to_objid()
22813 {
22814         local ost=$1
22815         local objid=$2
22816
22817         local vdevdir=$(dirname $(facet_vdevice $ost))
22818         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22819         local zfs_zapid=$(do_facet $ost $cmd |
22820                           grep -w "/O/0/d$((objid%32))" -C 5 |
22821                           awk '/Object/{getline; print $1}')
22822         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22823                           awk "/$objid = /"'{printf $3}')
22824
22825         echo $zfs_objid
22826 }
22827
22828 zfs_object_blksz() {
22829         local ost=$1
22830         local objid=$2
22831
22832         local vdevdir=$(dirname $(facet_vdevice $ost))
22833         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22834         local blksz=$(do_facet $ost $cmd $objid |
22835                       awk '/dblk/{getline; printf $4}')
22836
22837         case "${blksz: -1}" in
22838                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22839                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22840                 *) ;;
22841         esac
22842
22843         echo $blksz
22844 }
22845
22846 test_312() { # LU-4856
22847         remote_ost_nodsh && skip "remote OST with nodsh"
22848         [ "$ost1_FSTYPE" = "zfs" ] ||
22849                 skip_env "the test only applies to zfs"
22850
22851         local max_blksz=$(do_facet ost1 \
22852                           $ZFS get -p recordsize $(facet_device ost1) |
22853                           awk '!/VALUE/{print $3}')
22854
22855         # to make life a little bit easier
22856         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22857         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22858
22859         local tf=$DIR/$tdir/$tfile
22860         touch $tf
22861         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22862
22863         # Get ZFS object id
22864         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22865         # block size change by sequential overwrite
22866         local bs
22867
22868         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22869                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22870
22871                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22872                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22873         done
22874         rm -f $tf
22875
22876         # block size change by sequential append write
22877         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22878         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22879         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22880         local count
22881
22882         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22883                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22884                         oflag=sync conv=notrunc
22885
22886                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22887                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22888                         error "blksz error, actual $blksz, " \
22889                                 "expected: 2 * $count * $PAGE_SIZE"
22890         done
22891         rm -f $tf
22892
22893         # random write
22894         touch $tf
22895         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22896         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22897
22898         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22899         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22900         [ $blksz -eq $PAGE_SIZE ] ||
22901                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22902
22903         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22904         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22905         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22906
22907         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22908         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22909         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22910 }
22911 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22912
22913 test_313() {
22914         remote_ost_nodsh && skip "remote OST with nodsh"
22915
22916         local file=$DIR/$tfile
22917
22918         rm -f $file
22919         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22920
22921         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22922         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22923         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22924                 error "write should failed"
22925         do_facet ost1 "$LCTL set_param fail_loc=0"
22926         rm -f $file
22927 }
22928 run_test 313 "io should fail after last_rcvd update fail"
22929
22930 test_314() {
22931         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22932
22933         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22934         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22935         rm -f $DIR/$tfile
22936         wait_delete_completed
22937         do_facet ost1 "$LCTL set_param fail_loc=0"
22938 }
22939 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22940
22941 test_315() { # LU-618
22942         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22943
22944         local file=$DIR/$tfile
22945         rm -f $file
22946
22947         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22948                 error "multiop file write failed"
22949         $MULTIOP $file oO_RDONLY:r4063232_c &
22950         PID=$!
22951
22952         sleep 2
22953
22954         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22955         kill -USR1 $PID
22956
22957         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22958         rm -f $file
22959 }
22960 run_test 315 "read should be accounted"
22961
22962 test_316() {
22963         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22964         large_xattr_enabled || skip_env "ea_inode feature disabled"
22965
22966         rm -rf $DIR/$tdir/d
22967         mkdir -p $DIR/$tdir/d
22968         chown nobody $DIR/$tdir/d
22969         touch $DIR/$tdir/d/file
22970
22971         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22972 }
22973 run_test 316 "lfs mv"
22974
22975 test_317() {
22976         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22977                 skip "Need MDS version at least 2.11.53"
22978         if [ "$ost1_FSTYPE" == "zfs" ]; then
22979                 skip "LU-10370: no implementation for ZFS"
22980         fi
22981
22982         local trunc_sz
22983         local grant_blk_size
22984
22985         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22986                         awk '/grant_block_size:/ { print $2; exit; }')
22987         #
22988         # Create File of size 5M. Truncate it to below size's and verify
22989         # blocks count.
22990         #
22991         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22992                 error "Create file $DIR/$tfile failed"
22993         stack_trap "rm -f $DIR/$tfile" EXIT
22994
22995         for trunc_sz in 2097152 4097 4000 509 0; do
22996                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22997                         error "truncate $tfile to $trunc_sz failed"
22998                 local sz=$(stat --format=%s $DIR/$tfile)
22999                 local blk=$(stat --format=%b $DIR/$tfile)
23000                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23001                                      grant_blk_size) * 8))
23002
23003                 if [[ $blk -ne $trunc_blk ]]; then
23004                         $(which stat) $DIR/$tfile
23005                         error "Expected Block $trunc_blk got $blk for $tfile"
23006                 fi
23007
23008                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23009                         error "Expected Size $trunc_sz got $sz for $tfile"
23010         done
23011
23012         #
23013         # sparse file test
23014         # Create file with a hole and write actual two blocks. Block count
23015         # must be 16.
23016         #
23017         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23018                 conv=fsync || error "Create file : $DIR/$tfile"
23019
23020         # Calculate the final truncate size.
23021         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23022
23023         #
23024         # truncate to size $trunc_sz bytes. Strip the last block
23025         # The block count must drop to 8
23026         #
23027         $TRUNCATE $DIR/$tfile $trunc_sz ||
23028                 error "truncate $tfile to $trunc_sz failed"
23029
23030         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23031         sz=$(stat --format=%s $DIR/$tfile)
23032         blk=$(stat --format=%b $DIR/$tfile)
23033
23034         if [[ $blk -ne $trunc_bsz ]]; then
23035                 $(which stat) $DIR/$tfile
23036                 error "Expected Block $trunc_bsz got $blk for $tfile"
23037         fi
23038
23039         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23040                 error "Expected Size $trunc_sz got $sz for $tfile"
23041 }
23042 run_test 317 "Verify blocks get correctly update after truncate"
23043
23044 test_318() {
23045         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23046         local old_max_active=$($LCTL get_param -n \
23047                             ${llite_name}.max_read_ahead_async_active \
23048                             2>/dev/null)
23049
23050         $LCTL set_param llite.*.max_read_ahead_async_active=256
23051         local max_active=$($LCTL get_param -n \
23052                            ${llite_name}.max_read_ahead_async_active \
23053                            2>/dev/null)
23054         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23055
23056         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23057                 error "set max_read_ahead_async_active should succeed"
23058
23059         $LCTL set_param llite.*.max_read_ahead_async_active=512
23060         max_active=$($LCTL get_param -n \
23061                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23062         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23063
23064         # restore @max_active
23065         [ $old_max_active -ne 0 ] && $LCTL set_param \
23066                 llite.*.max_read_ahead_async_active=$old_max_active
23067
23068         local old_threshold=$($LCTL get_param -n \
23069                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23070         local max_per_file_mb=$($LCTL get_param -n \
23071                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23072
23073         local invalid=$(($max_per_file_mb + 1))
23074         $LCTL set_param \
23075                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23076                         && error "set $invalid should fail"
23077
23078         local valid=$(($invalid - 1))
23079         $LCTL set_param \
23080                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23081                         error "set $valid should succeed"
23082         local threshold=$($LCTL get_param -n \
23083                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23084         [ $threshold -eq $valid ] || error \
23085                 "expect threshold $valid got $threshold"
23086         $LCTL set_param \
23087                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23088 }
23089 run_test 318 "Verify async readahead tunables"
23090
23091 test_319() {
23092         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23093
23094         local before=$(date +%s)
23095         local evict
23096         local mdir=$DIR/$tdir
23097         local file=$mdir/xxx
23098
23099         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23100         touch $file
23101
23102 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23103         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23104         $LFS mv -m1 $file &
23105
23106         sleep 1
23107         dd if=$file of=/dev/null
23108         wait
23109         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23110           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23111
23112         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23113 }
23114 run_test 319 "lost lease lock on migrate error"
23115
23116 test_398a() { # LU-4198
23117         local ost1_imp=$(get_osc_import_name client ost1)
23118         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23119                          cut -d'.' -f2)
23120
23121         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23122         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23123
23124         # request a new lock on client
23125         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23126
23127         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23128         local lock_count=$($LCTL get_param -n \
23129                            ldlm.namespaces.$imp_name.lru_size)
23130         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23131
23132         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23133
23134         # no lock cached, should use lockless IO and not enqueue new lock
23135         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23136         lock_count=$($LCTL get_param -n \
23137                      ldlm.namespaces.$imp_name.lru_size)
23138         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23139 }
23140 run_test 398a "direct IO should cancel lock otherwise lockless"
23141
23142 test_398b() { # LU-4198
23143         which fio || skip_env "no fio installed"
23144         $LFS setstripe -c -1 $DIR/$tfile
23145
23146         local size=12
23147         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23148
23149         local njobs=4
23150         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23151         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23152                 --numjobs=$njobs --fallocate=none \
23153                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23154                 --filename=$DIR/$tfile &
23155         bg_pid=$!
23156
23157         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23158         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23159                 --numjobs=$njobs --fallocate=none \
23160                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23161                 --filename=$DIR/$tfile || true
23162         wait $bg_pid
23163
23164         rm -rf $DIR/$tfile
23165 }
23166 run_test 398b "DIO and buffer IO race"
23167
23168 test_398c() { # 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         which fio || skip_env "no fio installed"
23174
23175         saved_debug=$($LCTL get_param -n debug)
23176         $LCTL set_param debug=0
23177
23178         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23179         ((size /= 1024)) # by megabytes
23180         ((size /= 2)) # write half of the OST at most
23181         [ $size -gt 40 ] && size=40 #reduce test time anyway
23182
23183         $LFS setstripe -c 1 $DIR/$tfile
23184
23185         # it seems like ldiskfs reserves more space than necessary if the
23186         # writing blocks are not mapped, so it extends the file firstly
23187         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23188         cancel_lru_locks osc
23189
23190         # clear and verify rpc_stats later
23191         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23192
23193         local njobs=4
23194         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23195         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23196                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23197                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23198                 --filename=$DIR/$tfile
23199         [ $? -eq 0 ] || error "fio write error"
23200
23201         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23202                 error "Locks were requested while doing AIO"
23203
23204         # get the percentage of 1-page I/O
23205         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23206                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23207                 awk '{print $7}')
23208         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23209
23210         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23211         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23212                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23213                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23214                 --filename=$DIR/$tfile
23215         [ $? -eq 0 ] || error "fio mixed read write error"
23216
23217         echo "AIO with large block size ${size}M"
23218         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23219                 --numjobs=1 --fallocate=none --ioengine=libaio \
23220                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23221                 --filename=$DIR/$tfile
23222         [ $? -eq 0 ] || error "fio large block size failed"
23223
23224         rm -rf $DIR/$tfile
23225         $LCTL set_param debug="$saved_debug"
23226 }
23227 run_test 398c "run fio to test AIO"
23228
23229 test_398d() { #  LU-13846
23230         test -f aiocp || skip_env "no aiocp installed"
23231         local aio_file=$DIR/aio_file
23232
23233         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23234
23235         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23236         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23237
23238         diff $DIR/$tfile $aio_file || "file diff after aiocp"
23239
23240         # make sure we don't crash and fail properly
23241         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23242                 error "aio not aligned with PAGE SIZE should fail"
23243
23244         rm -rf $DIR/$tfile $aio_file
23245 }
23246 run_test 398d "run aiocp to verify block size > stripe size"
23247
23248 test_398e() {
23249         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23250         touch $DIR/$tfile.new
23251         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23252 }
23253 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23254
23255 test_fake_rw() {
23256         local read_write=$1
23257         if [ "$read_write" = "write" ]; then
23258                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23259         elif [ "$read_write" = "read" ]; then
23260                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23261         else
23262                 error "argument error"
23263         fi
23264
23265         # turn off debug for performance testing
23266         local saved_debug=$($LCTL get_param -n debug)
23267         $LCTL set_param debug=0
23268
23269         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23270
23271         # get ost1 size - $FSNAME-OST0000
23272         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23273         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23274         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23275
23276         if [ "$read_write" = "read" ]; then
23277                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23278         fi
23279
23280         local start_time=$(date +%s.%N)
23281         $dd_cmd bs=1M count=$blocks oflag=sync ||
23282                 error "real dd $read_write error"
23283         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23284
23285         if [ "$read_write" = "write" ]; then
23286                 rm -f $DIR/$tfile
23287         fi
23288
23289         # define OBD_FAIL_OST_FAKE_RW           0x238
23290         do_facet ost1 $LCTL set_param fail_loc=0x238
23291
23292         local start_time=$(date +%s.%N)
23293         $dd_cmd bs=1M count=$blocks oflag=sync ||
23294                 error "fake dd $read_write error"
23295         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23296
23297         if [ "$read_write" = "write" ]; then
23298                 # verify file size
23299                 cancel_lru_locks osc
23300                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23301                         error "$tfile size not $blocks MB"
23302         fi
23303         do_facet ost1 $LCTL set_param fail_loc=0
23304
23305         echo "fake $read_write $duration_fake vs. normal $read_write" \
23306                 "$duration in seconds"
23307         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23308                 error_not_in_vm "fake write is slower"
23309
23310         $LCTL set_param -n debug="$saved_debug"
23311         rm -f $DIR/$tfile
23312 }
23313 test_399a() { # LU-7655 for OST fake write
23314         remote_ost_nodsh && skip "remote OST with nodsh"
23315
23316         test_fake_rw write
23317 }
23318 run_test 399a "fake write should not be slower than normal write"
23319
23320 test_399b() { # LU-8726 for OST fake read
23321         remote_ost_nodsh && skip "remote OST with nodsh"
23322         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23323                 skip_env "ldiskfs only test"
23324         fi
23325
23326         test_fake_rw read
23327 }
23328 run_test 399b "fake read should not be slower than normal read"
23329
23330 test_400a() { # LU-1606, was conf-sanity test_74
23331         if ! which $CC > /dev/null 2>&1; then
23332                 skip_env "$CC is not installed"
23333         fi
23334
23335         local extra_flags=''
23336         local out=$TMP/$tfile
23337         local prefix=/usr/include/lustre
23338         local prog
23339
23340         # Oleg removes c files in his test rig so test if any c files exist
23341         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23342                 skip_env "Needed c test files are missing"
23343
23344         if ! [[ -d $prefix ]]; then
23345                 # Assume we're running in tree and fixup the include path.
23346                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23347                 extra_flags+=" -L$LUSTRE/utils/.lib"
23348         fi
23349
23350         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23351                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23352                         error "client api broken"
23353         done
23354         rm -f $out
23355 }
23356 run_test 400a "Lustre client api program can compile and link"
23357
23358 test_400b() { # LU-1606, LU-5011
23359         local header
23360         local out=$TMP/$tfile
23361         local prefix=/usr/include/linux/lustre
23362
23363         # We use a hard coded prefix so that this test will not fail
23364         # when run in tree. There are headers in lustre/include/lustre/
23365         # that are not packaged (like lustre_idl.h) and have more
23366         # complicated include dependencies (like config.h and lnet/types.h).
23367         # Since this test about correct packaging we just skip them when
23368         # they don't exist (see below) rather than try to fixup cppflags.
23369
23370         if ! which $CC > /dev/null 2>&1; then
23371                 skip_env "$CC is not installed"
23372         fi
23373
23374         for header in $prefix/*.h; do
23375                 if ! [[ -f "$header" ]]; then
23376                         continue
23377                 fi
23378
23379                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23380                         continue # lustre_ioctl.h is internal header
23381                 fi
23382
23383                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23384                         error "cannot compile '$header'"
23385         done
23386         rm -f $out
23387 }
23388 run_test 400b "packaged headers can be compiled"
23389
23390 test_401a() { #LU-7437
23391         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23392         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23393
23394         #count the number of parameters by "list_param -R"
23395         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23396         #count the number of parameters by listing proc files
23397         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23398         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23399         echo "proc_dirs='$proc_dirs'"
23400         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23401         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23402                       sort -u | wc -l)
23403
23404         [ $params -eq $procs ] ||
23405                 error "found $params parameters vs. $procs proc files"
23406
23407         # test the list_param -D option only returns directories
23408         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23409         #count the number of parameters by listing proc directories
23410         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23411                 sort -u | wc -l)
23412
23413         [ $params -eq $procs ] ||
23414                 error "found $params parameters vs. $procs proc files"
23415 }
23416 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23417
23418 test_401b() {
23419         # jobid_var may not allow arbitrary values, so use jobid_name
23420         # if available
23421         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23422                 local testname=jobid_name tmp='testing%p'
23423         else
23424                 local testname=jobid_var tmp=testing
23425         fi
23426
23427         local save=$($LCTL get_param -n $testname)
23428
23429         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23430                 error "no error returned when setting bad parameters"
23431
23432         local jobid_new=$($LCTL get_param -n foe $testname baz)
23433         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23434
23435         $LCTL set_param -n fog=bam $testname=$save bat=fog
23436         local jobid_old=$($LCTL get_param -n foe $testname bag)
23437         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23438 }
23439 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23440
23441 test_401c() {
23442         # jobid_var may not allow arbitrary values, so use jobid_name
23443         # if available
23444         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23445                 local testname=jobid_name
23446         else
23447                 local testname=jobid_var
23448         fi
23449
23450         local jobid_var_old=$($LCTL get_param -n $testname)
23451         local jobid_var_new
23452
23453         $LCTL set_param $testname= &&
23454                 error "no error returned for 'set_param a='"
23455
23456         jobid_var_new=$($LCTL get_param -n $testname)
23457         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23458                 error "$testname was changed by setting without value"
23459
23460         $LCTL set_param $testname &&
23461                 error "no error returned for 'set_param a'"
23462
23463         jobid_var_new=$($LCTL get_param -n $testname)
23464         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23465                 error "$testname was changed by setting without value"
23466 }
23467 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23468
23469 test_401d() {
23470         # jobid_var may not allow arbitrary values, so use jobid_name
23471         # if available
23472         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23473                 local testname=jobid_name new_value='foo=bar%p'
23474         else
23475                 local testname=jobid_var new_valuie=foo=bar
23476         fi
23477
23478         local jobid_var_old=$($LCTL get_param -n $testname)
23479         local jobid_var_new
23480
23481         $LCTL set_param $testname=$new_value ||
23482                 error "'set_param a=b' did not accept a value containing '='"
23483
23484         jobid_var_new=$($LCTL get_param -n $testname)
23485         [[ "$jobid_var_new" == "$new_value" ]] ||
23486                 error "'set_param a=b' failed on a value containing '='"
23487
23488         # Reset the $testname to test the other format
23489         $LCTL set_param $testname=$jobid_var_old
23490         jobid_var_new=$($LCTL get_param -n $testname)
23491         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23492                 error "failed to reset $testname"
23493
23494         $LCTL set_param $testname $new_value ||
23495                 error "'set_param a b' did not accept a value containing '='"
23496
23497         jobid_var_new=$($LCTL get_param -n $testname)
23498         [[ "$jobid_var_new" == "$new_value" ]] ||
23499                 error "'set_param a b' failed on a value containing '='"
23500
23501         $LCTL set_param $testname $jobid_var_old
23502         jobid_var_new=$($LCTL get_param -n $testname)
23503         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23504                 error "failed to reset $testname"
23505 }
23506 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23507
23508 test_402() {
23509         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23510         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23511                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23512         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23513                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23514                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23515         remote_mds_nodsh && skip "remote MDS with nodsh"
23516
23517         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23518 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23519         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23520         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23521                 echo "Touch failed - OK"
23522 }
23523 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23524
23525 test_403() {
23526         local file1=$DIR/$tfile.1
23527         local file2=$DIR/$tfile.2
23528         local tfile=$TMP/$tfile
23529
23530         rm -f $file1 $file2 $tfile
23531
23532         touch $file1
23533         ln $file1 $file2
23534
23535         # 30 sec OBD_TIMEOUT in ll_getattr()
23536         # right before populating st_nlink
23537         $LCTL set_param fail_loc=0x80001409
23538         stat -c %h $file1 > $tfile &
23539
23540         # create an alias, drop all locks and reclaim the dentry
23541         < $file2
23542         cancel_lru_locks mdc
23543         cancel_lru_locks osc
23544         sysctl -w vm.drop_caches=2
23545
23546         wait
23547
23548         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23549
23550         rm -f $tfile $file1 $file2
23551 }
23552 run_test 403 "i_nlink should not drop to zero due to aliasing"
23553
23554 test_404() { # LU-6601
23555         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23556                 skip "Need server version newer than 2.8.52"
23557         remote_mds_nodsh && skip "remote MDS with nodsh"
23558
23559         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23560                 awk '/osp .*-osc-MDT/ { print $4}')
23561
23562         local osp
23563         for osp in $mosps; do
23564                 echo "Deactivate: " $osp
23565                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23566                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23567                         awk -vp=$osp '$4 == p { print $2 }')
23568                 [ $stat = IN ] || {
23569                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23570                         error "deactivate error"
23571                 }
23572                 echo "Activate: " $osp
23573                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23574                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23575                         awk -vp=$osp '$4 == p { print $2 }')
23576                 [ $stat = UP ] || {
23577                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23578                         error "activate error"
23579                 }
23580         done
23581 }
23582 run_test 404 "validate manual {de}activated works properly for OSPs"
23583
23584 test_405() {
23585         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23586         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23587                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23588                         skip "Layout swap lock is not supported"
23589
23590         check_swap_layouts_support
23591         check_swap_layout_no_dom $DIR
23592
23593         test_mkdir $DIR/$tdir
23594         swap_lock_test -d $DIR/$tdir ||
23595                 error "One layout swap locked test failed"
23596 }
23597 run_test 405 "Various layout swap lock tests"
23598
23599 test_406() {
23600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23601         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23602         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23604         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23605                 skip "Need MDS version at least 2.8.50"
23606
23607         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23608         local test_pool=$TESTNAME
23609
23610         pool_add $test_pool || error "pool_add failed"
23611         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23612                 error "pool_add_targets failed"
23613
23614         save_layout_restore_at_exit $MOUNT
23615
23616         # parent set default stripe count only, child will stripe from both
23617         # parent and fs default
23618         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23619                 error "setstripe $MOUNT failed"
23620         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23621         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23622         for i in $(seq 10); do
23623                 local f=$DIR/$tdir/$tfile.$i
23624                 touch $f || error "touch failed"
23625                 local count=$($LFS getstripe -c $f)
23626                 [ $count -eq $OSTCOUNT ] ||
23627                         error "$f stripe count $count != $OSTCOUNT"
23628                 local offset=$($LFS getstripe -i $f)
23629                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23630                 local size=$($LFS getstripe -S $f)
23631                 [ $size -eq $((def_stripe_size * 2)) ] ||
23632                         error "$f stripe size $size != $((def_stripe_size * 2))"
23633                 local pool=$($LFS getstripe -p $f)
23634                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23635         done
23636
23637         # change fs default striping, delete parent default striping, now child
23638         # will stripe from new fs default striping only
23639         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23640                 error "change $MOUNT default stripe failed"
23641         $LFS setstripe -c 0 $DIR/$tdir ||
23642                 error "delete $tdir default stripe failed"
23643         for i in $(seq 11 20); do
23644                 local f=$DIR/$tdir/$tfile.$i
23645                 touch $f || error "touch $f failed"
23646                 local count=$($LFS getstripe -c $f)
23647                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23648                 local offset=$($LFS getstripe -i $f)
23649                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23650                 local size=$($LFS getstripe -S $f)
23651                 [ $size -eq $def_stripe_size ] ||
23652                         error "$f stripe size $size != $def_stripe_size"
23653                 local pool=$($LFS getstripe -p $f)
23654                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23655         done
23656
23657         unlinkmany $DIR/$tdir/$tfile. 1 20
23658
23659         local f=$DIR/$tdir/$tfile
23660         pool_remove_all_targets $test_pool $f
23661         pool_remove $test_pool $f
23662 }
23663 run_test 406 "DNE support fs default striping"
23664
23665 test_407() {
23666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23667         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23668                 skip "Need MDS version at least 2.8.55"
23669         remote_mds_nodsh && skip "remote MDS with nodsh"
23670
23671         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23672                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23673         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23674                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23675         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23676
23677         #define OBD_FAIL_DT_TXN_STOP    0x2019
23678         for idx in $(seq $MDSCOUNT); do
23679                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23680         done
23681         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23682         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23683                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23684         true
23685 }
23686 run_test 407 "transaction fail should cause operation fail"
23687
23688 test_408() {
23689         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23690
23691         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23692         lctl set_param fail_loc=0x8000040a
23693         # let ll_prepare_partial_page() fail
23694         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23695
23696         rm -f $DIR/$tfile
23697
23698         # create at least 100 unused inodes so that
23699         # shrink_icache_memory(0) should not return 0
23700         touch $DIR/$tfile-{0..100}
23701         rm -f $DIR/$tfile-{0..100}
23702         sync
23703
23704         echo 2 > /proc/sys/vm/drop_caches
23705 }
23706 run_test 408 "drop_caches should not hang due to page leaks"
23707
23708 test_409()
23709 {
23710         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23711
23712         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23713         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23714         touch $DIR/$tdir/guard || error "(2) Fail to create"
23715
23716         local PREFIX=$(str_repeat 'A' 128)
23717         echo "Create 1K hard links start at $(date)"
23718         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23719                 error "(3) Fail to hard link"
23720
23721         echo "Links count should be right although linkEA overflow"
23722         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23723         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23724         [ $linkcount -eq 1001 ] ||
23725                 error "(5) Unexpected hard links count: $linkcount"
23726
23727         echo "List all links start at $(date)"
23728         ls -l $DIR/$tdir/foo > /dev/null ||
23729                 error "(6) Fail to list $DIR/$tdir/foo"
23730
23731         echo "Unlink hard links start at $(date)"
23732         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23733                 error "(7) Fail to unlink"
23734         echo "Unlink hard links finished at $(date)"
23735 }
23736 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23737
23738 test_410()
23739 {
23740         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23741                 skip "Need client version at least 2.9.59"
23742         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23743                 skip "Need MODULES build"
23744
23745         # Create a file, and stat it from the kernel
23746         local testfile=$DIR/$tfile
23747         touch $testfile
23748
23749         local run_id=$RANDOM
23750         local my_ino=$(stat --format "%i" $testfile)
23751
23752         # Try to insert the module. This will always fail as the
23753         # module is designed to not be inserted.
23754         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23755             &> /dev/null
23756
23757         # Anything but success is a test failure
23758         dmesg | grep -q \
23759             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23760             error "no inode match"
23761 }
23762 run_test 410 "Test inode number returned from kernel thread"
23763
23764 cleanup_test411_cgroup() {
23765         trap 0
23766         rmdir "$1"
23767 }
23768
23769 test_411() {
23770         local cg_basedir=/sys/fs/cgroup/memory
23771         # LU-9966
23772         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23773                 skip "no setup for cgroup"
23774
23775         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23776                 error "test file creation failed"
23777         cancel_lru_locks osc
23778
23779         # Create a very small memory cgroup to force a slab allocation error
23780         local cgdir=$cg_basedir/osc_slab_alloc
23781         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23782         trap "cleanup_test411_cgroup $cgdir" EXIT
23783         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23784         echo 1M > $cgdir/memory.limit_in_bytes
23785
23786         # Should not LBUG, just be killed by oom-killer
23787         # dd will return 0 even allocation failure in some environment.
23788         # So don't check return value
23789         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23790         cleanup_test411_cgroup $cgdir
23791
23792         return 0
23793 }
23794 run_test 411 "Slab allocation error with cgroup does not LBUG"
23795
23796 test_412() {
23797         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23798         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23799                 skip "Need server version at least 2.10.55"
23800         fi
23801
23802         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23803                 error "mkdir failed"
23804         $LFS getdirstripe $DIR/$tdir
23805         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23806         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23807                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23808         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23809         [ $stripe_count -eq 2 ] ||
23810                 error "expect 2 get $stripe_count"
23811 }
23812 run_test 412 "mkdir on specific MDTs"
23813
23814 test_qos_mkdir() {
23815         local mkdir_cmd=$1
23816         local stripe_count=$2
23817         local mdts=$(comma_list $(mdts_nodes))
23818
23819         local testdir
23820         local lmv_qos_prio_free
23821         local lmv_qos_threshold_rr
23822         local lmv_qos_maxage
23823         local lod_qos_prio_free
23824         local lod_qos_threshold_rr
23825         local lod_qos_maxage
23826         local count
23827         local i
23828
23829         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23830         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23831         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23832                 head -n1)
23833         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23834         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23835         stack_trap "$LCTL set_param \
23836                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23837         stack_trap "$LCTL set_param \
23838                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23839         stack_trap "$LCTL set_param \
23840                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23841
23842         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23843                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23844         lod_qos_prio_free=${lod_qos_prio_free%%%}
23845         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23846                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23847         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23848         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23849                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23850         stack_trap "do_nodes $mdts $LCTL set_param \
23851                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23852         stack_trap "do_nodes $mdts $LCTL set_param \
23853                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23854                 EXIT
23855         stack_trap "do_nodes $mdts $LCTL set_param \
23856                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23857
23858         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23859         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23860
23861         testdir=$DIR/$tdir-s$stripe_count/rr
23862
23863         local stripe_index=$($LFS getstripe -m $testdir)
23864         local test_mkdir_rr=true
23865
23866         getfattr -d -m dmv $testdir | grep dmv
23867         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
23868                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
23869
23870                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
23871         fi
23872
23873         echo
23874         $test_mkdir_rr &&
23875                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
23876                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
23877
23878         for i in $(seq $((100 * MDSCOUNT))); do
23879                 eval $mkdir_cmd $testdir/subdir$i ||
23880                         error "$mkdir_cmd subdir$i failed"
23881         done
23882
23883         for i in $(seq $MDSCOUNT); do
23884                 count=$($LFS getdirstripe -i $testdir/* |
23885                                 grep ^$((i - 1))$ | wc -l)
23886                 echo "$count directories created on MDT$((i - 1))"
23887                 if $test_mkdir_rr; then
23888                         (( $count == 100 )) ||
23889                                 error "subdirs are not evenly distributed"
23890                 elif [ $((i - 1)) -eq $stripe_index ]; then
23891                         (( $count == 100 * MDSCOUNT )) ||
23892                                 error "$count subdirs created on MDT$((i - 1))"
23893                 else
23894                         (( $count == 0 )) ||
23895                                 error "$count subdirs created on MDT$((i - 1))"
23896                 fi
23897
23898                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
23899                         count=$($LFS getdirstripe $testdir/* |
23900                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23901                         echo "$count stripes created on MDT$((i - 1))"
23902                         # deviation should < 5% of average
23903                         (( $count < 95 * stripe_count )) ||
23904                         (( $count > 105 * stripe_count)) &&
23905                                 error "stripes are not evenly distributed"
23906                 fi
23907         done
23908
23909         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23910         do_nodes $mdts $LCTL set_param \
23911                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23912
23913         echo
23914         echo "Check for uneven MDTs: "
23915
23916         local ffree
23917         local bavail
23918         local max
23919         local min
23920         local max_index
23921         local min_index
23922         local tmp
23923
23924         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23925         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23926         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23927
23928         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23929         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23930         max_index=0
23931         min_index=0
23932         for ((i = 1; i < ${#ffree[@]}; i++)); do
23933                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23934                 if [ $tmp -gt $max ]; then
23935                         max=$tmp
23936                         max_index=$i
23937                 fi
23938                 if [ $tmp -lt $min ]; then
23939                         min=$tmp
23940                         min_index=$i
23941                 fi
23942         done
23943
23944         (( ${ffree[min_index]} == 0 )) &&
23945                 skip "no free files in MDT$min_index"
23946         (( ${ffree[min_index]} > 100000000 )) &&
23947                 skip "too many free files in MDT$min_index"
23948
23949         # Check if we need to generate uneven MDTs
23950         local threshold=50
23951         local diff=$(((max - min) * 100 / min))
23952         local value="$(generate_string 1024)"
23953
23954         while [ $diff -lt $threshold ]; do
23955                 # generate uneven MDTs, create till $threshold% diff
23956                 echo -n "weight diff=$diff% must be > $threshold% ..."
23957                 count=$((${ffree[min_index]} / 10))
23958                 # 50 sec per 10000 files in vm
23959                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
23960                         skip "$count files to create"
23961                 echo "Fill MDT$min_index with $count files"
23962                 [ -d $DIR/$tdir-MDT$min_index ] ||
23963                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23964                         error "mkdir $tdir-MDT$min_index failed"
23965                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
23966                         error "create d$count failed"
23967
23968                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23969                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23970                 max=$(((${ffree[max_index]} >> 8) * \
23971                         (${bavail[max_index]} * bsize >> 16)))
23972                 min=$(((${ffree[min_index]} >> 8) * \
23973                         (${bavail[min_index]} * bsize >> 16)))
23974                 diff=$(((max - min) * 100 / min))
23975         done
23976
23977         echo "MDT filesfree available: ${ffree[@]}"
23978         echo "MDT blocks available: ${bavail[@]}"
23979         echo "weight diff=$diff%"
23980
23981         echo
23982         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23983
23984         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23985         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23986         # decrease statfs age, so that it can be updated in time
23987         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23988         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23989
23990         sleep 1
23991
23992         testdir=$DIR/$tdir-s$stripe_count/qos
23993
23994         for i in $(seq $((100 * MDSCOUNT))); do
23995                 eval $mkdir_cmd $testdir/subdir$i ||
23996                         error "$mkdir_cmd subdir$i failed"
23997         done
23998
23999         for i in $(seq $MDSCOUNT); do
24000                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24001                         wc -l)
24002                 echo "$count directories created on MDT$((i - 1))"
24003
24004                 if [ $stripe_count -gt 1 ]; then
24005                         count=$($LFS getdirstripe $testdir/* |
24006                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24007                         echo "$count stripes created on MDT$((i - 1))"
24008                 fi
24009         done
24010
24011         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24012         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24013
24014         # D-value should > 10% of averge
24015         (( $max - $min < 10 )) &&
24016                 error "subdirs shouldn't be evenly distributed"
24017
24018         # ditto
24019         if [ $stripe_count -gt 1 ]; then
24020                 max=$($LFS getdirstripe $testdir/* |
24021                         grep -P "^\s+$max_index\t" | wc -l)
24022                 min=$($LFS getdirstripe $testdir/* |
24023                         grep -P "^\s+$min_index\t" | wc -l)
24024                 (( $max - $min < 10 * $stripe_count )) &&
24025                         error "stripes shouldn't be evenly distributed"|| true
24026         fi
24027 }
24028
24029 test_413a() {
24030         [ $MDSCOUNT -lt 2 ] &&
24031                 skip "We need at least 2 MDTs for this test"
24032
24033         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24034                 skip "Need server version at least 2.12.52"
24035
24036         local stripe_count
24037
24038         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24039                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24040                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24041                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24042                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24043         done
24044 }
24045 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24046
24047 test_413b() {
24048         [ $MDSCOUNT -lt 2 ] &&
24049                 skip "We need at least 2 MDTs for this test"
24050
24051         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24052                 skip "Need server version at least 2.12.52"
24053
24054         local testdir
24055         local stripe_count
24056
24057         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24058                 testdir=$DIR/$tdir-s$stripe_count
24059                 mkdir $testdir || error "mkdir $testdir failed"
24060                 mkdir $testdir/rr || error "mkdir rr failed"
24061                 mkdir $testdir/qos || error "mkdir qos failed"
24062                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24063                         $testdir/rr || error "setdirstripe rr failed"
24064                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24065                         error "setdirstripe failed"
24066                 test_qos_mkdir "mkdir" $stripe_count
24067         done
24068 }
24069 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24070
24071 test_413c() {
24072         [ $MDSCOUNT -ge 2 ] ||
24073                 skip "We need at least 2 MDTs for this test"
24074
24075         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24076                 skip "Need server version at least 2.14.50"
24077
24078         local testdir
24079         local inherit
24080         local inherit_rr
24081
24082         testdir=$DIR/${tdir}-s1
24083         mkdir $testdir || error "mkdir $testdir failed"
24084         mkdir $testdir/rr || error "mkdir rr failed"
24085         mkdir $testdir/qos || error "mkdir qos failed"
24086         # default max_inherit is -1, default max_inherit_rr is 0
24087         $LFS setdirstripe -D -c 1 $testdir/rr ||
24088                 error "setdirstripe rr failed"
24089         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24090                 error "setdirstripe qos failed"
24091         test_qos_mkdir "mkdir" 1
24092
24093         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24094         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24095         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24096         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24097         (( $inherit_rr == 0 )) ||
24098                 error "rr/level1 inherit-rr $inherit_rr != 0"
24099
24100         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24101         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24102         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24103         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24104         (( $inherit_rr == 0 )) ||
24105                 error "qos/level1 inherit-rr $inherit_rr !=0"
24106         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24107         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24108                 error "level2 shouldn't have default LMV" || true
24109 }
24110 run_test 413c "mkdir with default LMV max inherit rr"
24111
24112 test_414() {
24113 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24114         $LCTL set_param fail_loc=0x80000521
24115         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24116         rm -f $DIR/$tfile
24117 }
24118 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24119
24120 test_415() {
24121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24122         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24123                 skip "Need server version at least 2.11.52"
24124
24125         # LU-11102
24126         local total
24127         local setattr_pid
24128         local start_time
24129         local end_time
24130         local duration
24131
24132         total=500
24133         # this test may be slow on ZFS
24134         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24135
24136         # though this test is designed for striped directory, let's test normal
24137         # directory too since lock is always saved as CoS lock.
24138         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24139         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24140
24141         (
24142                 while true; do
24143                         touch $DIR/$tdir
24144                 done
24145         ) &
24146         setattr_pid=$!
24147
24148         start_time=$(date +%s)
24149         for i in $(seq $total); do
24150                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24151                         > /dev/null
24152         done
24153         end_time=$(date +%s)
24154         duration=$((end_time - start_time))
24155
24156         kill -9 $setattr_pid
24157
24158         echo "rename $total files took $duration sec"
24159         [ $duration -lt 100 ] || error "rename took $duration sec"
24160 }
24161 run_test 415 "lock revoke is not missing"
24162
24163 test_416() {
24164         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24165                 skip "Need server version at least 2.11.55"
24166
24167         # define OBD_FAIL_OSD_TXN_START    0x19a
24168         do_facet mds1 lctl set_param fail_loc=0x19a
24169
24170         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24171
24172         true
24173 }
24174 run_test 416 "transaction start failure won't cause system hung"
24175
24176 cleanup_417() {
24177         trap 0
24178         do_nodes $(comma_list $(mdts_nodes)) \
24179                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24180         do_nodes $(comma_list $(mdts_nodes)) \
24181                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24182         do_nodes $(comma_list $(mdts_nodes)) \
24183                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24184 }
24185
24186 test_417() {
24187         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24188         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24189                 skip "Need MDS version at least 2.11.56"
24190
24191         trap cleanup_417 RETURN EXIT
24192
24193         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24194         do_nodes $(comma_list $(mdts_nodes)) \
24195                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24196         $LFS migrate -m 0 $DIR/$tdir.1 &&
24197                 error "migrate dir $tdir.1 should fail"
24198
24199         do_nodes $(comma_list $(mdts_nodes)) \
24200                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24201         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24202                 error "create remote dir $tdir.2 should fail"
24203
24204         do_nodes $(comma_list $(mdts_nodes)) \
24205                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24206         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24207                 error "create striped dir $tdir.3 should fail"
24208         true
24209 }
24210 run_test 417 "disable remote dir, striped dir and dir migration"
24211
24212 # Checks that the outputs of df [-i] and lfs df [-i] match
24213 #
24214 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24215 check_lfs_df() {
24216         local dir=$2
24217         local inodes
24218         local df_out
24219         local lfs_df_out
24220         local count
24221         local passed=false
24222
24223         # blocks or inodes
24224         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24225
24226         for count in {1..100}; do
24227                 cancel_lru_locks
24228                 sync; sleep 0.2
24229
24230                 # read the lines of interest
24231                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24232                         error "df $inodes $dir | tail -n +2 failed"
24233                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24234                         error "lfs df $inodes $dir | grep summary: failed"
24235
24236                 # skip first substrings of each output as they are different
24237                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24238                 # compare the two outputs
24239                 passed=true
24240                 for i in {1..5}; do
24241                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24242                 done
24243                 $passed && break
24244         done
24245
24246         if ! $passed; then
24247                 df -P $inodes $dir
24248                 echo
24249                 lfs df $inodes $dir
24250                 error "df and lfs df $1 output mismatch: "      \
24251                       "df ${inodes}: ${df_out[*]}, "            \
24252                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24253         fi
24254 }
24255
24256 test_418() {
24257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24258
24259         local dir=$DIR/$tdir
24260         local numfiles=$((RANDOM % 4096 + 2))
24261         local numblocks=$((RANDOM % 256 + 1))
24262
24263         wait_delete_completed
24264         test_mkdir $dir
24265
24266         # check block output
24267         check_lfs_df blocks $dir
24268         # check inode output
24269         check_lfs_df inodes $dir
24270
24271         # create a single file and retest
24272         echo "Creating a single file and testing"
24273         createmany -o $dir/$tfile- 1 &>/dev/null ||
24274                 error "creating 1 file in $dir failed"
24275         check_lfs_df blocks $dir
24276         check_lfs_df inodes $dir
24277
24278         # create a random number of files
24279         echo "Creating $((numfiles - 1)) files and testing"
24280         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24281                 error "creating $((numfiles - 1)) files in $dir failed"
24282
24283         # write a random number of blocks to the first test file
24284         echo "Writing $numblocks 4K blocks and testing"
24285         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24286                 count=$numblocks &>/dev/null ||
24287                 error "dd to $dir/${tfile}-0 failed"
24288
24289         # retest
24290         check_lfs_df blocks $dir
24291         check_lfs_df inodes $dir
24292
24293         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24294                 error "unlinking $numfiles files in $dir failed"
24295 }
24296 run_test 418 "df and lfs df outputs match"
24297
24298 test_419()
24299 {
24300         local dir=$DIR/$tdir
24301
24302         mkdir -p $dir
24303         touch $dir/file
24304
24305         cancel_lru_locks mdc
24306
24307         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24308         $LCTL set_param fail_loc=0x1410
24309         cat $dir/file
24310         $LCTL set_param fail_loc=0
24311         rm -rf $dir
24312 }
24313 run_test 419 "Verify open file by name doesn't crash kernel"
24314
24315 test_420()
24316 {
24317         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24318                 skip "Need MDS version at least 2.12.53"
24319
24320         local SAVE_UMASK=$(umask)
24321         local dir=$DIR/$tdir
24322         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24323
24324         mkdir -p $dir
24325         umask 0000
24326         mkdir -m03777 $dir/testdir
24327         ls -dn $dir/testdir
24328         # Need to remove trailing '.' when SELinux is enabled
24329         local dirperms=$(ls -dn $dir/testdir |
24330                          awk '{ sub(/\.$/, "", $1); print $1}')
24331         [ $dirperms == "drwxrwsrwt" ] ||
24332                 error "incorrect perms on $dir/testdir"
24333
24334         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24335                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24336         ls -n $dir/testdir/testfile
24337         local fileperms=$(ls -n $dir/testdir/testfile |
24338                           awk '{ sub(/\.$/, "", $1); print $1}')
24339         [ $fileperms == "-rwxr-xr-x" ] ||
24340                 error "incorrect perms on $dir/testdir/testfile"
24341
24342         umask $SAVE_UMASK
24343 }
24344 run_test 420 "clear SGID bit on non-directories for non-members"
24345
24346 test_421a() {
24347         local cnt
24348         local fid1
24349         local fid2
24350
24351         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24352                 skip "Need MDS version at least 2.12.54"
24353
24354         test_mkdir $DIR/$tdir
24355         createmany -o $DIR/$tdir/f 3
24356         cnt=$(ls -1 $DIR/$tdir | wc -l)
24357         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24358
24359         fid1=$(lfs path2fid $DIR/$tdir/f1)
24360         fid2=$(lfs path2fid $DIR/$tdir/f2)
24361         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24362
24363         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24364         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24365
24366         cnt=$(ls -1 $DIR/$tdir | wc -l)
24367         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24368
24369         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24370         createmany -o $DIR/$tdir/f 3
24371         cnt=$(ls -1 $DIR/$tdir | wc -l)
24372         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24373
24374         fid1=$(lfs path2fid $DIR/$tdir/f1)
24375         fid2=$(lfs path2fid $DIR/$tdir/f2)
24376         echo "remove using fsname $FSNAME"
24377         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24378
24379         cnt=$(ls -1 $DIR/$tdir | wc -l)
24380         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24381 }
24382 run_test 421a "simple rm by fid"
24383
24384 test_421b() {
24385         local cnt
24386         local FID1
24387         local FID2
24388
24389         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24390                 skip "Need MDS version at least 2.12.54"
24391
24392         test_mkdir $DIR/$tdir
24393         createmany -o $DIR/$tdir/f 3
24394         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24395         MULTIPID=$!
24396
24397         FID1=$(lfs path2fid $DIR/$tdir/f1)
24398         FID2=$(lfs path2fid $DIR/$tdir/f2)
24399         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24400
24401         kill -USR1 $MULTIPID
24402         wait
24403
24404         cnt=$(ls $DIR/$tdir | wc -l)
24405         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24406 }
24407 run_test 421b "rm by fid on open file"
24408
24409 test_421c() {
24410         local cnt
24411         local FIDS
24412
24413         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24414                 skip "Need MDS version at least 2.12.54"
24415
24416         test_mkdir $DIR/$tdir
24417         createmany -o $DIR/$tdir/f 3
24418         touch $DIR/$tdir/$tfile
24419         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24420         cnt=$(ls -1 $DIR/$tdir | wc -l)
24421         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24422
24423         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24424         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24425
24426         cnt=$(ls $DIR/$tdir | wc -l)
24427         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24428 }
24429 run_test 421c "rm by fid against hardlinked files"
24430
24431 test_421d() {
24432         local cnt
24433         local FIDS
24434
24435         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24436                 skip "Need MDS version at least 2.12.54"
24437
24438         test_mkdir $DIR/$tdir
24439         createmany -o $DIR/$tdir/f 4097
24440         cnt=$(ls -1 $DIR/$tdir | wc -l)
24441         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24442
24443         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24444         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24445
24446         cnt=$(ls $DIR/$tdir | wc -l)
24447         rm -rf $DIR/$tdir
24448         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24449 }
24450 run_test 421d "rmfid en masse"
24451
24452 test_421e() {
24453         local cnt
24454         local FID
24455
24456         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24457         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24458                 skip "Need MDS version at least 2.12.54"
24459
24460         mkdir -p $DIR/$tdir
24461         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24462         createmany -o $DIR/$tdir/striped_dir/f 512
24463         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24464         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24465
24466         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24467                 sed "s/[/][^:]*://g")
24468         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24469
24470         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24471         rm -rf $DIR/$tdir
24472         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24473 }
24474 run_test 421e "rmfid in DNE"
24475
24476 test_421f() {
24477         local cnt
24478         local FID
24479
24480         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24481                 skip "Need MDS version at least 2.12.54"
24482
24483         test_mkdir $DIR/$tdir
24484         touch $DIR/$tdir/f
24485         cnt=$(ls -1 $DIR/$tdir | wc -l)
24486         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24487
24488         FID=$(lfs path2fid $DIR/$tdir/f)
24489         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24490         # rmfid should fail
24491         cnt=$(ls -1 $DIR/$tdir | wc -l)
24492         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24493
24494         chmod a+rw $DIR/$tdir
24495         ls -la $DIR/$tdir
24496         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24497         # rmfid should fail
24498         cnt=$(ls -1 $DIR/$tdir | wc -l)
24499         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24500
24501         rm -f $DIR/$tdir/f
24502         $RUNAS touch $DIR/$tdir/f
24503         FID=$(lfs path2fid $DIR/$tdir/f)
24504         echo "rmfid as root"
24505         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24506         cnt=$(ls -1 $DIR/$tdir | wc -l)
24507         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24508
24509         rm -f $DIR/$tdir/f
24510         $RUNAS touch $DIR/$tdir/f
24511         cnt=$(ls -1 $DIR/$tdir | wc -l)
24512         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24513         FID=$(lfs path2fid $DIR/$tdir/f)
24514         # rmfid w/o user_fid2path mount option should fail
24515         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24516         cnt=$(ls -1 $DIR/$tdir | wc -l)
24517         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24518
24519         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24520         stack_trap "rmdir $tmpdir"
24521         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24522                 error "failed to mount client'"
24523         stack_trap "umount_client $tmpdir"
24524
24525         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24526         # rmfid should succeed
24527         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24528         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24529
24530         # rmfid shouldn't allow to remove files due to dir's permission
24531         chmod a+rwx $tmpdir/$tdir
24532         touch $tmpdir/$tdir/f
24533         ls -la $tmpdir/$tdir
24534         FID=$(lfs path2fid $tmpdir/$tdir/f)
24535         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24536         return 0
24537 }
24538 run_test 421f "rmfid checks permissions"
24539
24540 test_421g() {
24541         local cnt
24542         local FIDS
24543
24544         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24545         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24546                 skip "Need MDS version at least 2.12.54"
24547
24548         mkdir -p $DIR/$tdir
24549         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24550         createmany -o $DIR/$tdir/striped_dir/f 512
24551         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24552         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24553
24554         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24555                 sed "s/[/][^:]*://g")
24556
24557         rm -f $DIR/$tdir/striped_dir/f1*
24558         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24559         removed=$((512 - cnt))
24560
24561         # few files have been just removed, so we expect
24562         # rmfid to fail on their fids
24563         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24564         [ $removed != $errors ] && error "$errors != $removed"
24565
24566         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24567         rm -rf $DIR/$tdir
24568         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24569 }
24570 run_test 421g "rmfid to return errors properly"
24571
24572 test_422() {
24573         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24574         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24575         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24576         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24577         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24578
24579         local amc=$(at_max_get client)
24580         local amo=$(at_max_get mds1)
24581         local timeout=`lctl get_param -n timeout`
24582
24583         at_max_set 0 client
24584         at_max_set 0 mds1
24585
24586 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24587         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24588                         fail_val=$(((2*timeout + 10)*1000))
24589         touch $DIR/$tdir/d3/file &
24590         sleep 2
24591 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24592         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24593                         fail_val=$((2*timeout + 5))
24594         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24595         local pid=$!
24596         sleep 1
24597         kill -9 $pid
24598         sleep $((2 * timeout))
24599         echo kill $pid
24600         kill -9 $pid
24601         lctl mark touch
24602         touch $DIR/$tdir/d2/file3
24603         touch $DIR/$tdir/d2/file4
24604         touch $DIR/$tdir/d2/file5
24605
24606         wait
24607         at_max_set $amc client
24608         at_max_set $amo mds1
24609
24610         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24611         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24612                 error "Watchdog is always throttled"
24613 }
24614 run_test 422 "kill a process with RPC in progress"
24615
24616 stat_test() {
24617     df -h $MOUNT &
24618     df -h $MOUNT &
24619     df -h $MOUNT &
24620     df -h $MOUNT &
24621     df -h $MOUNT &
24622     df -h $MOUNT &
24623 }
24624
24625 test_423() {
24626     local _stats
24627     # ensure statfs cache is expired
24628     sleep 2;
24629
24630     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24631     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24632
24633     return 0
24634 }
24635 run_test 423 "statfs should return a right data"
24636
24637 test_424() {
24638 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24639         $LCTL set_param fail_loc=0x80000522
24640         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24641         rm -f $DIR/$tfile
24642 }
24643 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24644
24645 test_425() {
24646         test_mkdir -c -1 $DIR/$tdir
24647         $LFS setstripe -c -1 $DIR/$tdir
24648
24649         lru_resize_disable "" 100
24650         stack_trap "lru_resize_enable" EXIT
24651
24652         sleep 5
24653
24654         for i in $(seq $((MDSCOUNT * 125))); do
24655                 local t=$DIR/$tdir/$tfile_$i
24656
24657                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24658                         error_noexit "Create file $t"
24659         done
24660         stack_trap "rm -rf $DIR/$tdir" EXIT
24661
24662         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24663                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24664                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24665
24666                 [ $lock_count -le $lru_size ] ||
24667                         error "osc lock count $lock_count > lru size $lru_size"
24668         done
24669
24670         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24671                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24672                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24673
24674                 [ $lock_count -le $lru_size ] ||
24675                         error "mdc lock count $lock_count > lru size $lru_size"
24676         done
24677 }
24678 run_test 425 "lock count should not exceed lru size"
24679
24680 test_426() {
24681         splice-test -r $DIR/$tfile
24682         splice-test -rd $DIR/$tfile
24683         splice-test $DIR/$tfile
24684         splice-test -d $DIR/$tfile
24685 }
24686 run_test 426 "splice test on Lustre"
24687
24688 test_427() {
24689         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24690         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24691                 skip "Need MDS version at least 2.12.4"
24692         local log
24693
24694         mkdir $DIR/$tdir
24695         mkdir $DIR/$tdir/1
24696         mkdir $DIR/$tdir/2
24697         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24698         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24699
24700         $LFS getdirstripe $DIR/$tdir/1/dir
24701
24702         #first setfattr for creating updatelog
24703         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24704
24705 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24706         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24707         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24708         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24709
24710         sleep 2
24711         fail mds2
24712         wait_recovery_complete mds2 $((2*TIMEOUT))
24713
24714         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24715         echo $log | grep "get update log failed" &&
24716                 error "update log corruption is detected" || true
24717 }
24718 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24719
24720 test_428() {
24721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24722         local cache_limit=$CACHE_MAX
24723
24724         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24725         $LCTL set_param -n llite.*.max_cached_mb=64
24726
24727         mkdir $DIR/$tdir
24728         $LFS setstripe -c 1 $DIR/$tdir
24729         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24730         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24731         #test write
24732         for f in $(seq 4); do
24733                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24734         done
24735         wait
24736
24737         cancel_lru_locks osc
24738         # Test read
24739         for f in $(seq 4); do
24740                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24741         done
24742         wait
24743 }
24744 run_test 428 "large block size IO should not hang"
24745
24746 test_429() { # LU-7915 / LU-10948
24747         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24748         local testfile=$DIR/$tfile
24749         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24750         local new_flag=1
24751         local first_rpc
24752         local second_rpc
24753         local third_rpc
24754
24755         $LCTL get_param $ll_opencache_threshold_count ||
24756                 skip "client does not have opencache parameter"
24757
24758         set_opencache $new_flag
24759         stack_trap "restore_opencache"
24760         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
24761                 error "enable opencache failed"
24762         touch $testfile
24763         # drop MDC DLM locks
24764         cancel_lru_locks mdc
24765         # clear MDC RPC stats counters
24766         $LCTL set_param $mdc_rpcstats=clear
24767
24768         # According to the current implementation, we need to run 3 times
24769         # open & close file to verify if opencache is enabled correctly.
24770         # 1st, RPCs are sent for lookup/open and open handle is released on
24771         #      close finally.
24772         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
24773         #      so open handle won't be released thereafter.
24774         # 3rd, No RPC is sent out.
24775         $MULTIOP $testfile oc || error "multiop failed"
24776         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24777         echo "1st: $first_rpc RPCs in flight"
24778
24779         $MULTIOP $testfile oc || error "multiop failed"
24780         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24781         echo "2nd: $second_rpc RPCs in flight"
24782
24783         $MULTIOP $testfile oc || error "multiop failed"
24784         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24785         echo "3rd: $third_rpc RPCs in flight"
24786
24787         #verify no MDC RPC is sent
24788         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
24789 }
24790 run_test 429 "verify if opencache flag on client side does work"
24791
24792 lseek_test_430() {
24793         local offset
24794         local file=$1
24795
24796         # data at [200K, 400K)
24797         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24798                 error "256K->512K dd fails"
24799         # data at [2M, 3M)
24800         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24801                 error "2M->3M dd fails"
24802         # data at [4M, 5M)
24803         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24804                 error "4M->5M dd fails"
24805         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24806         # start at first component hole #1
24807         printf "Seeking hole from 1000 ... "
24808         offset=$(lseek_test -l 1000 $file)
24809         echo $offset
24810         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24811         printf "Seeking data from 1000 ... "
24812         offset=$(lseek_test -d 1000 $file)
24813         echo $offset
24814         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24815
24816         # start at first component data block
24817         printf "Seeking hole from 300000 ... "
24818         offset=$(lseek_test -l 300000 $file)
24819         echo $offset
24820         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24821         printf "Seeking data from 300000 ... "
24822         offset=$(lseek_test -d 300000 $file)
24823         echo $offset
24824         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24825
24826         # start at the first component but beyond end of object size
24827         printf "Seeking hole from 1000000 ... "
24828         offset=$(lseek_test -l 1000000 $file)
24829         echo $offset
24830         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24831         printf "Seeking data from 1000000 ... "
24832         offset=$(lseek_test -d 1000000 $file)
24833         echo $offset
24834         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24835
24836         # start at second component stripe 2 (empty file)
24837         printf "Seeking hole from 1500000 ... "
24838         offset=$(lseek_test -l 1500000 $file)
24839         echo $offset
24840         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24841         printf "Seeking data from 1500000 ... "
24842         offset=$(lseek_test -d 1500000 $file)
24843         echo $offset
24844         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24845
24846         # start at second component stripe 1 (all data)
24847         printf "Seeking hole from 3000000 ... "
24848         offset=$(lseek_test -l 3000000 $file)
24849         echo $offset
24850         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24851         printf "Seeking data from 3000000 ... "
24852         offset=$(lseek_test -d 3000000 $file)
24853         echo $offset
24854         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24855
24856         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24857                 error "2nd dd fails"
24858         echo "Add data block at 640K...1280K"
24859
24860         # start at before new data block, in hole
24861         printf "Seeking hole from 600000 ... "
24862         offset=$(lseek_test -l 600000 $file)
24863         echo $offset
24864         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24865         printf "Seeking data from 600000 ... "
24866         offset=$(lseek_test -d 600000 $file)
24867         echo $offset
24868         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24869
24870         # start at the first component new data block
24871         printf "Seeking hole from 1000000 ... "
24872         offset=$(lseek_test -l 1000000 $file)
24873         echo $offset
24874         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24875         printf "Seeking data from 1000000 ... "
24876         offset=$(lseek_test -d 1000000 $file)
24877         echo $offset
24878         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24879
24880         # start at second component stripe 2, new data
24881         printf "Seeking hole from 1200000 ... "
24882         offset=$(lseek_test -l 1200000 $file)
24883         echo $offset
24884         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24885         printf "Seeking data from 1200000 ... "
24886         offset=$(lseek_test -d 1200000 $file)
24887         echo $offset
24888         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24889
24890         # start beyond file end
24891         printf "Using offset > filesize ... "
24892         lseek_test -l 4000000 $file && error "lseek should fail"
24893         printf "Using offset > filesize ... "
24894         lseek_test -d 4000000 $file && error "lseek should fail"
24895
24896         printf "Done\n\n"
24897 }
24898
24899 test_430a() {
24900         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24901                 skip "MDT does not support SEEK_HOLE"
24902
24903         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24904                 skip "OST does not support SEEK_HOLE"
24905
24906         local file=$DIR/$tdir/$tfile
24907
24908         mkdir -p $DIR/$tdir
24909
24910         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24911         # OST stripe #1 will have continuous data at [1M, 3M)
24912         # OST stripe #2 is empty
24913         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24914         lseek_test_430 $file
24915         rm $file
24916         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24917         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24918         lseek_test_430 $file
24919         rm $file
24920         $LFS setstripe -c2 -S 512K $file
24921         echo "Two stripes, stripe size 512K"
24922         lseek_test_430 $file
24923         rm $file
24924         # FLR with stale mirror
24925         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24926                        -N -c2 -S 1M $file
24927         echo "Mirrored file:"
24928         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24929         echo "Plain 2 stripes 1M"
24930         lseek_test_430 $file
24931         rm $file
24932 }
24933 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24934
24935 test_430b() {
24936         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24937                 skip "OST does not support SEEK_HOLE"
24938
24939         local offset
24940         local file=$DIR/$tdir/$tfile
24941
24942         mkdir -p $DIR/$tdir
24943         # Empty layout lseek should fail
24944         $MCREATE $file
24945         # seek from 0
24946         printf "Seeking hole from 0 ... "
24947         lseek_test -l 0 $file && error "lseek should fail"
24948         printf "Seeking data from 0 ... "
24949         lseek_test -d 0 $file && error "lseek should fail"
24950         rm $file
24951
24952         # 1M-hole file
24953         $LFS setstripe -E 1M -c2 -E eof $file
24954         $TRUNCATE $file 1048576
24955         printf "Seeking hole from 1000000 ... "
24956         offset=$(lseek_test -l 1000000 $file)
24957         echo $offset
24958         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24959         printf "Seeking data from 1000000 ... "
24960         lseek_test -d 1000000 $file && error "lseek should fail"
24961         rm $file
24962
24963         # full component followed by non-inited one
24964         $LFS setstripe -E 1M -c2 -E eof $file
24965         dd if=/dev/urandom of=$file bs=1M count=1
24966         printf "Seeking hole from 1000000 ... "
24967         offset=$(lseek_test -l 1000000 $file)
24968         echo $offset
24969         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24970         printf "Seeking hole from 1048576 ... "
24971         lseek_test -l 1048576 $file && error "lseek should fail"
24972         # init second component and truncate back
24973         echo "123" >> $file
24974         $TRUNCATE $file 1048576
24975         printf "Seeking hole from 1000000 ... "
24976         offset=$(lseek_test -l 1000000 $file)
24977         echo $offset
24978         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24979         printf "Seeking hole from 1048576 ... "
24980         lseek_test -l 1048576 $file && error "lseek should fail"
24981         # boundary checks for big values
24982         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24983         offset=$(lseek_test -d 0 $file.10g)
24984         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24985         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24986         offset=$(lseek_test -d 0 $file.100g)
24987         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24988         return 0
24989 }
24990 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24991
24992 test_430c() {
24993         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24994                 skip "OST does not support SEEK_HOLE"
24995
24996         local file=$DIR/$tdir/$tfile
24997         local start
24998
24999         mkdir -p $DIR/$tdir
25000         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25001
25002         # cp version 8.33+ prefers lseek over fiemap
25003         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25004                 start=$SECONDS
25005                 time cp $file /dev/null
25006                 (( SECONDS - start < 5 )) ||
25007                         error "cp: too long runtime $((SECONDS - start))"
25008
25009         fi
25010         # tar version 1.29+ supports SEEK_HOLE/DATA
25011         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25012                 start=$SECONDS
25013                 time tar cS $file - | cat > /dev/null
25014                 (( SECONDS - start < 5 )) ||
25015                         error "tar: too long runtime $((SECONDS - start))"
25016         fi
25017 }
25018 run_test 430c "lseek: external tools check"
25019
25020 test_431() { # LU-14187
25021         local file=$DIR/$tdir/$tfile
25022
25023         mkdir -p $DIR/$tdir
25024         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25025         dd if=/dev/urandom of=$file bs=4k count=1
25026         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25027         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25028         #define OBD_FAIL_OST_RESTART_IO 0x251
25029         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25030         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25031         cp $file $file.0
25032         cancel_lru_locks
25033         sync_all_data
25034         echo 3 > /proc/sys/vm/drop_caches
25035         diff  $file $file.0 || error "data diff"
25036 }
25037 run_test 431 "Restart transaction for IO"
25038
25039 prep_801() {
25040         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25041         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25042                 skip "Need server version at least 2.9.55"
25043
25044         start_full_debug_logging
25045 }
25046
25047 post_801() {
25048         stop_full_debug_logging
25049 }
25050
25051 barrier_stat() {
25052         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25053                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25054                            awk '/The barrier for/ { print $7 }')
25055                 echo $st
25056         else
25057                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25058                 echo \'$st\'
25059         fi
25060 }
25061
25062 barrier_expired() {
25063         local expired
25064
25065         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25066                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25067                           awk '/will be expired/ { print $7 }')
25068         else
25069                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25070         fi
25071
25072         echo $expired
25073 }
25074
25075 test_801a() {
25076         prep_801
25077
25078         echo "Start barrier_freeze at: $(date)"
25079         #define OBD_FAIL_BARRIER_DELAY          0x2202
25080         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25081         # Do not reduce barrier time - See LU-11873
25082         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25083
25084         sleep 2
25085         local b_status=$(barrier_stat)
25086         echo "Got barrier status at: $(date)"
25087         [ "$b_status" = "'freezing_p1'" ] ||
25088                 error "(1) unexpected barrier status $b_status"
25089
25090         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25091         wait
25092         b_status=$(barrier_stat)
25093         [ "$b_status" = "'frozen'" ] ||
25094                 error "(2) unexpected barrier status $b_status"
25095
25096         local expired=$(barrier_expired)
25097         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25098         sleep $((expired + 3))
25099
25100         b_status=$(barrier_stat)
25101         [ "$b_status" = "'expired'" ] ||
25102                 error "(3) unexpected barrier status $b_status"
25103
25104         # Do not reduce barrier time - See LU-11873
25105         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25106                 error "(4) fail to freeze barrier"
25107
25108         b_status=$(barrier_stat)
25109         [ "$b_status" = "'frozen'" ] ||
25110                 error "(5) unexpected barrier status $b_status"
25111
25112         echo "Start barrier_thaw at: $(date)"
25113         #define OBD_FAIL_BARRIER_DELAY          0x2202
25114         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25115         do_facet mgs $LCTL barrier_thaw $FSNAME &
25116
25117         sleep 2
25118         b_status=$(barrier_stat)
25119         echo "Got barrier status at: $(date)"
25120         [ "$b_status" = "'thawing'" ] ||
25121                 error "(6) unexpected barrier status $b_status"
25122
25123         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25124         wait
25125         b_status=$(barrier_stat)
25126         [ "$b_status" = "'thawed'" ] ||
25127                 error "(7) unexpected barrier status $b_status"
25128
25129         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25130         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25131         do_facet mgs $LCTL barrier_freeze $FSNAME
25132
25133         b_status=$(barrier_stat)
25134         [ "$b_status" = "'failed'" ] ||
25135                 error "(8) unexpected barrier status $b_status"
25136
25137         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25138         do_facet mgs $LCTL barrier_thaw $FSNAME
25139
25140         post_801
25141 }
25142 run_test 801a "write barrier user interfaces and stat machine"
25143
25144 test_801b() {
25145         prep_801
25146
25147         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25148         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25149         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25150         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25151         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25152
25153         cancel_lru_locks mdc
25154
25155         # 180 seconds should be long enough
25156         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25157
25158         local b_status=$(barrier_stat)
25159         [ "$b_status" = "'frozen'" ] ||
25160                 error "(6) unexpected barrier status $b_status"
25161
25162         mkdir $DIR/$tdir/d0/d10 &
25163         mkdir_pid=$!
25164
25165         touch $DIR/$tdir/d1/f13 &
25166         touch_pid=$!
25167
25168         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25169         ln_pid=$!
25170
25171         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25172         mv_pid=$!
25173
25174         rm -f $DIR/$tdir/d4/f12 &
25175         rm_pid=$!
25176
25177         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25178
25179         # To guarantee taht the 'stat' is not blocked
25180         b_status=$(barrier_stat)
25181         [ "$b_status" = "'frozen'" ] ||
25182                 error "(8) unexpected barrier status $b_status"
25183
25184         # let above commands to run at background
25185         sleep 5
25186
25187         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25188         ps -p $touch_pid || error "(10) touch should be blocked"
25189         ps -p $ln_pid || error "(11) link should be blocked"
25190         ps -p $mv_pid || error "(12) rename should be blocked"
25191         ps -p $rm_pid || error "(13) unlink should be blocked"
25192
25193         b_status=$(barrier_stat)
25194         [ "$b_status" = "'frozen'" ] ||
25195                 error "(14) unexpected barrier status $b_status"
25196
25197         do_facet mgs $LCTL barrier_thaw $FSNAME
25198         b_status=$(barrier_stat)
25199         [ "$b_status" = "'thawed'" ] ||
25200                 error "(15) unexpected barrier status $b_status"
25201
25202         wait $mkdir_pid || error "(16) mkdir should succeed"
25203         wait $touch_pid || error "(17) touch should succeed"
25204         wait $ln_pid || error "(18) link should succeed"
25205         wait $mv_pid || error "(19) rename should succeed"
25206         wait $rm_pid || error "(20) unlink should succeed"
25207
25208         post_801
25209 }
25210 run_test 801b "modification will be blocked by write barrier"
25211
25212 test_801c() {
25213         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25214
25215         prep_801
25216
25217         stop mds2 || error "(1) Fail to stop mds2"
25218
25219         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25220
25221         local b_status=$(barrier_stat)
25222         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25223                 do_facet mgs $LCTL barrier_thaw $FSNAME
25224                 error "(2) unexpected barrier status $b_status"
25225         }
25226
25227         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25228                 error "(3) Fail to rescan barrier bitmap"
25229
25230         # Do not reduce barrier time - See LU-11873
25231         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25232
25233         b_status=$(barrier_stat)
25234         [ "$b_status" = "'frozen'" ] ||
25235                 error "(4) unexpected barrier status $b_status"
25236
25237         do_facet mgs $LCTL barrier_thaw $FSNAME
25238         b_status=$(barrier_stat)
25239         [ "$b_status" = "'thawed'" ] ||
25240                 error "(5) unexpected barrier status $b_status"
25241
25242         local devname=$(mdsdevname 2)
25243
25244         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25245
25246         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25247                 error "(7) Fail to rescan barrier bitmap"
25248
25249         post_801
25250 }
25251 run_test 801c "rescan barrier bitmap"
25252
25253 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25254 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25255 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25256 saved_MOUNT_OPTS=$MOUNT_OPTS
25257
25258 cleanup_802a() {
25259         trap 0
25260
25261         stopall
25262         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25263         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25264         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25265         MOUNT_OPTS=$saved_MOUNT_OPTS
25266         setupall
25267 }
25268
25269 test_802a() {
25270         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25271         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25272         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25273                 skip "Need server version at least 2.9.55"
25274
25275         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25276
25277         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25278
25279         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25280                 error "(2) Fail to copy"
25281
25282         trap cleanup_802a EXIT
25283
25284         # sync by force before remount as readonly
25285         sync; sync_all_data; sleep 3; sync_all_data
25286
25287         stopall
25288
25289         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25290         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25291         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25292
25293         echo "Mount the server as read only"
25294         setupall server_only || error "(3) Fail to start servers"
25295
25296         echo "Mount client without ro should fail"
25297         mount_client $MOUNT &&
25298                 error "(4) Mount client without 'ro' should fail"
25299
25300         echo "Mount client with ro should succeed"
25301         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25302         mount_client $MOUNT ||
25303                 error "(5) Mount client with 'ro' should succeed"
25304
25305         echo "Modify should be refused"
25306         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25307
25308         echo "Read should be allowed"
25309         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25310                 error "(7) Read should succeed under ro mode"
25311
25312         cleanup_802a
25313 }
25314 run_test 802a "simulate readonly device"
25315
25316 test_802b() {
25317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25318         remote_mds_nodsh && skip "remote MDS with nodsh"
25319
25320         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25321                 skip "readonly option not available"
25322
25323         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25324
25325         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25326                 error "(2) Fail to copy"
25327
25328         # write back all cached data before setting MDT to readonly
25329         cancel_lru_locks
25330         sync_all_data
25331
25332         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25333         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25334
25335         echo "Modify should be refused"
25336         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25337
25338         echo "Read should be allowed"
25339         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25340                 error "(7) Read should succeed under ro mode"
25341
25342         # disable readonly
25343         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25344 }
25345 run_test 802b "be able to set MDTs to readonly"
25346
25347 test_803a() {
25348         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25349         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25350                 skip "MDS needs to be newer than 2.10.54"
25351
25352         mkdir -p $DIR/$tdir
25353         # Create some objects on all MDTs to trigger related logs objects
25354         for idx in $(seq $MDSCOUNT); do
25355                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25356                         $DIR/$tdir/dir${idx} ||
25357                         error "Fail to create $DIR/$tdir/dir${idx}"
25358         done
25359
25360         sync; sleep 3
25361         wait_delete_completed # ensure old test cleanups are finished
25362         echo "before create:"
25363         $LFS df -i $MOUNT
25364         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25365
25366         for i in {1..10}; do
25367                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25368                         error "Fail to create $DIR/$tdir/foo$i"
25369         done
25370
25371         sync; sleep 3
25372         echo "after create:"
25373         $LFS df -i $MOUNT
25374         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25375
25376         # allow for an llog to be cleaned up during the test
25377         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25378                 error "before ($before_used) + 10 > after ($after_used)"
25379
25380         for i in {1..10}; do
25381                 rm -rf $DIR/$tdir/foo$i ||
25382                         error "Fail to remove $DIR/$tdir/foo$i"
25383         done
25384
25385         sleep 3 # avoid MDT return cached statfs
25386         wait_delete_completed
25387         echo "after unlink:"
25388         $LFS df -i $MOUNT
25389         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25390
25391         # allow for an llog to be created during the test
25392         [ $after_used -le $((before_used + 1)) ] ||
25393                 error "after ($after_used) > before ($before_used) + 1"
25394 }
25395 run_test 803a "verify agent object for remote object"
25396
25397 test_803b() {
25398         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25399         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25400                 skip "MDS needs to be newer than 2.13.56"
25401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25402
25403         for i in $(seq 0 $((MDSCOUNT - 1))); do
25404                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25405         done
25406
25407         local before=0
25408         local after=0
25409
25410         local tmp
25411
25412         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25413         for i in $(seq 0 $((MDSCOUNT - 1))); do
25414                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25415                         awk '/getattr/ { print $2 }')
25416                 before=$((before + tmp))
25417         done
25418         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25419         for i in $(seq 0 $((MDSCOUNT - 1))); do
25420                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25421                         awk '/getattr/ { print $2 }')
25422                 after=$((after + tmp))
25423         done
25424
25425         [ $before -eq $after ] || error "getattr count $before != $after"
25426 }
25427 run_test 803b "remote object can getattr from cache"
25428
25429 test_804() {
25430         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25431         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25432                 skip "MDS needs to be newer than 2.10.54"
25433         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25434
25435         mkdir -p $DIR/$tdir
25436         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25437                 error "Fail to create $DIR/$tdir/dir0"
25438
25439         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25440         local dev=$(mdsdevname 2)
25441
25442         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25443                 grep ${fid} || error "NOT found agent entry for dir0"
25444
25445         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25446                 error "Fail to create $DIR/$tdir/dir1"
25447
25448         touch $DIR/$tdir/dir1/foo0 ||
25449                 error "Fail to create $DIR/$tdir/dir1/foo0"
25450         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25451         local rc=0
25452
25453         for idx in $(seq $MDSCOUNT); do
25454                 dev=$(mdsdevname $idx)
25455                 do_facet mds${idx} \
25456                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25457                         grep ${fid} && rc=$idx
25458         done
25459
25460         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25461                 error "Fail to rename foo0 to foo1"
25462         if [ $rc -eq 0 ]; then
25463                 for idx in $(seq $MDSCOUNT); do
25464                         dev=$(mdsdevname $idx)
25465                         do_facet mds${idx} \
25466                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25467                         grep ${fid} && rc=$idx
25468                 done
25469         fi
25470
25471         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25472                 error "Fail to rename foo1 to foo2"
25473         if [ $rc -eq 0 ]; then
25474                 for idx in $(seq $MDSCOUNT); do
25475                         dev=$(mdsdevname $idx)
25476                         do_facet mds${idx} \
25477                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25478                         grep ${fid} && rc=$idx
25479                 done
25480         fi
25481
25482         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25483
25484         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25485                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25486         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25487                 error "Fail to rename foo2 to foo0"
25488         unlink $DIR/$tdir/dir1/foo0 ||
25489                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25490         rm -rf $DIR/$tdir/dir0 ||
25491                 error "Fail to rm $DIR/$tdir/dir0"
25492
25493         for idx in $(seq $MDSCOUNT); do
25494                 dev=$(mdsdevname $idx)
25495                 rc=0
25496
25497                 stop mds${idx}
25498                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25499                         rc=$?
25500                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25501                         error "mount mds$idx failed"
25502                 df $MOUNT > /dev/null 2>&1
25503
25504                 # e2fsck should not return error
25505                 [ $rc -eq 0 ] ||
25506                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25507         done
25508 }
25509 run_test 804 "verify agent entry for remote entry"
25510
25511 cleanup_805() {
25512         do_facet $SINGLEMDS zfs set quota=$old $fsset
25513         unlinkmany $DIR/$tdir/f- 1000000
25514         trap 0
25515 }
25516
25517 test_805() {
25518         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25519         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25520         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25521                 skip "netfree not implemented before 0.7"
25522         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25523                 skip "Need MDS version at least 2.10.57"
25524
25525         local fsset
25526         local freekb
25527         local usedkb
25528         local old
25529         local quota
25530         local pref="osd-zfs.$FSNAME-MDT0000."
25531
25532         # limit available space on MDS dataset to meet nospace issue
25533         # quickly. then ZFS 0.7.2 can use reserved space if asked
25534         # properly (using netfree flag in osd_declare_destroy()
25535         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25536         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25537                 gawk '{print $3}')
25538         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25539         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25540         let "usedkb=usedkb-freekb"
25541         let "freekb=freekb/2"
25542         if let "freekb > 5000"; then
25543                 let "freekb=5000"
25544         fi
25545         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25546         trap cleanup_805 EXIT
25547         mkdir $DIR/$tdir
25548         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25549                 error "Can't set PFL layout"
25550         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25551         rm -rf $DIR/$tdir || error "not able to remove"
25552         do_facet $SINGLEMDS zfs set quota=$old $fsset
25553         trap 0
25554 }
25555 run_test 805 "ZFS can remove from full fs"
25556
25557 # Size-on-MDS test
25558 check_lsom_data()
25559 {
25560         local file=$1
25561         local expect=$(stat -c %s $file)
25562
25563         check_lsom_size $1 $expect
25564
25565         local blocks=$($LFS getsom -b $file)
25566         expect=$(stat -c %b $file)
25567         [[ $blocks == $expect ]] ||
25568                 error "$file expected blocks: $expect, got: $blocks"
25569 }
25570
25571 check_lsom_size()
25572 {
25573         local size
25574         local expect=$2
25575
25576         cancel_lru_locks mdc
25577
25578         size=$($LFS getsom -s $1)
25579         [[ $size == $expect ]] ||
25580                 error "$file expected size: $expect, got: $size"
25581 }
25582
25583 test_806() {
25584         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25585                 skip "Need MDS version at least 2.11.52"
25586
25587         local bs=1048576
25588
25589         touch $DIR/$tfile || error "touch $tfile failed"
25590
25591         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25592         save_lustre_params client "llite.*.xattr_cache" > $save
25593         lctl set_param llite.*.xattr_cache=0
25594         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25595
25596         # single-threaded write
25597         echo "Test SOM for single-threaded write"
25598         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25599                 error "write $tfile failed"
25600         check_lsom_size $DIR/$tfile $bs
25601
25602         local num=32
25603         local size=$(($num * $bs))
25604         local offset=0
25605         local i
25606
25607         echo "Test SOM for single client multi-threaded($num) write"
25608         $TRUNCATE $DIR/$tfile 0
25609         for ((i = 0; i < $num; i++)); do
25610                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25611                 local pids[$i]=$!
25612                 offset=$((offset + $bs))
25613         done
25614         for (( i=0; i < $num; i++ )); do
25615                 wait ${pids[$i]}
25616         done
25617         check_lsom_size $DIR/$tfile $size
25618
25619         $TRUNCATE $DIR/$tfile 0
25620         for ((i = 0; i < $num; i++)); do
25621                 offset=$((offset - $bs))
25622                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25623                 local pids[$i]=$!
25624         done
25625         for (( i=0; i < $num; i++ )); do
25626                 wait ${pids[$i]}
25627         done
25628         check_lsom_size $DIR/$tfile $size
25629
25630         # multi-client writes
25631         num=$(get_node_count ${CLIENTS//,/ })
25632         size=$(($num * $bs))
25633         offset=0
25634         i=0
25635
25636         echo "Test SOM for multi-client ($num) writes"
25637         $TRUNCATE $DIR/$tfile 0
25638         for client in ${CLIENTS//,/ }; do
25639                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25640                 local pids[$i]=$!
25641                 i=$((i + 1))
25642                 offset=$((offset + $bs))
25643         done
25644         for (( i=0; i < $num; i++ )); do
25645                 wait ${pids[$i]}
25646         done
25647         check_lsom_size $DIR/$tfile $offset
25648
25649         i=0
25650         $TRUNCATE $DIR/$tfile 0
25651         for client in ${CLIENTS//,/ }; do
25652                 offset=$((offset - $bs))
25653                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25654                 local pids[$i]=$!
25655                 i=$((i + 1))
25656         done
25657         for (( i=0; i < $num; i++ )); do
25658                 wait ${pids[$i]}
25659         done
25660         check_lsom_size $DIR/$tfile $size
25661
25662         # verify truncate
25663         echo "Test SOM for truncate"
25664         $TRUNCATE $DIR/$tfile 1048576
25665         check_lsom_size $DIR/$tfile 1048576
25666         $TRUNCATE $DIR/$tfile 1234
25667         check_lsom_size $DIR/$tfile 1234
25668
25669         # verify SOM blocks count
25670         echo "Verify SOM block count"
25671         $TRUNCATE $DIR/$tfile 0
25672         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25673                 error "failed to write file $tfile"
25674         check_lsom_data $DIR/$tfile
25675 }
25676 run_test 806 "Verify Lazy Size on MDS"
25677
25678 test_807() {
25679         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25680         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25681                 skip "Need MDS version at least 2.11.52"
25682
25683         # Registration step
25684         changelog_register || error "changelog_register failed"
25685         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25686         changelog_users $SINGLEMDS | grep -q $cl_user ||
25687                 error "User $cl_user not found in changelog_users"
25688
25689         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25690         save_lustre_params client "llite.*.xattr_cache" > $save
25691         lctl set_param llite.*.xattr_cache=0
25692         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25693
25694         rm -rf $DIR/$tdir || error "rm $tdir failed"
25695         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25696         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25697         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25698         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25699                 error "truncate $tdir/trunc failed"
25700
25701         local bs=1048576
25702         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25703                 error "write $tfile failed"
25704
25705         # multi-client wirtes
25706         local num=$(get_node_count ${CLIENTS//,/ })
25707         local offset=0
25708         local i=0
25709
25710         echo "Test SOM for multi-client ($num) writes"
25711         touch $DIR/$tfile || error "touch $tfile failed"
25712         $TRUNCATE $DIR/$tfile 0
25713         for client in ${CLIENTS//,/ }; do
25714                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25715                 local pids[$i]=$!
25716                 i=$((i + 1))
25717                 offset=$((offset + $bs))
25718         done
25719         for (( i=0; i < $num; i++ )); do
25720                 wait ${pids[$i]}
25721         done
25722
25723         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25724         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25725         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25726         check_lsom_data $DIR/$tdir/trunc
25727         check_lsom_data $DIR/$tdir/single_dd
25728         check_lsom_data $DIR/$tfile
25729
25730         rm -rf $DIR/$tdir
25731         # Deregistration step
25732         changelog_deregister || error "changelog_deregister failed"
25733 }
25734 run_test 807 "verify LSOM syncing tool"
25735
25736 check_som_nologged()
25737 {
25738         local lines=$($LFS changelog $FSNAME-MDT0000 |
25739                 grep 'x=trusted.som' | wc -l)
25740         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25741 }
25742
25743 test_808() {
25744         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25745                 skip "Need MDS version at least 2.11.55"
25746
25747         # Registration step
25748         changelog_register || error "changelog_register failed"
25749
25750         touch $DIR/$tfile || error "touch $tfile failed"
25751         check_som_nologged
25752
25753         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25754                 error "write $tfile failed"
25755         check_som_nologged
25756
25757         $TRUNCATE $DIR/$tfile 1234
25758         check_som_nologged
25759
25760         $TRUNCATE $DIR/$tfile 1048576
25761         check_som_nologged
25762
25763         # Deregistration step
25764         changelog_deregister || error "changelog_deregister failed"
25765 }
25766 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25767
25768 check_som_nodata()
25769 {
25770         $LFS getsom $1
25771         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25772 }
25773
25774 test_809() {
25775         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25776                 skip "Need MDS version at least 2.11.56"
25777
25778         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25779                 error "failed to create DoM-only file $DIR/$tfile"
25780         touch $DIR/$tfile || error "touch $tfile failed"
25781         check_som_nodata $DIR/$tfile
25782
25783         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25784                 error "write $tfile failed"
25785         check_som_nodata $DIR/$tfile
25786
25787         $TRUNCATE $DIR/$tfile 1234
25788         check_som_nodata $DIR/$tfile
25789
25790         $TRUNCATE $DIR/$tfile 4097
25791         check_som_nodata $DIR/$file
25792 }
25793 run_test 809 "Verify no SOM xattr store for DoM-only files"
25794
25795 test_810() {
25796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25797         $GSS && skip_env "could not run with gss"
25798         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25799                 skip "OST < 2.12.58 doesn't align checksum"
25800
25801         set_checksums 1
25802         stack_trap "set_checksums $ORIG_CSUM" EXIT
25803         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25804
25805         local csum
25806         local before
25807         local after
25808         for csum in $CKSUM_TYPES; do
25809                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25810                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25811                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25812                         eval set -- $i
25813                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25814                         before=$(md5sum $DIR/$tfile)
25815                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25816                         after=$(md5sum $DIR/$tfile)
25817                         [ "$before" == "$after" ] ||
25818                                 error "$csum: $before != $after bs=$1 seek=$2"
25819                 done
25820         done
25821 }
25822 run_test 810 "partial page writes on ZFS (LU-11663)"
25823
25824 test_812a() {
25825         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25826                 skip "OST < 2.12.51 doesn't support this fail_loc"
25827
25828         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25829         # ensure ost1 is connected
25830         stat $DIR/$tfile >/dev/null || error "can't stat"
25831         wait_osc_import_state client ost1 FULL
25832         # no locks, no reqs to let the connection idle
25833         cancel_lru_locks osc
25834
25835         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25836 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25837         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25838         wait_osc_import_state client ost1 CONNECTING
25839         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25840
25841         stat $DIR/$tfile >/dev/null || error "can't stat file"
25842 }
25843 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25844
25845 test_812b() { # LU-12378
25846         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25847                 skip "OST < 2.12.51 doesn't support this fail_loc"
25848
25849         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25850         # ensure ost1 is connected
25851         stat $DIR/$tfile >/dev/null || error "can't stat"
25852         wait_osc_import_state client ost1 FULL
25853         # no locks, no reqs to let the connection idle
25854         cancel_lru_locks osc
25855
25856         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25857 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25858         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25859         wait_osc_import_state client ost1 CONNECTING
25860         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25861
25862         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25863         wait_osc_import_state client ost1 IDLE
25864 }
25865 run_test 812b "do not drop no resend request for idle connect"
25866
25867 test_812c() {
25868         local old
25869
25870         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
25871
25872         $LFS setstripe -c 1 -o 0 $DIR/$tfile
25873         $LFS getstripe $DIR/$tfile
25874         $LCTL set_param osc.*.idle_timeout=10
25875         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
25876         # ensure ost1 is connected
25877         stat $DIR/$tfile >/dev/null || error "can't stat"
25878         wait_osc_import_state client ost1 FULL
25879         # no locks, no reqs to let the connection idle
25880         cancel_lru_locks osc
25881
25882 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
25883         $LCTL set_param fail_loc=0x80000533
25884         sleep 15
25885         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
25886 }
25887 run_test 812c "idle import vs lock enqueue race"
25888
25889 test_813() {
25890         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25891         [ -z "$file_heat_sav" ] && skip "no file heat support"
25892
25893         local readsample
25894         local writesample
25895         local readbyte
25896         local writebyte
25897         local readsample1
25898         local writesample1
25899         local readbyte1
25900         local writebyte1
25901
25902         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25903         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25904
25905         $LCTL set_param -n llite.*.file_heat=1
25906         echo "Turn on file heat"
25907         echo "Period second: $period_second, Decay percentage: $decay_pct"
25908
25909         echo "QQQQ" > $DIR/$tfile
25910         echo "QQQQ" > $DIR/$tfile
25911         echo "QQQQ" > $DIR/$tfile
25912         cat $DIR/$tfile > /dev/null
25913         cat $DIR/$tfile > /dev/null
25914         cat $DIR/$tfile > /dev/null
25915         cat $DIR/$tfile > /dev/null
25916
25917         local out=$($LFS heat_get $DIR/$tfile)
25918
25919         $LFS heat_get $DIR/$tfile
25920         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25921         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25922         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25923         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25924
25925         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25926         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25927         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25928         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25929
25930         sleep $((period_second + 3))
25931         echo "Sleep $((period_second + 3)) seconds..."
25932         # The recursion formula to calculate the heat of the file f is as
25933         # follow:
25934         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25935         # Where Hi is the heat value in the period between time points i*I and
25936         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25937         # to the weight of Ci.
25938         out=$($LFS heat_get $DIR/$tfile)
25939         $LFS heat_get $DIR/$tfile
25940         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25941         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25942         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25943         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25944
25945         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25946                 error "read sample ($readsample) is wrong"
25947         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25948                 error "write sample ($writesample) is wrong"
25949         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25950                 error "read bytes ($readbyte) is wrong"
25951         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25952                 error "write bytes ($writebyte) is wrong"
25953
25954         echo "QQQQ" > $DIR/$tfile
25955         echo "QQQQ" > $DIR/$tfile
25956         echo "QQQQ" > $DIR/$tfile
25957         cat $DIR/$tfile > /dev/null
25958         cat $DIR/$tfile > /dev/null
25959         cat $DIR/$tfile > /dev/null
25960         cat $DIR/$tfile > /dev/null
25961
25962         sleep $((period_second + 3))
25963         echo "Sleep $((period_second + 3)) seconds..."
25964
25965         out=$($LFS heat_get $DIR/$tfile)
25966         $LFS heat_get $DIR/$tfile
25967         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25968         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25969         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25970         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25971
25972         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25973                 4 * $decay_pct) / 100") -eq 1 ] ||
25974                 error "read sample ($readsample1) is wrong"
25975         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25976                 3 * $decay_pct) / 100") -eq 1 ] ||
25977                 error "write sample ($writesample1) is wrong"
25978         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25979                 20 * $decay_pct) / 100") -eq 1 ] ||
25980                 error "read bytes ($readbyte1) is wrong"
25981         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25982                 15 * $decay_pct) / 100") -eq 1 ] ||
25983                 error "write bytes ($writebyte1) is wrong"
25984
25985         echo "Turn off file heat for the file $DIR/$tfile"
25986         $LFS heat_set -o $DIR/$tfile
25987
25988         echo "QQQQ" > $DIR/$tfile
25989         echo "QQQQ" > $DIR/$tfile
25990         echo "QQQQ" > $DIR/$tfile
25991         cat $DIR/$tfile > /dev/null
25992         cat $DIR/$tfile > /dev/null
25993         cat $DIR/$tfile > /dev/null
25994         cat $DIR/$tfile > /dev/null
25995
25996         out=$($LFS heat_get $DIR/$tfile)
25997         $LFS heat_get $DIR/$tfile
25998         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25999         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26000         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26001         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26002
26003         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26004         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26005         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26006         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26007
26008         echo "Trun on file heat for the file $DIR/$tfile"
26009         $LFS heat_set -O $DIR/$tfile
26010
26011         echo "QQQQ" > $DIR/$tfile
26012         echo "QQQQ" > $DIR/$tfile
26013         echo "QQQQ" > $DIR/$tfile
26014         cat $DIR/$tfile > /dev/null
26015         cat $DIR/$tfile > /dev/null
26016         cat $DIR/$tfile > /dev/null
26017         cat $DIR/$tfile > /dev/null
26018
26019         out=$($LFS heat_get $DIR/$tfile)
26020         $LFS heat_get $DIR/$tfile
26021         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26022         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26023         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26024         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26025
26026         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26027         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26028         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26029         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26030
26031         $LFS heat_set -c $DIR/$tfile
26032         $LCTL set_param -n llite.*.file_heat=0
26033         echo "Turn off file heat support for the Lustre filesystem"
26034
26035         echo "QQQQ" > $DIR/$tfile
26036         echo "QQQQ" > $DIR/$tfile
26037         echo "QQQQ" > $DIR/$tfile
26038         cat $DIR/$tfile > /dev/null
26039         cat $DIR/$tfile > /dev/null
26040         cat $DIR/$tfile > /dev/null
26041         cat $DIR/$tfile > /dev/null
26042
26043         out=$($LFS heat_get $DIR/$tfile)
26044         $LFS heat_get $DIR/$tfile
26045         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26046         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26047         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26048         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26049
26050         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26051         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26052         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26053         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26054
26055         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26056         rm -f $DIR/$tfile
26057 }
26058 run_test 813 "File heat verfication"
26059
26060 test_814()
26061 {
26062         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26063         echo -n y >> $DIR/$tfile
26064         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26065         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26066 }
26067 run_test 814 "sparse cp works as expected (LU-12361)"
26068
26069 test_815()
26070 {
26071         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26072         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26073 }
26074 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26075
26076 test_816() {
26077         local ost1_imp=$(get_osc_import_name client ost1)
26078         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26079                          cut -d'.' -f2)
26080
26081         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26082         # ensure ost1 is connected
26083
26084         stat $DIR/$tfile >/dev/null || error "can't stat"
26085         wait_osc_import_state client ost1 FULL
26086         # no locks, no reqs to let the connection idle
26087         cancel_lru_locks osc
26088         lru_resize_disable osc
26089         local before
26090         local now
26091         before=$($LCTL get_param -n \
26092                  ldlm.namespaces.$imp_name.lru_size)
26093
26094         wait_osc_import_state client ost1 IDLE
26095         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26096         now=$($LCTL get_param -n \
26097               ldlm.namespaces.$imp_name.lru_size)
26098         [ $before == $now ] || error "lru_size changed $before != $now"
26099 }
26100 run_test 816 "do not reset lru_resize on idle reconnect"
26101
26102 cleanup_817() {
26103         umount $tmpdir
26104         exportfs -u localhost:$DIR/nfsexp
26105         rm -rf $DIR/nfsexp
26106 }
26107
26108 test_817() {
26109         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26110
26111         mkdir -p $DIR/nfsexp
26112         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26113                 error "failed to export nfs"
26114
26115         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26116         stack_trap cleanup_817 EXIT
26117
26118         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26119                 error "failed to mount nfs to $tmpdir"
26120
26121         cp /bin/true $tmpdir
26122         $DIR/nfsexp/true || error "failed to execute 'true' command"
26123 }
26124 run_test 817 "nfsd won't cache write lock for exec file"
26125
26126 test_818() {
26127         mkdir $DIR/$tdir
26128         $LFS setstripe -c1 -i0 $DIR/$tfile
26129         $LFS setstripe -c1 -i1 $DIR/$tfile
26130         stop $SINGLEMDS
26131         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26132         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26133         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26134                 error "start $SINGLEMDS failed"
26135         rm -rf $DIR/$tdir
26136 }
26137 run_test 818 "unlink with failed llog"
26138
26139 test_819a() {
26140         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26141         cancel_lru_locks osc
26142         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26143         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26144         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26145         rm -f $TDIR/$tfile
26146 }
26147 run_test 819a "too big niobuf in read"
26148
26149 test_819b() {
26150         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26151         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26152         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26153         cancel_lru_locks osc
26154         sleep 1
26155         rm -f $TDIR/$tfile
26156 }
26157 run_test 819b "too big niobuf in write"
26158
26159
26160 function test_820_start_ost() {
26161         sleep 5
26162
26163         for num in $(seq $OSTCOUNT); do
26164                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26165         done
26166 }
26167
26168 test_820() {
26169         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26170
26171         mkdir $DIR/$tdir
26172         umount_client $MOUNT || error "umount failed"
26173         for num in $(seq $OSTCOUNT); do
26174                 stop ost$num
26175         done
26176
26177         # mount client with no active OSTs
26178         # so that the client can't initialize max LOV EA size
26179         # from OSC notifications
26180         mount_client $MOUNT || error "mount failed"
26181         # delay OST starting to keep this 0 max EA size for a while
26182         test_820_start_ost &
26183
26184         # create a directory on MDS2
26185         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26186                 error "Failed to create directory"
26187         # open intent should update default EA size
26188         # see mdc_update_max_ea_from_body()
26189         # notice this is the very first RPC to MDS2
26190         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26191         ret=$?
26192         echo $out
26193         # With SSK, this situation can lead to -EPERM being returned.
26194         # In that case, simply retry.
26195         if [ $ret -ne 0 ] && $SHARED_KEY; then
26196                 if echo "$out" | grep -q "not permitted"; then
26197                         cp /etc/services $DIR/$tdir/mds2
26198                         ret=$?
26199                 fi
26200         fi
26201         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26202 }
26203 run_test 820 "update max EA from open intent"
26204
26205 test_822() {
26206         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26207
26208         save_lustre_params mds1 \
26209                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26210         do_facet $SINGLEMDS "$LCTL set_param -n \
26211                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26212         do_facet $SINGLEMDS "$LCTL set_param -n \
26213                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26214
26215         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26216         local maxage=$(do_facet mds1 $LCTL get_param -n \
26217                        osp.$FSNAME-OST0000*MDT0000.maxage)
26218         sleep $((maxage + 1))
26219
26220         #define OBD_FAIL_NET_ERROR_RPC          0x532
26221         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26222
26223         stack_trap "restore_lustre_params < $p; rm $p"
26224
26225         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26226                       osp.$FSNAME-OST0000*MDT0000.create_count")
26227         for i in $(seq 1 $count); do
26228                 touch $DIR/$tfile.${i} || error "touch failed"
26229         done
26230 }
26231 run_test 822 "test precreate failure"
26232
26233 #
26234 # tests that do cleanup/setup should be run at the end
26235 #
26236
26237 test_900() {
26238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26239         local ls
26240
26241         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26242         $LCTL set_param fail_loc=0x903
26243
26244         cancel_lru_locks MGC
26245
26246         FAIL_ON_ERROR=true cleanup
26247         FAIL_ON_ERROR=true setup
26248 }
26249 run_test 900 "umount should not race with any mgc requeue thread"
26250
26251 # LUS-6253/LU-11185
26252 test_901() {
26253         local oldc
26254         local newc
26255         local olds
26256         local news
26257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26258
26259         # some get_param have a bug to handle dot in param name
26260         cancel_lru_locks MGC
26261         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26262         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26263         umount_client $MOUNT || error "umount failed"
26264         mount_client $MOUNT || error "mount failed"
26265         cancel_lru_locks MGC
26266         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26267         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26268
26269         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26270         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26271
26272         return 0
26273 }
26274 run_test 901 "don't leak a mgc lock on client umount"
26275
26276 # LU-13377
26277 test_902() {
26278         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26279                 skip "client does not have LU-13377 fix"
26280         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26281         $LCTL set_param fail_loc=0x1415
26282         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26283         cancel_lru_locks osc
26284         rm -f $DIR/$tfile
26285 }
26286 run_test 902 "test short write doesn't hang lustre"
26287
26288 complete $SECONDS
26289 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26290 check_and_cleanup_lustre
26291 if [ "$I_MOUNTED" != "yes" ]; then
26292         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26293 fi
26294 exit_status